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 4.1.0 to 4.2.0

18

index.js

@@ -50,2 +50,9 @@ 'use strict'

if (opts.buildPrettyMeta) {
assert(typeof opts.buildPrettyMeta === 'function', 'buildPrettyMeta must be a function')
this.buildPrettyMeta = opts.buildPrettyMeta
} else {
this.buildPrettyMeta = defaultBuildPrettyMeta
}
this.caseSensitive = opts.caseSensitive === undefined ? true : opts.caseSensitive

@@ -577,3 +584,3 @@ this.ignoreTrailingSlash = opts.ignoreTrailingSlash || false

opts.commonPrefix = opts.commonPrefix === undefined ? true : opts.commonPrefix // default to original behaviour
if (!opts.commonPrefix) return prettyPrintRoutesArray(this.routes)
if (!opts.commonPrefix) return prettyPrintRoutesArray.call(this, this.routes, opts)
const root = {

@@ -593,3 +600,3 @@ prefix: '/',

return prettyPrintFlattenedNode(root, '', true)
return prettyPrintFlattenedNode.call(this, root, '', true, opts)
}

@@ -656,1 +663,8 @@

}
function defaultBuildPrettyMeta (route) {
// buildPrettyMeta function must return an object, which will be parsed into key/value pairs for display
if (!route) return {}
if (!route.store) return {}
return Object.assign({}, route.store)
}

2

lib/constrainer.js

@@ -107,3 +107,3 @@ 'use strict'

// There are some constraints that can be derived and marked as "must match", where if they are derived, they only match routes that actually have a constraint on the value, like the SemVer version constraint.
// An example: a request comes in for version 1.x, and this node has a handler that maches the path, but there's no version constraint. For SemVer, the find-my-way semantics do not match this handler to that request.
// An example: a request comes in for version 1.x, and this node has a handler that matches the path, but there's no version constraint. For SemVer, the find-my-way semantics do not match this handler to that request.
// This function is used by Nodes with handlers to match when they don't have any constrained routes to exclude request that do have must match derived constraints present.

@@ -110,0 +110,0 @@ if (mustMatchKeys.length > 0) {

@@ -13,3 +13,33 @@ 'use strict'

function prettyPrintRoutesArray (routeArray) {
function parseFunctionName (fn) {
let fName = fn.name || ''
fName = fName.replace('bound', '').trim()
fName = (fName || 'anonymous') + '()'
return fName
}
function parseMeta (meta) {
if (Array.isArray(meta)) return meta.map(m => parseMeta(m))
if (typeof meta === 'symbol') return meta.toString()
if (typeof meta === 'function') return parseFunctionName(meta)
return meta
}
function buildMetaObject (route, metaArray) {
const out = {}
const cleanMeta = this.buildPrettyMeta(route)
if (!Array.isArray(metaArray)) metaArray = cleanMeta ? Reflect.ownKeys(cleanMeta) : []
metaArray.forEach(m => {
const metaKey = typeof m === 'symbol' ? m.toString() : m
if (cleanMeta && cleanMeta[m]) {
out[metaKey] = parseMeta(cleanMeta[m])
}
})
return out
}
function prettyPrintRoutesArray (routeArray, opts = {}) {
if (!this.buildPrettyMeta) throw new Error('buildPrettyMeta not defined')
opts.includeMeta = opts.includeMeta || null // array of meta objects to display
const mergedRouteArray = []

@@ -32,3 +62,4 @@

method: route.method,
opts: route.opts.constraints || undefined
opts: route.opts.constraints || undefined,
meta: opts.includeMeta ? buildMetaObject.call(this, route, opts.includeMeta) : null
})

@@ -40,3 +71,4 @@ continue

method: route.method,
opts: route.opts.constraints || undefined
opts: route.opts.constraints || undefined,
meta: opts.includeMeta ? buildMetaObject.call(this, route, opts.includeMeta) : null
}

@@ -47,5 +79,3 @@ mergedRouteArray.push({

opts: [route.opts],
handlers: [routeHandler],
parents: [],
branchLevel: 1
handlers: [routeHandler]
})

@@ -61,4 +91,3 @@ }

opts: [],
handlers: [{}],
parents: [pathDelimiter]
handlers: [{}]
}

@@ -136,7 +165,15 @@

flatHandlers.forEach((handler, idx) => {
if (idx > 0) branch += `${noPrefix ? '' : prefix}${endBranch ? indent : branchIndent}${pathSeg.path}`
if (idx > 0) branch += `${noPrefix ? '' : prefix || ''}${endBranch ? indent : branchIndent}${pathSeg.path}`
branch += ` (${handler.method || '-'})`
if (handler.opts && JSON.stringify(handler.opts) !== '{}') branch += ` ${JSON.stringify(handler.opts)}`
if (handler.meta) {
Reflect.ownKeys(handler.meta).forEach((m, hidx) => {
branch += `\n${noPrefix ? '' : prefix || ''}${endBranch ? indent : branchIndent}`
branch += `• (${m}) ${JSON.stringify(handler.meta[m])}`
})
}
if (flatHandlers.length > 1 && idx !== flatHandlers.length - 1) branch += '\n'
})
} else {
if (pathSeg.children.length > 1) branch += ' (-)'
}

@@ -155,3 +192,5 @@

function prettyPrintFlattenedNode (flattenedNode, prefix, tail) {
function prettyPrintFlattenedNode (flattenedNode, prefix, tail, opts) {
if (!this.buildPrettyMeta) throw new Error('buildPrettyMeta not defined')
opts.includeMeta = opts.includeMeta || null // array of meta items to display
let paramName = ''

@@ -193,8 +232,12 @@ const printHandlers = []

paramName += `${name} ${suffix}`
return
} else {
paramName += '\n'
paramName += `\n${prefix}${tail ? indent : branchIndent}${name} ${suffix}`
}
paramName += `${prefix}${tail ? indent : branchIndent}${name} ${suffix}`
if (opts.includeMeta) {
const meta = buildMetaObject.call(this, handler, opts.includeMeta)
Object.keys(meta).forEach((m, hidx) => {
paramName += `\n${prefix || ''}${tail ? indent : branchIndent}`
paramName += `• (${m}) ${JSON.stringify(meta[m])}`
})
}
})

@@ -211,3 +254,3 @@ } else {

const child = flattenedNode.children[labels[i]]
tree += prettyPrintFlattenedNode(child, prefix, i === (labels.length - 1))
tree += prettyPrintFlattenedNode.call(this, child, prefix, i === (labels.length - 1), opts)
}

@@ -214,0 +257,0 @@ return tree

@@ -29,3 +29,3 @@ 'use strict'

this.constrainer = options.constrainer
this.hasConstraints = false || options.hasConstraints
this.hasConstraints = options.hasConstraints || false
this.constrainedHandlerStores = null

@@ -32,0 +32,0 @@ }

{
"name": "find-my-way",
"version": "4.1.0",
"version": "4.2.0",
"description": "Crazy fast http radix based router",

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

@@ -99,2 +99,33 @@ # find-my-way

You can assign a `buildPrettyMeta` function to sanitize a route's `store` object to use with the `prettyPrint` functions. This function should accept a single object and return an object.
```js
const privateKey = new Symbol('private key')
const store = { token: '12345', [privateKey]: 'private value' }
const router = require('find-my-way')({
buildPrettyMeta: route => {
const cleanMeta = Object.assign({}, route.store)
// remove private properties
Object.keys(cleanMeta).forEach(k => {
if (typeof k === 'symbol') delete cleanMeta[k]
})
return cleanMeta // this will show up in the pretty print output!
}
})
store[privateKey] = 'private value'
router.on('GET', '/hello_world', (req, res) => {}, store)
router.prettyPrintRouteArray()
//└── / (-)
// └── hello_world (GET)
// • (token) "12345"
```
## Constraints

@@ -413,4 +444,5 @@

<a name="pretty-print"></a>
#### prettyPrint([{ commonPrefix: false }])
#### prettyPrint([{ commonPrefix: false, includeMeta: true || [] }])
Prints the representation of the internal radix tree, useful for debugging.
```js

@@ -432,3 +464,4 @@ findMyWay.on('GET', '/test', () => {})

`prettyPrint` accepts an optional setting to use the internal routes array to render the tree.
`prettyPrint` accepts an optional setting to use the internal routes array
to render the tree.

@@ -445,2 +478,37 @@ ```js

To include a display of the `store` data passed to individual routes, the
option `includeMeta` may be passed. If set to `true` all items will be
displayed, this can also be set to an array specifying which keys (if
present) should be displayed. This information can be further sanitized
by specifying a `buildPrettyMeta` function which consumes and returns
an object.
```js
findMyWay.on('GET', '/test', () => {}, { onRequest: () => {}, authIDs => [1,2,3] })
findMyWay.on('GET', '/test/hello', () => {}, { token: 'df123-4567' })
findMyWay.on('GET', '/testing', () => {})
findMyWay.on('GET', '/testing/:param', () => {})
findMyWay.on('PUT', '/update', () => {})
console.log(findMyWay.prettyPrint({ commonPrefix: false, includeMeta: ['onRequest'] }))
// └── /
// ├── test (GET)
// │ • (onRequest) "anonymous()"
// │ ├── /hello (GET)
// │ └── ing (GET)
// │ └── /:param (GET)
// └── update (PUT)
console.log(findMyWay.prettyPrint({ commonPrefix: true, includeMeta: true }))
// └── / (-)
// ├── test (GET)
// │ • (onRequest) "anonymous()"
// │ • (authIDs) [1,2,3]
// │ └── /hello (GET)
// │ • (token) "df123-4567"
// ├── testing (GET)
// │ └── /:param (GET)
// └── update (PUT)
```
<a name="routes"></a>

@@ -447,0 +515,0 @@ #### routes

@@ -23,3 +23,3 @@ 'use strict'

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -44,3 +44,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -67,3 +67,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -88,3 +88,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -112,3 +112,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -136,3 +136,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -160,3 +160,3 @@ })

