fix(zod-openapi): support default response (#855)
* fix(zod-openapi): support default response * chore: changesetpull/858/head
parent
b1fdf7202f
commit
3f63c46fa6
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/zod-openapi': patch
|
||||
---
|
||||
|
||||
fix: support default response
|
|
@ -194,16 +194,26 @@ type RouteConfigStatusCode = keyof StatusCodeRangeDefinitions | StatusCode
|
|||
type ExtractStatusCode<T extends RouteConfigStatusCode> = T extends keyof StatusCodeRangeDefinitions
|
||||
? StatusCodeRangeDefinitions[T]
|
||||
: T
|
||||
export type RouteConfigToTypedResponse<R extends RouteConfig> = {
|
||||
[Status in keyof R['responses'] &
|
||||
RouteConfigStatusCode]: undefined extends R['responses'][Status]['content']
|
||||
? TypedResponse<{}, ExtractStatusCode<Status>, string>
|
||||
: ReturnJsonOrTextOrResponse<
|
||||
keyof R['responses'][Status]['content'],
|
||||
ExtractContent<R['responses'][Status]['content']>,
|
||||
Status
|
||||
>
|
||||
}[keyof R['responses'] & RouteConfigStatusCode]
|
||||
type DefinedStatusCodes<R extends RouteConfig> = keyof R['responses'] & RouteConfigStatusCode
|
||||
export type RouteConfigToTypedResponse<R extends RouteConfig> =
|
||||
| {
|
||||
[Status in DefinedStatusCodes<R>]: undefined extends R['responses'][Status]['content']
|
||||
? TypedResponse<{}, ExtractStatusCode<Status>, string>
|
||||
: ReturnJsonOrTextOrResponse<
|
||||
keyof R['responses'][Status]['content'],
|
||||
ExtractContent<R['responses'][Status]['content']>,
|
||||
Status
|
||||
>
|
||||
}[DefinedStatusCodes<R>]
|
||||
| ('default' extends keyof R['responses']
|
||||
? undefined extends R['responses']['default']['content']
|
||||
? TypedResponse<{}, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>, string>
|
||||
: ReturnJsonOrTextOrResponse<
|
||||
keyof R['responses']['default']['content'],
|
||||
ExtractContent<R['responses']['default']['content']>,
|
||||
Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>
|
||||
>
|
||||
: never)
|
||||
|
||||
export type Hook<T, E extends Env, P extends string, R> = (
|
||||
result: { target: keyof ValidationTargets } & (
|
||||
|
|
|
@ -147,4 +147,86 @@ describe('supports async handler', () => {
|
|||
const hono = new OpenAPIHono()
|
||||
hono.openapi(route, handler)
|
||||
})
|
||||
|
||||
test('handler should support default response for unspecified status codes', () => {
|
||||
const routeWithDefault = createRoute({
|
||||
method: 'get',
|
||||
path: '/users',
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({ id: z.string() }),
|
||||
},
|
||||
},
|
||||
description: 'Success response',
|
||||
},
|
||||
default: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({ error: z.string() }),
|
||||
},
|
||||
},
|
||||
description: 'Error response',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const errorHandler: RouteHandler<typeof routeWithDefault> = (c) => {
|
||||
return c.json({ error: 'Server Error' }, 500)
|
||||
}
|
||||
|
||||
const hono = new OpenAPIHono()
|
||||
hono.openapi(routeWithDefault, errorHandler)
|
||||
})
|
||||
|
||||
test('handler should respect explicitly defined status codes with default fallback', () => {
|
||||
const routeWithDefault = createRoute({
|
||||
method: 'get',
|
||||
path: '/users',
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({ id: z.string() }),
|
||||
},
|
||||
},
|
||||
description: 'Success response',
|
||||
},
|
||||
404: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({ message: z.string() }),
|
||||
},
|
||||
},
|
||||
description: 'Not found response',
|
||||
},
|
||||
default: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({ error: z.string() }),
|
||||
},
|
||||
},
|
||||
description: 'Error response',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const successHandler: RouteHandler<typeof routeWithDefault> = (c) => {
|
||||
return c.json({ id: '123' }, 200)
|
||||
}
|
||||
|
||||
const notFoundHandler: RouteHandler<typeof routeWithDefault> = (c) => {
|
||||
return c.json({ message: 'Not Found' }, 404)
|
||||
}
|
||||
|
||||
const errorHandler: RouteHandler<typeof routeWithDefault> = (c) => {
|
||||
return c.json({ error: 'Server Error' }, 500)
|
||||
}
|
||||
|
||||
const hono = new OpenAPIHono()
|
||||
hono.openapi(routeWithDefault, successHandler)
|
||||
hono.openapi(routeWithDefault, notFoundHandler)
|
||||
hono.openapi(routeWithDefault, errorHandler)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue