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 insteadpull/259/head
parent
53cd5f7bec
commit
368c3520fa
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@hono/zod-openapi': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix a bug that slashes were duplicated when mounting a path using the route method
|
|
@ -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':
|
||||||
|
|
|
@ -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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue