feat(zod-openapi): Add ability to exclude routes from OpenAPI docs (#984)

* Exclude route from OpenAPI docs

* add changeset

* update to minor

* test if a hidden route is available for requests
pull/987/head
Robert Michalak 2025-02-28 09:52:52 +01:00 committed by GitHub
parent fa8ed2804f
commit 59c6356aac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 73 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': minor
---
Add ability to exclude specific routes from OpenAPI docs

View File

@ -451,6 +451,17 @@ app.doc('/doc', (c) => ({
}))
```
### How to exclude a specific route from OpenAPI docs
You can use `hide` property as follows:
```ts
const route = createRoute({
// ...
hide: true,
})
```
## Limitations
### Combining with `Hono`

View File

@ -43,6 +43,7 @@ type MaybePromise<T> = Promise<T> | T
export type RouteConfig = RouteConfigBase & {
middleware?: MiddlewareHandler | MiddlewareHandler[]
hide?: boolean
}
type RequestTypes = {
@ -418,7 +419,7 @@ export class OpenAPIHono<
InputTypeJson<R>,
P extends string = ConvertPathType<R['path']>
>(
{ middleware: routeMiddleware, ...route }: R,
{ middleware: routeMiddleware, hide, ...route }: R,
handler: Handler<
// use the env from the middleware if it's defined
R['middleware'] extends MiddlewareHandler[] | MiddlewareHandler
@ -462,7 +463,9 @@ export class OpenAPIHono<
S & ToSchema<R['method'], MergePath<BasePath, P>, I, RouteConfigToTypedResponse<R>>,
BasePath
> => {
this.openAPIRegistry.registerPath(route)
if (!hide) {
this.openAPIRegistry.registerPath(route)
}
const validators: MiddlewareHandler[] = []

View File

@ -1923,3 +1923,55 @@ describe('Generate YAML', () => {
expect(() => stringify(doc)).to.not.throw()
})
})
describe('Hide Routes', () => {
const app = new OpenAPIHono()
app.openapi(
createRoute({
method: 'get',
hide: true,
path: '/books',
responses: {
200: {
description: 'Books',
content: {
'application/json': {
schema: z.array(
z.object({
title: z.string(),
})
),
},
},
},
},
}),
(c) => c.json([{ title: 'foo' }])
)
it('Should hide the route', async () => {
const doc = app.getOpenAPIDocument({
openapi: '3.0.0',
info: {
title: 'My API',
version: '1.0.0',
},
})
const doc31 = app.getOpenAPI31Document({
openapi: '3.1.0',
info: {
title: 'My API',
version: '1.0.0',
},
})
expect(doc.paths).not.toHaveProperty('/books')
expect(doc31.paths).not.toHaveProperty('/books')
})
it('Should return a HTTP 200 response from a hidden route', async () => {
const res = await app.request('/books')
expect(res.status).toBe(200)
expect(await res.json()).toEqual([{ title: 'foo' }])
})
})