feat(zod-openapi): extract range definitions to StatusCode (#535)

* fix: extract range definitions to StatusCode

* docs: add minor changeset
pull/540/head
taku-hatano 2024-05-23 22:01:05 +09:00 committed by GitHub
parent 1d5c467d5f
commit a595e4e260
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 7 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': minor
---
extract range definitions to StatusCode

View File

@ -27,7 +27,14 @@ import type {
TypedResponse,
} from 'hono'
import type { MergePath, MergeSchemaPath } from 'hono/types'
import type { StatusCode } from 'hono/utils/http-status'
import type {
ClientErrorStatusCode,
InfoStatusCode,
RedirectStatusCode,
ServerErrorStatusCode,
StatusCode,
SuccessStatusCode,
} from 'hono/utils/http-status'
import type { Prettify, RemoveBlankRecord } from 'hono/utils/types'
import { mergePath } from 'hono/utils/url'
import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
@ -143,13 +150,28 @@ type ExtractContent<T> = T extends {
: never
: never
type StatusCodeRangeDefinitions = {
'1XX': InfoStatusCode
'2XX': SuccessStatusCode
'3XX': RedirectStatusCode
'4XX': ClientErrorStatusCode
'5XX': ServerErrorStatusCode
}
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'] & StatusCode]: IsJson<
[Status in keyof R['responses'] & RouteConfigStatusCode]: IsJson<
keyof R['responses'][Status]['content']
> extends never
? TypedResponse<{}, Status, string>
: TypedResponse<ExtractContent<R['responses'][Status]['content']>, Status, 'json'>
}[keyof R['responses'] & StatusCode]
? TypedResponse<{}, ExtractStatusCode<Status>, string>
: TypedResponse<
ExtractContent<R['responses'][Status]['content']>,
ExtractStatusCode<Status>,
'json'
>
}[keyof R['responses'] & RouteConfigStatusCode]
export type Hook<T, E extends Env, P extends string, R> = (
result:

View File

@ -4,6 +4,7 @@ import { hc } from 'hono/client'
import { describe, it, expect, expectTypeOf } from 'vitest'
import { OpenAPIHono, createRoute, z, RouteConfigToTypedResponse } from '../src/index'
import { Expect, Equal } from 'hono/utils/types'
import { ServerErrorStatusCode } from 'hono/utils/http-status'
describe('Constructor', () => {
it('Should not require init object', () => {
@ -200,11 +201,19 @@ describe('Basic - params', () => {
responses: {
'200': {
description: 'Get the user',
content: { 'application/json': { schema: { $ref: '#/components/schemas/User' } } },
content: {
'application/json': {
schema: { $ref: '#/components/schemas/User' },
},
},
},
'400': {
description: 'Error!',
content: { 'application/json': { schema: { $ref: '#/components/schemas/Error' } } },
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
},
},
@ -1465,6 +1474,14 @@ describe('RouteConfigToTypedResponse', () => {
},
description: 'Error!',
},
'5XX': {
content: {
'application/json': {
schema: ErrorSchema,
},
},
description: 'Server Error!',
},
},
}
@ -1486,6 +1503,13 @@ describe('RouteConfigToTypedResponse', () => {
400,
'json'
>
| TypedResponse<
{
ok: boolean
},
ServerErrorStatusCode,
'json'
>
type verify = Expect<Equal<Expected, Actual>>
})
})