Skip to content

Commit

Permalink
WIP: v8
Browse files Browse the repository at this point in the history
  • Loading branch information
wesleytodd committed Sep 1, 2024
1 parent f5a99b0 commit 0d516c4
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 258 deletions.
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) {
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

0 comments on commit 0d516c4

Please # to comment.