fix(zod-openapi): Fix a bug that slashes were duplicated when mountin… (#258)

* fix(zod-openapi): Fix a bug that slashes were duplicated when mounting a path using the route method

* fix: Make the paths be merged using internally defined utility functions instead
pull/259/head
Karibash 2023-11-16 19:24:53 +09:00 committed by GitHub
parent 53cd5f7bec
commit 368c3520fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 145 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': patch
---
Fix a bug that slashes were duplicated when mounting a path using the route method

View File

@ -27,6 +27,7 @@ import type {
} from 'hono' } from 'hono'
import type { MergePath, MergeSchemaPath } from 'hono/types' import type { MergePath, MergeSchemaPath } from 'hono/types'
import type { RemoveBlankRecord } from 'hono/utils/types' import type { RemoveBlankRecord } from 'hono/utils/types'
import { mergePath } from 'hono/utils/url'
import type { AnyZodObject, ZodSchema, ZodError } from 'zod' import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
import { z, ZodType } from 'zod' import { z, ZodType } from 'zod'
@ -323,13 +324,13 @@ export class OpenAPIHono<
case 'route': case 'route':
return this.openAPIRegistry.registerPath({ return this.openAPIRegistry.registerPath({
...def.route, ...def.route,
path: `${path}${def.route.path}`, path: mergePath(path, def.route.path),
}) })
case 'webhook': case 'webhook':
return this.openAPIRegistry.registerWebhook({ return this.openAPIRegistry.registerWebhook({
...def.webhook, ...def.webhook,
path: `${path}${def.webhook.path}`, path: mergePath(path, def.webhook.path),
}) })
case 'schema': case 'schema':

View File

@ -977,3 +977,140 @@ describe('It allows the response type to be Response', () => {
expect(res.body).toBe(null) expect(res.body).toBe(null)
}) })
}) })
describe('Path normalization', () => {
const createRootApp = () => {
const app = new OpenAPIHono()
app.doc('/doc', {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
})
return app
}
const generateRoute = (path: string) => {
return createRoute({
path,
method: 'get',
responses: {
204: {
description: 'No Content',
},
},
})
}
const handler = (c) => c.body(null, 204)
describe('Duplicate slashes in the root path', () => {
const app = createRootApp()
const childApp = new OpenAPIHono()
childApp.openapi(generateRoute('/child'), handler)
app.route('/', childApp)
it('Should remove duplicate slashes', async () => {
const res = await app.request('/doc')
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
components: {
schemas: {},
parameters: {},
},
paths: {
'/child': {
get: {
responses: {
204: {
description: 'No Content',
},
},
},
},
},
})
})
})
describe('Duplicate slashes in the child path', () => {
const app = createRootApp()
const childApp = new OpenAPIHono()
const grandchildApp = new OpenAPIHono()
grandchildApp.openapi(generateRoute('/granchild'), handler)
childApp.route('/', grandchildApp)
app.route('/api', childApp)
it('Should remove duplicate slashes', async () => {
const res = await app.request('/doc')
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
components: {
schemas: {},
parameters: {},
},
paths: {
'/api/granchild': {
get: {
responses: {
204: {
description: 'No Content',
},
},
},
},
},
})
})
})
describe('Duplicate slashes in the trailing path', () => {
const app = createRootApp()
const childApp = new OpenAPIHono()
const grandchildApp = new OpenAPIHono()
grandchildApp.openapi(generateRoute('/'), handler)
childApp.route('/', grandchildApp)
app.route('/api', childApp)
it('Should remove duplicate slashes', async () => {
const res = await app.request('/doc')
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
components: {
schemas: {},
parameters: {},
},
paths: {
'/api': {
get: {
responses: {
204: {
description: 'No Content',
},
},
},
},
},
})
})
})
})