From d5d2e239974e03344a42cf92802f6afaa64b8d6a Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Mon, 1 Jan 2024 18:20:41 +0900 Subject: [PATCH] fix(dev): preserve original handler in [composedHandler]. (#1873) * fix(dev): preserve original handler in [composedHandler]. * chore: denoify * refactor(dev): better variable names --- deno_dist/helper/dev/index.ts | 23 +++++++++++++++++------ deno_dist/hono-base.ts | 17 ++++++++++++----- src/helper/dev/index.test.ts | 18 ++++++++++++++++++ src/helper/dev/index.ts | 23 +++++++++++++++++------ src/hono-base.ts | 17 ++++++++++++----- 5 files changed, 76 insertions(+), 22 deletions(-) diff --git a/deno_dist/helper/dev/index.ts b/deno_dist/helper/dev/index.ts index 69cd06d277..4760014ef6 100644 --- a/deno_dist/helper/dev/index.ts +++ b/deno_dist/helper/dev/index.ts @@ -1,4 +1,5 @@ import type { Hono } from '../../hono.ts' +import { COMPOSED_HANDLER } from '../../hono-base.ts' import type { Env, RouterRoute } from '../../types.ts' interface ShowRoutesOptions { @@ -16,14 +17,24 @@ const isMiddleware = (handler: Function) => handler.length > 1 const handlerName = (handler: Function) => { return handler.name || (isMiddleware(handler) ? '[middleware]' : '[handler]') } +const findTargetHandler = (handler: Function): Function => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (handler as any)[COMPOSED_HANDLER] + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + findTargetHandler((handler as any)[COMPOSED_HANDLER]) + : handler +} export const inspectRoutes = (hono: Hono): RouteData[] => { - return hono.routes.map(({ path, method, handler }: RouterRoute) => ({ - path, - method, - name: handlerName(handler), - isMiddleware: isMiddleware(handler), - })) + return hono.routes.map(({ path, method, handler }: RouterRoute) => { + const targetHandler = findTargetHandler(handler) + return { + path, + method, + name: handlerName(targetHandler), + isMiddleware: isMiddleware(targetHandler), + } + }) } export const showRoutes = (hono: Hono, opts?: ShowRoutesOptions) => { diff --git a/deno_dist/hono-base.ts b/deno_dist/hono-base.ts index 3b25c4ef67..67ff68324b 100644 --- a/deno_dist/hono-base.ts +++ b/deno_dist/hono-base.ts @@ -23,6 +23,8 @@ import type { } from './types.ts' import { getPath, getPathNoStrict, getQueryStrings, mergePath } from './utils/url.ts' +export const COMPOSED_HANDLER = Symbol('composedHandler') + type Methods = typeof METHODS[number] | typeof METHOD_NAME_ALL_LOWERCASE function defineDynamicClass(): { @@ -158,11 +160,16 @@ class Hono< } app.routes.map((r) => { - const handler = - app.errorHandler === errorHandler - ? r.handler - : async (c: Context, next: Next) => - (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res + let handler + if (app.errorHandler === errorHandler) { + handler = r.handler + } else { + handler = async (c: Context, next: Next) => + (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(handler as any)[COMPOSED_HANDLER] = r.handler + } + subApp.addRoute(r.method, r.path, handler) }) return this diff --git a/src/helper/dev/index.test.ts b/src/helper/dev/index.test.ts index c52094e27c..3646a473c8 100644 --- a/src/helper/dev/index.test.ts +++ b/src/helper/dev/index.test.ts @@ -36,6 +36,24 @@ describe('inspectRoutes()', () => { { path: '/static', method: 'GET', name: '[handler]', isMiddleware: false }, ]) }) + + it('should return [handler] also for sub app', async () => { + const subApp = new Hono() + + subApp.get('/', (c) => c.json(0)) + subApp.onError((_, c) => c.json(0)) + + const mainApp = new Hono() + mainApp.route('/', subApp) + expect(inspectRoutes(mainApp)).toEqual([ + { + isMiddleware: false, + method: 'GET', + name: '[handler]', + path: '/', + }, + ]) + }) }) describe('showRoutes()', () => { diff --git a/src/helper/dev/index.ts b/src/helper/dev/index.ts index 0ce094b58d..95a4879c2f 100644 --- a/src/helper/dev/index.ts +++ b/src/helper/dev/index.ts @@ -1,4 +1,5 @@ import type { Hono } from '../../hono' +import { COMPOSED_HANDLER } from '../../hono-base' import type { Env, RouterRoute } from '../../types' interface ShowRoutesOptions { @@ -16,14 +17,24 @@ const isMiddleware = (handler: Function) => handler.length > 1 const handlerName = (handler: Function) => { return handler.name || (isMiddleware(handler) ? '[middleware]' : '[handler]') } +const findTargetHandler = (handler: Function): Function => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (handler as any)[COMPOSED_HANDLER] + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + findTargetHandler((handler as any)[COMPOSED_HANDLER]) + : handler +} export const inspectRoutes = (hono: Hono): RouteData[] => { - return hono.routes.map(({ path, method, handler }: RouterRoute) => ({ - path, - method, - name: handlerName(handler), - isMiddleware: isMiddleware(handler), - })) + return hono.routes.map(({ path, method, handler }: RouterRoute) => { + const targetHandler = findTargetHandler(handler) + return { + path, + method, + name: handlerName(targetHandler), + isMiddleware: isMiddleware(targetHandler), + } + }) } export const showRoutes = (hono: Hono, opts?: ShowRoutesOptions) => { diff --git a/src/hono-base.ts b/src/hono-base.ts index a8da531ce2..a9d9585489 100644 --- a/src/hono-base.ts +++ b/src/hono-base.ts @@ -23,6 +23,8 @@ import type { } from './types' import { getPath, getPathNoStrict, getQueryStrings, mergePath } from './utils/url' +export const COMPOSED_HANDLER = Symbol('composedHandler') + type Methods = typeof METHODS[number] | typeof METHOD_NAME_ALL_LOWERCASE function defineDynamicClass(): { @@ -158,11 +160,16 @@ class Hono< } app.routes.map((r) => { - const handler = - app.errorHandler === errorHandler - ? r.handler - : async (c: Context, next: Next) => - (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res + let handler + if (app.errorHandler === errorHandler) { + handler = r.handler + } else { + handler = async (c: Context, next: Next) => + (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(handler as any)[COMPOSED_HANDLER] = r.handler + } + subApp.addRoute(r.method, r.path, handler) }) return this