find-my-way
Advanced tools
Comparing version
'use strict' | ||
const { workerData, parentPort } = require('worker_threads') | ||
const { workerData: benchmark, parentPort } = require('worker_threads') | ||
@@ -17,14 +17,5 @@ const Benchmark = require('benchmark') | ||
const FindMyWay = require('./') | ||
const findMyWay = new FindMyWay() | ||
const testingMethods = { | ||
lookup: findMyWay.lookup, | ||
find: findMyWay.find | ||
} | ||
const { name, setupURLs, testingMethodName, args } = workerData | ||
const testingMethod = testingMethods[testingMethodName] | ||
for (const { method, url, opts } of setupURLs) { | ||
for (const { method, url, opts } of benchmark.setupURLs) { | ||
if (opts !== undefined) { | ||
@@ -38,4 +29,4 @@ findMyWay.on(method, url, opts, () => true) | ||
suite | ||
.add(name, () => { | ||
testingMethod.call(findMyWay, ...args) | ||
.add(benchmark.name, () => { | ||
findMyWay.lookup(...benchmark.arguments) | ||
}) | ||
@@ -42,0 +33,0 @@ .on('cycle', (event) => { |
248
bench.js
@@ -8,208 +8,120 @@ 'use strict' | ||
const testCases = [ | ||
const benchmarks = [ | ||
{ | ||
name: 'lookup root "/" route', | ||
setupURLs: [{ method: 'GET', url: '/' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
arguments: [{ method: 'GET', url: '/' }] | ||
}, | ||
{ | ||
name: 'lookup static route', | ||
setupURLs: [{ method: 'GET', url: '/a' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/a', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
name: 'lookup short static route', | ||
setupURLs: [{ method: 'GET', url: '/static' }], | ||
arguments: [{ method: 'GET', url: '/static' }] | ||
}, | ||
{ | ||
name: 'lookup dynamic route', | ||
setupURLs: [{ method: 'GET', url: '/user/:id' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/user/tomas', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
}, | ||
{ | ||
name: 'lookup dynamic multi-parametric route', | ||
setupURLs: [{ method: 'GET', url: '/customer/:name-:surname' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/customer/john-doe', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
}, | ||
{ | ||
name: 'lookup dynamic multi-parametric route with regex', | ||
setupURLs: [{ method: 'GET', url: '/at/:hour(^\\d+)h:minute(^\\d+)m' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/at/12h00m', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
}, | ||
{ | ||
name: 'lookup long static route', | ||
setupURLs: [{ method: 'GET', url: '/abc/def/ghi/lmn/opq/rst/uvz' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ method: 'GET', url: '/abc/def/ghi/lmn/opq/rst/uvz', headers: { host: 'fastify.io' } }, | ||
null | ||
] | ||
setupURLs: [{ method: 'GET', url: '/static/static/static/static/static' }], | ||
arguments: [{ method: 'GET', url: '/static/static/static/static/static' }] | ||
}, | ||
{ | ||
name: 'lookup long dynamic route', | ||
setupURLs: [{ method: 'GET', url: '/user/:id/static' }], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ | ||
method: 'GET', | ||
url: '/user/qwertyuiopasdfghjklzxcvbnm/static', | ||
headers: { host: 'fastify.io' } | ||
}, | ||
null | ||
] | ||
}, | ||
{ | ||
name: 'lookup static route on constrained router', | ||
name: 'lookup long static route (common prefix)', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/' }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
{ method: 'GET', url: '/static' }, | ||
{ method: 'GET', url: '/static/static' }, | ||
{ method: 'GET', url: '/static/static/static' }, | ||
{ method: 'GET', url: '/static/static/static/static' }, | ||
{ method: 'GET', url: '/static/static/static/static/static' } | ||
], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ | ||
method: 'GET', | ||
url: '/', | ||
headers: { host: 'fastify.io' } | ||
}, | ||
null | ||
] | ||
arguments: [{ method: 'GET', url: '/static/static/static/static/static' }] | ||
}, | ||
{ | ||
name: 'lookup static versioned route', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/' }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ | ||
method: 'GET', | ||
url: '/versioned', | ||
headers: { 'accept-version': '1.x', host: 'fastify.io' } | ||
}, | ||
null | ||
] | ||
name: 'lookup short parametric route', | ||
setupURLs: [{ method: 'GET', url: '/:param' }], | ||
arguments: [{ method: 'GET', url: '/param1' }] | ||
}, | ||
{ | ||
name: 'lookup static constrained (version & host) route', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/' }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/versioned', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
testingMethodName: 'lookup', | ||
args: [ | ||
{ | ||
method: 'GET', | ||
url: '/versioned', | ||
headers: { 'accept-version': '2.x', host: 'fastify.io' } | ||
}, | ||
null | ||
] | ||
name: 'lookup long parametric route', | ||
setupURLs: [{ method: 'GET', url: '/:param' }], | ||
arguments: [{ method: 'GET', url: '/longParamParamParamParamParamParam' }] | ||
}, | ||
{ | ||
name: 'find root "/" route', | ||
setupURLs: [{ method: 'GET', url: '/' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/'] | ||
name: 'lookup short parametric route (encoded unoptimized)', | ||
setupURLs: [{ method: 'GET', url: '/:param' }], | ||
arguments: [{ method: 'GET', url: '/param%2B' }] | ||
}, | ||
{ | ||
name: 'find static route', | ||
setupURLs: [{ method: 'GET', url: '/a' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/a'] | ||
name: 'lookup short parametric route (encoded optimized)', | ||
setupURLs: [{ method: 'GET', url: '/:param' }], | ||
arguments: [{ method: 'GET', url: '/param%20' }] | ||
}, | ||
{ | ||
name: 'find dynamic route', | ||
setupURLs: [{ method: 'GET', url: '/user/:id' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/user/tomas'] | ||
name: 'lookup parametric route with two short params', | ||
setupURLs: [{ method: 'GET', url: '/:param1/:param2' }], | ||
arguments: [{ method: 'GET', url: '/param1/param2' }] | ||
}, | ||
{ | ||
name: 'find dynamic route with encoded parameter unoptimized', | ||
setupURLs: [{ method: 'GET', url: '/user/:id' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/user/maintainer%2Btomas'] | ||
name: 'lookup multi-parametric route with two short params', | ||
setupURLs: [{ method: 'GET', url: '/:param1-:param2' }], | ||
arguments: [{ method: 'GET', url: '/param1-param2' }] | ||
}, | ||
{ | ||
name: 'find dynamic route with encoded parameter optimized', | ||
setupURLs: [{ method: 'GET', url: '/user/:id' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/user/maintainer%20tomas'] | ||
name: 'lookup multi-parametric route with two short regex params', | ||
setupURLs: [{ method: 'GET', url: '/:param1([a-z]*)1:param2([a-z]*)2' }], | ||
arguments: [{ method: 'GET', url: '/param1param2' }] | ||
}, | ||
{ | ||
name: 'find dynamic multi-parametric route', | ||
setupURLs: [{ method: 'GET', url: '/customer/:name-:surname' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/customer/john-doe'] | ||
name: 'lookup long static + parametric route', | ||
setupURLs: [{ method: 'GET', url: '/static/:param1/static/:param2/static' }], | ||
arguments: [{ method: 'GET', url: '/static/param1/static/param2/static' }] | ||
}, | ||
{ | ||
name: 'find dynamic multi-parametric route with regex', | ||
setupURLs: [{ method: 'GET', url: '/at/:hour(^\\d+)h:minute(^\\d+)m' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/at/12h00m'] | ||
name: 'lookup short wildcard route', | ||
setupURLs: [{ method: 'GET', url: '/*' }], | ||
arguments: [{ method: 'GET', url: '/static' }] | ||
}, | ||
{ | ||
name: 'find long static route', | ||
setupURLs: [{ method: 'GET', url: '/abc/def/ghi/lmn/opq/rst/uvz' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/abc/def/ghi/lmn/opq/rst/uvz'] | ||
name: 'lookup long wildcard route', | ||
setupURLs: [{ method: 'GET', url: '/*' }], | ||
arguments: [{ method: 'GET', url: '/static/static/static/static/static' }] | ||
}, | ||
{ | ||
name: 'find long dynamic route', | ||
setupURLs: [{ method: 'GET', url: '/user/:id/static' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/user/qwertyuiopasdfghjklzxcvbnm/static'] | ||
name: 'lookup root route on constrained router', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/' }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
arguments: [{ method: 'GET', url: '/', headers: { host: 'fastify.io' } }] | ||
}, | ||
{ | ||
name: 'find long nested dynamic route', | ||
setupURLs: [{ method: 'GET', url: '/posts/:id/comments/:id/author' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/posts/10/comments/42/author'] | ||
name: 'lookup short static unconstraint route', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/static', opts: {} }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
arguments: [{ method: 'GET', url: '/static', headers: {} }] | ||
}, | ||
{ | ||
name: 'find long nested dynamic route with encoded parameter unoptimized', | ||
setupURLs: [{ method: 'GET', url: '/posts/:id/comments/:id/author' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/posts/10%2C10/comments/42%2C42/author'] | ||
name: 'lookup short static versioned route', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
arguments: [{ method: 'GET', url: '/static', headers: { 'accept-version': '1.x', host: 'fastify.io' } }] | ||
}, | ||
{ | ||
name: 'find long nested dynamic route with encoded parameter optimized', | ||
setupURLs: [{ method: 'GET', url: '/posts/:id/comments/:id/author' }], | ||
testingMethodName: 'find', | ||
args: ['GET', '/posts/10%2510/comments/42%2542/author'] | ||
}, | ||
{ | ||
name: 'find long nested dynamic route with other method', | ||
setupURLs: [{ method: 'POST', url: '/posts/:id/comments' }], | ||
testingMethodName: 'find', | ||
args: ['POST', '/posts/10/comments'] | ||
name: 'lookup short static constrained (version & host) route', | ||
setupURLs: [ | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '1.2.0' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'example.com' } } }, | ||
{ method: 'GET', url: '/static', opts: { constraints: { version: '2.0.0', host: 'fastify.io' } } } | ||
], | ||
arguments: [{ method: 'GET', url: '/static', headers: { 'accept-version': '2.x', host: 'fastify.io' } }] | ||
} | ||
] | ||
async function runBenchmark (testCase) { | ||
const worker = new Worker(BENCH_THREAD_PATH, { | ||
workerData: testCase | ||
}) | ||
async function runBenchmark (benchmark) { | ||
const worker = new Worker(BENCH_THREAD_PATH, { workerData: benchmark }) | ||
@@ -233,4 +145,10 @@ return new Promise((resolve, reject) => { | ||
async function runBenchmarks () { | ||
for (const testCase of testCases) { | ||
const resultMessage = await runBenchmark(testCase) | ||
let maxNameLength = 0 | ||
for (const benchmark of benchmarks) { | ||
maxNameLength = Math.max(benchmark.name.length, maxNameLength) | ||
} | ||
for (const benchmark of benchmarks) { | ||
benchmark.name = benchmark.name.padEnd(maxNameLength, '.') | ||
const resultMessage = await runBenchmark(benchmark) | ||
console.log(resultMessage) | ||
@@ -237,0 +155,0 @@ } |
@@ -25,11 +25,5 @@ 'use strict' | ||
const staticChild = this.staticChildren[path.charAt(pathIndex)] | ||
if (staticChild === undefined) { | ||
if (staticChild === undefined || !staticChild.matchPrefix(path, pathIndex)) { | ||
return null | ||
} | ||
for (let i = 0; i < staticChild.prefix.length; i++) { | ||
if (path.charCodeAt(pathIndex + i) !== staticChild.prefix.charCodeAt(i)) { | ||
return null | ||
} | ||
} | ||
return staticChild | ||
@@ -45,3 +39,3 @@ } | ||
if (staticChild) { | ||
let i = 0 | ||
let i = 1 | ||
for (; i < staticChild.prefix.length; i++) { | ||
@@ -69,2 +63,3 @@ if (path.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) { | ||
this.kind = NODE_TYPES.STATIC | ||
this._compilePrefixMatch() | ||
} | ||
@@ -95,2 +90,3 @@ | ||
this.prefix = childPrefix | ||
this._compilePrefixMatch() | ||
@@ -103,2 +99,16 @@ const staticNode = new StaticNode(parentPrefix) | ||
} | ||
_compilePrefixMatch () { | ||
if (this.prefix.length === 1) { | ||
this.matchPrefix = () => true | ||
return | ||
} | ||
const lines = [] | ||
for (let i = 1; i < this.prefix.length; i++) { | ||
const chatCode = this.prefix.charCodeAt(i) | ||
lines.push(`path.charCodeAt(i + ${i}) === ${chatCode}`) | ||
} | ||
this.matchPrefix = new Function('path', 'i', `return ${lines.join(' && ')}`) // eslint-disable-line | ||
} | ||
} | ||
@@ -105,0 +115,0 @@ |
@@ -141,3 +141,7 @@ import { IncomingMessage, ServerResponse } from 'http'; | ||
off(method: HTTPMethod | HTTPMethod[], path: string): void; | ||
off( | ||
method: HTTPMethod | HTTPMethod[], | ||
path: string, | ||
constraints?: { [key: string]: any } | ||
): void; | ||
@@ -144,0 +148,0 @@ lookup<Context>( |
64
index.js
@@ -31,2 +31,3 @@ 'use strict' | ||
const isRegexSafe = require('safe-regex2') | ||
const deepEqual = require('fast-deep-equal') | ||
const { flattenNode, compressFlattenedNode, prettyPrintFlattenedNode, prettyPrintRoutesArray } = require('./lib/pretty-print') | ||
@@ -265,3 +266,3 @@ const { StaticNode, NODE_TYPES } = require('./custom_node') | ||
Router.prototype.off = function off (method, path) { | ||
Router.prototype.off = function off (method, path, opts) { | ||
// path validation | ||
@@ -280,4 +281,4 @@ assert(typeof path === 'string', 'Path should be a string') | ||
this.off(method, pathFull) | ||
this.off(method, pathOptional) | ||
this.off(method, pathFull, opts) | ||
this.off(method, pathOptional, opts) | ||
return | ||
@@ -292,7 +293,7 @@ } | ||
for (const method of methods) { | ||
this._off(method, path) | ||
this._off(method, path, opts) | ||
} | ||
} | ||
Router.prototype._off = function _off (method, path) { | ||
Router.prototype._off = function _off (method, path, opts) { | ||
// method validation | ||
@@ -302,4 +303,10 @@ assert(typeof method === 'string', 'Method should be a string') | ||
function matcher (currentConstraints) { | ||
if (!opts || !currentConstraints) return true | ||
return deepEqual(opts, currentConstraints) | ||
} | ||
// Rebuild tree without the specific route | ||
const newRoutes = this.routes.filter((route) => method !== route.method || path !== route.path) | ||
const newRoutes = this.routes.filter((route) => method !== route.method || path !== route.path || !matcher(route.opts.constraints)) | ||
this.reset() | ||
@@ -352,7 +359,5 @@ | ||
const parametricBrothersStack = [] | ||
const wildcardBrothersStack = [] | ||
const brothersNodesStack = [] | ||
while (true) { | ||
// found the route | ||
if (pathIndex === pathLen) { | ||
@@ -388,22 +393,30 @@ const handle = currentNode.handlerStorage.getMatchingHandler(this.constrainer, derivedConstraints) | ||
if (currentNode.kind === NODE_TYPES.STATIC) { | ||
if (currentNode.parametricChild !== null) { | ||
if (node === null) { | ||
if (node === null) { | ||
if (currentNode.parametricChild !== null) { | ||
node = currentNode.parametricChild | ||
if (currentNode.wildcardChild !== null) { | ||
brothersNodesStack.push({ | ||
brotherPathIndex: pathIndex, | ||
paramsCount: params.length, | ||
brotherNode: currentNode.wildcardChild | ||
}) | ||
} | ||
} else { | ||
parametricBrothersStack.push({ | ||
node = currentNode.wildcardChild | ||
} | ||
} else { | ||
if (currentNode.wildcardChild !== null) { | ||
brothersNodesStack.push({ | ||
brotherPathIndex: pathIndex, | ||
paramsCount: params.length, | ||
brotherNode: currentNode.parametricChild | ||
brotherNode: currentNode.wildcardChild | ||
}) | ||
} | ||
} | ||
if (currentNode.wildcardChild !== null) { | ||
if (node === null) { | ||
node = currentNode.wildcardChild | ||
} else { | ||
wildcardBrothersStack.push({ | ||
if (currentNode.parametricChild !== null) { | ||
brothersNodesStack.push({ | ||
brotherPathIndex: pathIndex, | ||
paramsCount: params.length, | ||
brotherNode: currentNode.wildcardChild | ||
brotherNode: currentNode.parametricChild | ||
}) | ||
@@ -416,12 +429,7 @@ } | ||
if (node === null) { | ||
let brotherNodeState | ||
if (parametricBrothersStack.length === 0) { | ||
if (wildcardBrothersStack.length === 0) { | ||
return null | ||
} | ||
brotherNodeState = wildcardBrothersStack.pop() | ||
} else { | ||
brotherNodeState = parametricBrothersStack.pop() | ||
if (brothersNodesStack.length === 0) { | ||
return null | ||
} | ||
const brotherNodeState = brothersNodesStack.pop() | ||
pathIndex = brotherNodeState.brotherPathIndex | ||
@@ -428,0 +436,0 @@ params.splice(brotherNodeState.paramsCount) |
{ | ||
"name": "find-my-way", | ||
"version": "5.5.1", | ||
"version": "5.6.0", | ||
"description": "Crazy fast http radix based router", | ||
@@ -9,2 +9,4 @@ "main": "index.js", | ||
"bench": "node bench.js", | ||
"bench:cmp": "node bench-cmp.js", | ||
"bench:cmp:ci": "node bench-cmp.js --ci", | ||
"test:lint": "standard", | ||
@@ -39,6 +41,8 @@ "test:typescript": "tsd", | ||
"benchmark": "^2.1.4", | ||
"chalk": "^4.1.2", | ||
"inquirer": "^8.2.4", | ||
"pre-commit": "^1.2.2", | ||
"request": "^2.88.2", | ||
"simple-git": "^3.7.1", | ||
"standard": "^14.3.4", | ||
"tap": "^15.0.9", | ||
"tap": "^16.0.1", | ||
"tap-mocha-reporter": "^5.0.1", | ||
@@ -45,0 +49,0 @@ "tsd": "^0.13.1" |
@@ -377,3 +377,3 @@ # find-my-way | ||
##### off(methods[], path, handler, [store]) | ||
##### off(methods[], path) | ||
Deregister a route for each method specified in the `methods` array. | ||
@@ -387,2 +387,10 @@ It comes handy when you need to deregister multiple routes with the same path but different methods. | ||
##### off(methods, path, [constraints]) | ||
Deregister a route for each `constraints` key is matched, containing keys like the `host` for the request, the `version` for the route to be matched, or other custom constraint values. See the [constraints section](https://github.com/delvedor/find-my-way#constraints) to know more. | ||
```js | ||
router.off('GET', '/example', { host: 'fastify.io' }) | ||
// => [{ handler: Function, params: Object, store: Object}] | ||
// => null | ||
``` | ||
<a name="reset"></a> | ||
@@ -389,0 +397,0 @@ #### reset() |
@@ -6,7 +6,6 @@ 'use strict' | ||
const http = require('http') | ||
const request = require('request') | ||
const FindMyWay = require('../') | ||
test('basic router with http server', t => { | ||
t.plan(7) | ||
t.plan(6) | ||
const findMyWay = FindMyWay() | ||
@@ -28,8 +27,8 @@ findMyWay.on('GET', '/test', (req, res, params) => { | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port + '/test' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
http.get('http://localhost:' + server.address().port + '/test', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(JSON.parse(body), { hello: 'world' }) | ||
@@ -41,3 +40,3 @@ }) | ||
test('router with params with http server', t => { | ||
t.plan(7) | ||
t.plan(6) | ||
const findMyWay = FindMyWay() | ||
@@ -59,8 +58,8 @@ findMyWay.on('GET', '/test/:id', (req, res, params) => { | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port + '/test/hello' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
http.get('http://localhost:' + server.address().port + '/test/hello', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(JSON.parse(body), { hello: 'world' }) | ||
@@ -72,3 +71,3 @@ }) | ||
test('default route', t => { | ||
t.plan(3) | ||
t.plan(2) | ||
const findMyWay = FindMyWay({ | ||
@@ -89,8 +88,4 @@ defaultRoute: (req, res) => { | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 404) | ||
http.get('http://localhost:' + server.address().port, async (res) => { | ||
t.equal(res.statusCode, 404) | ||
}) | ||
@@ -101,3 +96,3 @@ }) | ||
test('automatic default route', t => { | ||
t.plan(3) | ||
t.plan(2) | ||
const findMyWay = FindMyWay() | ||
@@ -113,8 +108,4 @@ | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 404) | ||
http.get('http://localhost:' + server.address().port, async (res) => { | ||
t.equal(res.statusCode, 404) | ||
}) | ||
@@ -125,3 +116,3 @@ }) | ||
test('maps two routes when trailing slash should be trimmed', t => { | ||
t.plan(25) | ||
t.plan(21) | ||
const findMyWay = FindMyWay({ | ||
@@ -155,36 +146,36 @@ ignoreTrailingSlash: true | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/test/' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'test') | ||
http.get(baseURL + '/test/', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'test') | ||
}) | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/test' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'test') | ||
http.get(baseURL + '/test', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'test') | ||
}) | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/othertest' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'othertest') | ||
http.get(baseURL + '/othertest', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'othertest') | ||
}) | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/othertest/' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'othertest') | ||
http.get(baseURL + '/othertest/', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'othertest') | ||
}) | ||
@@ -195,3 +186,3 @@ }) | ||
test('does not trim trailing slash when ignoreTrailingSlash is false', t => { | ||
t.plan(9) | ||
t.plan(7) | ||
const findMyWay = FindMyWay({ | ||
@@ -218,17 +209,13 @@ ignoreTrailingSlash: false | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/test/' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'test') | ||
http.get(baseURL + '/test/', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'test') | ||
}) | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/test' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 404) | ||
http.get(baseURL + '/test', async (res) => { | ||
t.equal(res.statusCode, 404) | ||
}) | ||
@@ -239,3 +226,3 @@ }) | ||
test('does not map // when ignoreTrailingSlash is true', t => { | ||
t.plan(9) | ||
t.plan(7) | ||
const findMyWay = FindMyWay({ | ||
@@ -262,17 +249,13 @@ ignoreTrailingSlash: false | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '/' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
t.equal(body, 'test') | ||
http.get(baseURL + '/', async (res) => { | ||
let body = '' | ||
for await (const chunk of res) { | ||
body += chunk | ||
} | ||
t.equal(res.statusCode, 200) | ||
t.same(body, 'test') | ||
}) | ||
request({ | ||
method: 'GET', | ||
uri: baseURL + '//' | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 404) | ||
http.get(baseURL + '//', async (res) => { | ||
t.equal(res.statusCode, 404) | ||
}) | ||
@@ -283,3 +266,3 @@ }) | ||
test('versioned routes', t => { | ||
t.plan(5) | ||
t.plan(3) | ||
@@ -300,20 +283,22 @@ const findMyWay = FindMyWay() | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port + '/test', | ||
headers: { 'Accept-Version': '1.x' } | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 200) | ||
}) | ||
http.get( | ||
'http://localhost:' + server.address().port + '/test', | ||
{ | ||
headers: { 'Accept-Version': '1.x' } | ||
}, | ||
async (res) => { | ||
t.equal(res.statusCode, 200) | ||
} | ||
) | ||
request({ | ||
method: 'GET', | ||
uri: 'http://localhost:' + server.address().port + '/test', | ||
headers: { 'Accept-Version': '2.x' } | ||
}, (err, response, body) => { | ||
t.error(err) | ||
t.equal(response.statusCode, 404) | ||
}) | ||
http.get( | ||
'http://localhost:' + server.address().port + '/test', | ||
{ | ||
headers: { 'Accept-Version': '2.x' } | ||
}, | ||
async (res) => { | ||
t.equal(res.statusCode, 404) | ||
} | ||
) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
279940
4.5%77
10%7094
3.07%582
1.39%10
25%9
28.57%