Skip to content

Commit

Permalink
Merge branch 'main' into null-object-parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak authored Apr 23, 2024
2 parents ba6b613 + a9d1ee1 commit 6684511
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 67 deletions.
34 changes: 34 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
commit-message:
# Prefix all commit messages with "chore: "
prefix: "chore"
schedule:
interval: "monthly"
open-pull-requests-limit: 10

- package-ecosystem: "npm"
directory: "/"
commit-message:
# Prefix all commit messages with "chore: "
prefix: "chore"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
groups:
# Production dependencies without breaking changes
dependencies:
dependency-type: "production"
update-types:
- "minor"
- "patch"
# Production dependencies with breaking changes
dependencies-major:
dependency-type: "production"
update-types:
- "major"
# Development dependencies
dev-dependencies:
dependency-type: "development"
39 changes: 33 additions & 6 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: Node CI

on: [push, pull_request]
on:
push:
branches:
- main
- next
pull_request:

permissions:
contents: read
Expand All @@ -12,17 +17,25 @@ jobs:

strategy:
matrix:
node-version: [14.x, 16.x, 18.x, 20.x]
os: [ubuntu-latest, windows-latest, macOS-latest]
node-version:
- 14
- 16
- 18
- 20
- 21
os:
- ubuntu-latest
- windows-latest
- macOS-latest
exclude:
- os: windows-latest
node-version: 14.x
node-version: 14

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

Expand All @@ -41,3 +54,17 @@ jobs:
- name: Type Definitions
run: |
npm run test:typescript
automerge:
if: >
github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]'
needs: test
runs-on: ubuntu-latest
permissions:
actions: write
pull-requests: write
contents: write
steps:
- uses: fastify/github-action-merge-dependabot@9e7bfb249c69139d7bdcd8d984f9665edd49020b # v3.10.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
4 changes: 0 additions & 4 deletions .taprc
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
ts: false
jsx: false
flow: false
branches: 90
functions: 90
lines: 90
statements: 90
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ router.hasRoute('GET', '/:file(^\\D+).jpg')
// => false
```

```js
#### lookup(request, response, [context], [done])

Start a new search, `request` and `response` are the server req/res objects.<br>
If a route is found it will automatically call the handler, otherwise the default route will be called.<br>
The url is sanitized internally, all the parameters and wildcards are decoded automatically.
Expand Down
62 changes: 26 additions & 36 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
'~': 126 - ~
*/

const assert = require('assert')
const assert = require('node:assert')
const querystring = require('fast-querystring')
const isRegexSafe = require('safe-regex2')
const deepEqual = require('fast-deep-equal')
Expand Down Expand Up @@ -344,7 +344,6 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
const isRegexParam = charCode === 40
const isStaticPart = charCode === 45 || charCode === 46
const isEndOfNode = charCode === 47 || j === pattern.length

