Socket
Socket
Sign inDemoInstall

router

Package Overview
Dependencies
6
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0-alpha.1 to 2.0.0-beta.1

35

HISTORY.md

@@ -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 @@ })

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc