修改后台权限
This commit is contained in:
228
node_modules/router/HISTORY.md
generated
vendored
Normal file
228
node_modules/router/HISTORY.md
generated
vendored
Normal file
@@ -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
|
||||
23
node_modules/router/LICENSE
generated
vendored
Normal file
23
node_modules/router/LICENSE
generated
vendored
Normal file
@@ -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.
|
||||
416
node_modules/router/README.md
generated
vendored
Normal file
416
node_modules/router/README.md
generated
vendored
Normal file
@@ -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
|
||||
748
node_modules/router/index.js
generated
vendored
Normal file
748
node_modules/router/index.js
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
247
node_modules/router/lib/layer.js
generated
vendored
Normal file
247
node_modules/router/lib/layer.js
generated
vendored
Normal file
@@ -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, '')
|
||||
}
|
||||
242
node_modules/router/lib/route.js
generated
vendored
Normal file
242
node_modules/router/lib/route.js
generated
vendored
Normal file
@@ -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
|
||||
}
|
||||
})
|
||||
21
node_modules/router/node_modules/path-to-regexp/LICENSE
generated
vendored
Normal file
21
node_modules/router/node_modules/path-to-regexp/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.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.
|
||||
224
node_modules/router/node_modules/path-to-regexp/Readme.md
generated
vendored
Normal file
224
node_modules/router/node_modules/path-to-regexp/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
# Path-to-RegExp
|
||||
|
||||
> Turn a path string such as `/user/:name` into a regular expression.
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![NPM downloads][downloads-image]][downloads-url]
|
||||
[![Build status][build-image]][build-url]
|
||||
[![Build coverage][coverage-image]][coverage-url]
|
||||
[![License][license-image]][license-url]
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install path-to-regexp --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const {
|
||||
match,
|
||||
pathToRegexp,
|
||||
compile,
|
||||
parse,
|
||||
stringify,
|
||||
} = require("path-to-regexp");
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
Parameters match arbitrary strings in a path by matching up to the end of the segment, or up to any proceeding tokens. They are defined by prefixing a colon to the parameter name (`:foo`). Parameter names can use any valid JavaScript identifier, or be double quoted to use other characters (`:"param-name"`).
|
||||
|
||||
```js
|
||||
const fn = match("/:foo/:bar");
|
||||
|
||||
fn("/test/route");
|
||||
//=> { path: '/test/route', params: { foo: 'test', bar: 'route' } }
|
||||
```
|
||||
|
||||
### Wildcard
|
||||
|
||||
Wildcard parameters match one or more characters across multiple segments. They are defined the same way as regular parameters, but are prefixed with an asterisk (`*foo`).
|
||||
|
||||
```js
|
||||
const fn = match("/*splat");
|
||||
|
||||
fn("/bar/baz");
|
||||
//=> { path: '/bar/baz', params: { splat: [ 'bar', 'baz' ] } }
|
||||
```
|
||||
|
||||
### Optional
|
||||
|
||||
Braces can be used to define parts of the path that are optional.
|
||||
|
||||
```js
|
||||
const fn = match("/users{/:id}/delete");
|
||||
|
||||
fn("/users/delete");
|
||||
//=> { path: '/users/delete', params: {} }
|
||||
|
||||
fn("/users/123/delete");
|
||||
//=> { path: '/users/123/delete', params: { id: '123' } }
|
||||
```
|
||||
|
||||
## Match
|
||||
|
||||
The `match` function returns a function for matching strings against a path:
|
||||
|
||||
- **path** String, `TokenData` object, or array of strings and `TokenData` objects.
|
||||
- **options** _(optional)_ (Extends [pathToRegexp](#pathToRegexp) options)
|
||||
- **decode** Function for decoding strings to params, or `false` to disable all processing. (default: `decodeURIComponent`)
|
||||
|
||||
```js
|
||||
const fn = match("/foo/:bar");
|
||||
```
|
||||
|
||||
**Please note:** `path-to-regexp` is intended for ordered data (e.g. paths, hosts). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc).
|
||||
|
||||
## PathToRegexp
|
||||
|
||||
The `pathToRegexp` function returns the `regexp` for matching strings against paths, and an array of `keys` for understanding the `RegExp#exec` matches.
|
||||
|
||||
- **path** String, `TokenData` object, or array of strings and `TokenData` objects.
|
||||
- **options** _(optional)_ (See [parse](#parse) for more options)
|
||||
- **sensitive** Regexp will be case sensitive. (default: `false`)
|
||||
- **end** Validate the match reaches the end of the string. (default: `true`)
|
||||
- **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
|
||||
- **trailing** Allows optional trailing delimiter to match. (default: `true`)
|
||||
|
||||
```js
|
||||
const { regexp, keys } = pathToRegexp("/foo/:bar");
|
||||
|
||||
regexp.exec("/foo/123"); //=> ["/foo/123", "123"]
|
||||
```
|
||||
|
||||
## Compile ("Reverse" Path-To-RegExp)
|
||||
|
||||
The `compile` function will return a function for transforming parameters into a valid path:
|
||||
|
||||
- **path** A string or `TokenData` object.
|
||||
- **options** (See [parse](#parse) for more options)
|
||||
- **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
|
||||
- **encode** Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
|
||||
|
||||
```js
|
||||
const toPath = compile("/user/:id");
|
||||
|
||||
toPath({ id: "name" }); //=> "/user/name"
|
||||
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
|
||||
|
||||
const toPathRepeated = compile("/*segment");
|
||||
|
||||
toPathRepeated({ segment: ["foo"] }); //=> "/foo"
|
||||
toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"
|
||||
|
||||
// When disabling `encode`, you need to make sure inputs are encoded correctly. No arrays are accepted.
|
||||
const toPathRaw = compile("/user/:id", { encode: false });
|
||||
|
||||
toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
|
||||
```
|
||||
|
||||
## Stringify
|
||||
|
||||
Transform a `TokenData` object to a Path-to-RegExp string.
|
||||
|
||||
- **data** A `TokenData` object.
|
||||
|
||||
```js
|
||||
const data = {
|
||||
tokens: [
|
||||
{ type: "text", value: "/" },
|
||||
{ type: "param", name: "foo" },
|
||||
],
|
||||
};
|
||||
|
||||
const path = stringify(data); //=> "/:foo"
|
||||
```
|
||||
|
||||
## Developers
|
||||
|
||||
- If you are rewriting paths with match and compile, consider using `encode: false` and `decode: false` to keep raw paths passed around.
|
||||
- To ensure matches work on paths containing characters usually encoded, such as emoji, consider using [encodeurl](https://github.com/pillarjs/encodeurl) for `encodePath`.
|
||||
|
||||
### Parse
|
||||
|
||||
The `parse` function accepts a string and returns `TokenData`, which can be used with `match` and `compile`.
|
||||
|
||||
- **path** A string.
|
||||
- **options** _(optional)_
|
||||
- **encodePath** A function for encoding input strings. (default: `x => x`, recommended: [`encodeurl`](https://github.com/pillarjs/encodeurl))
|
||||
|
||||
### Tokens
|
||||
|
||||
`TokenData` has two properties:
|
||||
|
||||
- **tokens** A sequence of tokens, currently of types `text`, `parameter`, `wildcard`, or `group`.
|
||||
- **originalPath** The original path used with `parse`, shown in error messages to assist debugging.
|
||||
|
||||
### Custom path
|
||||
|
||||
In some applications you may not be able to use the `path-to-regexp` syntax, but you still want to use this library for `match` and `compile`. For example:
|
||||
|
||||
```js
|
||||
import { match } from "path-to-regexp";
|
||||
|
||||
const tokens = [
|
||||
{ type: "text", value: "/" },
|
||||
{ type: "parameter", name: "foo" },
|
||||
];
|
||||
const originalPath = "/[foo]"; // To help debug error messages.
|
||||
const path = { tokens, originalPath };
|
||||
const fn = match(path);
|
||||
|
||||
fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } }
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
An effort has been made to ensure ambiguous paths from previous releases throw an error. This means you might be seeing an error when things worked before.
|
||||
|
||||
### Missing parameter name
|
||||
|
||||
Parameter names must be provided after `:` or `*`, for example `/*path`. They can be valid JavaScript identifiers (e.g. `:myName`) or JSON strings (`:"my-name"`).
|
||||
|
||||
### Unexpected `?` or `+`
|
||||
|
||||
In past releases, `?`, `*`, and `+` were used to denote optional or repeating parameters. As an alternative, try these:
|
||||
|
||||
- For optional (`?`), use braces: `/file{.:ext}`.
|
||||
- For one or more (`+`), use a wildcard: `/*path`.
|
||||
- For zero or more (`*`), use both: `/files{/*path}`.
|
||||
|
||||
### Unexpected `(`, `)`, `[`, `]`, etc.
|
||||
|
||||
Previous versions of Path-to-RegExp used these for RegExp features. This version no longer supports them so they've been reserved to avoid ambiguity. To match these characters literally, escape them with a backslash, e.g. `"\\("`.
|
||||
|
||||
### Unterminated quote
|
||||
|
||||
Parameter names can be wrapped in double quote characters, and this error means you forgot to close the quote character. For example, `:"foo`.
|
||||
|
||||
### Express <= 4.x
|
||||
|
||||
Path-To-RegExp breaks compatibility with Express <= `4.x` in the following ways:
|
||||
|
||||
- The wildcard `*` must have a name and matches the behavior of parameters `:`.
|
||||
- The optional character `?` is no longer supported, use braces instead: `/:file{.:ext}`.
|
||||
- Regexp characters are not supported.
|
||||
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`).
|
||||
- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/path-to-regexp
|
||||
[npm-url]: https://npmjs.org/package/path-to-regexp
|
||||
[downloads-image]: https://img.shields.io/npm/dm/path-to-regexp
|
||||
[downloads-url]: https://npmjs.org/package/path-to-regexp
|
||||
[build-image]: https://img.shields.io/github/actions/workflow/status/pillarjs/path-to-regexp/ci.yml?branch=master
|
||||
[build-url]: https://github.com/pillarjs/path-to-regexp/actions/workflows/ci.yml?query=branch%3Amaster
|
||||
[coverage-image]: https://img.shields.io/codecov/c/gh/pillarjs/path-to-regexp
|
||||
[coverage-url]: https://codecov.io/gh/pillarjs/path-to-regexp
|
||||
[license-image]: http://img.shields.io/npm/l/path-to-regexp.svg?style=flat
|
||||
[license-url]: LICENSE.md
|
||||
144
node_modules/router/node_modules/path-to-regexp/dist/index.d.ts
generated
vendored
Normal file
144
node_modules/router/node_modules/path-to-regexp/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* Encode a string into another string.
|
||||
*/
|
||||
export type Encode = (value: string) => string;
|
||||
/**
|
||||
* Decode a string into another string.
|
||||
*/
|
||||
export type Decode = (value: string) => string;
|
||||
export interface ParseOptions {
|
||||
/**
|
||||
* A function for encoding input strings.
|
||||
*/
|
||||
encodePath?: Encode;
|
||||
}
|
||||
export interface PathToRegexpOptions {
|
||||
/**
|
||||
* Matches the path completely without trailing characters. (default: `true`)
|
||||
*/
|
||||
end?: boolean;
|
||||
/**
|
||||
* Allows optional trailing delimiter to match. (default: `true`)
|
||||
*/
|
||||
trailing?: boolean;
|
||||
/**
|
||||
* Match will be case sensitive. (default: `false`)
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* The default delimiter for segments. (default: `'/'`)
|
||||
*/
|
||||
delimiter?: string;
|
||||
}
|
||||
export interface MatchOptions extends PathToRegexpOptions {
|
||||
/**
|
||||
* Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)
|
||||
*/
|
||||
decode?: Decode | false;
|
||||
}
|
||||
export interface CompileOptions {
|
||||
/**
|
||||
* Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
|
||||
*/
|
||||
encode?: Encode | false;
|
||||
/**
|
||||
* The default delimiter for segments. (default: `'/'`)
|
||||
*/
|
||||
delimiter?: string;
|
||||
}
|
||||
/**
|
||||
* Plain text.
|
||||
*/
|
||||
export interface Text {
|
||||
type: "text";
|
||||
value: string;
|
||||
}
|
||||
/**
|
||||
* A parameter designed to match arbitrary text within a segment.
|
||||
*/
|
||||
export interface Parameter {
|
||||
type: "param";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* A wildcard parameter designed to match multiple segments.
|
||||
*/
|
||||
export interface Wildcard {
|
||||
type: "wildcard";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* A set of possible tokens to expand when matching.
|
||||
*/
|
||||
export interface Group {
|
||||
type: "group";
|
||||
tokens: Token[];
|
||||
}
|
||||
/**
|
||||
* A token that corresponds with a regexp capture.
|
||||
*/
|
||||
export type Key = Parameter | Wildcard;
|
||||
/**
|
||||
* A sequence of `path-to-regexp` keys that match capturing groups.
|
||||
*/
|
||||
export type Keys = Array<Key>;
|
||||
/**
|
||||
* A sequence of path match characters.
|
||||
*/
|
||||
export type Token = Text | Parameter | Wildcard | Group;
|
||||
/**
|
||||
* Tokenized path instance.
|
||||
*/
|
||||
export declare class TokenData {
|
||||
readonly tokens: Token[];
|
||||
readonly originalPath?: string | undefined;
|
||||
constructor(tokens: Token[], originalPath?: string | undefined);
|
||||
}
|
||||
/**
|
||||
* ParseError is thrown when there is an error processing the path.
|
||||
*/
|
||||
export declare class PathError extends TypeError {
|
||||
readonly originalPath: string | undefined;
|
||||
constructor(message: string, originalPath: string | undefined);
|
||||
}
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
export declare function parse(str: string, options?: ParseOptions): TokenData;
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
export declare function compile<P extends ParamData = ParamData>(path: Path, options?: CompileOptions & ParseOptions): (params?: P) => string;
|
||||
export type ParamData = Partial<Record<string, string | string[]>>;
|
||||
export type PathFunction<P extends ParamData> = (data?: P) => string;
|
||||
/**
|
||||
* A match result contains data about the path match.
|
||||
*/
|
||||
export interface MatchResult<P extends ParamData> {
|
||||
path: string;
|
||||
params: P;
|
||||
}
|
||||
/**
|
||||
* A match is either `false` (no match) or a match result.
|
||||
*/
|
||||
export type Match<P extends ParamData> = false | MatchResult<P>;
|
||||
/**
|
||||
* The match function takes a string and returns whether it matched the path.
|
||||
*/
|
||||
export type MatchFunction<P extends ParamData> = (path: string) => Match<P>;
|
||||
/**
|
||||
* Supported path types.
|
||||
*/
|
||||
export type Path = string | TokenData;
|
||||
/**
|
||||
* Transform a path into a match function.
|
||||
*/
|
||||
export declare function match<P extends ParamData>(path: Path | Path[], options?: MatchOptions & ParseOptions): MatchFunction<P>;
|
||||
export declare function pathToRegexp(path: Path | Path[], options?: PathToRegexpOptions & ParseOptions): {
|
||||
regexp: RegExp;
|
||||
keys: Keys;
|
||||
};
|
||||
/**
|
||||
* Stringify token data into a path string.
|
||||
*/
|
||||
export declare function stringify(data: TokenData): string;
|
||||
409
node_modules/router/node_modules/path-to-regexp/dist/index.js
generated
vendored
Normal file
409
node_modules/router/node_modules/path-to-regexp/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,409 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PathError = exports.TokenData = void 0;
|
||||
exports.parse = parse;
|
||||
exports.compile = compile;
|
||||
exports.match = match;
|
||||
exports.pathToRegexp = pathToRegexp;
|
||||
exports.stringify = stringify;
|
||||
const DEFAULT_DELIMITER = "/";
|
||||
const NOOP_VALUE = (value) => value;
|
||||
const ID_START = /^[$_\p{ID_Start}]$/u;
|
||||
const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
|
||||
const SIMPLE_TOKENS = {
|
||||
// Groups.
|
||||
"{": "{",
|
||||
"}": "}",
|
||||
// Reserved.
|
||||
"(": "(",
|
||||
")": ")",
|
||||
"[": "[",
|
||||
"]": "]",
|
||||
"+": "+",
|
||||
"?": "?",
|
||||
"!": "!",
|
||||
};
|
||||
/**
|
||||
* Escape text for stringify to path.
|
||||
*/
|
||||
function escapeText(str) {
|
||||
return str.replace(/[{}()\[\]+?!:*\\]/g, "\\$&");
|
||||
}
|
||||
/**
|
||||
* Escape a regular expression string.
|
||||
*/
|
||||
function escape(str) {
|
||||
return str.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&");
|
||||
}
|
||||
/**
|
||||
* Tokenized path instance.
|
||||
*/
|
||||
class TokenData {
|
||||
constructor(tokens, originalPath) {
|
||||
this.tokens = tokens;
|
||||
this.originalPath = originalPath;
|
||||
}
|
||||
}
|
||||
exports.TokenData = TokenData;
|
||||
/**
|
||||
* ParseError is thrown when there is an error processing the path.
|
||||
*/
|
||||
class PathError extends TypeError {
|
||||
constructor(message, originalPath) {
|
||||
let text = message;
|
||||
if (originalPath)
|
||||
text += `: ${originalPath}`;
|
||||
text += `; visit https://git.new/pathToRegexpError for info`;
|
||||
super(text);
|
||||
this.originalPath = originalPath;
|
||||
}
|
||||
}
|
||||
exports.PathError = PathError;
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
function parse(str, options = {}) {
|
||||
const { encodePath = NOOP_VALUE } = options;
|
||||
const chars = [...str];
|
||||
const tokens = [];
|
||||
let index = 0;
|
||||
let pos = 0;
|
||||
function name() {
|
||||
let value = "";
|
||||
if (ID_START.test(chars[index])) {
|
||||
do {
|
||||
value += chars[index++];
|
||||
} while (ID_CONTINUE.test(chars[index]));
|
||||
}
|
||||
else if (chars[index] === '"') {
|
||||
let quoteStart = index;
|
||||
while (index++ < chars.length) {
|
||||
if (chars[index] === '"') {
|
||||
index++;
|
||||
quoteStart = 0;
|
||||
break;
|
||||
}
|
||||
// Increment over escape characters.
|
||||
if (chars[index] === "\\")
|
||||
index++;
|
||||
value += chars[index];
|
||||
}
|
||||
if (quoteStart) {
|
||||
throw new PathError(`Unterminated quote at index ${quoteStart}`, str);
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
throw new PathError(`Missing parameter name at index ${index}`, str);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
while (index < chars.length) {
|
||||
const value = chars[index];
|
||||
const type = SIMPLE_TOKENS[value];
|
||||
if (type) {
|
||||
tokens.push({ type, index: index++, value });
|
||||
}
|
||||
else if (value === "\\") {
|
||||
tokens.push({ type: "escape", index: index++, value: chars[index++] });
|
||||
}
|
||||
else if (value === ":") {
|
||||
tokens.push({ type: "param", index: index++, value: name() });
|
||||
}
|
||||
else if (value === "*") {
|
||||
tokens.push({ type: "wildcard", index: index++, value: name() });
|
||||
}
|
||||
else {
|
||||
tokens.push({ type: "char", index: index++, value });
|
||||
}
|
||||
}
|
||||
tokens.push({ type: "end", index, value: "" });
|
||||
function consumeUntil(endType) {
|
||||
const output = [];
|
||||
while (true) {
|
||||
const token = tokens[pos++];
|
||||
if (token.type === endType)
|
||||
break;
|
||||
if (token.type === "char" || token.type === "escape") {
|
||||
let path = token.value;
|
||||
let cur = tokens[pos];
|
||||
while (cur.type === "char" || cur.type === "escape") {
|
||||
path += cur.value;
|
||||
cur = tokens[++pos];
|
||||
}
|
||||
output.push({
|
||||
type: "text",
|
||||
value: encodePath(path),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (token.type === "param" || token.type === "wildcard") {
|
||||
output.push({
|
||||
type: token.type,
|
||||
name: token.value,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (token.type === "{") {
|
||||
output.push({
|
||||
type: "group",
|
||||
tokens: consumeUntil("}"),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
throw new PathError(`Unexpected ${token.type} at index ${token.index}, expected ${endType}`, str);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return new TokenData(consumeUntil("end"), str);
|
||||
}
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
function compile(path, options = {}) {
|
||||
const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
||||
const data = typeof path === "object" ? path : parse(path, options);
|
||||
const fn = tokensToFunction(data.tokens, delimiter, encode);
|
||||
return function path(params = {}) {
|
||||
const [path, ...missing] = fn(params);
|
||||
if (missing.length) {
|
||||
throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
|
||||
}
|
||||
return path;
|
||||
};
|
||||
}
|
||||
function tokensToFunction(tokens, delimiter, encode) {
|
||||
const encoders = tokens.map((token) => tokenToFunction(token, delimiter, encode));
|
||||
return (data) => {
|
||||
const result = [""];
|
||||
for (const encoder of encoders) {
|
||||
const [value, ...extras] = encoder(data);
|
||||
result[0] += value;
|
||||
result.push(...extras);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert a single token into a path building function.
|
||||
*/
|
||||
function tokenToFunction(token, delimiter, encode) {
|
||||
if (token.type === "text")
|
||||
return () => [token.value];
|
||||
if (token.type === "group") {
|
||||
const fn = tokensToFunction(token.tokens, delimiter, encode);
|
||||
return (data) => {
|
||||
const [value, ...missing] = fn(data);
|
||||
if (!missing.length)
|
||||
return [value];
|
||||
return [""];
|
||||
};
|
||||
}
|
||||
const encodeValue = encode || NOOP_VALUE;
|
||||
if (token.type === "wildcard" && encode !== false) {
|
||||
return (data) => {
|
||||
const value = data[token.name];
|
||||
if (value == null)
|
||||
return ["", token.name];
|
||||
if (!Array.isArray(value) || value.length === 0) {
|
||||
throw new TypeError(`Expected "${token.name}" to be a non-empty array`);
|
||||
}
|
||||
return [
|
||||
value
|
||||
.map((value, index) => {
|
||||
if (typeof value !== "string") {
|
||||
throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
|
||||
}
|
||||
return encodeValue(value);
|
||||
})
|
||||
.join(delimiter),
|
||||
];
|
||||
};
|
||||
}
|
||||
return (data) => {
|
||||
const value = data[token.name];
|
||||
if (value == null)
|
||||
return ["", token.name];
|
||||
if (typeof value !== "string") {
|
||||
throw new TypeError(`Expected "${token.name}" to be a string`);
|
||||
}
|
||||
return [encodeValue(value)];
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Transform a path into a match function.
|
||||
*/
|
||||
function match(path, options = {}) {
|
||||
const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
||||
const { regexp, keys } = pathToRegexp(path, options);
|
||||
const decoders = keys.map((key) => {
|
||||
if (decode === false)
|
||||
return NOOP_VALUE;
|
||||
if (key.type === "param")
|
||||
return decode;
|
||||
return (value) => value.split(delimiter).map(decode);
|
||||
});
|
||||
return function match(input) {
|
||||
const m = regexp.exec(input);
|
||||
if (!m)
|
||||
return false;
|
||||
const path = m[0];
|
||||
const params = Object.create(null);
|
||||
for (let i = 1; i < m.length; i++) {
|
||||
if (m[i] === undefined)
|
||||
continue;
|
||||
const key = keys[i - 1];
|
||||
const decoder = decoders[i - 1];
|
||||
params[key.name] = decoder(m[i]);
|
||||
}
|
||||
return { path, params };
|
||||
};
|
||||
}
|
||||
function pathToRegexp(path, options = {}) {
|
||||
const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true, } = options;
|
||||
const keys = [];
|
||||
const flags = sensitive ? "" : "i";
|
||||
const sources = [];
|
||||
for (const input of pathsToArray(path, [])) {
|
||||
const data = typeof input === "object" ? input : parse(input, options);
|
||||
for (const tokens of flatten(data.tokens, 0, [])) {
|
||||
sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath));
|
||||
}
|
||||
}
|
||||
let pattern = `^(?:${sources.join("|")})`;
|
||||
if (trailing)
|
||||
pattern += `(?:${escape(delimiter)}$)?`;
|
||||
pattern += end ? "$" : `(?=${escape(delimiter)}|$)`;
|
||||
const regexp = new RegExp(pattern, flags);
|
||||
return { regexp, keys };
|
||||
}
|
||||
/**
|
||||
* Convert a path or array of paths into a flat array.
|
||||
*/
|
||||
function pathsToArray(paths, init) {
|
||||
if (Array.isArray(paths)) {
|
||||
for (const p of paths)
|
||||
pathsToArray(p, init);
|
||||
}
|
||||
else {
|
||||
init.push(paths);
|
||||
}
|
||||
return init;
|
||||
}
|
||||
/**
|
||||
* Generate a flat list of sequence tokens from the given tokens.
|
||||
*/
|
||||
function* flatten(tokens, index, init) {
|
||||
if (index === tokens.length) {
|
||||
return yield init;
|
||||
}
|
||||
const token = tokens[index];
|
||||
if (token.type === "group") {
|
||||
for (const seq of flatten(token.tokens, 0, init.slice())) {
|
||||
yield* flatten(tokens, index + 1, seq);
|
||||
}
|
||||
}
|
||||
else {
|
||||
init.push(token);
|
||||
}
|
||||
yield* flatten(tokens, index + 1, init);
|
||||
}
|
||||
/**
|
||||
* Transform a flat sequence of tokens into a regular expression.
|
||||
*/
|
||||
function toRegExpSource(tokens, delimiter, keys, originalPath) {
|
||||
let result = "";
|
||||
let backtrack = "";
|
||||
let isSafeSegmentParam = true;
|
||||
for (const token of tokens) {
|
||||
if (token.type === "text") {
|
||||
result += escape(token.value);
|
||||
backtrack += token.value;
|
||||
isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter));
|
||||
continue;
|
||||
}
|
||||
if (token.type === "param" || token.type === "wildcard") {
|
||||
if (!isSafeSegmentParam && !backtrack) {
|
||||
throw new PathError(`Missing text before "${token.name}" ${token.type}`, originalPath);
|
||||
}
|
||||
if (token.type === "param") {
|
||||
result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`;
|
||||
}
|
||||
else {
|
||||
result += `([\\s\\S]+)`;
|
||||
}
|
||||
keys.push(token);
|
||||
backtrack = "";
|
||||
isSafeSegmentParam = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Block backtracking on previous text and ignore delimiter string.
|
||||
*/
|
||||
function negate(delimiter, backtrack) {
|
||||
if (backtrack.length < 2) {
|
||||
if (delimiter.length < 2)
|
||||
return `[^${escape(delimiter + backtrack)}]`;
|
||||
return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;
|
||||
}
|
||||
if (delimiter.length < 2) {
|
||||
return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;
|
||||
}
|
||||
return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`;
|
||||
}
|
||||
/**
|
||||
* Stringify an array of tokens into a path string.
|
||||
*/
|
||||
function stringifyTokens(tokens) {
|
||||
let value = "";
|
||||
let i = 0;
|
||||
function name(value) {
|
||||
const isSafe = isNameSafe(value) && isNextNameSafe(tokens[i]);
|
||||
return isSafe ? value : JSON.stringify(value);
|
||||
}
|
||||
while (i < tokens.length) {
|
||||
const token = tokens[i++];
|
||||
if (token.type === "text") {
|
||||
value += escapeText(token.value);
|
||||
continue;
|
||||
}
|
||||
if (token.type === "group") {
|
||||
value += `{${stringifyTokens(token.tokens)}}`;
|
||||
continue;
|
||||
}
|
||||
if (token.type === "param") {
|
||||
value += `:${name(token.name)}`;
|
||||
continue;
|
||||
}
|
||||
if (token.type === "wildcard") {
|
||||
value += `*${name(token.name)}`;
|
||||
continue;
|
||||
}
|
||||
throw new TypeError(`Unknown token type: ${token.type}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Stringify token data into a path string.
|
||||
*/
|
||||
function stringify(data) {
|
||||
return stringifyTokens(data.tokens);
|
||||
}
|
||||
/**
|
||||
* Validate the parameter name contains valid ID characters.
|
||||
*/
|
||||
function isNameSafe(name) {
|
||||
const [first, ...rest] = name;
|
||||
return ID_START.test(first) && rest.every((char) => ID_CONTINUE.test(char));
|
||||
}
|
||||
/**
|
||||
* Validate the next token does not interfere with the current param name.
|
||||
*/
|
||||
function isNextNameSafe(token) {
|
||||
if (token && token.type === "text")
|
||||
return !ID_CONTINUE.test(token.value[0]);
|
||||
return true;
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/router/node_modules/path-to-regexp/dist/index.js.map
generated
vendored
Normal file
1
node_modules/router/node_modules/path-to-regexp/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
64
node_modules/router/node_modules/path-to-regexp/package.json
generated
vendored
Normal file
64
node_modules/router/node_modules/path-to-regexp/package.json
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "path-to-regexp",
|
||||
"version": "8.3.0",
|
||||
"description": "Express style path to RegExp utility",
|
||||
"keywords": [
|
||||
"express",
|
||||
"regexp",
|
||||
"route",
|
||||
"routing"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pillarjs/path-to-regexp.git"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
},
|
||||
"license": "MIT",
|
||||
"exports": "./dist/index.js",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"scripts": {
|
||||
"bench": "vitest bench",
|
||||
"build": "ts-scripts build",
|
||||
"format": "ts-scripts format",
|
||||
"lint": "ts-scripts lint",
|
||||
"prepare": "ts-scripts install && npm run build",
|
||||
"size": "size-limit",
|
||||
"specs": "ts-scripts specs",
|
||||
"test": "ts-scripts test && npm run size"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@borderless/ts-scripts": "^0.15.0",
|
||||
"@size-limit/preset-small-lib": "^11.1.2",
|
||||
"@types/node": "^22.7.2",
|
||||
"@types/semver": "^7.3.1",
|
||||
"@vitest/coverage-v8": "^3.0.5",
|
||||
"recheck": "^4.4.5",
|
||||
"size-limit": "^11.1.2",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.5"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"size-limit": [
|
||||
{
|
||||
"path": "dist/index.js",
|
||||
"limit": "2 kB"
|
||||
}
|
||||
],
|
||||
"ts-scripts": {
|
||||
"dist": [
|
||||
"dist"
|
||||
],
|
||||
"project": [
|
||||
"tsconfig.build.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
44
node_modules/router/package.json
generated
vendored
Normal file
44
node_modules/router/package.json
generated
vendored
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user