From ba6f432473c71c50bd855d5a1d7293d7148bc980 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 19 Nov 2023 06:33:38 +0900 Subject: [PATCH 1/5] feat(helper/factory): introduce `createHandlers()` --- src/helper/factory/index.ts | 85 ++++++++++++++++++++++++++++++++++++- src/types.ts | 2 +- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/helper/factory/index.ts b/src/helper/factory/index.ts index 55381ca68..422ec0479 100644 --- a/src/helper/factory/index.ts +++ b/src/helper/factory/index.ts @@ -1,6 +1,87 @@ -import type { Env, Input, MiddlewareHandler } from '../../types' +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Env, Input, MiddlewareHandler, H, HandlerResponse } from '../../types' -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const createMiddleware = ( middleware: MiddlewareHandler ) => middleware + +export function createHandlers( + handler1: H +): [H] + +export function createHandlers< + E extends Env = any, + P extends string = any, + I extends Input = {}, + I2 extends Input = I +>(handler1: H, handler2: H): [H, H] + +export function createHandlers< + E extends Env = any, + P extends string = any, + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + R extends HandlerResponse = any +>( + handler1: H, + handler2: H, + handler3: H +): [H, H, H] + +export function createHandlers< + E extends Env = any, + P extends string = any, + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + R extends HandlerResponse = any +>( + handler1: H, + handler2: H, + handler3: H, + handler4: H +): [H, H, H, H] + +export function createHandlers< + E extends Env = any, + P extends string = any, + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + R extends HandlerResponse = any +>( + handler1: H, + handler2: H, + handler3: H, + handler4: H +): [H, H, H, H] + +export function createHandlers< + E extends Env = any, + P extends string = any, + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + R extends HandlerResponse = any +>( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H +): [H, H, H, H, H] + +export function createHandlers( + handler1: H, + handler2?: H, + handler3?: H, + handler4?: H, + handler5?: H +) { + return [handler1, handler2, handler3, handler4, handler5] +} diff --git a/src/types.ts b/src/types.ts index f3bbe51bd..bd3c84bfe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -33,7 +33,7 @@ export type Input = { ////// ////// //////////////////////////////////////// -type HandlerResponse = Response | TypedResponse | Promise> +export type HandlerResponse = Response | TypedResponse | Promise> export type Handler< E extends Env = any, From f450ab00d259763711f9234215f753639307ce96 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Tue, 28 Nov 2023 21:40:39 +0900 Subject: [PATCH 2/5] create `Factory` class --- src/helper/factory/index.test.ts | 154 ++++++++++++++++++++++++++++++- src/helper/factory/index.ts | 140 +++++++++++++--------------- 2 files changed, 216 insertions(+), 78 deletions(-) diff --git a/src/helper/factory/index.test.ts b/src/helper/factory/index.test.ts index 78f880421..70d021a50 100644 --- a/src/helper/factory/index.test.ts +++ b/src/helper/factory/index.test.ts @@ -1,6 +1,9 @@ +import { expectTypeOf } from 'vitest' import { hc } from '../../client' import { Hono } from '../../index' -import { createMiddleware } from './index' +import type { ExtractSchema } from '../../types' +import { validator } from '../../validator' +import { createMiddleware, createFactory } from './index' describe('createMiddleware', () => { type Env = { Variables: { foo: string } } @@ -30,3 +33,152 @@ describe('createMiddleware', () => { expect(url.pathname).toBe('/message') }) }) + +// A fake function for testing types. +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function extractSchema(_: T): ExtractSchema { + return 0 as ExtractSchema +} + +describe('createHandler', () => { + const mw = (message: string) => + createMiddleware(async (c, next) => { + await next() + c.header('x-message', message) + }) + + describe('Basic', () => { + const factory = createFactory() + const app = new Hono() + + const handlersA = factory.createHandlers((c) => { + return c.text('A') + }) + app.get('/a', ...handlersA) + + const handlersB = factory.createHandlers(mw('B'), (c) => { + return c.text('B') + }) + app.get('/b', ...handlersB) + + it('Should return 200 response - GET /a', async () => { + const res = await app.request('/a') + expect(res.status).toBe(200) + expect(await res.text()).toBe('A') + }) + + it('Should return 200 response with a custom header - GET /b', async () => { + const res = await app.request('/b') + expect(res.status).toBe(200) + expect(res.headers.get('x-message')).toBe('B') + expect(await res.text()).toBe('B') + }) + }) + + describe('Types', () => { + type Env = { Variables: { foo: string } } + + const factory = createFactory() + const app = new Hono() + + const handlersA = factory.createHandlers( + validator('query', () => { + return { + page: '1', + } + }), + (c) => { + const foo = c.var.foo + const { page } = c.req.valid('query') + return c.jsonT({ page, foo }) + } + ) + const routesA = app.get('/posts', ...handlersA) + + type ExpectedA = { + '/posts': { + $get: { + input: { + query: { + page: string + } + } + output: { + foo: string + page: string + } + } + } + } + + it('Should return correct types', () => { + expectTypeOf(extractSchema(routesA)).toEqualTypeOf() + }) + }) + + // It's difficult to cover all possible patterns, + // so these tests will only cover the minimal cases. + + describe('Types - Complex', () => { + type Env = { Variables: { foo: string } } + + const factory = createFactory() + const app = new Hono() + + const handlersA = factory.createHandlers( + validator('header', () => { + return { + auth: 'token', + } + }), + validator('query', () => { + return { + page: '1', + } + }), + validator('json', () => { + return { + id: 123, + } + }), + (c) => { + const foo = c.var.foo + const { auth } = c.req.valid('header') + const { page } = c.req.valid('query') + const { id } = c.req.valid('json') + return c.jsonT({ auth, page, foo, id }) + } + ) + const routesA = app.get('/posts', ...handlersA) + + type ExpectedA = { + '/posts': { + $get: { + input: { + header: { + auth: string + } + } & { + query: { + page: string + } + } & { + json: { + id: number + } + } + output: { + auth: string + page: string + foo: string + id: number + } + } + } + } + + it('Should return correct types', () => { + expectTypeOf(extractSchema(routesA)).toEqualTypeOf() + }) + }) +}) diff --git a/src/helper/factory/index.ts b/src/helper/factory/index.ts index 422ec0479..c1fe1e30e 100644 --- a/src/helper/factory/index.ts +++ b/src/helper/factory/index.ts @@ -1,87 +1,73 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { Env, Input, MiddlewareHandler, H, HandlerResponse } from '../../types' -export const createMiddleware = ( - middleware: MiddlewareHandler -) => middleware - -export function createHandlers( - handler1: H -): [H] +export class Factory { + createMiddleware = (middleware: MiddlewareHandler) => middleware -export function createHandlers< - E extends Env = any, - P extends string = any, - I extends Input = {}, - I2 extends Input = I ->(handler1: H, handler2: H): [H, H] + createHandlers(handler1: H): [H] + createHandlers = any>( + handler1: H, + handler2: H + ): [H, H] -export function createHandlers< - E extends Env = any, - P extends string = any, - I extends Input = {}, - I2 extends Input = I, - I3 extends Input = I & I2, - R extends HandlerResponse = any ->( - handler1: H, - handler2: H, - handler3: H -): [H, H, H] + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H + ): [H, H, H] -export function createHandlers< - E extends Env = any, - P extends string = any, - I extends Input = {}, - I2 extends Input = I, - I3 extends Input = I & I2, - I4 extends Input = I & I2 & I3, - R extends HandlerResponse = any ->( - handler1: H, - handler2: H, - handler3: H, - handler4: H -): [H, H, H, H] + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H + ): [H, H, H, H] -export function createHandlers< - E extends Env = any, - P extends string = any, - I extends Input = {}, - I2 extends Input = I, - I3 extends Input = I & I2, - I4 extends Input = I & I2 & I3, - R extends HandlerResponse = any ->( - handler1: H, - handler2: H, - handler3: H, - handler4: H -): [H, H, H, H] + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H + ): [H, H, H, H] -export function createHandlers< - E extends Env = any, - P extends string = any, - I extends Input = {}, - I2 extends Input = I, - I3 extends Input = I & I2, - I4 extends Input = I & I2 & I3, - I5 extends Input = I & I2 & I3 & I4, - R extends HandlerResponse = any ->( - handler1: H, - handler2: H, - handler3: H, - handler4: H, - handler5: H -): [H, H, H, H, H] + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H + ): [H, H, H, H, H] -export function createHandlers( - handler1: H, - handler2?: H, - handler3?: H, - handler4?: H, - handler5?: H -) { - return [handler1, handler2, handler3, handler4, handler5] + createHandlers(handler1: H, handler2?: H, handler3?: H, handler4?: H, handler5?: H) { + return [handler1, handler2, handler3, handler4, handler5] + } } + +export const createFactory = () => new Factory() +export const createMiddleware = ( + middleware: MiddlewareHandler +) => createFactory().createMiddleware(middleware) From 7b9ca6d9a0e149440f97fd425c4ab478117dd106 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Wed, 29 Nov 2023 05:46:40 +0900 Subject: [PATCH 3/5] support up to 10 handlers --- src/helper/factory/index.ts | 235 +++++++++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 6 deletions(-) diff --git a/src/helper/factory/index.ts b/src/helper/factory/index.ts index c1fe1e30e..26b8d46d2 100644 --- a/src/helper/factory/index.ts +++ b/src/helper/factory/index.ts @@ -1,15 +1,38 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { Env, Input, MiddlewareHandler, H, HandlerResponse } from '../../types' +/** + * @experimental + * `Factory` class is an experimental feature. + * The API might be changed. + */ export class Factory { createMiddleware = (middleware: MiddlewareHandler) => middleware + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers(handler1: H): [H] + + // handler x2 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers = any>( handler1: H, handler2: H ): [H, H] + // handler x3 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers< I extends Input = {}, I2 extends Input = I, @@ -21,6 +44,12 @@ export class Factory { handler3: H ): [H, H, H] + // handler x4 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers< I extends Input = {}, I2 extends Input = I, @@ -34,40 +63,234 @@ export class Factory { handler4: H ): [H, H, H, H] + // handler x5 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers< I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, R extends HandlerResponse = any >( handler1: H, handler2: H, handler3: H, - handler4: H - ): [H, H, H, H] + handler4: H, + handler5: H + ): [H, H, H, H, H] + // handler x6 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ createHandlers< I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, R extends HandlerResponse = any >( handler1: H, handler2: H, handler3: H, handler4: H, - handler5: H - ): [H, H, H, H, H] + handler5: H, + handler6: H + ): [H, H, H, H, H, H] + + // handler x7 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H + ): [ + H, + H, + H, + H, + H, + H, + H + ] + + // handler x8 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H + ] - createHandlers(handler1: H, handler2?: H, handler3?: H, handler4?: H, handler5?: H) { - return [handler1, handler2, handler3, handler4, handler5] + // handler x9 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H, + handler9: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H, + H + ] + + // handler x10 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, + I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H, + handler9: H, + handler10: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H, + H, + H + ] + + createHandlers( + handler1: H, + handler2?: H, + handler3?: H, + handler4?: H, + handler5?: H, + handler6?: H, + handler7?: H, + handler8?: H, + handler9?: H, + handler10?: H + ) { + return [ + handler1, + handler2, + handler3, + handler4, + handler5, + handler6, + handler7, + handler8, + handler9, + handler10, + ] } } +/** + * @experimental + * `createFactory` is an experimental feature. + * The API might be changed. + */ export const createFactory = () => new Factory() + export const createMiddleware = ( middleware: MiddlewareHandler ) => createFactory().createMiddleware(middleware) From 94069c958cc705f47694f23136c45356e5f26a45 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Wed, 29 Nov 2023 06:08:28 +0900 Subject: [PATCH 4/5] denoify --- deno_dist/helper/factory/index.ts | 298 +++++++++++++++++++++++++++++- deno_dist/types.ts | 2 +- src/helper/factory/index.test.ts | 24 ++- 3 files changed, 316 insertions(+), 8 deletions(-) diff --git a/deno_dist/helper/factory/index.ts b/deno_dist/helper/factory/index.ts index 39d9f5130..307a8bec7 100644 --- a/deno_dist/helper/factory/index.ts +++ b/deno_dist/helper/factory/index.ts @@ -1,6 +1,296 @@ -import type { Env, Input, MiddlewareHandler } from '../../types.ts' +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Env, Input, MiddlewareHandler, H, HandlerResponse } from '../../types.ts' + +/** + * @experimental + * `Factory` class is an experimental feature. + * The API might be changed. + */ +export class Factory { + createMiddleware = (middleware: MiddlewareHandler) => middleware + + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers(handler1: H): [H] + + // handler x2 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers = any>( + handler1: H, + handler2: H + ): [H, H] + + // handler x3 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H + ): [H, H, H] + + // handler x4 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H + ): [H, H, H, H] + + // handler x5 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H + ): [H, H, H, H, H] + + // handler x6 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H + ): [H, H, H, H, H, H] + + // handler x7 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H + ): [ + H, + H, + H, + H, + H, + H, + H + ] + + // handler x8 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H + ] + + // handler x9 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H, + handler9: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H, + H + ] + + // handler x10 + /** + * @experimental + * `createHandlers` is an experimental feature. + * The API might be changed. + */ + createHandlers< + I extends Input = {}, + I2 extends Input = I, + I3 extends Input = I & I2, + I4 extends Input = I & I2 & I3, + I5 extends Input = I & I2 & I3 & I4, + I6 extends Input = I & I2 & I3 & I4 & I5, + I7 extends Input = I & I2 & I3 & I4 & I5 & I6, + I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, + I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, + I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, + R extends HandlerResponse = any + >( + handler1: H, + handler2: H, + handler3: H, + handler4: H, + handler5: H, + handler6: H, + handler7: H, + handler8: H, + handler9: H, + handler10: H + ): [ + H, + H, + H, + H, + H, + H, + H, + H, + H, + H + ] + + createHandlers( + handler1: H, + handler2?: H, + handler3?: H, + handler4?: H, + handler5?: H, + handler6?: H, + handler7?: H, + handler8?: H, + handler9?: H, + handler10?: H + ) { + return [ + handler1, + handler2, + handler3, + handler4, + handler5, + handler6, + handler7, + handler8, + handler9, + handler10, + ] + } +} + +/** + * @experimental + * `createFactory` is an experimental feature. + * The API might be changed. + */ +export const createFactory = () => new Factory() -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const createMiddleware = ( - middleware: MiddlewareHandler -) => middleware + middleware: MiddlewareHandler +) => createFactory().createMiddleware(middleware) diff --git a/deno_dist/types.ts b/deno_dist/types.ts index b502aea76..5e7e23e28 100644 --- a/deno_dist/types.ts +++ b/deno_dist/types.ts @@ -33,7 +33,7 @@ export type Input = { ////// ////// //////////////////////////////////////// -type HandlerResponse = Response | TypedResponse | Promise> +export type HandlerResponse = Response | TypedResponse | Promise> export type Handler< E extends Env = any, diff --git a/src/helper/factory/index.test.ts b/src/helper/factory/index.test.ts index 70d021a50..996609f90 100644 --- a/src/helper/factory/index.test.ts +++ b/src/helper/factory/index.test.ts @@ -1,7 +1,7 @@ import { expectTypeOf } from 'vitest' import { hc } from '../../client' import { Hono } from '../../index' -import type { ExtractSchema } from '../../types' +import type { ExtractSchema, ToSchema } from '../../types' import { validator } from '../../validator' import { createMiddleware, createFactory } from './index' @@ -37,7 +37,7 @@ describe('createMiddleware', () => { // A fake function for testing types. // eslint-disable-next-line @typescript-eslint/no-unused-vars function extractSchema(_: T): ExtractSchema { - return 0 as ExtractSchema + return true as ExtractSchema } describe('createHandler', () => { @@ -112,7 +112,25 @@ describe('createHandler', () => { } it('Should return correct types', () => { - expectTypeOf(extractSchema(routesA)).toEqualTypeOf() + expectTypeOf(routesA).toEqualTypeOf< + Hono< + Env, + ToSchema< + 'get', + '/posts', + { + query: { + page: string + } + }, + { + page: string + foo: string + } + >, + '/' + > + >() }) }) From 80094d54573e8b030f654e4c6d5f3f04c1e6d7de Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Wed, 29 Nov 2023 06:30:49 +0900 Subject: [PATCH 5/5] fixed tests --- src/helper/factory/index.test.ts | 110 +++++++++++++------------------ 1 file changed, 45 insertions(+), 65 deletions(-) diff --git a/src/helper/factory/index.test.ts b/src/helper/factory/index.test.ts index 996609f90..7b6e4cfa8 100644 --- a/src/helper/factory/index.test.ts +++ b/src/helper/factory/index.test.ts @@ -1,7 +1,7 @@ import { expectTypeOf } from 'vitest' import { hc } from '../../client' import { Hono } from '../../index' -import type { ExtractSchema, ToSchema } from '../../types' +import type { ToSchema } from '../../types' import { validator } from '../../validator' import { createMiddleware, createFactory } from './index' @@ -34,12 +34,6 @@ describe('createMiddleware', () => { }) }) -// A fake function for testing types. -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function extractSchema(_: T): ExtractSchema { - return true as ExtractSchema -} - describe('createHandler', () => { const mw = (message: string) => createMiddleware(async (c, next) => { @@ -81,7 +75,7 @@ describe('createHandler', () => { const factory = createFactory() const app = new Hono() - const handlersA = factory.createHandlers( + const handlers = factory.createHandlers( validator('query', () => { return { page: '1', @@ -93,44 +87,28 @@ describe('createHandler', () => { return c.jsonT({ page, foo }) } ) - const routesA = app.get('/posts', ...handlersA) - - type ExpectedA = { - '/posts': { - $get: { - input: { - query: { - page: string - } - } - output: { - foo: string + const routes = app.get('/posts', ...handlers) + + type Expected = Hono< + Env, + ToSchema< + 'get', + '/posts', + { + query: { page: string } + }, + { + page: string + foo: string } - } - } + >, + '/' + > it('Should return correct types', () => { - expectTypeOf(routesA).toEqualTypeOf< - Hono< - Env, - ToSchema< - 'get', - '/posts', - { - query: { - page: string - } - }, - { - page: string - foo: string - } - >, - '/' - > - >() + expectTypeOf(routes).toEqualTypeOf() }) }) @@ -143,7 +121,7 @@ describe('createHandler', () => { const factory = createFactory() const app = new Hono() - const handlersA = factory.createHandlers( + const handlers = factory.createHandlers( validator('header', () => { return { auth: 'token', @@ -167,36 +145,38 @@ describe('createHandler', () => { return c.jsonT({ auth, page, foo, id }) } ) - const routesA = app.get('/posts', ...handlersA) - - type ExpectedA = { - '/posts': { - $get: { - input: { - header: { - auth: string - } - } & { - query: { - page: string - } - } & { - json: { - id: number - } - } - output: { + const routes = app.get('/posts', ...handlers) + + type Expected = Hono< + Env, + ToSchema< + 'get', + '/posts', + { + header: { auth: string + } + } & { + query: { page: string - foo: string + } + } & { + json: { id: number } + }, + { + auth: string + page: string + foo: string + id: number } - } - } + >, + '/' + > it('Should return correct types', () => { - expectTypeOf(extractSchema(routesA)).toEqualTypeOf() + expectTypeOf(routes).toEqualTypeOf() }) }) })