From 38f9860313ecc1162851585bd481c420e815e4bc Mon Sep 17 00:00:00 2001 From: EGOIST <0x142857@gmail.com> Date: Fri, 19 Mar 2021 01:07:16 +0800 Subject: [PATCH] fix: return all matched handlers (publish release) --- README.md | 8 ++++---- src/index.spec.ts | 31 +++++++++++++++++++++---------- src/index.ts | 25 ++++++++++++++++++------- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 93c7a51..4d94eab 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @egoist/router -A router that works in Node.js, browser and Deno. +An Express-like router that works in Node.js, browser and Deno. ## Install @@ -33,10 +33,10 @@ router.get('/', () => { // do something }) -const { params, handlers } = router.find('GET', '/user/egoist') +const matches = router.find('GET', '/user/egoist') -for (const handler of handlers) { - handler(params) +for (const m of matches) { + m.handler(m.params) } // prints: 'egoist' ``` diff --git a/src/index.spec.ts b/src/index.spec.ts index c8ee171..ea80d8b 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -4,21 +4,32 @@ type Handler = (params: Record) => void test('simple', () => { const router = new Router() + let msg = '' router.get('/:user', (params) => params.user) - router.get('/home', () => 'home') - const route = router.find('GET', '/home') - const result = route.handlers[0](route.params) - expect(result).toBe('home') + router.get('/home', () => (msg = 'home')) + const matches = router.find('GET', '/home') + for (const m of matches) { + m.handler(m.params) + } + expect(msg).toBe('home') }) test('wildcard path', () => { const router = new Router({ sortRoutes: true }) - router.use('/*', (params) => params.wild) - router.use('/user/*', (params) => params.wild) - const route1 = router.find('GET', '/foo') - expect(route1.handlers[0](route1.params)).toBe('foo') + let msg = '' + router.use('/*', (params) => (msg += params.wild as string)) + router.use('/user/*', (params) => (msg += params.wild as string)) - const route2 = router.find('GET', '/user/foo') - expect(route2.handlers[0](route2.params)).toBe('foo') + for (const m of router.find('GET', '/foo')) { + m.handler(m.params) + } + expect(msg).toBe('foo') + + msg = '' + + for (const m of router.find('GET', '/user/bar')) { + m.handler(m.params) + } + expect(msg).toBe('baruser/bar') }) diff --git a/src/index.ts b/src/index.ts index ba4144b..f703d74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -93,11 +93,19 @@ export class Router { ) } - find(method: HTTPMethod, url: string) { + find( + method: HTTPMethod, + url: string, + { exitOnFirstMatch }: { exitOnFirstMatch?: boolean } = {}, + ) { const isHEAD = method === 'HEAD' const arr = this.routes - let params: Record = {}, - handlers: THandler[] = [] + + const routes: { + handler: THandler + params: Record + }[] = [] + for (let i = 0; i < arr.length; i++) { const tmp = arr[i] if ( @@ -107,13 +115,16 @@ export class Router { ) { const match = tmp.parser.parse(url) if (match) { - params = match - handlers = tmp.handlers - break + for (const handler of tmp.handlers) { + routes.push({ params: match, handler }) + } + if (exitOnFirstMatch) { + break + } } } } - return { params, handlers } + return routes } }