t.is(typeof tree, 'string')
t.equal(typeof tree, 'string')
t.equal(tree, expected)

@@ -194,4 +194,4 @@ })

t.is(typeof radixTree, 'string')
t.is(typeof arrayTree, 'string')
t.equal(typeof radixTree, 'string')
t.equal(typeof arrayTree, 'string')

@@ -222,3 +222,3 @@ t.equal(radixTree, radixExpected)

t.is(typeof arrayTree, 'string')
t.equal(typeof arrayTree, 'string')
t.equal(arrayTree, arrayExpected)

@@ -247,4 +247,252 @@ })

`
t.is(typeof arrayTree, 'string')
t.equal(typeof arrayTree, 'string')
t.equal(arrayTree, arrayExpected)
})
test('pretty print includeMeta - commonPrefix: true', t => {
t.plan(6)
const findMyWay = FindMyWay()
const namedFunction = () => {}
const store = {
onRequest: [() => {}, namedFunction],
onTimeout: [() => {}],
genericMeta: 'meta',
mixedMeta: ['mixed items', { an: 'object' }],
objectMeta: { one: '1', two: 2 },
functionMeta: namedFunction
}
store[Symbol('symbolKey')] = Symbol('symbolValue')
findMyWay.on('GET', '/test', () => {}, store)
findMyWay.on('GET', '/test', { constraints: { host: 'auth.fastify.io' } }, () => {}, store)
findMyWay.on('GET', '/testing/:hello', () => {}, store)
findMyWay.on('PUT', '/tested/:hello', () => {}, store)
findMyWay.on('GET', '/test/:hello', { constraints: { version: '1.1.2' } }, () => {})
findMyWay.on('GET', '/test/:hello', { constraints: { version: '2.0.0' } }, () => {})
const radixTree = findMyWay.prettyPrint({ commonPrefix: true, includeMeta: true })
const radixTreeExpected = `└── /
├── test (GET)
│ • (onRequest) ["anonymous()","namedFunction()"]
│ • (onTimeout) ["anonymous()"]
│ • (genericMeta) "meta"
│ • (mixedMeta) ["mixed items",{"an":"object"}]
│ • (objectMeta) {"one":"1","two":2}
│ • (functionMeta) "namedFunction()"
│ • (Symbol(symbolKey)) "Symbol(symbolValue)"
│ test (GET) {"host":"auth.fastify.io"}
│ • (onRequest) ["anonymous()","namedFunction()"]
│ • (onTimeout) ["anonymous()"]
│ • (genericMeta) "meta"
│ • (mixedMeta) ["mixed items",{"an":"object"}]
│ • (objectMeta) {"one":"1","two":2}
│ • (functionMeta) "namedFunction()"
│ • (Symbol(symbolKey)) "Symbol(symbolValue)"
│ ├── ing/:hello (GET)
│ │ • (onRequest) ["anonymous()","namedFunction()"]
│ │ • (onTimeout) ["anonymous()"]
│ │ • (genericMeta) "meta"
│ │ • (mixedMeta) ["mixed items",{"an":"object"}]
│ │ • (objectMeta) {"one":"1","two":2}
│ │ • (functionMeta) "namedFunction()"
│ │ • (Symbol(symbolKey)) "Symbol(symbolValue)"
│ └── /:hello (GET) {"version":"1.1.2"}
│ /:hello (GET) {"version":"2.0.0"}
└── tested/:hello (PUT)
• (onRequest) ["anonymous()","namedFunction()"]
• (onTimeout) ["anonymous()"]
• (genericMeta) "meta"
• (mixedMeta) ["mixed items",{"an":"object"}]
• (objectMeta) {"one":"1","two":2}
• (functionMeta) "namedFunction()"
• (Symbol(symbolKey)) "Symbol(symbolValue)"
`
const radixTreeSpecific = findMyWay.prettyPrint({ commonPrefix: true, includeMeta: ['onTimeout', 'objectMeta', 'nonExistent'] })
const radixTreeSpecificExpected = `└── /
├── test (GET)
│ • (onTimeout) ["anonymous()"]
│ • (objectMeta) {"one":"1","two":2}
│ test (GET) {"host":"auth.fastify.io"}
│ • (onTimeout) ["anonymous()"]
│ • (objectMeta) {"one":"1","two":2}
│ ├── ing/:hello (GET)
│ │ • (onTimeout) ["anonymous()"]
│ │ • (objectMeta) {"one":"1","two":2}
│ └── /:hello (GET) {"version":"1.1.2"}
│ /:hello (GET) {"version":"2.0.0"}
└── tested/:hello (PUT)
• (onTimeout) ["anonymous()"]
• (objectMeta) {"one":"1","two":2}
`
const radixTreeNoMeta = findMyWay.prettyPrint({ commonPrefix: true, includeMeta: false })
const radixTreeNoMetaExpected = `└── /
├── test (GET)
│ test (GET) {"host":"auth.fastify.io"}
│ ├── ing/:hello (GET)
│ └── /:hello (GET) {"version":"1.1.2"}
│ /:hello (GET) {"version":"2.0.0"}
└── tested/:hello (PUT)
`
t.equal(typeof radixTree, 'string')
t.equal(radixTree, radixTreeExpected)
t.equal(typeof radixTreeSpecific, 'string')
t.equal(radixTreeSpecific, radixTreeSpecificExpected)
t.equal(typeof radixTreeNoMeta, 'string')
t.equal(radixTreeNoMeta, radixTreeNoMetaExpected)
})
test('pretty print includeMeta - commonPrefix: false', t => {
t.plan(6)
const findMyWay = FindMyWay()
const namedFunction = () => {}
const store = {
onRequest: [() => {}, namedFunction],
onTimeout: [() => {}],
genericMeta: 'meta',
mixedMeta: ['mixed items', { an: 'object' }],
objectMeta: { one: '1', two: 2 },
functionMeta: namedFunction
}
store[Symbol('symbolKey')] = Symbol('symbolValue')
findMyWay.on('GET', '/test', () => {}, store)
findMyWay.on('GET', '/test', { constraints: { host: 'auth.fastify.io' } }, () => {}, store)
findMyWay.on('GET', '/test/:hello', () => {}, store)
findMyWay.on('PUT', '/test/:hello', () => {}, store)
findMyWay.on('GET', '/test/:hello', { constraints: { version: '1.1.2' } }, () => {})
findMyWay.on('GET', '/test/:hello', { constraints: { version: '2.0.0' } }, () => {})
const arrayTree = findMyWay.prettyPrint({ commonPrefix: false, includeMeta: true })
const arrayExpected = `└── / (-)
└── test (GET)
• (onRequest) ["anonymous()","namedFunction()"]
• (onTimeout) ["anonymous()"]
• (genericMeta) "meta"
• (mixedMeta) ["mixed items",{"an":"object"}]
• (objectMeta) {"one":"1","two":2}
• (functionMeta) "namedFunction()"
• (Symbol(symbolKey)) "Symbol(symbolValue)"
test (GET) {"host":"auth.fastify.io"}
• (onRequest) ["anonymous()","namedFunction()"]
• (onTimeout) ["anonymous()"]
• (genericMeta) "meta"
• (mixedMeta) ["mixed items",{"an":"object"}]
• (objectMeta) {"one":"1","two":2}
• (functionMeta) "namedFunction()"
• (Symbol(symbolKey)) "Symbol(symbolValue)"
└── /:hello (GET, PUT)
• (onRequest) ["anonymous()","namedFunction()"]
• (onTimeout) ["anonymous()"]
• (genericMeta) "meta"
• (mixedMeta) ["mixed items",{"an":"object"}]
• (objectMeta) {"one":"1","two":2}
• (functionMeta) "namedFunction()"
• (Symbol(symbolKey)) "Symbol(symbolValue)"
/:hello (GET) {"version":"1.1.2"}
/:hello (GET) {"version":"2.0.0"}
`
const arraySpecific = findMyWay.prettyPrint({ commonPrefix: false, includeMeta: ['onRequest', 'mixedMeta', 'nonExistent'] })
const arraySpecificExpected = `└── / (-)
└── test (GET)
• (onRequest) ["anonymous()","namedFunction()"]
• (mixedMeta) ["mixed items",{"an":"object"}]
test (GET) {"host":"auth.fastify.io"}
• (onRequest) ["anonymous()","namedFunction()"]
• (mixedMeta) ["mixed items",{"an":"object"}]
└── /:hello (GET, PUT)
• (onRequest) ["anonymous()","namedFunction()"]
• (mixedMeta) ["mixed items",{"an":"object"}]
/:hello (GET) {"version":"1.1.2"}
/:hello (GET) {"version":"2.0.0"}
`
const arrayNoMeta = findMyWay.prettyPrint({ commonPrefix: false, includeMeta: false })
const arrayNoMetaExpected = `└── / (-)
└── test (GET)
test (GET) {"host":"auth.fastify.io"}
└── /:hello (GET, PUT)
/:hello (GET) {"version":"1.1.2"}
/:hello (GET) {"version":"2.0.0"}
`
t.equal(typeof arrayTree, 'string')
t.equal(arrayTree, arrayExpected)
t.equal(typeof arraySpecific, 'string')
t.equal(arraySpecific, arraySpecificExpected)
t.equal(typeof arrayNoMeta, 'string')
t.equal(arrayNoMeta, arrayNoMetaExpected)
})
test('pretty print includeMeta - buildPrettyMeta function', t => {
t.plan(4)
const findMyWay = FindMyWay({
buildPrettyMeta: route => {
// routes from radix tree do not contain a path element
// returns 'no path' to avoid an undefined value
return { metaKey: route.path || 'no path' }
}
})
const namedFunction = () => {}
const store = {
onRequest: [() => {}, namedFunction],
onTimeout: [() => {}],
genericMeta: 'meta',
mixedMeta: ['mixed items', { an: 'object' }],
objectMeta: { one: '1', two: 2 },
functionMeta: namedFunction
}
store[Symbol('symbolKey')] = Symbol('symbolValue')
findMyWay.on('GET', '/test', () => {}, store)
findMyWay.on('GET', '/test', { constraints: { host: 'auth.fastify.io' } }, () => {}, store)
findMyWay.on('GET', '/test/:hello', () => {}, store)
findMyWay.on('PUT', '/test/:hello', () => {}, store)
findMyWay.on('GET', '/test/:hello', { constraints: { version: '1.1.2' } }, () => {})
findMyWay.on('GET', '/test/:hello', { constraints: { version: '2.0.0' } }, () => {})
const arrayTree = findMyWay.prettyPrint({ commonPrefix: false, includeMeta: true })
const arrayExpected = `└── / (-)
└── test (GET)
• (metaKey) "/test"
test (GET) {"host":"auth.fastify.io"}
• (metaKey) "/test"
└── /:hello (GET, PUT)
• (metaKey) "/test/:hello"
/:hello (GET) {"version":"1.1.2"}
• (metaKey) "/test/:hello"
/:hello (GET) {"version":"2.0.0"}
• (metaKey) "/test/:hello"
`
const radixTree = findMyWay.prettyPrint({ includeMeta: true })
const radixExpected = `└── /test (GET)
• (metaKey) "no path"
/test (GET) {"host":"auth.fastify.io"}
• (metaKey) "no path"
└── /
└── :hello (GET)
• (metaKey) "no path"
:hello (GET) {"version":"1.1.2"}
• (metaKey) "no path"
:hello (GET) {"version":"2.0.0"}
• (metaKey) "no path"
:hello (PUT)
• (metaKey) "no path"
`
t.equal(typeof arrayTree, 'string')
t.equal(arrayTree, arrayExpected)
t.equal(typeof radixTree, 'string')
t.equal(radixTree, radixExpected)
})
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