router
Advanced tools
Comparing version 2.0.0-alpha.1 to 2.0.0-beta.1
@@ -0,1 +1,23 @@ | ||
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.parmas[0]`. | ||
- Regular expressions can only be used in a matching group. | ||
`/\\d+` is no longer valid and must be written as `/(\\d+)`. | ||
- 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 | ||
@@ -14,2 +36,15 @@ ========================== | ||
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 | ||
@@ -16,0 +51,0 @@ ================== |
258
index.js
@@ -15,4 +15,3 @@ /*! | ||
var debug = require('debug')('router') | ||
var flatten = require('array-flatten') | ||
var flatten = require('array-flatten').flatten | ||
var Layer = require('./lib/layer') | ||
@@ -52,3 +51,3 @@ var methods = require('methods') | ||
function Router(options) { | ||
function Router (options) { | ||
if (!(this instanceof Router)) { | ||
@@ -60,3 +59,3 @@ return new Router(options) | ||
function router(req, res, next) { | ||
function router (req, res, next) { | ||
router.handle(req, res, next) | ||
@@ -117,3 +116,3 @@ } | ||
Router.prototype.param = function param(name, fn) { | ||
Router.prototype.param = function param (name, fn) { | ||
if (!name) { | ||
@@ -152,3 +151,3 @@ throw new TypeError('argument name is required') | ||
Router.prototype.handle = function handle(req, res, callback) { | ||
Router.prototype.handle = function handle (req, res, callback) { | ||
if (!callback) { | ||
@@ -158,4 +157,2 @@ throw new TypeError('argument callback is required') | ||
debug('dispatching %s %s', req.method, req.url) | ||
var idx = 0 | ||
@@ -192,3 +189,3 @@ var methods | ||
function next(err) { | ||
function next (err) { | ||
var layerError = err === 'route' | ||
@@ -261,6 +258,6 @@ ? null | ||
var method = req.method | ||
var has_method = route._handles_method(method) | ||
var hasMethod = route._handlesMethod(method) | ||
// build up automatic options response | ||
if (!has_method && method === 'OPTIONS' && methods) { | ||
if (!hasMethod && method === 'OPTIONS' && methods) { | ||
methods.push.apply(methods, route._methods()) | ||
@@ -270,3 +267,3 @@ } | ||
// don't even bother matching route | ||
if (!has_method && method !== 'HEAD') { | ||
if (!hasMethod && method !== 'HEAD') { | ||
match = false | ||
@@ -294,3 +291,3 @@ continue | ||
// this should be done for the layer | ||
self.process_params(layer, paramcalled, req, res, function (err) { | ||
processParams(self.params, layer, paramcalled, req, res, function (err) { | ||
if (err) { | ||
@@ -301,11 +298,17 @@ return next(layerError || err) | ||
if (route) { | ||
return layer.handle_request(req, res, next) | ||
return layer.handleRequest(req, res, next) | ||
} | ||
trim_prefix(layer, layerError, layerPath, path) | ||
trimPrefix(layer, layerError, layerPath, path) | ||
}) | ||
} | ||
function trim_prefix(layer, layerError, layerPath, path) { | ||
function trimPrefix (layer, layerError, layerPath, path) { | ||
if (layerPath.length !== 0) { | ||
// Validate path is a prefix match | ||
if (layerPath !== path.substr(0, layerPath.length)) { | ||
next(layerError) | ||
return | ||
} | ||
// Validate path breaks on a path separator | ||
@@ -320,3 +323,2 @@ var c = path[layerPath.length] | ||
// middleware (.use stuff) needs to have the path stripped | ||
debug('trim prefix (%s) from url %s', layerPath, req.url) | ||
removed = layerPath | ||
@@ -337,8 +339,6 @@ req.url = protohost + req.url.substr(protohost.length + removed.length) | ||
debug('%s %s : %s', layer.name, layerPath, req.originalUrl) | ||
if (layerError) { | ||
layer.handle_error(layerError, req, res, next) | ||
layer.handleError(layerError, req, res, next) | ||
} else { | ||
layer.handle_request(req, res, next) | ||
layer.handleRequest(req, res, next) | ||
} | ||
@@ -349,94 +349,2 @@ } | ||
/** | ||
* Process any parameters for the layer. | ||
* | ||
* @private | ||
*/ | ||
Router.prototype.process_params = function process_params(layer, called, req, res, done) { | ||
var params = this.params | ||
// captured parameters from the layer, keys and values | ||
var keys = layer.keys | ||
// fast track | ||
if (!keys || keys.length === 0) { | ||
return done() | ||
} | ||
var i = 0 | ||
var name | ||
var paramIndex = 0 | ||
var key | ||
var paramVal | ||
var paramCallbacks | ||
var 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++] | ||
name = key.name | ||
paramVal = req.params[name] | ||
paramCallbacks = params[name] | ||
paramCalled = called[name] | ||
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[name] = paramCalled.value | ||
// next param | ||
return param(paramCalled.error) | ||
} | ||
called[name] = paramCalled = { | ||
error: null, | ||
match: paramVal, | ||
value: paramVal | ||
} | ||
paramCallback() | ||
} | ||
// single param callbacks | ||
function paramCallback(err) { | ||
var fn = paramCallbacks[paramIndex++] | ||
// store updated value | ||
paramCalled.value = req.params[key.name] | ||
if (err) { | ||
// store error | ||
paramCalled.error = err | ||
param(err) | ||
return | ||
} | ||
if (!fn) return param() | ||
try { | ||
fn(req, res, paramCallback, paramVal, key.name) | ||
} catch (e) { | ||
paramCallback(e) | ||
} | ||
} | ||
param() | ||
} | ||
/** | ||
* Use the given middleware function, with optional path, defaulting to "/". | ||
@@ -456,3 +364,3 @@ * | ||
Router.prototype.use = function use(handler) { | ||
Router.prototype.use = function use (handler) { | ||
var offset = 0 | ||
@@ -491,4 +399,2 @@ var path = '/' | ||
// add the middleware | ||
debug('use %o %s', path, fn.name || '<anonymous>') | ||
var layer = new Layer(path, { | ||
@@ -521,3 +427,3 @@ sensitive: this.caseSensitive, | ||
Router.prototype.route = function route(path) { | ||
Router.prototype.route = function route (path) { | ||
var route = new Route(path) | ||
@@ -531,3 +437,3 @@ | ||
function handle(req, res, next) { | ||
function handle (req, res, next) { | ||
route.dispatch(req, res, next) | ||
@@ -543,3 +449,3 @@ } | ||
// create Router#VERB functions | ||
methods.concat('all').forEach(function(method){ | ||
methods.concat('all').forEach(function (method) { | ||
Router.prototype[method] = function (path) { | ||
@@ -560,4 +466,4 @@ var route = this.route(path) | ||
function generateOptionsResponder(res, methods) { | ||
return function onDone(fn, err) { | ||
function generateOptionsResponder (res, methods) { | ||
return function onDone (fn, err) { | ||
if (err || methods.length === 0) { | ||
@@ -578,3 +484,3 @@ return fn(err) | ||
function getPathname(req) { | ||
function getPathname (req) { | ||
try { | ||
@@ -594,3 +500,3 @@ return parseUrl(req).pathname | ||
function getProtohost(url) { | ||
function getProtohost (url) { | ||
if (typeof url !== 'string' || url.length === 0 || url[0] === '/') { | ||
@@ -619,3 +525,3 @@ return undefined | ||
function matchLayer(layer, path) { | ||
function matchLayer (layer, path) { | ||
try { | ||
@@ -634,3 +540,3 @@ return layer.match(path) | ||
function mergeParams(params, parent) { | ||
function mergeParams (params, parent) { | ||
if (typeof parent !== 'object' || !parent) { | ||
@@ -675,2 +581,92 @@ return params | ||
/** | ||
* Process any parameters for the layer. | ||
* | ||
* @private | ||
*/ | ||
function processParams (params, layer, called, req, res, done) { | ||
// captured parameters from the layer, keys and values | ||
var keys = layer.keys | ||
// fast track | ||
if (!keys || keys.length === 0) { | ||
return done() | ||
} | ||
var i = 0 | ||
var name | ||
var paramIndex = 0 | ||
var key | ||
var paramVal | ||
var paramCallbacks | ||
var 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++] | ||
name = key.name | ||
paramVal = req.params[name] | ||
paramCallbacks = params[name] | ||
paramCalled = called[name] | ||
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[name] = paramCalled.value | ||
// next param | ||
return param(paramCalled.error) | ||
} | ||
called[name] = paramCalled = { | ||
error: null, | ||
match: paramVal, | ||
value: paramVal | ||
} | ||
paramCallback() | ||
} | ||
// single param callbacks | ||
function paramCallback (err) { | ||
var fn = paramCallbacks[paramIndex++] | ||
// store updated value | ||
paramCalled.value = req.params[key.name] | ||
if (err) { | ||
// store error | ||
paramCalled.error = err | ||
param(err) | ||
return | ||
} | ||
if (!fn) return param() | ||
try { | ||
fn(req, res, paramCallback, paramVal, key.name) | ||
} catch (e) { | ||
paramCallback(e) | ||
} | ||
} | ||
param() | ||
} | ||
/** | ||
* Restore obj props after function | ||
@@ -681,3 +677,3 @@ * | ||
function restore(fn, obj) { | ||
function restore (fn, obj) { | ||
var props = new Array(arguments.length - 2) | ||
@@ -691,3 +687,3 @@ var vals = new Array(arguments.length - 2) | ||
return function(){ | ||
return function () { | ||
// restore vals | ||
@@ -708,3 +704,3 @@ for (var i = 0; i < props.length; i++) { | ||
function sendOptionsResponse(res, methods) { | ||
function sendOptionsResponse (res, methods) { | ||
var options = Object.create(null) | ||
@@ -734,3 +730,3 @@ | ||
function trySendOptionsResponse(res, methods, next) { | ||
function trySendOptionsResponse (res, methods, next) { | ||
try { | ||
@@ -749,4 +745,4 @@ sendOptionsResponse(res, methods) | ||
function wrap(old, fn) { | ||
return function proxy() { | ||
function wrap (old, fn) { | ||
return function proxy () { | ||
var args = new Array(arguments.length + 1) | ||
@@ -753,0 +749,0 @@ |
@@ -16,3 +16,2 @@ /*! | ||
var pathRegexp = require('path-to-regexp') | ||
var debug = require('debug')('router:layer') | ||
@@ -25,2 +24,3 @@ /** | ||
var hasOwnProperty = Object.prototype.hasOwnProperty | ||
var TRAILING_SLASH_REGEXP = /\/+$/ | ||
@@ -33,3 +33,3 @@ /** | ||
function Layer(path, options, fn) { | ||
function Layer (path, options, fn) { | ||
if (!(this instanceof Layer)) { | ||
@@ -39,14 +39,13 @@ return new Layer(path, options, fn) | ||
debug('new %o', path) | ||
var opts = options || {} | ||
this.handle = fn | ||
this.keys = [] | ||
this.name = fn.name || '<anonymous>' | ||
this.params = undefined | ||
this.path = undefined | ||
this.regexp = pathRegexp(path, this.keys = [], opts) | ||
this.regexp = pathRegexp((opts.strict ? path : loosen(path)), this.keys, opts) | ||
// set fast path flags | ||
this.regexp.fast_star = path === '*' | ||
this.regexp.fast_slash = path === '/' && opts.end === false | ||
this.regexp._slash = path === '/' && opts.end === false | ||
} | ||
@@ -64,3 +63,3 @@ | ||
Layer.prototype.handle_error = function handle_error(error, req, res, next) { | ||
Layer.prototype.handleError = function handleError (error, req, res, next) { | ||
var fn = this.handle | ||
@@ -97,3 +96,3 @@ | ||
Layer.prototype.handle_request = function handle(req, res, next) { | ||
Layer.prototype.handleRequest = function handleRequest (req, res, next) { | ||
var fn = this.handle | ||
@@ -130,3 +129,3 @@ | ||
Layer.prototype.match = function match(path) { | ||
Layer.prototype.match = function match (path) { | ||
var match | ||
@@ -136,3 +135,3 @@ | ||
// fast path non-ending match for / (any path matches) | ||
if (this.regexp.fast_slash) { | ||
if (this.regexp._slash) { | ||
this.params = {} | ||
@@ -143,9 +142,2 @@ this.path = '' | ||
// fast path for * (everything matched in a param) | ||
if (this.regexp.fast_star) { | ||
this.params = {'0': decode_param(path)} | ||
this.path = path | ||
return true | ||
} | ||
// match the path | ||
@@ -172,3 +164,3 @@ match = this.regexp.exec(path) | ||
var prop = key.name | ||
var val = decode_param(match[i]) | ||
var val = decodeParam(match[i]) | ||
@@ -191,3 +183,3 @@ if (val !== undefined || !(hasOwnProperty.call(params, prop))) { | ||
function decode_param(val){ | ||
function decodeParam (val) { | ||
if (typeof val !== 'string' || val.length === 0) { | ||
@@ -222,1 +214,14 @@ return val | ||
} | ||
/** | ||
* Loosens the given path for path-to-regexp matching. | ||
*/ | ||
function loosen (path) { | ||
if (path instanceof RegExp) { | ||
return path | ||
} | ||
return Array.isArray(path) | ||
? path.map(function (p) { return loosen(p) }) | ||
: String(path).replace(TRAILING_SLASH_REGEXP, '') | ||
} |
@@ -15,4 +15,3 @@ /*! | ||
var debug = require('debug')('router:route') | ||
var flatten = require('array-flatten') | ||
var flatten = require('array-flatten').flatten | ||
var Layer = require('./layer') | ||
@@ -41,4 +40,3 @@ var methods = require('methods') | ||
function Route(path) { | ||
debug('new %o', path) | ||
function Route (path) { | ||
this.path = path | ||
@@ -48,3 +46,3 @@ this.stack = [] | ||
// route handlers for various http methods | ||
this.methods = {} | ||
this.methods = Object.create(null) | ||
} | ||
@@ -56,3 +54,3 @@ | ||
Route.prototype._handles_method = function _handles_method(method) { | ||
Route.prototype._handlesMethod = function _handlesMethod (method) { | ||
if (this.methods._all) { | ||
@@ -65,3 +63,3 @@ return true | ||
if (name === 'head' && !this.methods['head']) { | ||
if (name === 'head' && !this.methods.head) { | ||
name = 'get' | ||
@@ -78,3 +76,3 @@ } | ||
Route.prototype._methods = function _methods() { | ||
Route.prototype._methods = function _methods () { | ||
var methods = Object.keys(this.methods) | ||
@@ -101,3 +99,3 @@ | ||
Route.prototype.dispatch = function dispatch(req, res, done) { | ||
Route.prototype.dispatch = function dispatch (req, res, done) { | ||
var idx = 0 | ||
@@ -110,3 +108,3 @@ var stack = this.stack | ||
var method = req.method.toLowerCase() | ||
if (method === 'head' && !this.methods['head']) { | ||
if (method === 'head' && !this.methods.head) { | ||
method = 'get' | ||
@@ -119,3 +117,3 @@ } | ||
function next(err) { | ||
function next (err) { | ||
// signal to exit route | ||
@@ -151,5 +149,5 @@ if (err && err === 'route') { | ||
if (err) { | ||
layer.handle_error(err, req, res, next) | ||
layer.handleError(err, req, res, next) | ||
} else { | ||
layer.handle_request(req, res, next) | ||
layer.handleRequest(req, res, next) | ||
} | ||
@@ -187,3 +185,3 @@ } | ||
Route.prototype.all = function all(handler) { | ||
Route.prototype.all = function all (handler) { | ||
var callbacks = flatten(slice.call(arguments)) | ||
@@ -227,4 +225,2 @@ | ||
debug('%s %s', method, this.path) | ||
var layer = Layer('/', {}, fn) | ||
@@ -231,0 +227,0 @@ layer.method = method |
{ | ||
"name": "router", | ||
"description": "Simple middleware-style router", | ||
"version": "2.0.0-alpha.1", | ||
"version": "2.0.0-beta.1", | ||
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>", | ||
@@ -12,8 +12,7 @@ "contributors": [ | ||
"dependencies": { | ||
"array-flatten": "2.1.1", | ||
"debug": "3.1.0", | ||
"array-flatten": "3.0.0", | ||
"methods": "~1.1.2", | ||
"parseurl": "~1.3.2", | ||
"path-to-regexp": "0.1.7", | ||
"setprototypeof": "1.1.0", | ||
"parseurl": "~1.3.3", | ||
"path-to-regexp": "3.2.0", | ||
"setprototypeof": "1.2.0", | ||
"utils-merge": "1.0.1" | ||
@@ -23,8 +22,14 @@ }, | ||
"after": "0.8.2", | ||
"eslint": "3.19.0", | ||
"eslint-plugin-markdown": "1.0.0-beta.6", | ||
"finalhandler": "1.1.1", | ||
"mocha": "3.5.3", | ||
"nyc": "10.3.2", | ||
"supertest": "1.2.0" | ||
"eslint": "6.8.0", | ||
"eslint-config-standard": "14.1.1", | ||
"eslint-plugin-import": "2.20.1", | ||
"eslint-plugin-markdown": "1.0.2", | ||
"eslint-plugin-node": "11.0.0", | ||
"eslint-plugin-promise": "4.2.1", | ||
"eslint-plugin-standard": "4.0.1", | ||
"finalhandler": "1.1.2", | ||
"mocha": "7.1.1", | ||
"nyc": "15.0.0", | ||
"safe-buffer": "5.2.0", | ||
"supertest": "4.0.2" | ||
}, | ||
@@ -45,4 +50,5 @@ "files": [ | ||
"test-cov": "nyc --reporter=text npm test", | ||
"test-travis": "nyc --reporter=html --reporter=text npm test" | ||
"test-travis": "nyc --reporter=html --reporter=text npm test", | ||
"version": "node scripts/version-history.js && git add HISTORY.md" | ||
} | ||
} |
@@ -25,4 +25,4 @@ # router | ||
var finalhandler = require('finalhandler') | ||
var http = require('http') | ||
var Router = require('router') | ||
var http = require('http') | ||
var Router = require('router') | ||
@@ -35,3 +35,3 @@ var router = Router() | ||
var server = http.createServer(function(req, res) { | ||
var server = http.createServer(function (req, res) { | ||
router(req, res, finalhandler(req, res)) | ||
@@ -71,2 +71,4 @@ }) | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
@@ -95,2 +97,4 @@ router.use(function (req, res, next) { | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
@@ -123,2 +127,4 @@ // handle a `GET` request | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
@@ -150,2 +156,4 @@ router.param('user_id', function (req, res, next, id) { | ||
<!-- eslint-disable no-undef, no-unused-vars --> | ||
```js | ||
@@ -157,4 +165,4 @@ var api = router.route('/api/') | ||
Represents a single route as an instance that can be used can be used to handle | ||
http `methods` with it's own, optional middleware. | ||
Represents a single route as an instance that can be used to handle http | ||
`methods` with it's own, optional middleware. | ||
@@ -166,2 +174,4 @@ ### route\[method](handler) | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
@@ -184,12 +194,14 @@ // handle a `GET` request | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
router.route('/') | ||
.all(function (req, res, next) { | ||
next() | ||
}) | ||
.all(check_something) | ||
.get(function (req, res) { | ||
res.setHeader('Content-Type', 'text/plain; charset=utf-8') | ||
res.end('Hello World!') | ||
}) | ||
.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!') | ||
}) | ||
``` | ||
@@ -219,2 +231,4 @@ | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
@@ -226,3 +240,3 @@ router.get('/error_route', function (req, res, next) { | ||
router.use(function (err, req, res, next) { | ||
res.end(err.message) //=> "Bad Request" | ||
res.end(err.message) //= > "Bad Request" | ||
}) | ||
@@ -239,14 +253,14 @@ ``` | ||
// import our modules | ||
var http = require('http') | ||
var Router = require('router') | ||
var http = require('http') | ||
var Router = require('router') | ||
var finalhandler = require('finalhandler') | ||
var compression = require('compression') | ||
var bodyParser = require('body-parser') | ||
var compression = require('compression') | ||
var bodyParser = require('body-parser') | ||
// store our message to display | ||
var message = "Hello World!" | ||
var message = 'Hello World!' | ||
// initialize the router & server and add a final callback. | ||
var router = Router() | ||
var server = http.createServer(function onRequest(req, res) { | ||
var server = http.createServer(function onRequest (req, res) { | ||
router(req, res, finalhandler(req, res)) | ||
@@ -305,4 +319,4 @@ }) | ||
```js | ||
var http = require('http') | ||
var Router = require('router') | ||
var http = require('http') | ||
var Router = require('router') | ||
var finalhandler = require('finalhandler') | ||
@@ -315,4 +329,3 @@ | ||
var router = Router(opts) | ||
var server = http.createServer(function onRequest(req, res) { | ||
var server = http.createServer(function onRequest (req, res) { | ||
// set something to be passed into the router | ||
@@ -343,3 +356,3 @@ req.params = { type: 'kitten' } | ||
// will respond with the param of the router's parent route | ||
res.end(path + '\n') | ||
res.end(req.params.path + '\n') | ||
}) | ||
@@ -374,3 +387,3 @@ | ||
var router = new Router() | ||
var server = http.createServer(function onRequest(req, res) { | ||
var server = http.createServer(function onRequest (req, res) { | ||
router(req, res, finalhandler(req, res)) | ||
@@ -377,0 +390,0 @@ }) |
42756
6
412
13
+ Addedarray-flatten@3.0.0(transitive)
+ Addedpath-to-regexp@3.2.0(transitive)
+ Addedsetprototypeof@1.2.0(transitive)
- Removeddebug@3.1.0
- Removedarray-flatten@2.1.1(transitive)
- Removeddebug@3.1.0(transitive)
- Removedms@2.0.0(transitive)
- Removedpath-to-regexp@0.1.7(transitive)
- Removedsetprototypeof@1.1.0(transitive)
Updatedarray-flatten@3.0.0
Updatedparseurl@~1.3.3
Updatedpath-to-regexp@3.2.0
Updatedsetprototypeof@1.2.0