Socket
Socket
Sign inDemoInstall

find-my-way

Package Overview
Dependencies
Maintainers
2
Versions
112
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

find-my-way - npm Package Compare versions

Comparing version 3.0.4 to 3.0.5

lib/pretty-print.js

27

bench.js

@@ -20,3 +20,6 @@ 'use strict'

findMyWay.on('GET', '/user/:id/static', () => true)
findMyWay.on('POST', '/user/:id', () => true)
findMyWay.on('PUT', '/user/:id', () => true)
findMyWay.on('GET', '/customer/:name-:surname', () => true)
findMyWay.on('POST', '/customer', () => true)
findMyWay.on('GET', '/at/:hour(^\\d+)h:minute(^\\d+)m', () => true)

@@ -26,2 +29,20 @@ findMyWay.on('GET', '/abc/def/ghi/lmn/opq/rst/uvz', () => true)

findMyWay.on('GET', '/products', () => true)
findMyWay.on('GET', '/products/:id', () => true)
findMyWay.on('GET', '/products/:id/options', () => true)
findMyWay.on('GET', '/posts', () => true)
findMyWay.on('POST', '/posts', () => true)
findMyWay.on('GET', '/posts/:id', () => true)
findMyWay.on('GET', '/posts/:id/author', () => true)
findMyWay.on('GET', '/posts/:id/comments', () => true)
findMyWay.on('POST', '/posts/:id/comments', () => true)
findMyWay.on('GET', '/posts/:id/comments/:id', () => true)
findMyWay.on('GET', '/posts/:id/comments/:id/author', () => true)
findMyWay.on('GET', '/posts/:id/counter', () => true)
findMyWay.on('GET', '/pages', () => true)
findMyWay.on('POST', '/pages', () => true)
findMyWay.on('GET', '/pages/:id', () => true)
suite

