fix(zod-openapi): supports named params in nested routes (#316)

* fix(zod-openapi): supports named params in nested routes

* changeset

* github works fine?

* fixed
pull/317/head
Yusuke Wada 2023-12-16 15:35:36 +09:00 committed by GitHub
parent 28a8dfa312
commit 5eeb555c89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': patch
---
fix: supports named params in nested routes

View File

@ -356,6 +356,7 @@ export class OpenAPIHono<
path: SubPath, path: SubPath,
app?: Hono<SubEnv, SubSchema, SubBasePath> app?: Hono<SubEnv, SubSchema, SubBasePath>
): OpenAPIHono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath> { ): OpenAPIHono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath> {
const pathForOpenAPI = path.replaceAll(/:([^\/]+)/g, '{$1}')
super.route(path, app as any) super.route(path, app as any)
if (!(app instanceof OpenAPIHono)) { if (!(app instanceof OpenAPIHono)) {
@ -370,13 +371,13 @@ export class OpenAPIHono<
case 'route': case 'route':
return this.openAPIRegistry.registerPath({ return this.openAPIRegistry.registerPath({
...def.route, ...def.route,
path: mergePath(path, def.route.path), path: mergePath(pathForOpenAPI, def.route.path),
}) })
case 'webhook': case 'webhook':
return this.openAPIRegistry.registerWebhook({ return this.openAPIRegistry.registerWebhook({
...def.webhook, ...def.webhook,
path: mergePath(path, def.webhook.path), path: mergePath(pathForOpenAPI, def.webhook.path),
}) })
case 'schema': case 'schema':

View File

@ -1228,3 +1228,49 @@ describe('Context can be accessible in the doc route', () => {
}) })
}) })
}) })
describe('Named params in nested routes', () => {
const root = new OpenAPIHono()
root.doc('/doc', () => ({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'my API',
},
}))
const sub = new OpenAPIHono()
sub.openapi(
createRoute({
method: 'get',
path: '/sub/{subId}',
responses: {
200: {
description: 'Nested response',
},
},
}),
(c) => c.json({ params: c.req.param() })
)
root.route('/root/:rootId', sub)
it('Should return a correct content', async () => {
const res = await root.request('/root/123/sub/456')
expect(res.status).toBe(200)
const data = await res.json()
expect(data).toEqual({
params: {
subId: '456',
rootId: '123',
},
})
})
it('Should return a correct path', async () => {
const res = await root.request('/doc')
expect(res.status).toBe(200)
const data = await res.json()
expect(Object.keys(data['paths'])[0]).toBe('/root/{rootId}/sub/{subId}')
})
})