Skip to content

Commit

Permalink
fix(zod-openapi): infer env type parameter from middleware (#828)
Browse files Browse the repository at this point in the history
* fix(zod-openapi): infer env type parameter from middleware

* add test
  • Loading branch information
daniel-pedersen authored Nov 16, 2024
1 parent e37c313 commit bbb48ef
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-toes-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hono/zod-openapi': patch
---

infer env type parameter from middleware
14 changes: 11 additions & 3 deletions packages/zod-openapi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,17 @@ export type MiddlewareToHandlerType<M extends MiddlewareHandler<any, any, any>[]
? Last // Return the last remaining handler in the array
: never

type RouteMiddlewareParams<R extends RouteConfig> = OfHandlerType<
MiddlewareToHandlerType<AsArray<R['middleware']>>
>

export type RouteConfigToEnv<R extends RouteConfig> = RouteMiddlewareParams<R> extends never
? Env
: RouteMiddlewareParams<R>['env']

export type RouteHandler<
R extends RouteConfig,
E extends Env = Env,
E extends Env = RouteConfigToEnv<R>,
I extends Input = InputTypeParam<R> &
InputTypeQuery<R> &
InputTypeHeader<R> &
Expand Down Expand Up @@ -299,7 +307,7 @@ export type RouteHandler<

export type RouteHook<
R extends RouteConfig,
E extends Env = Env,
E extends Env = RouteConfigToEnv<R>,
I extends Input = InputTypeParam<R> &
InputTypeQuery<R> &
InputTypeHeader<R> &
Expand Down Expand Up @@ -381,7 +389,7 @@ export class OpenAPIHono<
handler: Handler<
// use the env from the middleware if it's defined
R['middleware'] extends MiddlewareHandler[] | MiddlewareHandler
? OfHandlerType<MiddlewareToHandlerType<AsArray<R['middleware']>>>['env'] & E
? RouteMiddlewareParams<R>['env'] & E
: E,
P,
I,
Expand Down
37 changes: 37 additions & 0 deletions packages/zod-openapi/test/handler.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { MiddlewareHandler } from 'hono'
import type { RouteHandler } from '../src'
import { OpenAPIHono, createRoute, z } from '../src'

Expand Down Expand Up @@ -52,4 +53,40 @@ describe('supports async handler', () => {
hono.openapi(route, handler)
hono.openapi(route, asyncHandler)
})

test('RouteHandler infers env type from middleware', () => {
type CustomEnv = { Variables: { customKey: string } }

const customMiddleware: MiddlewareHandler<CustomEnv> = (c, next) => {
c.set('customKey', 'customValue')
return next()
}

const routeWithMiddleware = createRoute({
method: 'get',
path: '/users',
middleware: [customMiddleware] as const,
responses: {
200: {
content: {
'application/json': {
schema: z.object({
id: z.string(),
}),
},
},
description: 'Retrieve the user',
},
},
})

const handler: RouteHandler<typeof routeWithMiddleware> = (c) => {
return c.json({
id: c.get('customKey'),
})
}

const hono = new OpenAPIHono()
hono.openapi(routeWithMiddleware, handler)
})
})

0 comments on commit bbb48ef

Please sign in to comment.