@@ -70,2 +91,8 @@ .add('lookup static route', function () {

})
.add('find long nested dynamic route', function () {
findMyWay.find('GET', '/posts/10/comments/42/author', undefined)
})
.add('find long nested dynamic route with other method', function () {
findMyWay.find('POST', '/posts/10/comments', undefined)
})
.on('cycle', function (event) {

@@ -72,0 +99,0 @@ console.log(String(event.target))

87

index.js

@@ -18,2 +18,3 @@ 'use strict'

const isRegexSafe = require('safe-regex2')
const { flattenNode, compressFlattenedNode, prettyPrintFlattenedNode } = require('./lib/pretty-print')
const Node = require('./node')

@@ -54,4 +55,4 @@ const NODE_TYPES = Node.prototype.types

this.allowUnsafeRegex = opts.allowUnsafeRegex || false
this.versioning = opts.versioning || acceptVersionStrategy
this.tree = new Node({ versions: this.versioning.storage() })
this.versioning = opts.versioning || acceptVersionStrategy(false)
this.trees = {}
this.routes = []

@@ -115,2 +116,5 @@ }

const version = opts.version
if (version != null && this.versioning.disabled) {
this.versioning = acceptVersionStrategy(true)
}

@@ -201,3 +205,2 @@ for (var i = 0, len = path.length; i < len; i++) {

const route = path
var currentNode = this.tree
var prefix = ''

@@ -210,2 +213,8 @@ var pathLen = 0

var currentNode = this.trees[method]
if (typeof currentNode === 'undefined') {
currentNode = new Node({ method: method, versions: this.versioning.storage() })
this.trees[method] = currentNode
}
while (true) {

@@ -226,6 +235,7 @@ prefix = currentNode.prefix

{
method: method,
prefix: prefix.slice(len),
children: currentNode.children,
kind: currentNode.kind,
handlers: new Node.Handlers(currentNode.handlers),
handler: currentNode.handler,
regex: currentNode.regex,

@@ -248,7 +258,7 @@ versions: currentNode.versions

if (version) {
assert(!currentNode.getVersionHandler(version, method), `Method '${method}' already declared for route '${route}' version '${version}'`)
currentNode.setVersionHandler(version, method, handler, params, store)
assert(!currentNode.getVersionHandler(version), `Method '${method}' already declared for route '${route}' version '${version}'`)
currentNode.setVersionHandler(version, handler, params, store)
} else {
assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${route}'`)
currentNode.setHandler(method, handler, params, store)
assert(!currentNode.handler, `Method '${method}' already declared for route '${route}'`)
currentNode.setHandler(handler, params, store)
}

@@ -258,2 +268,3 @@ currentNode.kind = kind

node = new Node({
method: method,
prefix: path.slice(len),

@@ -266,5 +277,5 @@ kind: kind,

if (version) {
node.setVersionHandler(version, method, handler, params, store)
node.setVersionHandler(version, handler, params, store)
} else {
node.setHandler(method, handler, params, store)
node.setHandler(handler, params, store)
}

@@ -287,7 +298,7 @@ currentNode.addChild(node)

// there are not children within the given label, let's create a new one!
node = new Node({ prefix: path, kind: kind, handlers: null, regex: regex, versions: this.versioning.storage() })
node = new Node({ method: method, prefix: path, kind: kind, regex: regex, versions: this.versioning.storage() })
if (version) {
node.setVersionHandler(version, method, handler, params, store)
node.setVersionHandler(version, handler, params, store)
} else {
node.setHandler(method, handler, params, store)
node.setHandler(handler, params, store)
}

@@ -300,7 +311,7 @@

if (version) {
assert(!currentNode.getVersionHandler(version, method), `Method '${method}' already declared for route '${route}' version '${version}'`)
currentNode.setVersionHandler(version, method, handler, params, store)
assert(!currentNode.getVersionHandler(version), `Method '${method}' already declared for route '${route}' version '${version}'`)
currentNode.setVersionHandler(version, handler, params, store)
} else {
assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${route}'`)
currentNode.setHandler(method, handler, params, store)
assert(!currentNode.handler, `Method '${method}' already declared for route '${route}'`)
currentNode.setHandler(handler, params, store)
}

@@ -313,3 +324,3 @@ }

Router.prototype.reset = function reset () {
this.tree = new Node({ versions: this.versioning.storage() })
this.trees = {}
this.routes = []

@@ -373,2 +384,5 @@ }

Router.prototype.find = function find (method, path, version) {
var currentNode = this.trees[method]
if (!currentNode) return null
if (path.charCodeAt(0) !== 47) { // 47 is '/'

@@ -386,3 +400,2 @@ path = path.replace(FULL_PATH_REGEXP, '/')

var maxParamLength = this.maxParamLength
var currentNode = this.tree
var wildcardNode = null

@@ -405,4 +418,4 @@ var pathLenWildcard = 0

var handle = version === undefined
? currentNode.handlers[method]
: currentNode.getVersionHandler(version, method)
? currentNode.handler
: currentNode.getVersionHandler(version)
if (handle !== null && handle !== undefined) {

@@ -437,4 +450,4 @@ var paramsObj = {}

var node = version === undefined
? currentNode.findChild(path, method)
: currentNode.findVersionChild(version, path, method)
? currentNode.findChild(path)
: currentNode.findVersionChild(version, path)

@@ -444,3 +457,3 @@ if (node === null) {

if (node === null) {
return this._getWildcardNode(wildcardNode, method, originalPath, pathLenWildcard)
return this._getWildcardNode(wildcardNode, originalPath, pathLenWildcard)
}

@@ -468,3 +481,3 @@

// if exist, save the wildcard child
if (currentNode.wildcardChild !== null && currentNode.wildcardChild.handlers[method] !== null) {
if (currentNode.wildcardChild !== null) {
wildcardNode = currentNode.wildcardChild

@@ -478,7 +491,7 @@ pathLenWildcard = pathLen

if (len !== prefixLen) {
return this._getWildcardNode(wildcardNode, method, originalPath, pathLenWildcard)
return this._getWildcardNode(wildcardNode, originalPath, pathLenWildcard)
}
// if exist, save the wildcard child
if (currentNode.wildcardChild !== null && currentNode.wildcardChild.handlers[method] !== null) {
if (currentNode.wildcardChild !== null) {
wildcardNode = currentNode.wildcardChild

@@ -567,3 +580,3 @@ pathLenWildcard = pathLen

Router.prototype._getWildcardNode = function (node, method, path, len) {
Router.prototype._getWildcardNode = function (node, path, len) {
if (node === null) return null

@@ -576,3 +589,3 @@ var decoded = fastDecode(path.slice(-len))

}
var handle = node.handlers[method]
var handle = node.handler
if (handle !== null && handle !== undefined) {

@@ -609,3 +622,17 @@ return {

Router.prototype.prettyPrint = function () {
return this.tree.prettyPrint('', true)
const root = {
prefix: '/',
nodes: [],
children: {}
}
for (const node of Object.values(this.trees)) {
if (node) {
flattenNode(root, node)
}
}
compressFlattenedNode(root)
return prettyPrintFlattenedNode(root, '', true)
}

@@ -612,0 +639,0 @@

@@ -5,7 +5,18 @@ 'use strict'

module.exports = {
storage: SemVerStore,
deriveVersion: function (req, ctx) {
return req.headers['accept-version']
function build (enabled) {
if (enabled) {
return {
storage: SemVerStore,
deriveVersion: function (req, ctx) {
return req.headers['accept-version']
}
}
}
return {
storage: SemVerStore,
deriveVersion: function (req, ctx) {},
disabled: true
}
}
module.exports = build
'use strict'
const assert = require('assert')
const http = require('http')
const Handlers = buildHandlers()

@@ -17,10 +15,10 @@ const types = {

function Node (options) {
// former arguments order: prefix, children, kind, handlers, regex, versions
options = options || {}
this.prefix = options.prefix || '/'
this.label = this.prefix[0]
this.method = options.method // just for debugging and error messages
this.children = options.children || {}
this.numberOfChildren = Object.keys(this.children).length
this.kind = options.kind || this.types.STATIC
this.handlers = new Handlers(options.handlers)
this.handler = options.handler
this.regex = options.regex || null

@@ -106,3 +104,3 @@ this.wildcardChild = null

this.kind = this.types.STATIC
this.handlers = new Handlers()
this.handler = null
this.numberOfChildren = 0

@@ -119,5 +117,5 @@ this.regex = null

Node.prototype.findChild = function (path, method) {
Node.prototype.findChild = function (path) {
var child = this.children[path[0]]
if (child !== undefined && (child.numberOfChildren > 0 || child.handlers[method] !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.handler !== null)) {
if (path.slice(0, child.prefix.length) === child.prefix) {

@@ -129,3 +127,3 @@ return child

child = this.children[':']
if (child !== undefined && (child.numberOfChildren > 0 || child.handlers[method] !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.handler !== null)) {
return child

@@ -135,3 +133,3 @@ }

child = this.children['*']
if (child !== undefined && (child.numberOfChildren > 0 || child.handlers[method] !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.handler !== null)) {
return child

@@ -143,5 +141,5 @@ }

Node.prototype.findVersionChild = function (version, path, method) {
Node.prototype.findVersionChild = function (version, path) {
var child = this.children[path[0]]
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version, method) !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version) !== null)) {
if (path.slice(0, child.prefix.length) === child.prefix) {

@@ -153,3 +151,3 @@ return child

child = this.children[':']
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version, method) !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version) !== null)) {
return child

@@ -159,3 +157,3 @@ }

child = this.children['*']
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version, method) !== null)) {
if (child !== undefined && (child.numberOfChildren > 0 || child.getVersionHandler(version) !== null)) {
return child

@@ -167,11 +165,11 @@ }

Node.prototype.setHandler = function (method, handler, params, store) {
Node.prototype.setHandler = function (handler, params, store) {
if (!handler) return
assert(
this.handlers[method] !== undefined,
`There is already an handler with method '${method}'`
!this.handler,
`There is already an handler with method '${this.method}'`
)
this.handlers[method] = {
this.handler = {
handler: handler,

@@ -184,12 +182,11 @@ params: params,

Node.prototype.setVersionHandler = function (version, method, handler, params, store) {
Node.prototype.setVersionHandler = function (version, handler, params, store) {
if (!handler) return
const handlers = this.versions.get(version) || new Handlers()
assert(
handlers[method] === null,
`There is already an handler with version '${version}' and method '${method}'`
!this.versions.get(version),
`There is already an handler with version '${version}' and method '${this.method}'`
)
handlers[method] = {
this.versions.set(version, {
handler: handler,

@@ -199,64 +196,9 @@ params: params,

paramsLength: params.length
}
this.versions.set(version, handlers)
})
}
Node.prototype.getHandler = function (method) {
return this.handlers[method]
Node.prototype.getVersionHandler = function (version) {
return this.versions.get(version)
}
Node.prototype.getVersionHandler = function (version, method) {
var handlers = this.versions.get(version)
return handlers === null ? handlers : handlers[method]
}
Node.prototype.prettyPrint = function (prefix, tail) {
var paramName = ''
var handlers = this.handlers || {}
var methods = Object.keys(handlers).filter(method => handlers[method] && handlers[method].handler)
if (this.prefix === ':') {
methods.forEach((method, index) => {
var params = this.handlers[method].params
var param = params[params.length - 1]
if (methods.length > 1) {
if (index === 0) {
paramName += param + ` (${method})\n`
return
}
paramName += prefix + ' :' + param + ` (${method})`
paramName += (index === methods.length - 1 ? '' : '\n')
} else {
paramName = params[params.length - 1] + ` (${method})`
}
})
} else if (methods.length) {
paramName = ` (${methods.join('|')})`
}
var tree = `${prefix}${tail ? '└── ' : '├── '}${this.prefix}${paramName}\n`
prefix = `${prefix}${tail ? ' ' : '│ '}`
const labels = Object.keys(this.children)
for (var i = 0; i < labels.length - 1; i++) {
tree += this.children[labels[i]].prettyPrint(prefix, false)
}
if (labels.length > 0) {
tree += this.children[labels[labels.length - 1]].prettyPrint(prefix, true)
}
return tree
}
function buildHandlers (handlers) {
var code = `handlers = handlers || {}
`
for (var i = 0; i < http.METHODS.length; i++) {
var m = http.METHODS[i]
code += `this['${m}'] = handlers['${m}'] || null
`
}
return new Function('handlers', code) // eslint-disable-line
}
module.exports = Node
module.exports.Handlers = Handlers
{
"name": "find-my-way",
"version": "3.0.4",
"version": "3.0.5",
"description": "Crazy fast http radix based router",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -147,4 +147,6 @@ # find-my-way

If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route.
If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route. If you never configure a versioned route, the `'Accept-Version'` header will be ignored.
Remember to set a [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) header in your responses with the value you are using for deifning the versioning (e.g.: 'Accept-Version'), to prevent cache poisoning attacks. You can also configure this as part your Proxy/CDN.
###### default

@@ -151,0 +153,0 @@ <a name="semver"></a>

@@ -39,6 +39,4 @@ 'use strict'

├── test (GET)
│ └── /
│ └── :hello (GET)
└── hello/
└── :world (GET)
│ └── /:hello (GET)
└── hello/:world (GET)
`

@@ -61,8 +59,7 @@

const expected = `└── /
└── test (GET)
└── /
└── :hello (GET)
:hello (POST)
└── /world (GET)
const expected = `└── /test (GET)
└── /
└── :hello (GET)
:hello (POST)
└── /world (GET)
`

@@ -86,6 +83,4 @@

├── test (GET)
│ └── /
│ └── * (GET)
└── hello/
└── * (GET)
│ └── /* (GET)
└── hello/* (GET)
`

@@ -108,9 +103,8 @@

const expected = `└── /
└── test (GET)
└── /hello
├── /
│ └── :id (GET)
│ :id (POST)
└── world (GET)
const expected = `└── /test (GET)
└── /hello
├── /
│ └── :id (GET)
│ :id (POST)
└── world (GET)
`

@@ -117,0 +111,0 @@

@@ -243,1 +243,26 @@ 'use strict'

})
test('Versioning won\'t work if there are no versioned routes', t => {
t.plan(2)
const findMyWay = FindMyWay({
defaultRoute: (req, res) => {
t.fail('We should not be here')
}
})
findMyWay.on('GET', '/', (req, res) => {
t.pass('Yeah!')
})
findMyWay.lookup({
method: 'GET',
url: '/',
headers: { 'accept-version': '2.x' }
}, null)
findMyWay.lookup({
method: 'GET',
url: '/'
}, null)
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc