feat: Add `getRoutingPath` to the return value of `createRoute`. (#161)
* feat(zod-openapi): add getRoutingPath * feat(zod-openapi): add docs * feat(zod-openapi): add versioning docpull/162/head
parent
928f84a226
commit
05b8e9a751
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/zod-openapi': minor
|
||||
---
|
||||
|
||||
Add getRoutingPath to the return value of createRoute.
|
|
@ -203,6 +203,18 @@ import { prettyJSON } from 'hono/pretty-json'
|
|||
app.use('/doc/*', prettyJSON())
|
||||
```
|
||||
|
||||
### Configure middleware for each endpoint
|
||||
|
||||
You can configure middleware for each endpoint from a route created by `createRoute` as follows.
|
||||
|
||||
```ts
|
||||
import { prettyJSON } from 'hono/pretty-json'
|
||||
import { cache } from 'honoc/cache'
|
||||
|
||||
app.use(route.getRoutingPath(), prettyJSON(), cache({ cacheName: "my-cache" }))
|
||||
app.openapi(route, handler)
|
||||
```
|
||||
|
||||
### RPC Mode
|
||||
|
||||
Zod OpenAPI Hono supports Hono's RPC mode. You can define types for the Hono Client as follows:
|
||||
|
|
|
@ -323,9 +323,18 @@ export class OpenAPIHono<
|
|||
}
|
||||
}
|
||||
|
||||
type RoutingPath<P extends string> = P extends `${infer Head}/{${infer Param}}${infer Tail}` ? `${Head}/:${Param}${RoutingPath<Tail>}` : P
|
||||
|
||||
export const createRoute = <P extends string, R extends Omit<RouteConfig, 'path'> & { path: P }>(
|
||||
routeConfig: R
|
||||
) => routeConfig
|
||||
) => {
|
||||
return {
|
||||
...routeConfig,
|
||||
getRoutingPath(): RoutingPath<R['path']> {
|
||||
return routeConfig.path.replaceAll(/\/{(.+?)}/g, '/:$1') as RoutingPath<P>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extendZodWithOpenApi(z)
|
||||
export { z }
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* eslint-disable node/no-extraneous-import */
|
||||
import { describe, it, expect, expectTypeOf } from 'vitest'
|
||||
import { createRoute, z } from '../src'
|
||||
|
||||
describe('createRoute', () => {
|
||||
it.each([
|
||||
{ path: '/users', expected: '/users' },
|
||||
{ path: '/users/{id}', expected: '/users/:id' },
|
||||
{ path: '/users/{uid}/posts/{postId}', expected: '/users/:uid/posts/:postId' },
|
||||
])('createRoute(%j)', ({ path, expected }) => {
|
||||
const ParamsSchema = z.object({
|
||||
id: z
|
||||
.string()
|
||||
.min(3)
|
||||
.openapi({
|
||||
param: {
|
||||
name: 'id',
|
||||
in: 'path',
|
||||
},
|
||||
example: '1212121',
|
||||
}),
|
||||
})
|
||||
|
||||
const UserSchema = z.object({
|
||||
id: z.string().openapi({
|
||||
example: '123',
|
||||
}),
|
||||
name: z.string().openapi({
|
||||
example: 'John Doe',
|
||||
}),
|
||||
age: z.number().openapi({
|
||||
example: 42,
|
||||
}),
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'get',
|
||||
path,
|
||||
request: {
|
||||
params: ParamsSchema,
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: UserSchema,
|
||||
},
|
||||
},
|
||||
description: 'Retrieve the user',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
const route = createRoute(config)
|
||||
|
||||
expect(route).toEqual({
|
||||
...config,
|
||||
getRoutingPath: expect.any(Function),
|
||||
})
|
||||
expect(route.getRoutingPath()).toBe(expected)
|
||||
expectTypeOf(route.getRoutingPath()).toEqualTypeOf<typeof expected>()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue