Skip to content

Commit

Permalink
feat(helper/factory): Calculate Context<Env> Type in createHandlers (#…
Browse files Browse the repository at this point in the history
…3670)

* chore(types): export IntersectNonAnyTypes (#3467)

* feat(helper/factory): Calculate context env type in createHandlers (#3467)

* feat(factory): test context env type in createHandlers
  • Loading branch information
sushichan044 authored Nov 14, 2024
1 parent 1e8ebe9 commit a15bec3
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 107 deletions.
23 changes: 23 additions & 0 deletions src/helper/factory/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,29 @@ describe('createHandler', () => {
expectTypeOf(routes).toEqualTypeOf<Expected>()
})
})

describe('Types - Context Env with Multiple Middlewares', () => {
const factory = createFactory()

const mw1 = createMiddleware<{ Variables: { foo: string } }>(async (c, next) => {
c.set('foo', 'bar')
await next()
})

const mw2 = createMiddleware<{ Variables: { bar: number } }>(async (c, next) => {
c.set('bar', 1)
await next()
})

it('Should set the correct type for context from multiple middlewares', () => {
factory.createHandlers(mw1, mw2, (c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.var.bar).toEqualTypeOf<number>()

return c.json({ foo: c.var.foo, bar: c.var.bar })
})
})
})
})

describe('createApp', () => {
Expand Down
285 changes: 179 additions & 106 deletions src/helper/factory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,66 @@

/* eslint-disable @typescript-eslint/no-explicit-any */
import { Hono } from '../../hono'
import type { Env, H, HandlerResponse, Input, MiddlewareHandler } from '../../types'
import type {
Env,
H,
HandlerResponse,
Input,
IntersectNonAnyTypes,
MiddlewareHandler,
} from '../../types'

type InitApp<E extends Env = Env> = (app: Hono<E>) => void

export interface CreateHandlersInterface<E extends Env, P extends string> {
<I extends Input = {}, R extends HandlerResponse<any> = any>(handler1: H<E, P, I, R>): [
H<E, P, I, R>
]
<I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E>(
handler1: H<E2, P, I, R>
): [H<E2, P, I, R>]

// handler x2
<I extends Input = {}, I2 extends Input = I, R extends HandlerResponse<any> = any>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>
): [H<E, P, I, R>, H<E, P, I2, R>]
<
I extends Input = {},
I2 extends Input = I,
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = IntersectNonAnyTypes<[E, E2]>
>(
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>
): [H<E2, P, I, R>, H<E3, P, I2, R>]

// handler x3
<
I extends Input = {},
I2 extends Input = I,
I3 extends Input = I & I2,
R extends HandlerResponse<any> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>
): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>]
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>
): [H<E2, P, I, R>, H<E3, P, I2, R>, H<E4, P, I3, R>]

// handler x4
<
I extends Input = {},
I2 extends Input = I,
I3 extends Input = I & I2,
I4 extends Input = I & I2 & I3,
R extends HandlerResponse<any> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>
): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>]
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>
): [H<E2, P, I, R>, H<E3, P, I2, R>, H<E4, P, I3, R>, H<E5, P, I4, R>]

// handler x5
<
Expand All @@ -52,14 +73,19 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
I3 extends Input = I & I2,
I4 extends Input = I & I2 & I3,
I5 extends Input = I & I2 & I3 & I4,
R extends HandlerResponse<any> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>
): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>, H<E, P, I5, R>]
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>
): [H<E2, P, I, R>, H<E3, P, I2, R>, H<E4, P, I3, R>, H<E5, P, I4, R>, H<E6, P, I5, R>]

// handler x6
<
Expand All @@ -69,15 +95,28 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
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> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>,
handler6: H<E, P, I6, R>
): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>, H<E, P, I5, R>, H<E, P, I6, R>]
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>,
handler6: H<E7, P, I6, R>
): [
H<E2, P, I, R>,
H<E3, P, I2, R>,
H<E4, P, I3, R>,
H<E5, P, I4, R>,
H<E6, P, I5, R>,
H<E7, P, I6, R>
]

// handler x7
<
Expand All @@ -88,23 +127,30 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
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> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>,
handler6: H<E, P, I6, R>,
handler7: H<E, P, I7, R>
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>,
handler6: H<E7, P, I6, R>,
handler7: H<E8, P, I7, R>
): [
H<E, P, I, R>,
H<E, P, I2, R>,
H<E, P, I3, R>,
H<E, P, I4, R>,
H<E, P, I5, R>,
H<E, P, I6, R>,
H<E, P, I7, R>
H<E2, P, I, R>,
H<E3, P, I2, R>,
H<E4, P, I3, R>,
H<E5, P, I4, R>,
H<E6, P, I5, R>,
H<E7, P, I6, R>,
H<E8, P, I7, R>
]

// handler x8
Expand All @@ -117,25 +163,33 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
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> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = E,
E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>,
handler6: H<E, P, I6, R>,
handler7: H<E, P, I7, R>,
handler8: H<E, P, I8, R>
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>,
handler6: H<E7, P, I6, R>,
handler7: H<E8, P, I7, R>,
handler8: H<E9, P, I8, R>
): [
H<E, P, I, R>,
H<E, P, I2, R>,
H<E, P, I3, R>,
H<E, P, I4, R>,
H<E, P, I5, R>,
H<E, P, I6, R>,
H<E, P, I7, R>,
H<E, P, I8, R>
H<E2, P, I, R>,
H<E3, P, I2, R>,
H<E4, P, I3, R>,
H<E5, P, I4, R>,
H<E6, P, I5, R>,
H<E7, P, I6, R>,
H<E8, P, I7, R>,
H<E9, P, I8, R>
]

// handler x9
Expand All @@ -149,27 +203,36 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
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> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = E,
E9 extends Env = E,
E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>,
handler6: H<E, P, I6, R>,
handler7: H<E, P, I7, R>,
handler8: H<E, P, I8, R>,
handler9: H<E, P, I9, R>
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>,
handler6: H<E7, P, I6, R>,
handler7: H<E8, P, I7, R>,
handler8: H<E9, P, I8, R>,
handler9: H<E10, P, I9, R>
): [
H<E, P, I, R>,
H<E, P, I2, R>,
H<E, P, I3, R>,
H<E, P, I4, R>,
H<E, P, I5, R>,
H<E, P, I6, R>,
H<E, P, I7, R>,
H<E, P, I8, R>,
H<E, P, I9, R>
H<E2, P, I, R>,
H<E3, P, I2, R>,
H<E4, P, I3, R>,
H<E5, P, I4, R>,
H<E6, P, I5, R>,
H<E7, P, I6, R>,
H<E8, P, I7, R>,
H<E9, P, I8, R>,
H<E10, P, I9, R>
]

// handler x10
Expand All @@ -184,29 +247,39 @@ export interface CreateHandlersInterface<E extends Env, P extends string> {
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> = any
R extends HandlerResponse<any> = any,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = E,
E9 extends Env = E,
E10 extends Env = E,
E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>
>(
handler1: H<E, P, I, R>,
handler2: H<E, P, I2, R>,
handler3: H<E, P, I3, R>,
handler4: H<E, P, I4, R>,
handler5: H<E, P, I5, R>,
handler6: H<E, P, I6, R>,
handler7: H<E, P, I7, R>,
handler8: H<E, P, I8, R>,
handler9: H<E, P, I9, R>,
handler10: H<E, P, I10, R>
handler1: H<E2, P, I, R>,
handler2: H<E3, P, I2, R>,
handler3: H<E4, P, I3, R>,
handler4: H<E5, P, I4, R>,
handler5: H<E6, P, I5, R>,
handler6: H<E7, P, I6, R>,
handler7: H<E8, P, I7, R>,
handler8: H<E9, P, I8, R>,
handler9: H<E10, P, I9, R>,
handler10: H<E11, P, I10, R>
): [
H<E, P, I, R>,
H<E, P, I2, R>,
H<E, P, I3, R>,
H<E, P, I4, R>,
H<E, P, I5, R>,
H<E, P, I6, R>,
H<E, P, I7, R>,
H<E, P, I8, R>,
H<E, P, I9, R>,
H<E, P, I10, R>
H<E2, P, I, R>,
H<E3, P, I2, R>,
H<E4, P, I3, R>,
H<E5, P, I4, R>,
H<E6, P, I5, R>,
H<E7, P, I6, R>,
H<E8, P, I7, R>,
H<E9, P, I8, R>,
H<E10, P, I9, R>,
H<E11, P, I10, R>
]
}

Expand Down
Loading

0 comments on commit a15bec3

Please sign in to comment.