feat(zod-openapi): Make context accessible in the doc route (#272)
* feat(zod-openapi): Make context accessible in the doc route * docs(zod-openapi): Fix typo * docs(zod-openapi): Add a tips to the README.md on how to access the context in app.docpull/278/head
parent
b0adaab247
commit
d4aa8ec5ad
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/zod-openapi': minor
|
||||
---
|
||||
|
||||
Make context accessible in the doc route
|
|
@ -231,7 +231,7 @@ You can generate OpenAPI v3.1 spec using the following methods:
|
|||
|
||||
```ts
|
||||
app.doc31('/docs', {openapi: '3.1.0'}) // new endpoint
|
||||
app.getOpenAPI31Document(, {openapi: '3.1.0'}) // raw json
|
||||
app.getOpenAPI31Document({openapi: '3.1.0'}) // raw json
|
||||
```
|
||||
|
||||
### The Registry
|
||||
|
@ -312,7 +312,7 @@ app.openAPIRegistry.registerComponent('securitySchema', {
|
|||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
And setup the security scheme for specific routes:
|
||||
|
@ -328,6 +328,26 @@ const route = createRoute({
|
|||
})
|
||||
```
|
||||
|
||||
### How to access context in app.doc
|
||||
|
||||
You can access the context in `app.doc` as follows:
|
||||
|
||||
```ts
|
||||
app.doc('/doc', c => ({
|
||||
openapi: '3.0.0',
|
||||
info: {
|
||||
version: '1.0.0',
|
||||
title: 'My API',
|
||||
},
|
||||
servers: [
|
||||
{
|
||||
url: new URL(c.req.url).hostname,
|
||||
description: 'Current environment',
|
||||
},
|
||||
],
|
||||
}))
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
### Combining with `Hono`
|
||||
|
|
|
@ -185,6 +185,10 @@ export type RouteHook<
|
|||
P extends string = ConvertPathType<R['path']>
|
||||
> = Hook<I, E, P, OutputType<R>>
|
||||
|
||||
export type OpenAPIObjectConfigure<E extends Env, P extends string> =
|
||||
OpenAPIObjectConfig |
|
||||
((context: Context<E, P>) => OpenAPIObjectConfig)
|
||||
|
||||
export class OpenAPIHono<
|
||||
E extends Env = Env,
|
||||
S extends Schema = {},
|
||||
|
@ -279,9 +283,10 @@ export class OpenAPIHono<
|
|||
|
||||
doc = <P extends string>(
|
||||
path: P,
|
||||
config: OpenAPIObjectConfig
|
||||
configure: OpenAPIObjectConfigure<E, P>
|
||||
): OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath> => {
|
||||
return this.get(path, (c) => {
|
||||
const config = typeof configure === 'function' ? configure(c) : configure
|
||||
const document = this.getOpenAPIDocument(config)
|
||||
return c.json(document)
|
||||
}) as any
|
||||
|
@ -289,9 +294,10 @@ export class OpenAPIHono<
|
|||
|
||||
doc31 = <P extends string>(
|
||||
path: P,
|
||||
config: OpenAPIObjectConfig
|
||||
configure: OpenAPIObjectConfigure<E, P>
|
||||
): OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath> => {
|
||||
return this.get(path, (c) => {
|
||||
const config = typeof configure === 'function' ? configure(c) : configure
|
||||
const document = this.getOpenAPI31Document(config)
|
||||
return c.json(document)
|
||||
}) as any
|
||||
|
|
|
@ -1121,3 +1121,57 @@ describe('Path normalization', () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Context can be accessible in the doc route', () => {
|
||||
const app = new OpenAPIHono<{ Bindings: { TITLE: string } }>()
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
method: 'get',
|
||||
path: '/no-content',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'No Content',
|
||||
},
|
||||
},
|
||||
}),
|
||||
(c) => {
|
||||
return c.body(null, 204)
|
||||
}
|
||||
)
|
||||
|
||||
app.doc('/doc', context => ({
|
||||
openapi: '3.0.0',
|
||||
info: {
|
||||
version: '1.0.0',
|
||||
title: context.env.TITLE,
|
||||
},
|
||||
}))
|
||||
|
||||
it('Should return with the title set as specified in env', async () => {
|
||||
const res = await app.request('/doc', null, { TITLE: 'My API' })
|
||||
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: {
|
||||
'/no-content': {
|
||||
get: {
|
||||
responses: {
|
||||
204: {
|
||||
description: 'No Content',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue