feat(zod-openapi): allow multiple mimetype (#710)

* feat(zod-openapi): allow multiple mimetype

Signed-off-by: Axel Meinhardt <26243798+ameinhardt@users.noreply.github.com>

* simplify the test

---------

Signed-off-by: Axel Meinhardt <26243798+ameinhardt@users.noreply.github.com>
Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
pull/714/head
Axel Meinhardt 2024-08-25 11:01:09 +08:00 committed by GitHub
parent c49996d6f3
commit dadf5ce3c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 4 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': minor
---
Allow multiple mime type response

View File

@ -180,7 +180,7 @@ export type RouteConfigToTypedResponse<R extends RouteConfig> = {
: TypedResponse<
JSONParsed<ExtractContent<R['responses'][Status]['content']>>,
ExtractStatusCode<Status>,
'json'
'json' | 'text'
>
}[keyof R['responses'] & RouteConfigStatusCode]

View File

@ -8,6 +8,7 @@ import { OpenAPIHono, createRoute, z } from '../src/index'
import type { Equal, Expect } from 'hono/utils/types'
import type { ServerErrorStatusCode } from 'hono/utils/http-status'
import { stringify } from 'yaml'
import { accepts } from 'hono/accepts'
describe('Constructor', () => {
it('Should not require init object', () => {
@ -788,6 +789,60 @@ describe('JSON and Form', () => {
})
})
describe('JSON and Text response', () => {
const route = createRoute({
method: 'get',
path: '/hello',
responses: {
200: {
content: {
'application/json': {
schema: z.object({}),
},
'text/plain': {
schema: z.string(),
},
},
description: 'response',
},
},
})
const app = new OpenAPIHono()
app.openapi(route, (c) => {
const mimeTypes = ['application/json', 'text/plain']
if (
accepts(c, {
default: mimeTypes[0],
header: 'Accept',
supports: mimeTypes,
}) === mimeTypes[0]
) {
return c.json({})
}
return c.text('')
})
test('should respond with JSON fallback', async () => {
const res = await app.request('/hello', {
method: 'GET',
})
expect(res.status).toBe(200)
expect(await res.json()).toEqual({})
})
test('should respond with Text', async () => {
const res = await app.request('/hello', {
method: 'GET',
headers: {
accept: 'text/plain',
},
})
expect(res.status).toBe(200)
expect(await res.text()).toEqual('')
})
})
describe('Input types', () => {
const ParamsSchema = z.object({
id: z
@ -1724,21 +1779,21 @@ describe('RouteConfigToTypedResponse', () => {
age: number
},
200,
'json'
'json' | 'text'
>
| TypedResponse<
{
ok: boolean
},
400,
'json'
'json' | 'text'
>
| TypedResponse<
{
ok: boolean
},
ServerErrorStatusCode,
'json'
'json' | 'text'
>
type verify = Expect<Equal<Expected, Actual>>
})