@dokploy/trpc-openapi 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -16
- package/README.md +164 -86
- package/dist/cjs/adapters/express.d.ts +6 -0
- package/dist/cjs/adapters/express.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/express.js +2 -2
- package/dist/cjs/adapters/express.js.map +1 -0
- package/dist/cjs/adapters/fastify.d.ts +9 -0
- package/dist/cjs/adapters/fastify.d.ts.map +1 -0
- package/dist/cjs/adapters/fastify.js +65 -0
- package/dist/cjs/adapters/fastify.js.map +1 -0
- package/dist/cjs/adapters/fetch.d.ts +8 -0
- package/dist/cjs/adapters/fetch.d.ts.map +1 -0
- package/dist/cjs/adapters/fetch.js +100 -0
- package/dist/cjs/adapters/fetch.js.map +1 -0
- package/dist/cjs/adapters/index.d.ts +9 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -0
- package/dist/cjs/adapters/index.js +25 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/koa.d.ts +9 -0
- package/dist/cjs/adapters/koa.d.ts.map +1 -0
- package/dist/cjs/adapters/koa.js +12 -0
- package/dist/cjs/adapters/koa.js.map +1 -0
- package/dist/cjs/adapters/next.d.ts +6 -0
- package/dist/cjs/adapters/next.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/next.js +15 -10
- package/dist/cjs/adapters/next.js.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/core.d.ts +4 -3
- package/dist/cjs/adapters/node-http/core.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/core.js +72 -49
- package/dist/cjs/adapters/node-http/core.js.map +1 -0
- package/dist/cjs/adapters/node-http/errors.d.ts +6 -0
- package/dist/cjs/adapters/node-http/errors.d.ts.map +1 -0
- package/dist/cjs/adapters/node-http/errors.js +94 -0
- package/dist/cjs/adapters/node-http/errors.js.map +1 -0
- package/dist/cjs/adapters/node-http/index.d.ts +5 -0
- package/dist/cjs/adapters/node-http/index.d.ts.map +1 -0
- package/dist/cjs/adapters/node-http/index.js +21 -0
- package/dist/cjs/adapters/node-http/index.js.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/input.d.ts +2 -2
- package/dist/cjs/adapters/node-http/input.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/input.js +7 -10
- package/dist/cjs/adapters/node-http/input.js.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/procedures.d.ts +2 -2
- package/dist/cjs/adapters/node-http/procedures.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/node-http/procedures.js +10 -21
- package/dist/cjs/adapters/node-http/procedures.js.map +1 -0
- package/dist/cjs/adapters/nuxt.d.ts +6 -0
- package/dist/cjs/adapters/nuxt.d.ts.map +1 -0
- package/dist/cjs/adapters/nuxt.js +50 -0
- package/dist/cjs/adapters/nuxt.js.map +1 -0
- package/dist/{adapters → cjs/adapters}/standalone.d.ts +3 -3
- package/dist/cjs/adapters/standalone.d.ts.map +1 -0
- package/dist/{adapters → cjs/adapters}/standalone.js +5 -1
- package/dist/cjs/adapters/standalone.js.map +1 -0
- package/dist/cjs/generator/index.d.ts +40 -0
- package/dist/cjs/generator/index.d.ts.map +1 -0
- package/dist/cjs/generator/index.js +33 -0
- package/dist/cjs/generator/index.js.map +1 -0
- package/dist/cjs/generator/paths.d.ts +16 -0
- package/dist/cjs/generator/paths.d.ts.map +1 -0
- package/dist/cjs/generator/paths.js +122 -0
- package/dist/cjs/generator/paths.js.map +1 -0
- package/dist/cjs/generator/schema.d.ts +15 -0
- package/dist/cjs/generator/schema.d.ts.map +1 -0
- package/dist/cjs/generator/schema.js +195 -0
- package/dist/cjs/generator/schema.js.map +1 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +24 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types.d.ts +55 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +5 -0
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/{adapters → cjs/utils}/index.js +4 -3
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/method.d.ts +6 -0
- package/dist/cjs/utils/method.d.ts.map +1 -0
- package/dist/cjs/utils/method.js +29 -0
- package/dist/cjs/utils/method.js.map +1 -0
- package/dist/cjs/utils/path.d.ts.map +1 -0
- package/dist/{utils → cjs/utils}/path.js +1 -1
- package/dist/cjs/utils/path.js.map +1 -0
- package/dist/cjs/utils/procedure.d.ts +18 -0
- package/dist/cjs/utils/procedure.d.ts.map +1 -0
- package/dist/cjs/utils/procedure.js +83 -0
- package/dist/cjs/utils/procedure.js.map +1 -0
- package/dist/cjs/utils/zod.d.ts +16 -0
- package/dist/cjs/utils/zod.d.ts.map +1 -0
- package/dist/cjs/utils/zod.js +96 -0
- package/dist/cjs/utils/zod.js.map +1 -0
- package/dist/esm/adapters/express.d.ts +6 -0
- package/dist/esm/adapters/express.d.ts.map +1 -0
- package/dist/esm/adapters/express.js +8 -0
- package/dist/esm/adapters/express.js.map +1 -0
- package/dist/esm/adapters/fastify.d.ts +9 -0
- package/dist/esm/adapters/fastify.d.ts.map +1 -0
- package/dist/esm/adapters/fastify.js +61 -0
- package/dist/esm/adapters/fastify.js.map +1 -0
- package/dist/esm/adapters/fetch.d.ts +8 -0
- package/dist/esm/adapters/fetch.d.ts.map +1 -0
- package/dist/esm/adapters/fetch.js +95 -0
- package/dist/esm/adapters/fetch.js.map +1 -0
- package/dist/esm/adapters/index.d.ts +9 -0
- package/dist/esm/adapters/index.d.ts.map +1 -0
- package/dist/esm/adapters/index.js +9 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/koa.d.ts +9 -0
- package/dist/esm/adapters/koa.d.ts.map +1 -0
- package/dist/esm/adapters/koa.js +8 -0
- package/dist/esm/adapters/koa.js.map +1 -0
- package/dist/esm/adapters/next.d.ts +6 -0
- package/dist/esm/adapters/next.d.ts.map +1 -0
- package/dist/esm/adapters/next.js +45 -0
- package/dist/esm/adapters/next.js.map +1 -0
- package/dist/esm/adapters/node-http/core.d.ts +7 -0
- package/dist/esm/adapters/node-http/core.d.ts.map +1 -0
- package/dist/esm/adapters/node-http/core.js +166 -0
- package/dist/esm/adapters/node-http/core.js.map +1 -0
- package/dist/esm/adapters/node-http/errors.d.ts +6 -0
- package/dist/esm/adapters/node-http/errors.d.ts.map +1 -0
- package/dist/esm/adapters/node-http/errors.js +90 -0
- package/dist/esm/adapters/node-http/errors.js.map +1 -0
- package/dist/esm/adapters/node-http/index.d.ts +5 -0
- package/dist/esm/adapters/node-http/index.d.ts.map +1 -0
- package/dist/esm/adapters/node-http/index.js +5 -0
- package/dist/esm/adapters/node-http/index.js.map +1 -0
- package/dist/esm/adapters/node-http/input.d.ts +4 -0
- package/dist/esm/adapters/node-http/input.d.ts.map +1 -0
- package/dist/esm/adapters/node-http/input.js +65 -0
- package/dist/esm/adapters/node-http/input.js.map +1 -0
- package/dist/esm/adapters/node-http/procedures.d.ts +12 -0
- package/dist/esm/adapters/node-http/procedures.d.ts.map +1 -0
- package/dist/esm/adapters/node-http/procedures.js +34 -0
- package/dist/esm/adapters/node-http/procedures.js.map +1 -0
- package/dist/esm/adapters/nuxt.d.ts +6 -0
- package/dist/esm/adapters/nuxt.d.ts.map +1 -0
- package/dist/esm/adapters/nuxt.js +45 -0
- package/dist/esm/adapters/nuxt.js.map +1 -0
- package/dist/esm/adapters/standalone.d.ts +6 -0
- package/dist/esm/adapters/standalone.d.ts.map +1 -0
- package/dist/esm/adapters/standalone.js +11 -0
- package/dist/esm/adapters/standalone.js.map +1 -0
- package/dist/esm/generator/index.d.ts +40 -0
- package/dist/esm/generator/index.d.ts.map +1 -0
- package/dist/esm/generator/index.js +31 -0
- package/dist/esm/generator/index.js.map +1 -0
- package/dist/esm/generator/paths.d.ts +16 -0
- package/dist/esm/generator/paths.d.ts.map +1 -0
- package/dist/esm/generator/paths.js +129 -0
- package/dist/esm/generator/paths.js.map +1 -0
- package/dist/esm/generator/schema.d.ts +15 -0
- package/dist/esm/generator/schema.d.ts.map +1 -0
- package/dist/esm/generator/schema.js +203 -0
- package/dist/esm/generator/schema.js.map +1 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types.d.ts +55 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils/index.d.ts +5 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +5 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/method.d.ts +6 -0
- package/dist/esm/utils/method.d.ts.map +1 -0
- package/dist/esm/utils/method.js +22 -0
- package/dist/esm/utils/method.js.map +1 -0
- package/dist/esm/utils/path.d.ts +4 -0
- package/dist/esm/utils/path.d.ts.map +1 -0
- package/dist/esm/utils/path.js +11 -0
- package/dist/esm/utils/path.js.map +1 -0
- package/dist/esm/utils/procedure.d.ts +18 -0
- package/dist/esm/utils/procedure.d.ts.map +1 -0
- package/dist/esm/utils/procedure.js +79 -0
- package/dist/esm/utils/procedure.js.map +1 -0
- package/dist/esm/utils/zod.d.ts +16 -0
- package/dist/esm/utils/zod.d.ts.map +1 -0
- package/dist/esm/utils/zod.js +82 -0
- package/dist/esm/utils/zod.js.map +1 -0
- package/package.json +52 -46
- package/dist/adapters/express.d.ts +0 -8
- package/dist/adapters/express.d.ts.map +0 -1
- package/dist/adapters/express.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -4
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/next.d.ts +0 -6
- package/dist/adapters/next.d.ts.map +0 -1
- package/dist/adapters/next.js.map +0 -1
- package/dist/adapters/node-http/core.d.ts.map +0 -1
- package/dist/adapters/node-http/core.js.map +0 -1
- package/dist/adapters/node-http/errors.d.ts +0 -4
- package/dist/adapters/node-http/errors.d.ts.map +0 -1
- package/dist/adapters/node-http/errors.js +0 -43
- package/dist/adapters/node-http/errors.js.map +0 -1
- package/dist/adapters/node-http/input.d.ts.map +0 -1
- package/dist/adapters/node-http/input.js.map +0 -1
- package/dist/adapters/node-http/procedures.d.ts.map +0 -1
- package/dist/adapters/node-http/procedures.js.map +0 -1
- package/dist/adapters/standalone.d.ts.map +0 -1
- package/dist/adapters/standalone.js.map +0 -1
- package/dist/generator/index.d.ts +0 -14
- package/dist/generator/index.d.ts.map +0 -1
- package/dist/generator/index.js +0 -39
- package/dist/generator/index.js.map +0 -1
- package/dist/generator/paths.d.ts +0 -4
- package/dist/generator/paths.d.ts.map +0 -1
- package/dist/generator/paths.js +0 -76
- package/dist/generator/paths.js.map +0 -1
- package/dist/generator/schema.d.ts +0 -7
- package/dist/generator/schema.d.ts.map +0 -1
- package/dist/generator/schema.js +0 -209
- package/dist/generator/schema.js.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -11
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts +0 -55
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/method.d.ts +0 -3
- package/dist/utils/method.d.ts.map +0 -1
- package/dist/utils/method.js +0 -11
- package/dist/utils/method.js.map +0 -1
- package/dist/utils/path.d.ts.map +0 -1
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/procedure.d.ts +0 -14
- package/dist/utils/procedure.d.ts.map +0 -1
- package/dist/utils/procedure.js +0 -62
- package/dist/utils/procedure.js.map +0 -1
- package/dist/utils/zod.d.ts +0 -14
- package/dist/utils/zod.d.ts.map +0 -1
- package/dist/utils/zod.js +0 -106
- package/dist/utils/zod.js.map +0 -1
- /package/dist/{types.js → cjs/types.js} +0 -0
- /package/dist/{utils → cjs/utils}/path.d.ts +0 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright
|
|
3
|
+
Copyright 2024 Mario Campa
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
11
6
|
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
14
8
|
|
|
15
|
-
THE SOFTWARE IS PROVIDED
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,60 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/trpc-openapi.svg">
|
|
3
|
+
</p>
|
|
3
4
|
<div align="center">
|
|
4
|
-
<h1>trpc-openapi</h1>
|
|
5
|
-
<a href="https://www.npmjs.com/package/trpc-openapi"><img src="https://img.shields.io/npm/v/trpc-openapi.svg?style=flat&color=brightgreen" target="_blank" /></a>
|
|
5
|
+
<h1>trpc-to-openapi</h1>
|
|
6
|
+
<a href="https://www.npmjs.com/package/trpc-to-openapi"><img src="https://img.shields.io/npm/v/trpc-to-openapi.svg?style=flat&color=brightgreen" target="_blank" /></a>
|
|
6
7
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-black" /></a>
|
|
7
|
-
<a href="https://trpc.io/discord" target="_blank"><img src="https://img.shields.io/badge/chat-discord-blue.svg" /></a>
|
|
8
8
|
<br />
|
|
9
9
|
<hr />
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
12
|
## **[OpenAPI](https://swagger.io/specification/) support for [tRPC](https://trpc.io/)** 🧩
|
|
15
13
|
|
|
14
|
+
- Support for tRPC ^11.1.0
|
|
15
|
+
- Easy REST endpoints for your tRPC procedures.
|
|
16
|
+
- Perfect for incremental adoption.
|
|
17
|
+
- Supports all OpenAPI versions.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
We use this package to generate OpenAPI documents for our tRPC endpoints in https://github.com/Dokploy/dokploy
|
|
19
|
+
Note: This project is a fork of a fork, with full credit to the original authors. It appears that the original author has abandoned the project, so I plan to add new features in the near future.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
### Customizations (Dokploy-style)
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
2. We make .meta optional for all procedures.
|
|
25
|
-
3. Introduce 2 flags to .meta() to override and additional parameters.
|
|
26
|
-
4. `override` parameter overrides the default value and will take the whole object of openapi.
|
|
27
|
-
5. `additional` parameters will be default values + the values provided in the openapi object.
|
|
23
|
+
This fork adds the following behaviour (inspired by [Dokploy](https://github.com/Dokploy/dokploy)):
|
|
28
24
|
|
|
25
|
+
1. **Optional input and output parameters are required by default** – In the generated OpenAPI document, optional input/output parameters are treated as required.
|
|
26
|
+
2. **`.meta` is optional for all procedures** – Procedures without `.meta({ openapi: ... })` are still exposed with default OpenAPI metadata (method from procedure type, path from procedure path, `enabled: true`, `protect: true`).
|
|
27
|
+
3. **Two flags on `meta.openapi`**:
|
|
28
|
+
- **`override`** – When `true`, only the provided `openapi` object is used (no defaults merged).
|
|
29
|
+
- **`additional`** – When `true`, defaults are applied first, then your `openapi` values are merged on top.
|
|
29
30
|
|
|
30
31
|
## Usage
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
- Perfect for incremental adoption.
|
|
34
|
-
- OpenAPI version 3.0.3.
|
|
35
|
-
|
|
36
|
-
**1. Install `@dokploy/trpc-openapi`.**
|
|
33
|
+
**1. Install `trpc-to-openapi`.**
|
|
37
34
|
|
|
38
35
|
```bash
|
|
36
|
+
# pnpm
|
|
37
|
+
pnpm add trpc-to-openapi
|
|
39
38
|
# npm
|
|
40
|
-
npm install
|
|
39
|
+
npm install trpc-to-openapi
|
|
41
40
|
# yarn
|
|
42
|
-
yarn add
|
|
41
|
+
yarn add trpc-to-openapi
|
|
43
42
|
```
|
|
44
43
|
|
|
45
44
|
**2. Add `OpenApiMeta` to your tRPC instance.**
|
|
46
45
|
|
|
47
46
|
```typescript
|
|
48
47
|
import { initTRPC } from '@trpc/server';
|
|
49
|
-
import { OpenApiMeta } from '
|
|
48
|
+
import { OpenApiMeta } from 'trpc-to-openapi';
|
|
50
49
|
|
|
51
50
|
const t = initTRPC.meta<OpenApiMeta>().create(); /* 👈 */
|
|
52
51
|
```
|
|
53
52
|
|
|
54
53
|
**3. Enable `openapi` support for a procedure.**
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
55
|
```typescript
|
|
59
56
|
export const appRouter = t.router({
|
|
60
57
|
sayHello: t.procedure
|
|
@@ -63,6 +60,13 @@ export const appRouter = t.router({
|
|
|
63
60
|
.output(z.object({ greeting: z.string() }))
|
|
64
61
|
.query(({ input }) => {
|
|
65
62
|
return { greeting: `Hello ${input.name}!` };
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
getStatus: t.procedure
|
|
66
|
+
.meta({ /* 👉 */ openapi: { method: 'GET', path: '/status' } })
|
|
67
|
+
.output(z.object({ status: z.string() }))
|
|
68
|
+
.query(() => {
|
|
69
|
+
return { status: 'healthy' };
|
|
66
70
|
});
|
|
67
71
|
});
|
|
68
72
|
```
|
|
@@ -70,27 +74,34 @@ export const appRouter = t.router({
|
|
|
70
74
|
**4. Generate an OpenAPI document.**
|
|
71
75
|
|
|
72
76
|
```typescript
|
|
73
|
-
import { generateOpenApiDocument } from 'trpc-openapi';
|
|
77
|
+
import { generateOpenApiDocument } from 'trpc-to-openapi';
|
|
74
78
|
|
|
75
79
|
import { appRouter } from '../appRouter';
|
|
80
|
+
import { UserSchema, ProductSchema } from '../schemas';
|
|
76
81
|
|
|
77
82
|
/* 👇 */
|
|
78
83
|
export const openApiDocument = generateOpenApiDocument(appRouter, {
|
|
79
84
|
title: 'tRPC OpenAPI',
|
|
80
85
|
version: '1.0.0',
|
|
81
86
|
baseUrl: 'http://localhost:3000',
|
|
87
|
+
defs: {
|
|
88
|
+
UserSchema,
|
|
89
|
+
ProductSchema,
|
|
90
|
+
},
|
|
82
91
|
});
|
|
83
92
|
```
|
|
84
93
|
|
|
85
|
-
**5. Add an `trpc-openapi` handler to your app.**
|
|
94
|
+
**5. Add an `trpc-to-openapi` handler to your app.**
|
|
86
95
|
|
|
87
|
-
We currently support adapters for [`Express`](http://expressjs.com/), [`Next.js`](https://nextjs.org/), [`
|
|
96
|
+
We currently support adapters for [`Express`](http://expressjs.com/), [`Next.js`](https://nextjs.org/), [`Fastify`](https://www.fastify.io/), [`Nuxt`](https://nuxtjs.org/) & [`Node:HTTP`](https://nodejs.org/api/http.html).
|
|
88
97
|
|
|
89
98
|
[`Fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), [`Cloudflare Workers`](https://workers.cloudflare.com/) & more soon™, PRs are welcomed 🙌.
|
|
90
99
|
|
|
100
|
+
No support for AWS lambdas
|
|
101
|
+
|
|
91
102
|
```typescript
|
|
92
103
|
import http from 'http';
|
|
93
|
-
import { createOpenApiHttpHandler } from 'trpc-openapi';
|
|
104
|
+
import { createOpenApiHttpHandler } from 'trpc-to-openapi';
|
|
94
105
|
|
|
95
106
|
import { appRouter } from '../appRouter';
|
|
96
107
|
|
|
@@ -103,22 +114,29 @@ server.listen(3000);
|
|
|
103
114
|
|
|
104
115
|
```typescript
|
|
105
116
|
// client.ts
|
|
106
|
-
const res = await fetch('http://localhost:3000/say-hello?name=
|
|
107
|
-
const body = await res.json(); /* { greeting: 'Hello
|
|
117
|
+
const res = await fetch('http://localhost:3000/say-hello?name=OpenAPI', { method: 'GET' });
|
|
118
|
+
const body = await res.json(); /* { greeting: 'Hello OpenAPI!' } */
|
|
119
|
+
|
|
120
|
+
const statusRes = await fetch('http://localhost:3000/status', { method: 'GET' });
|
|
121
|
+
const statusBody = await statusRes.json(); /* { status: 'healthy' } */
|
|
108
122
|
```
|
|
109
123
|
|
|
110
124
|
## Requirements
|
|
111
125
|
|
|
112
126
|
Peer dependencies:
|
|
113
127
|
|
|
114
|
-
- [`tRPC`](https://github.com/trpc/trpc) Server
|
|
115
|
-
- [`Zod`](https://github.com/colinhacks/zod)
|
|
128
|
+
- [`tRPC`](https://github.com/trpc/trpc) Server v11 (`@trpc/server`) must be installed.
|
|
129
|
+
- [`Zod`](https://github.com/colinhacks/zod) v4 (`zod@^4.0.0`) must be installed.
|
|
116
130
|
|
|
117
131
|
For a procedure to support OpenAPI the following _must_ be true:
|
|
118
132
|
|
|
133
|
+
- An `output` parser is present AND uses `Zod` validation.
|
|
134
|
+
- If an `input` parser is present, it must use `Zod` validation.
|
|
135
|
+
- Query `input` parsers (when present) extend `Object<{ [string]: String | Number | BigInt | Date }>` or `Void`.
|
|
136
|
+
- Mutation `input` parsers (when present) extend `Object<{ [string]: AnyType }>` or `Void`.
|
|
119
137
|
- `meta.openapi.method` is `GET`, `POST`, `PATCH`, `PUT` or `DELETE`.
|
|
120
138
|
- `meta.openapi.path` is a string starting with `/`.
|
|
121
|
-
- `meta.openapi.path` parameters exist in `input` parser as `String | Number | BigInt | Date`
|
|
139
|
+
- `meta.openapi.path` parameters (when present) exist in `input` parser as `String | Number | BigInt | Date`
|
|
122
140
|
|
|
123
141
|
Please note:
|
|
124
142
|
|
|
@@ -128,7 +146,7 @@ Please note:
|
|
|
128
146
|
|
|
129
147
|
## HTTP Requests
|
|
130
148
|
|
|
131
|
-
Procedures with a `GET`/`DELETE` method will accept inputs via URL `query parameters`. Procedures with a `POST`/`PATCH`/`PUT` method will accept inputs via the `request body` with a `application/json`
|
|
149
|
+
Procedures with a `GET`/`DELETE` method will accept inputs via URL `query parameters`. Procedures with a `POST`/`PATCH`/`PUT` method will accept inputs via the `request body` with a `application/json` content type.
|
|
132
150
|
|
|
133
151
|
### Path parameters
|
|
134
152
|
|
|
@@ -151,10 +169,10 @@ export const appRouter = t.router({
|
|
|
151
169
|
});
|
|
152
170
|
|
|
153
171
|
// Client
|
|
154
|
-
const res = await fetch('http://localhost:3000/say-hello/
|
|
172
|
+
const res = await fetch('http://localhost:3000/say-hello/Lily?greeting=Hello' /* 👈 */, {
|
|
155
173
|
method: 'GET',
|
|
156
174
|
});
|
|
157
|
-
const body = await res.json(); /* { greeting: 'Hello
|
|
175
|
+
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
|
|
158
176
|
```
|
|
159
177
|
|
|
160
178
|
### Request body
|
|
@@ -172,17 +190,17 @@ export const appRouter = t.router({
|
|
|
172
190
|
});
|
|
173
191
|
|
|
174
192
|
// Client
|
|
175
|
-
const res = await fetch('http://localhost:3000/say-hello/
|
|
193
|
+
const res = await fetch('http://localhost:3000/say-hello/Lily' /* 👈 */, {
|
|
176
194
|
method: 'POST',
|
|
177
195
|
headers: { 'Content-Type': 'application/json' },
|
|
178
196
|
body: JSON.stringify({ greeting: 'Hello' }),
|
|
179
197
|
});
|
|
180
|
-
const body = await res.json(); /* { greeting: 'Hello
|
|
198
|
+
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
|
|
181
199
|
```
|
|
182
200
|
|
|
183
201
|
### Custom headers
|
|
184
202
|
|
|
185
|
-
Any custom headers can be specified in the `meta.openapi.
|
|
203
|
+
Any custom headers can be specified in the `meta.openapi.requestHeaders` and `meta.openapi.responseHeaders` zod object schema, these headers will not be validated. Please consider using [Authorization](#authorization) for first-class OpenAPI auth/security support.
|
|
186
204
|
|
|
187
205
|
## HTTP Responses
|
|
188
206
|
|
|
@@ -202,14 +220,14 @@ Explore a [complete example here](examples/with-nextjs/src/server/router.ts).
|
|
|
202
220
|
|
|
203
221
|
```typescript
|
|
204
222
|
import { TRPCError, initTRPC } from '@trpc/server';
|
|
205
|
-
import { OpenApiMeta } from '
|
|
223
|
+
import { OpenApiMeta } from 'trpc-to-openapi';
|
|
206
224
|
|
|
207
225
|
type User = { id: string; name: string };
|
|
208
226
|
|
|
209
227
|
const users: User[] = [
|
|
210
228
|
{
|
|
211
229
|
id: 'usr_123',
|
|
212
|
-
name: '
|
|
230
|
+
name: 'Lily',
|
|
213
231
|
},
|
|
214
232
|
];
|
|
215
233
|
|
|
@@ -247,7 +265,7 @@ const res = await fetch('http://localhost:3000/say-hello', {
|
|
|
247
265
|
method: 'GET',
|
|
248
266
|
headers: { Authorization: 'Bearer usr_123' } /* 👈 */,
|
|
249
267
|
});
|
|
250
|
-
const body = await res.json(); /* { greeting: 'Hello
|
|
268
|
+
const body = await res.json(); /* { greeting: 'Hello Lily!' } */
|
|
251
269
|
```
|
|
252
270
|
|
|
253
271
|
## Examples
|
|
@@ -261,7 +279,7 @@ Please see [full example here](examples/with-express).
|
|
|
261
279
|
```typescript
|
|
262
280
|
import { createExpressMiddleware } from '@trpc/server/adapters/express';
|
|
263
281
|
import express from 'express';
|
|
264
|
-
import { createOpenApiExpressMiddleware } from 'trpc-openapi';
|
|
282
|
+
import { createOpenApiExpressMiddleware } from 'trpc-to-openapi';
|
|
265
283
|
|
|
266
284
|
import { appRouter } from '../appRouter';
|
|
267
285
|
|
|
@@ -273,29 +291,51 @@ app.use('/api', createOpenApiExpressMiddleware({ router: appRouter })); /* 👈
|
|
|
273
291
|
app.listen(3000);
|
|
274
292
|
```
|
|
275
293
|
|
|
276
|
-
#### With Next.js
|
|
294
|
+
#### With Next.js app router
|
|
277
295
|
|
|
278
|
-
Please see [full example here](examples/with-nextjs).
|
|
296
|
+
Please see [full example here](examples/with-nextjs-appdir).
|
|
279
297
|
|
|
280
298
|
```typescript
|
|
281
|
-
//
|
|
282
|
-
import {
|
|
283
|
-
|
|
284
|
-
import {
|
|
299
|
+
// src/app/[...trpc]/route.ts
|
|
300
|
+
import { appRouter } from '~/server/api/root';
|
|
301
|
+
import { createContext } from '~/server/api/trpc';
|
|
302
|
+
import { type NextRequest } from 'next/server';
|
|
303
|
+
import { createOpenApiFetchHandler } from 'trpc-to-openapi';
|
|
304
|
+
|
|
305
|
+
export const dynamic = 'force-dynamic';
|
|
306
|
+
|
|
307
|
+
const handler = (req: NextRequest) => {
|
|
308
|
+
// Handle incoming OpenAPI requests
|
|
309
|
+
return createOpenApiFetchHandler({
|
|
310
|
+
endpoint: '/',
|
|
311
|
+
router: appRouter,
|
|
312
|
+
createContext: () => createContext(req),
|
|
313
|
+
req,
|
|
314
|
+
});
|
|
315
|
+
};
|
|
285
316
|
|
|
286
|
-
export
|
|
317
|
+
export {
|
|
318
|
+
handler as GET,
|
|
319
|
+
handler as POST,
|
|
320
|
+
handler as PUT,
|
|
321
|
+
handler as PATCH,
|
|
322
|
+
handler as DELETE,
|
|
323
|
+
handler as OPTIONS,
|
|
324
|
+
handler as HEAD,
|
|
325
|
+
};
|
|
287
326
|
```
|
|
288
327
|
|
|
289
|
-
#### With
|
|
328
|
+
#### With Next.js pages router
|
|
290
329
|
|
|
291
|
-
Please see [full example here](examples/with-
|
|
330
|
+
Please see [full example here](examples/with-nextjs).
|
|
292
331
|
|
|
293
332
|
```typescript
|
|
294
|
-
|
|
333
|
+
// pages/api/[...trpc].ts
|
|
334
|
+
import { createOpenApiNextHandler } from 'trpc-to-openapi';
|
|
295
335
|
|
|
296
|
-
import { appRouter } from '
|
|
336
|
+
import { appRouter } from '../../server/appRouter';
|
|
297
337
|
|
|
298
|
-
export
|
|
338
|
+
export default createOpenApiNextHandler({ router: appRouter });
|
|
299
339
|
```
|
|
300
340
|
|
|
301
341
|
#### With Fastify
|
|
@@ -305,7 +345,7 @@ Please see [full example here](examples/with-fastify).
|
|
|
305
345
|
```typescript
|
|
306
346
|
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
|
|
307
347
|
import Fastify from 'fastify';
|
|
308
|
-
import { fastifyTRPCOpenApiPlugin } from 'trpc-openapi';
|
|
348
|
+
import { fastifyTRPCOpenApiPlugin } from 'trpc-to-openapi';
|
|
309
349
|
|
|
310
350
|
import { appRouter } from './router';
|
|
311
351
|
|
|
@@ -327,34 +367,36 @@ main();
|
|
|
327
367
|
|
|
328
368
|
Please see [full typings here](src/generator/index.ts).
|
|
329
369
|
|
|
330
|
-
| Property | Type
|
|
331
|
-
| ----------------- |
|
|
332
|
-
| `title` | `string`
|
|
333
|
-
| `description` | `string`
|
|
334
|
-
| `version` | `string`
|
|
335
|
-
| `baseUrl` | `string`
|
|
336
|
-
| `docsUrl` | `string`
|
|
337
|
-
| `tags` | `string[]`
|
|
338
|
-
| `securitySchemes` | `Record<string, SecuritySchemeObject>`
|
|
370
|
+
| Property | Type | Description | Required |
|
|
371
|
+
| ----------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | -------- |
|
|
372
|
+
| `title` | `string` | The title of the API. | `true` |
|
|
373
|
+
| `description` | `string` | A short description of the API. | `false` |
|
|
374
|
+
| `version` | `string` | The version of the OpenAPI document. | `true` |
|
|
375
|
+
| `baseUrl` | `string` | The base URL of the target server. | `true` |
|
|
376
|
+
| `docsUrl` | `string` | A URL to any external documentation. | `false` |
|
|
377
|
+
| `tags` | `string[]` | A list for ordering endpoint groups. | `false` |
|
|
378
|
+
| `securitySchemes` | `Record<string, SecuritySchemeObject>` | Defaults to `Authorization` header with `Bearer` scheme | `false` |
|
|
379
|
+
| `filter` | `(ctx: { metadata: { openapi: NonNullable<OpenApiMeta['openapi']> } & TMeta }) => boolean` | Optional filter function to include/exclude procedures from the generated OpenAPI document. | `false` |
|
|
339
380
|
|
|
340
381
|
#### OpenApiMeta
|
|
341
382
|
|
|
342
383
|
Please see [full typings here](src/types.ts).
|
|
343
384
|
|
|
344
|
-
| Property
|
|
345
|
-
|
|
|
346
|
-
| `enabled`
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
385
|
+
| Property | Type | Description | Required | Default |
|
|
386
|
+
| -------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------- | ----------------------- |
|
|
387
|
+
| `enabled` | `boolean` | Exposes this procedure to `trpc-to-openapi` adapters and on the OpenAPI document. | `false` | `true` |
|
|
388
|
+
| `method` | `HttpMethod` | HTTP method this endpoint is exposed on. Value can be `GET`, `POST`, `PATCH`, `PUT` or `DELETE`. | `true` | `undefined` |
|
|
389
|
+
| `path` | `string` | Pathname this endpoint is exposed on. Value must start with `/`, specify path parameters using `{}`. | `true` | `undefined` |
|
|
390
|
+
| `protect` | `boolean` | Requires this endpoint to use a security scheme. | `false` | `true` |
|
|
391
|
+
| `summary` | `string` | A short summary of the endpoint included in the OpenAPI document. | `false` | `undefined` |
|
|
392
|
+
| `description` | `string` | A verbose description of the endpoint included in the OpenAPI document. | `false` | `undefined` |
|
|
393
|
+
| `tags` | `string[]` | A list of tags used for logical grouping of endpoints in the OpenAPI document. | `false` | `undefined` |
|
|
394
|
+
| `requestHeaders` | `AnyZodObject` | A zod object schema describing any custom headers to add to the request for this endpoint in the OpenAPI document. | `false` | `undefined` |
|
|
395
|
+
| `responseHeaders` | `AnyZodObject` | A zod object schema describing any custom headers to add to the response for this endpoint in the OpenAPI document. | `false` | `undefined` |
|
|
396
|
+
| `successDescription` | `string` | A string to use as the description for a successful response. | `false` | `'Successful response'` |
|
|
397
|
+
| `errorResponses` | `number[] \| { [key: number]: string }` | A list of error response codes or an object of response codes and their description to add to the responses for this endpoint. | `false` | `undefined` |
|
|
398
|
+
| `contentTypes` | `OpenApiContentType[]` | A set of content types specified as accepted in the OpenAPI document. | `false` | `['application/json']` |
|
|
399
|
+
| `deprecated` | `boolean` | Whether or not to mark an endpoint as deprecated | `false` | `false` |
|
|
358
400
|
|
|
359
401
|
#### CreateOpenApiNodeHttpHandlerOptions
|
|
360
402
|
|
|
@@ -370,13 +412,49 @@ Please see [full typings here](src/adapters/node-http/core.ts).
|
|
|
370
412
|
|
|
371
413
|
---
|
|
372
414
|
|
|
373
|
-
_Still using tRPC v9? See our [`.interop()`](examples/with-interop) example._
|
|
374
|
-
|
|
375
415
|
## License
|
|
376
416
|
|
|
377
417
|
Distributed under the MIT License. See LICENSE for more information.
|
|
378
418
|
|
|
379
|
-
|
|
419
|
+
**Filtering Procedures in OpenAPI Output**
|
|
420
|
+
|
|
421
|
+
You can use the `filter` option to selectively include or exclude procedures from the generated OpenAPI document. The filter function receives a context object with the procedure's metadata. Return `true` to include the procedure, or `false` to exclude it.
|
|
422
|
+
|
|
423
|
+
**Example:**
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
const appRouter = t.router({
|
|
427
|
+
publicProc: t.procedure
|
|
428
|
+
.meta({ openapi: { method: 'GET', path: '/public' }, isPublic: true })
|
|
429
|
+
.input(z.object({}))
|
|
430
|
+
.output(z.object({ result: z.string() }))
|
|
431
|
+
.query(() => ({ result: 'public' })),
|
|
432
|
+
privateProc: t.procedure
|
|
433
|
+
.meta({ openapi: { method: 'GET', path: '/private' }, isPublic: false })
|
|
434
|
+
.input(z.object({}))
|
|
435
|
+
.output(z.object({ result: z.string() }))
|
|
436
|
+
.query(() => ({ result: 'private' })),
|
|
437
|
+
});
|
|
380
438
|
|
|
381
|
-
|
|
382
|
-
|
|
439
|
+
// Only include procedures where isPublic is true
|
|
440
|
+
const openApiDocument = generateOpenApiDocument(appRouter, {
|
|
441
|
+
...defaultDocOpts,
|
|
442
|
+
filter: ({ metadata }) => metadata.isPublic === true,
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// openApiDocument.paths will only include '/public'
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
You can also pass a metadata generic to `generateOpenApiDocument` to get proper types for your custom metadata in the filter function:
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
// Define your custom metadata type
|
|
452
|
+
interface MyMeta {
|
|
453
|
+
isPublic: boolean;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const openApiDocument = generateOpenApiDocument<MyMeta>(appRouter, {
|
|
457
|
+
...defaultDocOpts,
|
|
458
|
+
filter: ({ metadata }) => metadata.isPublic === true,
|
|
459
|
+
});
|
|
460
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { OpenApiRouter } from '../types';
|
|
3
|
+
import { CreateOpenApiNodeHttpHandlerOptions } from './node-http';
|
|
4
|
+
export type CreateOpenApiExpressMiddlewareOptions<TRouter extends OpenApiRouter> = CreateOpenApiNodeHttpHandlerOptions<TRouter, Request, Response>;
|
|
5
|
+
export declare const createOpenApiExpressMiddleware: <TRouter extends OpenApiRouter>(opts: CreateOpenApiExpressMiddlewareOptions<TRouter>) => (req: Request, res: Response) => Promise<void>;
|
|
6
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,mCAAmC,EAAgC,MAAM,aAAa,CAAC;AAEhG,MAAM,MAAM,qCAAqC,CAAC,OAAO,SAAS,aAAa,IAC7E,mCAAmC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAElE,eAAO,MAAM,8BAA8B,GAAI,OAAO,SAAS,aAAa,EAC1E,MAAM,qCAAqC,CAAC,OAAO,CAAC,MAItC,KAAK,OAAO,EAAE,KAAK,QAAQ,kBAG1C,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createOpenApiExpressMiddleware = void 0;
|
|
4
|
-
const
|
|
4
|
+
const node_http_1 = require("./node-http");
|
|
5
5
|
const createOpenApiExpressMiddleware = (opts) => {
|
|
6
|
-
const openApiHttpHandler = (0,
|
|
6
|
+
const openApiHttpHandler = (0, node_http_1.createOpenApiNodeHttpHandler)(opts);
|
|
7
7
|
return async (req, res) => {
|
|
8
8
|
await openApiHttpHandler(req, res);
|
|
9
9
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/adapters/express.ts"],"names":[],"mappings":";;;AAGA,2CAAgG;AAKzF,MAAM,8BAA8B,GAAG,CAC5C,IAAoD,EACpD,EAAE;IACF,MAAM,kBAAkB,GAAG,IAAA,wCAA4B,EAAC,IAAI,CAAC,CAAC;IAE9D,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC3C,MAAM,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,8BAA8B,kCAQzC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AnyRouter } from '@trpc/server';
|
|
2
|
+
import { FastifyInstance } from 'fastify';
|
|
3
|
+
import { OpenApiRouter } from '../types';
|
|
4
|
+
import { CreateOpenApiNodeHttpHandlerOptions } from './node-http';
|
|
5
|
+
export type CreateOpenApiFastifyPluginOptions<TRouter extends OpenApiRouter> = CreateOpenApiNodeHttpHandlerOptions<TRouter, any, any> & {
|
|
6
|
+
basePath?: `/${string}`;
|
|
7
|
+
};
|
|
8
|
+
export declare function fastifyTRPCOpenApiPlugin<TRouter extends AnyRouter>(fastify: FastifyInstance, opts: CreateOpenApiFastifyPluginOptions<TRouter>, done: (err?: Error) => void): void;
|
|
9
|
+
//# sourceMappingURL=fastify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/adapters/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAIxE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,mCAAmC,EAAgC,MAAM,aAAa,CAAC;AAyBhG,MAAM,MAAM,iCAAiC,CAAC,OAAO,SAAS,aAAa,IACzE,mCAAmC,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG;IACvD,QAAQ,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;CACzB,CAAC;AAEJ,wBAAgB,wBAAwB,CAAC,OAAO,SAAS,SAAS,EAChE,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,iCAAiC,CAAC,OAAO,CAAC,EAChD,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,QAwE5B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fastifyTRPCOpenApiPlugin = fastifyTRPCOpenApiPlugin;
|
|
4
|
+
const node_http_1 = require("./node-http");
|
|
5
|
+
function fastifyTRPCOpenApiPlugin(fastify, opts, done) {
|
|
6
|
+
var _a;
|
|
7
|
+
let prefix = (_a = opts.basePath) !== null && _a !== void 0 ? _a : '';
|
|
8
|
+
// if prefix ends with a slash, remove it
|
|
9
|
+
if (prefix.endsWith('/')) {
|
|
10
|
+
prefix = prefix.slice(0, -1);
|
|
11
|
+
}
|
|
12
|
+
const openApiHttpHandler = (0, node_http_1.createOpenApiNodeHttpHandler)(opts);
|
|
13
|
+
fastify.route({
|
|
14
|
+
method: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],
|
|
15
|
+
url: `${prefix}/*`,
|
|
16
|
+
handler: async (request, reply) => {
|
|
17
|
+
const prefixRemovedFromUrl = request.url.replace(fastify.prefix, '').replace(prefix, '');
|
|
18
|
+
request.raw.url = prefixRemovedFromUrl;
|
|
19
|
+
// Add Node.js request methods to Fastify request
|
|
20
|
+
const requestWithNodeMethods = request;
|
|
21
|
+
// Add event emitter methods
|
|
22
|
+
requestWithNodeMethods.once = request.raw.once.bind(request.raw);
|
|
23
|
+
requestWithNodeMethods.on = request.raw.on.bind(request.raw);
|
|
24
|
+
requestWithNodeMethods.off = request.raw.off.bind(request.raw);
|
|
25
|
+
requestWithNodeMethods.destroy = request.raw.destroy.bind(request.raw);
|
|
26
|
+
// Add Node.js response methods to Fastify reply
|
|
27
|
+
const replyWithNodeMethods = reply;
|
|
28
|
+
// Add statusCode property
|
|
29
|
+
void Object.defineProperty(replyWithNodeMethods, 'statusCode', {
|
|
30
|
+
set(value) {
|
|
31
|
+
void reply.code(value);
|
|
32
|
+
},
|
|
33
|
+
get() {
|
|
34
|
+
return reply.raw.statusCode;
|
|
35
|
+
},
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
});
|
|
39
|
+
// Add setHeader method
|
|
40
|
+
replyWithNodeMethods.setHeader = (key, value) => {
|
|
41
|
+
void reply.header(key, value);
|
|
42
|
+
};
|
|
43
|
+
// Add end method
|
|
44
|
+
replyWithNodeMethods.end = (data) => {
|
|
45
|
+
if (!reply.sent) {
|
|
46
|
+
void reply.send(data);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
// Add properties and methods needed by incomingMessageToRequest
|
|
50
|
+
replyWithNodeMethods.socket = reply.raw.socket;
|
|
51
|
+
replyWithNodeMethods.connection = reply.raw.connection;
|
|
52
|
+
replyWithNodeMethods.finished = reply.raw.finished;
|
|
53
|
+
replyWithNodeMethods.headersSent = reply.raw.headersSent;
|
|
54
|
+
// Add event emitter methods
|
|
55
|
+
replyWithNodeMethods.once = reply.raw.once.bind(reply.raw);
|
|
56
|
+
replyWithNodeMethods.on = reply.raw.on.bind(reply.raw);
|
|
57
|
+
replyWithNodeMethods.off = reply.raw.off.bind(reply.raw);
|
|
58
|
+
replyWithNodeMethods.emit = reply.raw.emit.bind(reply.raw);
|
|
59
|
+
replyWithNodeMethods.removeListener = reply.raw.removeListener.bind(reply.raw);
|
|
60
|
+
return await openApiHttpHandler(requestWithNodeMethods, replyWithNodeMethods);
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
done();
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=fastify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/adapters/fastify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FetchHandlerOptions } from '@trpc/server/adapters/fetch';
|
|
2
|
+
import { OpenApiRouter } from '../types';
|
|
3
|
+
export type CreateOpenApiFetchHandlerOptions<TRouter extends OpenApiRouter> = Omit<FetchHandlerOptions<TRouter>, 'batching'> & {
|
|
4
|
+
req: Request;
|
|
5
|
+
endpoint: `/${string}`;
|
|
6
|
+
};
|
|
7
|
+
export declare const createOpenApiFetchHandler: <TRouter extends OpenApiRouter>(opts: CreateOpenApiFetchHandlerOptions<TRouter>) => Promise<Response>;
|
|
8
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/adapters/fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,MAAM,gCAAgC,CAAC,OAAO,SAAS,aAAa,IAAI,IAAI,CAChF,mBAAmB,CAAC,OAAO,CAAC,EAC5B,UAAU,CACX,GAAG;IACF,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,IAAI,MAAM,EAAE,CAAC;CACxB,CAAC;AAsEF,eAAO,MAAM,yBAAyB,GAAU,OAAO,SAAS,aAAa,EAC3E,MAAM,gCAAgC,CAAC,OAAO,CAAC,KAC9C,OAAO,CAAC,QAAQ,CAuClB,CAAC"}
|