if (isRegexParam || isStaticPart || isEndOfNode) {
const paramName = pattern.slice(lastParamStartIndex, j)
params.push(paramName)
Expand Down Expand Up @@ -407,9 +406,7 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
// add the wildcard parameter
params.push('*')
currentNode = currentNode.getWildcardChild()
if (currentNode === null) {
return null
}

parentNodePathIndex = i + 1

if (i !== pattern.length - 1) {
Expand All @@ -422,10 +419,6 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
pattern = pattern.toLowerCase()
}

if (pattern === '*') {
pattern = '/*'
}

for (const existRoute of this.routes) {
const routeConstraints = existRoute.opts.constraints || {}
if (
Expand All @@ -436,7 +429,7 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
return {
handler: existRoute.handler,
store: existRoute.store,
params: existRoute.params || []
params: existRoute.params
}
}
}
Expand Down Expand Up @@ -642,37 +635,36 @@ Router.prototype.find = function find (method, path, derivedConstraints) {
continue
}

if (currentNode.kind === NODE_TYPES.PARAMETRIC) {
let paramEndIndex = originPath.indexOf('/', pathIndex)
if (paramEndIndex === -1) {
paramEndIndex = pathLen
}
// parametric node
let paramEndIndex = originPath.indexOf('/', pathIndex)
if (paramEndIndex === -1) {
paramEndIndex = pathLen
}

let param = originPath.slice(pathIndex, paramEndIndex)
if (shouldDecodeParam) {
param = safeDecodeURIComponent(param)
}
let param = originPath.slice(pathIndex, paramEndIndex)
if (shouldDecodeParam) {
param = safeDecodeURIComponent(param)
}

if (currentNode.isRegex) {
const matchedParameters = currentNode.regex.exec(param)
if (matchedParameters === null) continue
if (currentNode.isRegex) {
const matchedParameters = currentNode.regex.exec(param)
if (matchedParameters === null) continue

for (let i = 1; i < matchedParameters.length; i++) {
const matchedParam = matchedParameters[i]
if (matchedParam.length > maxParamLength) {
return null
}
params.push(matchedParam)
}
} else {
if (param.length > maxParamLength) {
for (let i = 1; i < matchedParameters.length; i++) {
const matchedParam = matchedParameters[i]
if (matchedParam.length > maxParamLength) {
return null
}
params.push(param)
params.push(matchedParam)
}

pathIndex = paramEndIndex
} else {
if (param.length > maxParamLength) {
return null
}
params.push(param)
}

pathIndex = paramEndIndex
}
}

Expand Down Expand Up @@ -742,8 +734,6 @@ for (const i in httpMethods) {
const m = httpMethods[i]
const methodName = m.toLowerCase()

if (Router.prototype[methodName]) throw new Error('Method already exists: ' + methodName)

Router.prototype[methodName] = function (path, handler, store) {
return this.on(m, path, handler, store)
}
Expand Down
6 changes: 2 additions & 4 deletions lib/constrainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const acceptVersionStrategy = require('./strategies/accept-version')
const acceptHostStrategy = require('./strategies/accept-host')
const assert = require('assert')
const assert = require('node:assert')

class Constrainer {
constructor (customStrategies) {
Expand Down Expand Up @@ -153,10 +153,8 @@ class Constrainer {
if (!strategy.isCustom) {
if (key === 'version') {
lines.push(' version: req.headers[\'accept-version\'],')
} else if (key === 'host') {
lines.push(' host: req.headers.host || req.headers[\':authority\'],')
} else {
throw new Error('unknown non-custom strategy for compiling constraint derivation function')
lines.push(' host: req.headers.host || req.headers[\':authority\'],')
}
} else {
lines.push(` ${strategy.name}: this.strategies.${key}.deriveConstraint(req, ctx),`)
Expand Down
5 changes: 1 addition & 4 deletions lib/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,7 @@ class StaticNode extends ParentNode {
}

getWildcardChild () {
if (this.wildcardChild) {
return this.wildcardChild
}
return null
return this.wildcardChild
}

createWildcardChild () {
Expand Down
2 changes: 1 addition & 1 deletion lib/strategies/accept-host.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict'
const assert = require('assert')
const assert = require('node:assert')

function HostStorage () {
const hosts = {}
Expand Down
10 changes: 7 additions & 3 deletions lib/strategies/accept-version.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const assert = require('assert')
const assert = require('node:assert')

function SemVerStore () {
if (!(this instanceof SemVerStore)) {
Expand All @@ -20,7 +20,11 @@ SemVerStore.prototype.set = function (version, store) {
}
let [major, minor, patch] = version.split('.')

major = Number(major) || 0
if (isNaN(major)) {
throw new TypeError('Major version must be a numeric value')
}

major = Number(major)
minor = Number(minor) || 0
patch = Number(patch) || 0

Expand All @@ -38,7 +42,7 @@ SemVerStore.prototype.set = function (version, store) {
this.store[`${major}.x.x`] = store
}

if (patch >= (this.store[`${major}.${minor}`] || 0)) {
if (patch >= (this.maxPatches[`${major}.${minor}`] || 0)) {
this.maxPatches[`${major}.${minor}`] = patch
this.store[`${major}.${minor}.x`] = store
}
Expand Down
5 changes: 1 addition & 4 deletions lib/strategies/http-method.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ module.exports = {
set: (type, store) => { handlers[type] = store }
}
},
deriveConstraint: (req) => {
/* istanbul ignore next */
return req.method
},
deriveConstraint: /* istanbul ignore next */ (req) => req.method,
mustMatchWhenDerived: true
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"chalk": "^4.1.2",
"inquirer": "^8.2.4",
"pre-commit": "^1.2.2",
"proxyquire": "^2.1.3",
"rfdc": "^1.3.0",
"simple-git": "^3.7.1",
"standard": "^14.3.4",
Expand All @@ -50,7 +51,7 @@
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-querystring": "^1.0.0",
"safe-regex2": "^2.0.0"
"safe-regex2": "^3.1.0"
},
"tsd": {
"directory": "test/types"
Expand Down
10 changes: 7 additions & 3 deletions test/constraint.custom.async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const t = require('tap')
const test = t.test
const FindMyWay = require('..')
const rfdc = require('rfdc')({ proto: true })

const customHeaderConstraint = {
name: 'requestedBy',
Expand All @@ -23,11 +24,14 @@ const customHeaderConstraint = {
}
}

test('should derive async constraint', t => {
test('should derive multiple async constraints', t => {
t.plan(2)

const router = FindMyWay({ constraints: { requestedBy: customHeaderConstraint } })
router.on('GET', '/', { constraints: { requestedBy: 'node' } }, () => 'asyncHandler')
const customHeaderConstraint2 = rfdc(customHeaderConstraint)
customHeaderConstraint2.name = 'requestedBy2'

const router = FindMyWay({ constraints: { requestedBy: customHeaderConstraint, requestedBy2: customHeaderConstraint2 } })
router.on('GET', '/', { constraints: { requestedBy: 'node', requestedBy2: 'node' } }, () => 'asyncHandler')

router.lookup(
{
Expand Down
Loading

0 comments on commit 6684511

Please sign in to comment.