Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2re8 2 #120

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@ function processParams (params, layer, called, req, res, done) {
}

let i = 0
let name
let paramIndex = 0
let key
let paramVal
Expand All @@ -596,10 +595,9 @@ function processParams (params, layer, called, req, res, done) {

paramIndex = 0
key = keys[i++]
name = key.name
paramVal = req.params[name]
paramCallbacks = params[name]
paramCalled = called[name]
paramVal = req.params[key]
paramCallbacks = params[key]
paramCalled = called[key]

if (paramVal === undefined || !paramCallbacks) {
return param()
Expand All @@ -609,13 +607,13 @@ function processParams (params, layer, called, req, res, done) {
if (paramCalled && (paramCalled.match === paramVal ||
(paramCalled.error && paramCalled.error !== 'route'))) {
// restore value
req.params[name] = paramCalled.value
req.params[key] = paramCalled.value

// next param
return param(paramCalled.error)
}

called[name] = paramCalled = {
called[key] = paramCalled = {
error: null,
match: paramVal,
value: paramVal
Expand All @@ -629,7 +627,7 @@ function processParams (params, layer, called, req, res, done) {
const fn = paramCallbacks[paramIndex++]

// store updated value
paramCalled.value = req.params[key.name]
paramCalled.value = req.params[key]

if (err) {
// store error
Expand All @@ -641,7 +639,7 @@ function processParams (params, layer, called, req, res, done) {
if (!fn) return param()

try {
const ret = fn(req, res, paramCallback, paramVal, key.name)
const ret = fn(req, res, paramCallback, paramVal, key)
if (isPromise(ret)) {
ret.then(null, function (error) {
paramCallback(error || new Error('Rejected promise'))
Expand Down
81 changes: 58 additions & 23 deletions lib/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const pathRegexp = require('path-to-regexp')

const hasOwnProperty = Object.prototype.hasOwnProperty
const TRAILING_SLASH_REGEXP = /\/+$/
const MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g

/**
* Expose `Layer`.
Expand All @@ -41,10 +42,53 @@ function Layer (path, options, fn) {
this.name = fn.name || '<anonymous>'
this.params = undefined
this.path = undefined
this.regexp = pathRegexp((opts.strict ? path : loosen(path)), this.keys, opts)
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 || !(hasOwnProperty.call(params, prop))) {
params[prop] = val
}
}

return {
params,
path: p
}
}
}

// set fast path flags
this.regexp._slash = path === '/' && opts.end === false
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)]
}

/**
Expand Down Expand Up @@ -126,14 +170,18 @@ Layer.prototype.match = function match (path) {

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

// match the path
match = this.regexp.exec(path)
let i = 0
while (!match && i < this.matchers.length) {
// match the path
match = this.matchers[i](path)
i++
}
}

if (!match) {
Expand All @@ -143,22 +191,9 @@ Layer.prototype.match = function match (path) {
}

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

// iterate matches
const keys = this.keys
const params = this.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 || !(hasOwnProperty.call(params, prop))) {
params[prop] = val
}
}
this.params = match.params
this.path = match.path
this.keys = Object.keys(match.params)

return true
}
Expand Down Expand Up @@ -192,7 +227,7 @@ function decodeParam (val) {
* Loosens the given path for path-to-regexp matching.
*/
function loosen (path) {
if (path instanceof RegExp) {
if (path instanceof RegExp || path === '/') {
return path
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"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"
Expand Down
40 changes: 0 additions & 40 deletions test/req.params.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,46 +124,6 @@ describe('req.params', function () {
.expect('x-params-1', '{"foo":"buzz"}')
.expect(200, '{"foo":"bar"}', done)
})

describe('with numeric properties in req.params', function () {
it('should merge numeric properties by offsetting', function (done) {
const router = Router({ mergeParams: true })
const server = createServer(function (req, res, next) {
req.params = { 0: 'foo', 1: 'bar' }

router(req, res, function (err) {
if (err) return next(err)
sawParams(req, res)
})
})

router.get('/(.*)', hitParams(1))

request(server)
.get('/buzz')
.expect('x-params-1', '{"0":"foo","1":"bar","2":"buzz"}')
.expect(200, '{"0":"foo","1":"bar"}', done)
})

it('should merge with same numeric properties', function (done) {
const router = Router({ mergeParams: true })
const server = createServer(function (req, res, next) {
req.params = { 0: 'foo' }

router(req, res, function (err) {
if (err) return next(err)
sawParams(req, res)
})
})

router.get('/(.*)', hitParams(1))

request(server)
.get('/bar')
.expect('x-params-1', '{"0":"foo","1":"bar"}')
.expect(200, '{"0":"foo"}', done)
})
})
})
})

Expand Down
Loading
Loading