find-my-way
Advanced tools
Comparing version 7.2.1 to 7.3.0
31
index.js
@@ -377,4 +377,31 @@ 'use strict' | ||
Router.prototype.lookup = function lookup (req, res, ctx) { | ||
var handle = this.find(req.method, req.url, this.constrainer.deriveConstraints(req, ctx)) | ||
Router.prototype.lookup = function lookup (req, res, ctx, done) { | ||
if (typeof ctx === 'function') { | ||
done = ctx | ||
ctx = undefined | ||
} | ||
if (done === undefined) { | ||
const constraints = this.constrainer.deriveConstraints(req, ctx) | ||
const handle = this.find(req.method, req.url, constraints) | ||
return this.callHandler(handle, req, res, ctx) | ||
} | ||
this.constrainer.deriveConstraints(req, ctx, (err, constraints) => { | ||
if (err !== null) { | ||
done(err) | ||
return | ||
} | ||
try { | ||
const handle = this.find(req.method, req.url, constraints) | ||
const result = this.callHandler(handle, req, res, ctx) | ||
done(null, result) | ||
} catch (err) { | ||
done(err) | ||
} | ||
}) | ||
} | ||
Router.prototype.callHandler = function callHandler (handle, req, res, ctx) { | ||
if (handle === null) return this._defaultRoute(req, res, ctx) | ||
@@ -381,0 +408,0 @@ return ctx === undefined |
@@ -15,2 +15,3 @@ 'use strict' | ||
this.strategiesInUse = new Set() | ||
this.asyncStrategiesInUse = new Set() | ||
@@ -25,6 +26,12 @@ // validate and optimize prototypes of given custom strategies | ||
isStrategyUsed (strategyName) { | ||
return this.strategiesInUse.has(strategyName) || | ||
this.asyncStrategiesInUse.has(strategyName) | ||
} | ||
hasConstraintStrategy (strategyName) { | ||
const customConstraintStrategy = this.strategies[strategyName] | ||
if (customConstraintStrategy !== undefined) { | ||
return customConstraintStrategy.isCustom || this.strategiesInUse.has(strategyName) | ||
return customConstraintStrategy.isCustom || | ||
this.isStrategyUsed(strategyName) | ||
} | ||
@@ -43,3 +50,3 @@ return false | ||
if (this.strategiesInUse.has(strategy.name)) { | ||
if (this.isStrategyUsed(strategy.name)) { | ||
throw new Error(`There already exists a route with ${strategy.name} constraint.`) | ||
@@ -49,2 +56,3 @@ } | ||
strategy.isCustom = true | ||
strategy.isAsync = strategy.deriveConstraint.length === 3 | ||
this.strategies[strategy.name] = strategy | ||
@@ -57,3 +65,13 @@ | ||
deriveConstraints (req, ctx) { | ||
deriveConstraints (req, ctx, done) { | ||
const constraints = this.deriveSyncConstraints(req, ctx) | ||
if (done === undefined) { | ||
return constraints | ||
} | ||
this.deriveAsyncConstraints(constraints, req, ctx, done) | ||
} | ||
deriveSyncConstraints (req, ctx) { | ||
return undefined | ||
@@ -67,3 +85,8 @@ } | ||
for (const key in constraints) { | ||
this.strategiesInUse.add(key) | ||
const strategy = this.strategies[key] | ||
if (strategy.isAsync) { | ||
this.asyncStrategiesInUse.add(key) | ||
} else { | ||
this.strategiesInUse.add(key) | ||
} | ||
} | ||
@@ -99,2 +122,28 @@ if (beforeSize !== this.strategiesInUse.size) { | ||
deriveAsyncConstraints (constraints, req, ctx, done) { | ||
let asyncConstraintsCount = this.asyncStrategiesInUse.size | ||
if (asyncConstraintsCount === 0) { | ||
done(null, constraints) | ||
return | ||
} | ||
constraints = constraints || {} | ||
for (const key of this.asyncStrategiesInUse) { | ||
const strategy = this.strategies[key] | ||
strategy.deriveConstraint(req, ctx, (err, constraintValue) => { | ||
if (err !== null) { | ||
done(err) | ||
return | ||
} | ||
constraints[key] = constraintValue | ||
if (--asyncConstraintsCount === 0) { | ||
done(null, constraints) | ||
} | ||
}) | ||
} | ||
} | ||
// Optimization: build a fast function for deriving the constraints for all the strategies at once. We inline the definitions of the version constraint and the host constraint for performance. | ||
@@ -126,3 +175,3 @@ // If no constraining strategies are in use (no routes constrain on host, or version, or any custom strategies) then we don't need to derive constraints for each route match, so don't do anything special, and just return undefined | ||
this.deriveConstraints = new Function('req', 'ctx', lines.join('\n')).bind(this) // eslint-disable-line | ||
this.deriveSyncConstraints = new Function('req', 'ctx', lines.join('\n')).bind(this) // eslint-disable-line | ||
} | ||
@@ -129,0 +178,0 @@ } |
{ | ||
"name": "find-my-way", | ||
"version": "7.2.1", | ||
"version": "7.3.0", | ||
"description": "Crazy fast http radix based router", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -25,3 +25,3 @@ # find-my-way | ||
- [off(methods, path, [constraints])](#offmethods-path-constraints) | ||
- [lookup(request, response, [context])](#lookuprequest-response-context) | ||
- [lookup(request, response, [context], [done])](#lookuprequest-response-context) | ||
- [find(method, path, [constraints])](#findmethod-path-constraints) | ||
@@ -382,3 +382,3 @@ - [prettyPrint([{ commonPrefix: false, includeMeta: true || [] }])](#prettyprint-commonprefix-false-includemeta-true---) | ||
#### lookup(request, response, [context]) | ||
#### lookup(request, response, [context], [done]) | ||
Start a new search, `request` and `response` are the server req/res objects.<br> | ||
@@ -399,2 +399,15 @@ If a route is found it will automatically call the handler, otherwise the default route will be called.<br> | ||
`lookup` accepts an optional `done` callback for case when you use an async `deriveConstraint` function. | ||
```js | ||
router.on('GET', '*', function(req, res) { | ||
res.end({ hello: 'world' }); | ||
}) | ||
router.lookup(req, res, (err) => { | ||
if (err !== null) { | ||
// handle error | ||
} | ||
console.log('Handler executed!!!'); | ||
}) | ||
``` | ||
<a name="find"></a> | ||
@@ -608,3 +621,26 @@ #### find(method, path, [constraints]) | ||
Add a custom constraint strategy using the addConstraintStrategy method: | ||
```js | ||
const asyncCustomResponseTypeStrategy = { | ||
// strategy name for referencing in the route handler `constraints` options | ||
name: 'accept', | ||
// storage factory for storing routes in the find-my-way route tree | ||
storage: function () { | ||
let handlers = {} | ||
return { | ||
get: (type) => { return handlers[type] || null }, | ||
set: (type, store) => { handlers[type] = store } | ||
} | ||
}, | ||
// function to get the value of the constraint from each incoming request | ||
deriveConstraint: (req, ctx, done) => { | ||
done(null, req.headers['accept']) | ||
}, | ||
// optional flag marking if handlers without constraints can match requests that have a value for this constraint | ||
mustMatchWhenDerived: true | ||
} | ||
const router = FindMyWay({ constraints: { accept: asyncCustomResponseTypeStrategy } }); | ||
``` | ||
Add an async custom constrain strategy when constructing a router: | ||
```js | ||
@@ -611,0 +647,0 @@ const customResponseTypeStrategy = { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
324696
84
8106
731