Skip to content

Commit

Permalink
feat: Updating to the latest path-to-regexp.
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Latest version of path-to-regexp no longer allows path routes like /* (use /(.*) instead), /users/id:(\\d+) (use /users/id-(\\d+) instead)
  • Loading branch information
joeyguerra committed Dec 23, 2023
1 parent 5a3a9ef commit 9a759c7
Show file tree
Hide file tree
Showing 9 changed files with 1,166 additions and 39 deletions.
214 changes: 214 additions & 0 deletions lib/Layer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*!
* router
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/

'use strict'

/**
* Module dependencies.
* @private
*/

var {pathToRegexp} = require('path-to-regexp')

/**
* Module variables.
* @private
*/

var hasOwnProperty = Object.prototype.hasOwnProperty
var TRAILING_SLASH_REGEXP = /\/+$/

/**
* Expose `Layer`.
*/

module.exports = Layer

function Layer (path, options, fn) {
if (!(this instanceof Layer)) {
return new Layer(path, options, fn)
}

var opts = options || {}

this.handle = fn
this.keys = []
this.name = fn.name || '<anonymous>'
this.params = undefined
this.path = undefined
this.regexp = pathToRegexp((opts.strict ? path : loosen(path)), this.keys, opts)

// set fast path flags
this.regexp._slash = path === '/' && opts.end === false
}

/**
* 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) {
var fn = this.handle

if (fn.length !== 4) {
// not a standard error handler
return next(error)
}

try {
// invoke function
var ret = fn(error, req, res, next)

// wait for returned promise
if (isPromise(ret)) {
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) {
var fn = this.handle
if (fn.length > 3) {
// not a standard request handler
return next()
}

try {
// invoke function
var ret = fn(req, res, next)

// wait for returned promise
if (isPromise(ret)) {
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) {
var match

if (path != null) {
// fast path non-ending match for / (any path matches)
if (this.regexp._slash) {
this.params = {}
this.path = ''
return true
}

// match the path
match = this.regexp.exec(path)
}

if (!match) {
this.params = undefined
this.path = undefined
return false
}

// store values
this.params = {}
this.path = match[0]

// iterate matches
var keys = this.keys
var params = this.params

for (var i = 1; i < match.length; i++) {
var key = keys[i - 1]
var prop = key.name
var val = decodeParam(match[i])

if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
params[prop] = val
}
}

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

/**
* Returns true if the val is a Promise.
*
* @param {*} val
* @return {boolean}
* @private
*/

function isPromise (val) {
return val &&
typeof val === 'object' &&
typeof val.then === 'function'
}

/**
* 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, '')
}
Loading

0 comments on commit 9a759c7

Please sign in to comment.