find-my-way
Advanced tools
Comparing version 1.17.1 to 1.18.0
@@ -70,2 +70,12 @@ import { IncomingMessage, ServerResponse } from 'http'; | ||
): void; | ||
versioning? : { | ||
storage() : { | ||
get(version: String) : Handler<V> | null, | ||
set(version: String, store: Handler<V>) : void, | ||
del(version: String) : void, | ||
empty() : void | ||
}, | ||
deriveVersion<Context>(req: V extends HTTPVersion.V1 ? IncomingMessage : Http2ServerRequest, ctx?: Context) : String, | ||
} | ||
} | ||
@@ -72,0 +82,0 @@ |
33
index.js
@@ -27,2 +27,4 @@ 'use strict' | ||
const acceptVersionStrategy = require('./lib/accept-version') | ||
function Router (opts) { | ||
@@ -45,3 +47,4 @@ if (!(this instanceof Router)) { | ||
this.allowUnsafeRegex = opts.allowUnsafeRegex || false | ||
this.tree = new Node() | ||
this.versioning = opts.versioning || acceptVersionStrategy | ||
this.tree = new Node({ versions: this.versioning.storage() }) | ||
this.routes = [] | ||
@@ -203,8 +206,8 @@ } | ||
node = new Node( | ||
prefix.slice(len), | ||
currentNode.children, | ||
currentNode.kind, | ||
new Node.Handlers(currentNode.handlers), | ||
currentNode.regex, | ||
currentNode.versions | ||
{ prefix: prefix.slice(len), | ||
children: currentNode.children, | ||
kind: currentNode.kind, | ||
handlers: new Node.Handlers(currentNode.handlers), | ||
regex: currentNode.regex, | ||
versions: currentNode.versions } | ||
) | ||
@@ -217,3 +220,3 @@ if (currentNode.wildcardChild !== null) { | ||
currentNode | ||
.reset(prefix.slice(0, len)) | ||
.reset(prefix.slice(0, len), this.versioning.storage()) | ||
.addChild(node) | ||
@@ -233,3 +236,9 @@ | ||
} else { | ||
node = new Node(path.slice(len), {}, kind, null, regex, null) | ||
node = new Node({ | ||
prefix: path.slice(len), | ||
kind: kind, | ||
handlers: null, | ||
regex: regex, | ||
versions: this.versioning.storage() | ||
}) | ||
if (version) { | ||
@@ -256,3 +265,3 @@ node.setVersionHandler(version, method, handler, params, store) | ||
// there are not children within the given label, let's create a new one! | ||
node = new Node(path, {}, kind, null, regex, null) | ||
node = new Node({ prefix: path, kind: kind, handlers: null, regex: regex, versions: this.versioning.storage() }) | ||
if (version) { | ||
@@ -281,3 +290,3 @@ node.setVersionHandler(version, method, handler, params, store) | ||
Router.prototype.reset = function reset () { | ||
this.tree = new Node() | ||
this.tree = new Node({ versions: this.versioning.storage() }) | ||
this.routes = [] | ||
@@ -333,3 +342,3 @@ } | ||
Router.prototype.lookup = function lookup (req, res, ctx) { | ||
var handle = this.find(req.method, sanitizeUrl(req.url), req.headers['accept-version']) | ||
var handle = this.find(req.method, sanitizeUrl(req.url), this.versioning.deriveVersion(req, ctx)) | ||
if (handle === null) return this._defaultRoute(req, res, ctx) | ||
@@ -336,0 +345,0 @@ return ctx === undefined |
21
node.js
@@ -5,3 +5,2 @@ 'use strict' | ||
const http = require('http') | ||
const SemVerStore = require('semver-store') | ||
const Handlers = buildHandlers() | ||
@@ -18,13 +17,15 @@ | ||
function Node (prefix, children, kind, handlers, regex, versions) { | ||
this.prefix = prefix || '/' | ||
function Node (options) { | ||
// former arguments order: prefix, children, kind, handlers, regex, versions | ||
options = options || {} | ||
this.prefix = options.prefix || '/' | ||
this.label = this.prefix[0] | ||
this.children = children || {} | ||
this.children = options.children || {} | ||
this.numberOfChildren = Object.keys(this.children).length | ||
this.kind = kind || this.types.STATIC | ||
this.handlers = new Handlers(handlers) | ||
this.regex = regex || null | ||
this.kind = options.kind || this.types.STATIC | ||
this.handlers = new Handlers(options.handlers) | ||
this.regex = options.regex || null | ||
this.wildcardChild = null | ||
this.parametricBrother = null | ||
this.versions = versions || SemVerStore() | ||
this.versions = options.versions | ||
} | ||
@@ -102,3 +103,3 @@ | ||
Node.prototype.reset = function (prefix) { | ||
Node.prototype.reset = function (prefix, versions) { | ||
this.prefix = prefix | ||
@@ -111,3 +112,3 @@ this.children = {} | ||
this.wildcardChild = null | ||
this.versions = SemVerStore() | ||
this.versions = versions | ||
return this | ||
@@ -114,0 +115,0 @@ } |
{ | ||
"name": "find-my-way", | ||
"version": "1.17.1", | ||
"version": "1.18.0", | ||
"description": "Crazy fast http radix based router", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -91,2 +91,33 @@ # find-my-way | ||
<a name="custom-versioning"></a> | ||
By default `find-my-way` uses [accept-version](./lib/accept-version.js) strategy to match requests with different versions of the handlers. The matching logic of that strategy is explained [below](#semver). It is possible to define the alternative strategy: | ||
```js | ||
const customVersioning = { | ||
// storage factory | ||
storage: function () { | ||
let versions = {} | ||
return { | ||
get: (version) => { return versions[version] || null }, | ||
set: (version, store) => { versions[version] = store }, | ||
del: (version) => { delete versions[version] }, | ||
empty: () => { versions = {} } | ||
} | ||
}, | ||
deriveVersion: (req, ctx) => { | ||
return req.headers['accept'] | ||
} | ||
} | ||
const router = FindMyWay({ versioning: customVersioning }); | ||
``` | ||
The custom strategy object should contain next properties: | ||
* `storage` - the factory function for the Storage of the handlers based on their version. | ||
* `deriveVersion` - the function to determine the version based on the request | ||
The signature of the functions and objects must match the one from the example above. | ||
*Please, be aware, if you use custom versioning strategy - you use it on your own risk. This can lead both to the performance degradation and bugs which are not related to `find-my-way` itself* | ||
<a name="on"></a> | ||
@@ -107,5 +138,9 @@ #### on(method, path, [opts], handler, [store]) | ||
##### Versioned routes | ||
If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route. | ||
###### default | ||
<a name="semver"></a> | ||
##### Versioned routes | ||
If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route. The versioning should follow the [semver](https://semver.org/) specification.<br/> | ||
Default versioning strategy is called `accept-version` and it follows the [semver](https://semver.org/) specification.<br/> | ||
When using `lookup`, `find-my-way` will automatically detect the `Accept-Version` header and route the request accordingly.<br/> | ||
@@ -127,2 +162,5 @@ Internally `find-my-way` uses the [`semver-store`](https://github.com/delvedor/semver-store) to get the correct version of the route; *advanced ranges* and *pre-releases* currently are not supported.<br/> | ||
###### custom | ||
It's also possible to define a [custom versioning strategy](#custom-versioning) during the `find-my-way` initialization. In this case the logic of matching the request to the specific handler depends on the versioning strategy you use. | ||
##### on(methods[], path, [opts], handler, [store]) | ||
@@ -279,3 +317,3 @@ Register a new route for each method specified in the `methods` array. | ||
The path must be sanitized, all the parameters and wildcards are decoded automatically.<br/> | ||
You can also pass an optional version string, which should be conform to the [semver](https://semver.org/) specification. | ||
You can also pass an optional version string. In case of the default versioning strategy it should be conform to the [semver](https://semver.org/) specification. | ||
```js | ||
@@ -282,0 +320,0 @@ router.find('GET', '/example') |
@@ -189,4 +189,4 @@ 'use strict' | ||
t.plan(1) | ||
const parent = new Node('/a') | ||
const parametricChild = new Node(':id', null, parent.types.PARAM) | ||
const parent = new Node({ prefix: '/a' }) | ||
const parametricChild = new Node({ prefix: ':id', kind: parent.types.PARAM }) | ||
parent.addChild(parametricChild) | ||
@@ -198,5 +198,5 @@ t.equal(parent.parametricBrother, null) | ||
t.plan(1) | ||
const parent = new Node('/a') | ||
const parametricChild = new Node(':id', null, parent.types.PARAM) | ||
const staticChild = new Node('/b', null, parent.types.STATIC) | ||
const parent = new Node({ prefix: '/a' }) | ||
const parametricChild = new Node({ prefix: ':id', kind: parent.types.PARAM }) | ||
const staticChild = new Node({ prefix: '/b', kind: parent.types.STATIC }) | ||
parent.addChild(parametricChild) | ||
@@ -203,0 +203,0 @@ parent.addChild(staticChild) |
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
152874
39
4318
356