feat(zod-openapi): extract range definitions to StatusCode (#535)
* fix: extract range definitions to StatusCode * docs: add minor changesetpull/540/head
parent
1d5c467d5f
commit
a595e4e260
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@hono/zod-openapi': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
extract range definitions to StatusCode
|
|
@ -27,7 +27,14 @@ import type {
|
||||||
TypedResponse,
|
TypedResponse,
|
||||||
} from 'hono'
|
} from 'hono'
|
||||||
import type { MergePath, MergeSchemaPath } from 'hono/types'
|
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 type { Prettify, RemoveBlankRecord } from 'hono/utils/types'
|
||||||
import { mergePath } from 'hono/utils/url'
|
import { mergePath } from 'hono/utils/url'
|
||||||
import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
|
import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
|
||||||
|
@ -143,13 +150,28 @@ type ExtractContent<T> = T extends {
|
||||||
: never
|
: never
|
||||||
: 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> = {
|
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']
|
keyof R['responses'][Status]['content']
|
||||||
> extends never
|
> extends never
|
||||||
? TypedResponse<{}, Status, string>
|
? TypedResponse<{}, ExtractStatusCode<Status>, string>
|
||||||
: TypedResponse<ExtractContent<R['responses'][Status]['content']>, Status, 'json'>
|
: TypedResponse<
|
||||||
}[keyof R['responses'] & StatusCode]
|
ExtractContent<R['responses'][Status]['content']>,
|
||||||
|
ExtractStatusCode<Status>,
|
||||||
|
'json'
|
||||||
|
>
|
||||||
|
}[keyof R['responses'] & RouteConfigStatusCode]
|
||||||
|
|
||||||
export type Hook<T, E extends Env, P extends string, R> = (
|
export type Hook<T, E extends Env, P extends string, R> = (
|
||||||
result:
|
result:
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { hc } from 'hono/client'
|
||||||
import { describe, it, expect, expectTypeOf } from 'vitest'
|
import { describe, it, expect, expectTypeOf } from 'vitest'
|
||||||
import { OpenAPIHono, createRoute, z, RouteConfigToTypedResponse } from '../src/index'
|
import { OpenAPIHono, createRoute, z, RouteConfigToTypedResponse } from '../src/index'
|
||||||
import { Expect, Equal } from 'hono/utils/types'
|
import { Expect, Equal } from 'hono/utils/types'
|
||||||
|
import { ServerErrorStatusCode } from 'hono/utils/http-status'
|
||||||
|
|
||||||
describe('Constructor', () => {
|
describe('Constructor', () => {
|
||||||
it('Should not require init object', () => {
|
it('Should not require init object', () => {
|
||||||
|
@ -200,11 +201,19 @@ describe('Basic - params', () => {
|
||||||
responses: {
|
responses: {
|
||||||
'200': {
|
'200': {
|
||||||
description: 'Get the user',
|
description: 'Get the user',
|
||||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/User' } } },
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: { $ref: '#/components/schemas/User' },
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'400': {
|
'400': {
|
||||||
description: 'Error!',
|
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!',
|
description: 'Error!',
|
||||||
},
|
},
|
||||||
|
'5XX': {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: ErrorSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Server Error!',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,6 +1503,13 @@ describe('RouteConfigToTypedResponse', () => {
|
||||||
400,
|
400,
|
||||||
'json'
|
'json'
|
||||||
>
|
>
|
||||||
|
| TypedResponse<
|
||||||
|
{
|
||||||
|
ok: boolean
|
||||||
|
},
|
||||||
|
ServerErrorStatusCode,
|
||||||
|
'json'
|
||||||
|
>
|
||||||
type verify = Expect<Equal<Expected, Actual>>
|
type verify = Expect<Equal<Expected, Actual>>
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue