From b0f880d1594a491f13f6234f22546249adebae74 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 12 Nov 2023 18:00:54 +0900 Subject: [PATCH 1/2] feat: `next()` without `await` --- src/compose.test.ts | 49 +++++++++++++++++++++++ src/hono.test.ts | 97 +++++++++++++++++++++++++++++++++++++++++++++ src/types.ts | 4 +- 3 files changed, 148 insertions(+), 2 deletions(-) diff --git a/src/compose.test.ts b/src/compose.test.ts index 259939c32..36b2fee4f 100644 --- a/src/compose.test.ts +++ b/src/compose.test.ts @@ -709,3 +709,52 @@ describe('Compose', function () { expect(ctx.next).toEqual(1) }) }) + +describe('compose without `await`', () => { + const middleware: MiddlewareTuple[] = [] + + const a = async (c: C, next: Function) => { + c.req['log'] = 'log' + next() + } + + const b = async (c: C, next: Function) => { + next() + c.res['headers'] = 'custom-header' + } + + const c = async (c: C, next: Function) => { + c.req['xxx'] = 'yyy' + next() + c.res['zzz'] = c.req['xxx'] + } + + const handler = async (c: C, next: Function) => { + c.req['log'] = `${c.req.log} message` + next() + c.res = { message: 'new response' } + } + + middleware.push(buildMiddlewareTuple(a)) + middleware.push(buildMiddlewareTuple(b)) + middleware.push(buildMiddlewareTuple(c)) + middleware.push(buildMiddlewareTuple(handler)) + + it('Request', async () => { + const c: C = { req: {}, res: {}, finalized: false } + const composed = compose(middleware) + const context = await composed(c) + expect(context.req['log']).not.toBeNull() + expect(context.req['log']).toBe('log message') + expect(context.req['xxx']).toBe('yyy') + }) + it('Response', async () => { + const c: C = { req: {}, res: {}, finalized: false } + const composed = compose(middleware) + const context = await composed(c) + expect(context.res['headers']).not.toBeNull() + expect(context.res['headers']).toBe('custom-header') + expect(context.res['message']).toBe('new response') + expect(context.res['zzz']).toBe('yyy') + }) +}) diff --git a/src/hono.test.ts b/src/hono.test.ts index 29b15cc71..396d9bd0c 100644 --- a/src/hono.test.ts +++ b/src/hono.test.ts @@ -830,6 +830,103 @@ describe('Middleware', () => { }) }) + describe('Without `await`', () => { + const app = new Hono() + + // Custom Logger + app.use('*', (c, next) => { + console.log(`${c.req.method} : ${c.req.url}`) + next() + }) + + // Append Custom Header + app.use('*', (c, next) => { + next() + c.res.headers.append('x-custom', 'root') + }) + + app.use('/hello', async (c, next) => { + next() + c.res.headers.append('x-message', 'custom-header') + }) + + app.use('/hello/*', async (c, next) => { + next() + c.res.headers.append('x-message-2', 'custom-header-2') + }) + + app.get('/hello', (c) => { + return c.text('hello') + }) + + app.use('/json/*', async (c, next) => { + c.res.headers.append('foo', 'bar') + await next() + }) + + app.get('/json', (c) => { + // With a raw response + return new Response( + JSON.stringify({ + message: 'hello', + }), + { + headers: { + 'content-type': 'application/json', + }, + } + ) + }) + + app.get('/hello/:message', (c) => { + const message = c.req.param('message') + return c.text(`${message}`) + }) + + app.get('/error', () => { + throw new Error('Error!') + }) + + app.notFound((c) => { + return c.text('Not Found Foo', 404) + }) + + it('logging and custom header', async () => { + const res = await app.request('http://localhost/hello') + expect(res.status).toBe(200) + expect(await res.text()).toBe('hello') + expect(res.headers.get('x-custom')).toBe('root') + expect(res.headers.get('x-message')).toBe('custom-header') + expect(res.headers.get('x-message-2')).toBe('custom-header-2') + }) + + it('logging and custom header with named param', async () => { + const res = await app.request('http://localhost/hello/message') + expect(res.status).toBe(200) + expect(await res.text()).toBe('message') + expect(res.headers.get('x-custom')).toBe('root') + expect(res.headers.get('x-message-2')).toBe('custom-header-2') + }) + + it('should return correct the content-type header', async () => { + const res = await app.request('http://localhost/json') + expect(res.status).toBe(200) + expect(res.headers.get('content-type')).toMatch(/^application\/json/) + }) + + it('not found', async () => { + const res = await app.request('http://localhost/foo') + expect(res.status).toBe(404) + expect(await res.text()).toBe('Not Found Foo') + }) + + it('internal server error', async () => { + const res = await app.request('http://localhost/error') + expect(res.status).toBe(500) + console.log(await res.text()) + }) + }) + describe('Chained route', () => { const app = new Hono() app diff --git a/src/types.ts b/src/types.ts index 6023fea7b..0c031ac6b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,7 @@ export type Env = { Variables?: Variables } -export type Next = () => Promise +export type Next = () => void | Promise export type Input = { in?: Partial @@ -46,7 +46,7 @@ export type MiddlewareHandler< E extends Env = any, P extends string = string, I extends Input = {} -> = (c: Context, next: Next) => Promise +> = (c: Context, next: Next) => Response | void | Promise export type H< E extends Env = any, From 864fae668c7505e523cfe9d57e4e0778ddaa2fe5 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 12 Nov 2023 18:18:51 +0900 Subject: [PATCH 2/2] denoify --- deno_dist/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deno_dist/types.ts b/deno_dist/types.ts index 1bd7bd329..293199b26 100644 --- a/deno_dist/types.ts +++ b/deno_dist/types.ts @@ -20,7 +20,7 @@ export type Env = { Variables?: Variables } -export type Next = () => Promise +export type Next = () => void | Promise export type Input = { in?: Partial @@ -46,7 +46,7 @@ export type MiddlewareHandler< E extends Env = any, P extends string = string, I extends Input = {} -> = (c: Context, next: Next) => Promise +> = (c: Context, next: Next) => Response | void | Promise export type H< E extends Env = any,