0
0
mirror of https://github.com/honojs/hono.git synced 2024-12-01 10:51:01 +00:00
hono/deno_dist/router/static-router/router.ts
Taku Amano a149dddfdc
Introduce StaticRouter and SmartRouter (#501)
* refactor(router): Export supported HTTP methods.

* refactor(router): Introduce UnsupportedPathError.

* feat(static-router): Introduce StaticRouter.

* feat(reg-exp-router): Add "allowAmbiguous" option to RegExpRouter.

* feat(smart-router):  Introduce SmartRouter.

* feat(hono): Make SmartRouter the default router.

* chore: denoify

* refactor(smart-router): routers is never undefined.

* chore: denoify

* refactor: Fix test for SmartRouter.
2022-09-12 20:49:18 +09:00

82 lines
2.2 KiB
TypeScript

/* eslint-disable @typescript-eslint/ban-ts-comment */
import type { Router, Result } from '../../router.ts'
import { METHOD_NAME_ALL, METHODS, UnsupportedPathError } from '../../router.ts'
export class StaticRouter<T> implements Router<T> {
middleware: Record<string, Result<T>>
routes: Record<string, Record<string, Result<T>>>
constructor() {
this.middleware = {}
this.routes = {} as StaticRouter<T>['routes']
;[METHOD_NAME_ALL, ...METHODS].forEach((method) => {
this.routes[method.toUpperCase()] = {}
})
}
add(method: string, path: string, handler: T) {
const { middleware, routes } = this
if (path === '/*') {
path = '*'
}
if (path === '*') {
if (method === METHOD_NAME_ALL) {
middleware[METHOD_NAME_ALL] ||= { handlers: [], params: {} }
Object.keys(middleware).forEach((m) => {
middleware[m].handlers.push(handler)
})
Object.keys(routes).forEach((m) => {
Object.values(routes[m]).forEach((matchRes) => matchRes.handlers.push(handler))
})
} else {
middleware[method] ||= {
handlers: [...(middleware[METHOD_NAME_ALL]?.handlers || [])],
params: {},
}
middleware[method].handlers.push(handler)
if (routes[method]) {
Object.values(routes[method]).forEach((matchRes) => matchRes.handlers.push(handler))
}
}
return
}
if (/\*|\/:/.test(path)) {
throw new UnsupportedPathError(path)
}
routes[method][path] ||= {
handlers: [
...(routes[METHOD_NAME_ALL][path]?.handlers ||
middleware[method]?.handlers ||
middleware[METHOD_NAME_ALL]?.handlers ||
[]),
],
params: {},
}
if (method === METHOD_NAME_ALL) {
Object.keys(routes).forEach((m) => {
routes[m][path]?.handlers?.push(handler)
})
} else {
routes[method][path].handlers.push(handler)
}
}
match(method: string, path: string): Result<T> | null {
const { routes, middleware } = this
this.match = (method, path) =>
routes[method][path] ||
routes[METHOD_NAME_ALL][path] ||
middleware[method] ||
middleware[METHOD_NAME_ALL] ||
null
return this.match(method, path)
}
}