@orpc/nest 2.0.0-beta.3 → 2.0.0-beta.30
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/{LICENCE → LICENSE} +2 -2
- package/README.md +74 -105
- package/dist/index.d.mts +40 -10
- package/dist/index.d.ts +40 -10
- package/dist/index.mjs +87 -54
- package/package.json +32 -15
package/{LICENCE → LICENSE}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2023 oRPC
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<h1 align="center">oRPC - Typesafe APIs Made Simple 🪄</h1>
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
-
<a href="https://codecov.io/gh/middleapi/orpc
|
|
5
|
-
<img alt="codecov" src="https://codecov.io/gh/middleapi/orpc
|
|
4
|
+
<a href="https://codecov.io/gh/middleapi/orpc">
|
|
5
|
+
<img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg">
|
|
6
6
|
</a>
|
|
7
|
-
<a href="https://
|
|
7
|
+
<a href="https://npmx.dev/package/@orpc/nest">
|
|
8
8
|
<img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fnest?logo=npm" />
|
|
9
9
|
</a>
|
|
10
|
-
<a href="https://
|
|
11
|
-
<img alt="
|
|
10
|
+
<a href="https://app.codspeed.io/middleapi/orpc?utm_source=badge">
|
|
11
|
+
<img alt="CodSpeed" src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" />
|
|
12
|
+
</a>
|
|
13
|
+
<a href="https://github.com/middleapi/orpc/blob/main/LICENSE">
|
|
14
|
+
<img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" />
|
|
12
15
|
</a>
|
|
13
16
|
<a href="https://discord.gg/TXEbwRBvQn">
|
|
14
17
|
<img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" />
|
|
@@ -26,61 +29,63 @@ You can read the documentation [here](https://orpc.dev).
|
|
|
26
29
|
|
|
27
30
|
**Core**
|
|
28
31
|
|
|
29
|
-
- [@orpc/contract](https://
|
|
30
|
-
- [@orpc/server](https://
|
|
31
|
-
- [@orpc/client](https://
|
|
32
|
-
- [@orpc/openapi](https://
|
|
32
|
+
- [@orpc/contract](https://npmx.dev/package/@orpc/contract): Define API contract as the single source of truth.
|
|
33
|
+
- [@orpc/server](https://npmx.dev/package/@orpc/server): Build APIs or implement contracts.
|
|
34
|
+
- [@orpc/client](https://npmx.dev/package/@orpc/client): Consume APIs with end-to-end type safety.
|
|
35
|
+
- [@orpc/openapi](https://npmx.dev/package/@orpc/openapi): Add OpenAPI compatibility to APIs.
|
|
33
36
|
|
|
34
37
|
**Schema validation**
|
|
35
38
|
|
|
36
|
-
- [@orpc/zod](https://
|
|
37
|
-
- [@orpc/valibot](https://
|
|
38
|
-
- [@orpc/arktype](https://
|
|
39
|
+
- [@orpc/zod](https://npmx.dev/package/@orpc/zod): Integrate with [Zod](https://zod.dev/).
|
|
40
|
+
- [@orpc/valibot](https://npmx.dev/package/@orpc/valibot): Integrate with [Valibot](https://valibot.dev/).
|
|
41
|
+
- [@orpc/arktype](https://npmx.dev/package/@orpc/arktype): Integrate with [ArkType](https://arktype.io/).
|
|
39
42
|
|
|
40
43
|
**Built-in features**
|
|
41
44
|
|
|
42
|
-
- [@orpc/publisher](https://
|
|
43
|
-
- [@orpc/ratelimit](https://
|
|
44
|
-
- [@orpc/
|
|
45
|
+
- [@orpc/publisher](https://npmx.dev/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
|
|
46
|
+
- [@orpc/ratelimit](https://npmx.dev/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
|
|
47
|
+
- [@orpc/hibernation](https://npmx.dev/package/@orpc/hibernation): Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api).
|
|
48
|
+
- [@orpc/json-schema](https://npmx.dev/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
|
|
45
49
|
|
|
46
50
|
**Framework & ecosystem integrations**
|
|
47
51
|
|
|
48
|
-
- [@orpc/next](https://
|
|
49
|
-
- [@orpc/
|
|
50
|
-
- [@orpc/
|
|
51
|
-
- [@orpc/
|
|
52
|
+
- [@orpc/next](https://npmx.dev/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
|
|
53
|
+
- [@orpc/ai-sdk](https://npmx.dev/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
|
|
54
|
+
- [@orpc/tanstack-query](https://npmx.dev/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
|
|
55
|
+
- [@orpc/pinia-colada](https://npmx.dev/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
|
|
56
|
+
- [@orpc/swr](https://npmx.dev/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
|
|
57
|
+
- [@orpc/experimental-msw](https://npmx.dev/package/@orpc/experimental-msw): Mock procedures with [Mock Service Worker](https://mswjs.io/).
|
|
58
|
+
- [@orpc/experimental-effect](https://npmx.dev/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
|
|
59
|
+
- [@orpc/nest](https://npmx.dev/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
|
|
60
|
+
- [@orpc/node](https://npmx.dev/package/@orpc/node): [Node.js](https://nodejs.org/) plugins for static file serving and large uploads.
|
|
61
|
+
- [@orpc/bun](https://npmx.dev/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
|
|
62
|
+
- [@orpc/cloudflare](https://npmx.dev/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
|
|
63
|
+
- [@orpc/trpc](https://npmx.dev/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
|
|
52
64
|
|
|
53
65
|
**Observability**
|
|
54
66
|
|
|
55
|
-
- [@orpc/opentelemetry](https://
|
|
56
|
-
- [@orpc/pino](https://
|
|
57
|
-
- [@orpc/evlog](https://
|
|
67
|
+
- [@orpc/opentelemetry](https://npmx.dev/package/@orpc/opentelemetry): Integrate with [OpenTelemetry](https://opentelemetry.io/) for distributed tracing.
|
|
68
|
+
- [@orpc/pino](https://npmx.dev/package/@orpc/pino): Integrate with [Pino](https://getpino.io/) for logging.
|
|
69
|
+
- [@orpc/evlog](https://npmx.dev/package/@orpc/evlog): Integrate with [Evlog](https://evlog.dev/) for logging.
|
|
58
70
|
|
|
59
71
|
## Sponsors
|
|
60
72
|
|
|
61
|
-
Like what we build over at [middleapi](https://github.com/middleapi)? You can help keep it going
|
|
62
|
-
|
|
63
|
-
### 🏆 Platinum Sponsor
|
|
73
|
+
Like what we build over at [middleapi](https://github.com/middleapi)? You can help keep it going through [GitHub Sponsors](https://github.com/sponsors/dinwwwh) or [Open Collective](https://opencollective.com/middleapi). Every bit helps! 🚀
|
|
64
74
|
|
|
65
75
|
<table>
|
|
66
76
|
<tr>
|
|
67
|
-
<td
|
|
77
|
+
<td width="2000"><a href="https://screenshotone.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener" title="The screenshot API for developers"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="64" align="left" hspace="12" alt="ScreenshotOne.com"/><b>ScreenshotOne.com</b></a><br /><sub>The screenshot API for developers</sub></td>
|
|
68
78
|
</tr>
|
|
69
|
-
</table>
|
|
70
|
-
|
|
71
|
-
### 🥈 Silver Sponsor
|
|
72
|
-
|
|
73
|
-
<table>
|
|
74
79
|
<tr>
|
|
75
|
-
<td
|
|
80
|
+
<td width="2000"><a href="https://misskey.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Decentralized microblogging SNS born on Earth"><img src="https://github.com/MisskeyIO.png" width="64" align="left" hspace="12" alt="MisskeyHQ"/><b>MisskeyHQ</b></a><br /><sub>Decentralized microblogging SNS born on Earth</sub></td>
|
|
76
81
|
</tr>
|
|
77
82
|
</table>
|
|
78
83
|
|
|
79
|
-
###
|
|
84
|
+
### Organization Sponsors
|
|
80
85
|
|
|
81
86
|
<table>
|
|
82
87
|
<tr>
|
|
83
|
-
<td align="center"><a href="https://
|
|
88
|
+
<td align="center"><a href="https://lnmarkets.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td>
|
|
84
89
|
</tr>
|
|
85
90
|
</table>
|
|
86
91
|
|
|
@@ -88,26 +93,26 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
88
93
|
|
|
89
94
|
<table>
|
|
90
95
|
<tr>
|
|
91
|
-
<td align="center"><a href="https://github.com/hrmcdonald?ref=
|
|
92
|
-
<td align="center"><a href="https://
|
|
93
|
-
<td align="center"><a href="https://github.com/
|
|
94
|
-
<td align="center"><a href="https://
|
|
95
|
-
<td align="center"><a href="https://github.com/
|
|
96
|
-
<td align="center"><a href="https://github.com/
|
|
96
|
+
<td align="center"><a href="https://github.com/hrmcdonald?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td>
|
|
97
|
+
<td align="center"><a href="https://soymilk.party/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td>
|
|
98
|
+
<td align="center"><a href="https://github.com/nicognaW?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td>
|
|
99
|
+
<td align="center"><a href="https://supastarter.dev/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td>
|
|
100
|
+
<td align="center"><a href="https://github.com/divmgl?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td>
|
|
101
|
+
<td align="center"><a href="https://github.com/herrfugbaum?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td>
|
|
97
102
|
</tr>
|
|
98
103
|
<tr>
|
|
99
|
-
<td align="center"><a href="https://
|
|
100
|
-
<td align="center"><a href="https://
|
|
101
|
-
<td align="center"><a href="https://github.
|
|
102
|
-
<td align="center"><a href="https://
|
|
103
|
-
<td align="center"><a href="https://
|
|
104
|
-
<td align="center"><a href="https://github.com/
|
|
104
|
+
<td align="center"><a href="https://laststance.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td>
|
|
105
|
+
<td align="center"><a href="https://cra.mr/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td>
|
|
106
|
+
<td align="center"><a href="https://valerii15298.github.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
|
|
107
|
+
<td align="center"><a href="https://letstri.dev/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
|
|
108
|
+
<td align="center"><a href="https://blacklight.sh/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
|
|
109
|
+
<td align="center"><a href="https://github.com/christ12938?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
|
|
105
110
|
</tr>
|
|
106
111
|
<tr>
|
|
107
|
-
<td align="center"><a href="https://github.com/
|
|
108
|
-
<td align="center"><a href="https://github.com/
|
|
109
|
-
<td align="center"><a href="https://github.com/
|
|
110
|
-
<td align="center"><a href="https://github.com/
|
|
112
|
+
<td align="center"><a href="https://github.com/Ryanjso?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
|
|
113
|
+
<td align="center"><a href="https://github.com/itigoore01?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td>
|
|
114
|
+
<td align="center"><a href="https://github.com/ellis-driscoll?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
|
|
115
|
+
<td align="center"><a href="https://github.com/hoangbn?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
|
|
111
116
|
</tr>
|
|
112
117
|
</table>
|
|
113
118
|
|
|
@@ -115,67 +120,31 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
115
120
|
|
|
116
121
|
<table>
|
|
117
122
|
<tr>
|
|
118
|
-
<td align="center"><a href="https://github.com/rhinodavid?ref=
|
|
119
|
-
<td align="center"><a href="https://
|
|
120
|
-
<td align="center"><a href="https://github.com/aidansunbury?ref=
|
|
121
|
-
<td align="center"><a href="https://github.com/soonoo?ref=
|
|
122
|
-
<td align="center"><a href="https://
|
|
123
|
-
<td align="center"><a href="https://github.com/pumpkinlink?ref=
|
|
124
|
-
<td align="center"><a href="https://github.com/christopher-kapic?ref=
|
|
123
|
+
<td align="center"><a href="https://github.com/rhinodavid?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
|
|
124
|
+
<td align="center"><a href="https://robbevaes.be/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
|
|
125
|
+
<td align="center"><a href="https://github.com/aidansunbury?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
|
|
126
|
+
<td align="center"><a href="https://github.com/soonoo?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
|
|
127
|
+
<td align="center"><a href="https://kevinporten.dev/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
|
|
128
|
+
<td align="center"><a href="https://github.com/pumpkinlink?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td>
|
|
129
|
+
<td align="center"><a href="https://github.com/christopher-kapic?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
|
|
125
130
|
</tr>
|
|
126
131
|
<tr>
|
|
127
|
-
<td align="center"><a href="
|
|
128
|
-
<td align="center"><a href="https://
|
|
129
|
-
<td align="center"><a href="https://github.com/Titoine?ref=
|
|
130
|
-
<td align="center"><a href="https://
|
|
131
|
-
<td align="center"><a href="https://
|
|
132
|
-
<td align="center"><a href="https://
|
|
133
|
-
<td align="center"><a href="https://
|
|
132
|
+
<td align="center"><a href="http://ballingt.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
|
|
133
|
+
<td align="center"><a href="https://lee-sam.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td>
|
|
134
|
+
<td align="center"><a href="https://github.com/Titoine?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
|
|
135
|
+
<td align="center"><a href="https://rigtch.fm/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
|
|
136
|
+
<td align="center"><a href="https://blog.cwang.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
|
|
137
|
+
<td align="center"><a href="https://dubinets.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
|
|
138
|
+
<td align="center"><a href="https://bika.ai/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
134
139
|
</tr>
|
|
135
140
|
<tr>
|
|
136
|
-
<td align="center"><a href="https://
|
|
137
|
-
<td align="center"><a href="https://
|
|
138
|
-
<td align="center"><a href="https://
|
|
141
|
+
<td align="center"><a href="https://guyariely.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
|
|
142
|
+
<td align="center"><a href="https://piscis.dev/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td>
|
|
143
|
+
<td align="center"><a href="https://opensource.gubanov.eu/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
|
|
139
144
|
</tr>
|
|
140
145
|
</table>
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<p>
|
|
145
|
-
<a href="https://github.com/MrMaxie?ref=orpc" target="_blank" rel="noopener" title="Maxie"><img src="https://avatars.githubusercontent.com/u/3857836?u=5e6b57973d4385d655663ffdd836e487856f2984&v=4" width="32" height="32" alt="Maxie" /></a>
|
|
146
|
-
<a href="https://github.com/Stijn-Timmer?ref=orpc" target="_blank" rel="noopener" title="Stijn Timmer"><img src="https://avatars.githubusercontent.com/u/100147665?u=106b2c18e9c98a61861b4ee7fc100f5b9906a6c9&v=4" width="32" height="32" alt="Stijn Timmer" /></a>
|
|
147
|
-
<a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="32" height="32" alt="あわわわとーにゅ" /></a>
|
|
148
|
-
<a href="https://github.com/zuplo?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="32" height="32" alt="Zuplo" /></a>
|
|
149
|
-
<a href="https://github.com/motopods?ref=orpc" target="_blank" rel="noopener" title="motopods"><img src="https://avatars.githubusercontent.com/u/58200641?v=4" width="32" height="32" alt="motopods" /></a>
|
|
150
|
-
<a href="https://github.com/franciscohermida?ref=orpc" target="_blank" rel="noopener" title="Francisco Hermida"><img src="https://avatars.githubusercontent.com/u/483242?u=bbcbc80eb9d8781ff401f7dafc3b59cd7bea0561&v=4" width="32" height="32" alt="Francisco Hermida" /></a>
|
|
151
|
-
<a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="Théo LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&v=4" width="32" height="32" alt="Théo LUDWIG" /></a>
|
|
152
|
-
<a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&v=4" width="32" height="32" alt="Abhay Ramesh" /></a>
|
|
153
|
-
<a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oü"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oü" /></a>
|
|
154
|
-
<a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=505e54608466ab53754f702973687b04c6424c1f&v=4" width="32" height="32" alt="0x4e32" /></a>
|
|
155
|
-
<a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&v=4" width="32" height="32" alt="Ryuz" /></a>
|
|
156
|
-
<a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&v=4" width="32" height="32" alt="happyboy" /></a>
|
|
157
|
-
<a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&v=4" width="32" height="32" alt="yicchi" /></a>
|
|
158
|
-
<a href="https://github.com/cloudycotton?ref=orpc" target="_blank" rel="noopener" title="Saksham"><img src="https://avatars.githubusercontent.com/u/168998965?u=9b9634a5aed66a51c1b880663272725b00b92b14&v=4" width="32" height="32" alt="Saksham" /></a>
|
|
159
|
-
<a href="https://github.com/hrynevychroman?ref=orpc" target="_blank" rel="noopener" title="Roman Hrynevych"><img src="https://avatars.githubusercontent.com/u/82209198?u=1a1d111ab3d589855b9cc8a7fefb1b5c6a4fbbaf&v=4" width="32" height="32" alt="Roman Hrynevych" /></a>
|
|
160
|
-
<a href="https://github.com/rokitgg?ref=orpc" target="_blank" rel="noopener" title="rokitg"><img src="https://avatars.githubusercontent.com/u/125133357?u=06c74aefaa2236b06a2e5fba5a5c612339f45912&v=4" width="32" height="32" alt="rokitg" /></a>
|
|
161
|
-
<a href="https://github.com/omarkhatibgg?ref=orpc" target="_blank" rel="noopener" title="Omar Khatib"><img src="https://avatars.githubusercontent.com/u/9054278?u=afbba7331b85c51b8eee4130f5fd31b1017dc919&v=4" width="32" height="32" alt="Omar Khatib" /></a>
|
|
162
|
-
<a href="https://github.com/YuSabo90002?ref=orpc" target="_blank" rel="noopener" title="Yu-Sabo"><img src="https://avatars.githubusercontent.com/u/13120582?v=4" width="32" height="32" alt="Yu-Sabo" /></a>
|
|
163
|
-
<a href="https://github.com/bapspatil?ref=orpc" target="_blank" rel="noopener" title="Bapusaheb Patil"><img src="https://avatars.githubusercontent.com/u/16699418?u=6d9d8e0a64a6f91ca1c4d559c72d931172bdcbbd&v=4" width="32" height="32" alt="Bapusaheb Patil" /></a>
|
|
164
|
-
<a href="https://github.com/ripgrim?ref=orpc" target="_blank" rel="noopener" title="grim"><img src="https://avatars.githubusercontent.com/u/75869731?u=b17c42ec2309552fdb822a86b25a2f99146a4d72&v=4" width="32" height="32" alt="grim" /></a>
|
|
165
|
-
<a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&v=4" width="32" height="32" alt="Nelson Lai" /></a>
|
|
166
|
-
<a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
|
|
167
|
-
<a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a>
|
|
168
|
-
<a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
|
|
169
|
-
<a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
|
|
170
|
-
<a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&v=4" width="32" height="32" alt="Novak Antonijevic" /></a>
|
|
171
|
-
<a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a>
|
|
172
|
-
<a href="https://github.com/yukimotochern?ref=orpc" target="_blank" rel="noopener" title="Chen, Zhi-Yuan"><img src="https://avatars.githubusercontent.com/u/20896173?u=945c33fc21725e4d566a0d02afc54b136ca1d67a&v=4" width="32" height="32" alt="Chen, Zhi-Yuan" /></a>
|
|
173
|
-
<a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&v=4" width="32" height="32" alt="Illarion Koperski" /></a>
|
|
174
|
-
<a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&v=4" width="32" height="32" alt="Anees Iqbal" /></a>
|
|
175
|
-
<a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a>
|
|
176
|
-
<a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="32" height="32" alt="Adam Tkaczyk" /></a>
|
|
177
|
-
<a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a>
|
|
178
|
-
</p>
|
|
147
|
+
With thanks to [37 past sponsors](https://htmlpreview.github.io/?https://github.com/middleapi/static/blob/main/sponsors.svg) who helped get oRPC here.
|
|
179
148
|
|
|
180
149
|
## References
|
|
181
150
|
|
|
@@ -186,4 +155,4 @@ oRPC is inspired by existing solutions that prioritize type safety and developer
|
|
|
186
155
|
|
|
187
156
|
## License
|
|
188
157
|
|
|
189
|
-
Distributed under the MIT License. See [LICENSE](https://github.com/middleapi/orpc
|
|
158
|
+
Distributed under the MIT License. See [LICENSE](https://github.com/middleapi/orpc/blob/main/LICENSE) for more information.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DynamicModule, NestInterceptor,
|
|
1
|
+
import { ExecutionContext, DynamicModule, NestInterceptor, CallHandler } from '@nestjs/common';
|
|
2
2
|
import { RouterContract } from '@orpc/contract';
|
|
3
3
|
import { DefaultInitialContext, ContractedRouter } from '@orpc/server';
|
|
4
|
-
import { Promisable } from '@orpc/shared';
|
|
4
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import { OpenAPIHandlerCodecCoreOptions } from '@orpc/openapi/standard';
|
|
7
7
|
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
@@ -10,18 +10,30 @@ import { ToEventStreamOptions } from '@standardserver/node';
|
|
|
10
10
|
import { HttpAdapterHost } from '@nestjs/core';
|
|
11
11
|
|
|
12
12
|
declare const ORPC_MODULE_CONFIG_SYMBOL: unique symbol;
|
|
13
|
+
/**
|
|
14
|
+
* A standard lazy request extended with NestJS route parameters,
|
|
15
|
+
* used as the request representation inside the `@orpc/nest` integration.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#toneststandardlazyrequest-option | Implement oRPC contract with NestJS - toNestStandardLazyRequest option}
|
|
18
|
+
*/
|
|
19
|
+
interface NestStandardLazyRequest extends StandardLazyRequest {
|
|
20
|
+
/**
|
|
21
|
+
* Route parameters extracted from the request path.
|
|
22
|
+
*/
|
|
23
|
+
params?: undefined | Record<string, string | string[]>;
|
|
24
|
+
}
|
|
13
25
|
type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> & StandardHandlerOptions<DefaultInitialContext> & (object extends DefaultInitialContext ? {
|
|
14
|
-
context?: DefaultInitialContext
|
|
26
|
+
context?: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
15
27
|
} : {
|
|
16
|
-
context: DefaultInitialContext
|
|
28
|
+
context: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
17
29
|
}) & {
|
|
18
30
|
/**
|
|
19
|
-
* Customize how convert
|
|
20
|
-
* You might need define this if you not using express or fastify adapters
|
|
31
|
+
* Customize how to convert NestJS `req` and `res` to {@link NestStandardLazyRequest}.
|
|
32
|
+
* You might need to define this if you are not using express or fastify adapters.
|
|
21
33
|
*/
|
|
22
|
-
|
|
34
|
+
toNestStandardLazyRequest?: undefined | ((req: any, res: any) => NestStandardLazyRequest);
|
|
23
35
|
/**
|
|
24
|
-
* Options for how to convert the Standard Response to a Nest Response (returning value), like event
|
|
36
|
+
* Options for how to convert the Standard Response to a Nest Response (returning value), like event stream options, etc.
|
|
25
37
|
*/
|
|
26
38
|
toNestResponse?: undefined | {
|
|
27
39
|
/**
|
|
@@ -30,6 +42,13 @@ type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> &
|
|
|
30
42
|
eventStream?: undefined | ToEventStreamOptions;
|
|
31
43
|
};
|
|
32
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* NestJS module that configures the `@orpc/nest` integration via `forRoot`
|
|
47
|
+
* or `forRootAsync`, providing options such as initial context, plugins,
|
|
48
|
+
* and interceptors to `@Implement` handlers.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#configuration | Implement oRPC contract with NestJS - Configuration}
|
|
51
|
+
*/
|
|
33
52
|
declare class ORPCModule {
|
|
34
53
|
static forRoot(config: ORPCModuleConfig): DynamicModule;
|
|
35
54
|
static forRootAsync(options: {
|
|
@@ -39,15 +58,26 @@ declare class ORPCModule {
|
|
|
39
58
|
}): DynamicModule;
|
|
40
59
|
}
|
|
41
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Decorator that implements an oRPC contract (procedure or router contract)
|
|
63
|
+
* on a NestJS controller method. It registers the corresponding NestJS routes
|
|
64
|
+
* and handles request decoding and response encoding for you.
|
|
65
|
+
*
|
|
66
|
+
* @remarks
|
|
67
|
+
* **Note**: Every procedure contract must define an `openapi.path` meta;
|
|
68
|
+
* use `populateRouterContractOpenAPIPaths` from `@orpc/openapi` to fill in missing paths.
|
|
69
|
+
*
|
|
70
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#implement-your-contract | Implement oRPC contract with NestJS - Implement Your Contract}
|
|
71
|
+
*/
|
|
42
72
|
declare function Implement<T extends RouterContract>(contract: T): <U extends Promisable<ContractedRouter<T, DefaultInitialContext>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
|
43
73
|
declare class ImplementInterceptor implements NestInterceptor {
|
|
44
74
|
private readonly config;
|
|
45
75
|
private readonly codec;
|
|
46
|
-
private readonly
|
|
76
|
+
private readonly toNestStandardLazyRequest;
|
|
47
77
|
private readonly httpAdapterHost;
|
|
48
78
|
constructor(config: ORPCModuleConfig | undefined, httpAdapterHost: HttpAdapterHost);
|
|
49
79
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
|
50
80
|
}
|
|
51
81
|
|
|
52
82
|
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL };
|
|
53
|
-
export type { ORPCModuleConfig };
|
|
83
|
+
export type { NestStandardLazyRequest, ORPCModuleConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DynamicModule, NestInterceptor,
|
|
1
|
+
import { ExecutionContext, DynamicModule, NestInterceptor, CallHandler } from '@nestjs/common';
|
|
2
2
|
import { RouterContract } from '@orpc/contract';
|
|
3
3
|
import { DefaultInitialContext, ContractedRouter } from '@orpc/server';
|
|
4
|
-
import { Promisable } from '@orpc/shared';
|
|
4
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import { OpenAPIHandlerCodecCoreOptions } from '@orpc/openapi/standard';
|
|
7
7
|
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
@@ -10,18 +10,30 @@ import { ToEventStreamOptions } from '@standardserver/node';
|
|
|
10
10
|
import { HttpAdapterHost } from '@nestjs/core';
|
|
11
11
|
|
|
12
12
|
declare const ORPC_MODULE_CONFIG_SYMBOL: unique symbol;
|
|
13
|
+
/**
|
|
14
|
+
* A standard lazy request extended with NestJS route parameters,
|
|
15
|
+
* used as the request representation inside the `@orpc/nest` integration.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#toneststandardlazyrequest-option | Implement oRPC contract with NestJS - toNestStandardLazyRequest option}
|
|
18
|
+
*/
|
|
19
|
+
interface NestStandardLazyRequest extends StandardLazyRequest {
|
|
20
|
+
/**
|
|
21
|
+
* Route parameters extracted from the request path.
|
|
22
|
+
*/
|
|
23
|
+
params?: undefined | Record<string, string | string[]>;
|
|
24
|
+
}
|
|
13
25
|
type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> & StandardHandlerOptions<DefaultInitialContext> & (object extends DefaultInitialContext ? {
|
|
14
|
-
context?: DefaultInitialContext
|
|
26
|
+
context?: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
15
27
|
} : {
|
|
16
|
-
context: DefaultInitialContext
|
|
28
|
+
context: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
17
29
|
}) & {
|
|
18
30
|
/**
|
|
19
|
-
* Customize how convert
|
|
20
|
-
* You might need define this if you not using express or fastify adapters
|
|
31
|
+
* Customize how to convert NestJS `req` and `res` to {@link NestStandardLazyRequest}.
|
|
32
|
+
* You might need to define this if you are not using express or fastify adapters.
|
|
21
33
|
*/
|
|
22
|
-
|
|
34
|
+
toNestStandardLazyRequest?: undefined | ((req: any, res: any) => NestStandardLazyRequest);
|
|
23
35
|
/**
|
|
24
|
-
* Options for how to convert the Standard Response to a Nest Response (returning value), like event
|
|
36
|
+
* Options for how to convert the Standard Response to a Nest Response (returning value), like event stream options, etc.
|
|
25
37
|
*/
|
|
26
38
|
toNestResponse?: undefined | {
|
|
27
39
|
/**
|
|
@@ -30,6 +42,13 @@ type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> &
|
|
|
30
42
|
eventStream?: undefined | ToEventStreamOptions;
|
|
31
43
|
};
|
|
32
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* NestJS module that configures the `@orpc/nest` integration via `forRoot`
|
|
47
|
+
* or `forRootAsync`, providing options such as initial context, plugins,
|
|
48
|
+
* and interceptors to `@Implement` handlers.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#configuration | Implement oRPC contract with NestJS - Configuration}
|
|
51
|
+
*/
|
|
33
52
|
declare class ORPCModule {
|
|
34
53
|
static forRoot(config: ORPCModuleConfig): DynamicModule;
|
|
35
54
|
static forRootAsync(options: {
|
|
@@ -39,15 +58,26 @@ declare class ORPCModule {
|
|
|
39
58
|
}): DynamicModule;
|
|
40
59
|
}
|
|
41
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Decorator that implements an oRPC contract (procedure or router contract)
|
|
63
|
+
* on a NestJS controller method. It registers the corresponding NestJS routes
|
|
64
|
+
* and handles request decoding and response encoding for you.
|
|
65
|
+
*
|
|
66
|
+
* @remarks
|
|
67
|
+
* **Note**: Every procedure contract must define an `openapi.path` meta;
|
|
68
|
+
* use `populateRouterContractOpenAPIPaths` from `@orpc/openapi` to fill in missing paths.
|
|
69
|
+
*
|
|
70
|
+
* @see {@link https://orpc.dev/docs/integrations/nest#implement-your-contract | Implement oRPC contract with NestJS - Implement Your Contract}
|
|
71
|
+
*/
|
|
42
72
|
declare function Implement<T extends RouterContract>(contract: T): <U extends Promisable<ContractedRouter<T, DefaultInitialContext>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
|
43
73
|
declare class ImplementInterceptor implements NestInterceptor {
|
|
44
74
|
private readonly config;
|
|
45
75
|
private readonly codec;
|
|
46
|
-
private readonly
|
|
76
|
+
private readonly toNestStandardLazyRequest;
|
|
47
77
|
private readonly httpAdapterHost;
|
|
48
78
|
constructor(config: ORPCModuleConfig | undefined, httpAdapterHost: HttpAdapterHost);
|
|
49
79
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
|
50
80
|
}
|
|
51
81
|
|
|
52
82
|
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL };
|
|
53
|
-
export type { ORPCModuleConfig };
|
|
83
|
+
export type { NestStandardLazyRequest, ORPCModuleConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { Module, applyDecorators, Options, Delete, Patch, Put, Post, Get, Head, HttpCode,
|
|
2
|
+
import { Module, applyDecorators, UseInterceptors, StreamableFile, HttpException, Options, Delete, Patch, Put, Post, Get, Head, HttpCode, Injectable, Inject, Optional } from '@nestjs/common';
|
|
3
3
|
import { HttpAdapterHost } from '@nestjs/core';
|
|
4
4
|
import { ProcedureContract, getPathMeta } from '@orpc/contract';
|
|
5
5
|
import { getOpenAPIMeta, DEFAULT_OPENAPI_METHOD, getDynamicPathParams } from '@orpc/openapi';
|
|
6
6
|
import { OpenAPIHandlerCodecCore } from '@orpc/openapi/standard';
|
|
7
|
-
import {
|
|
7
|
+
import { unlazy, Procedure, DEFAULT_SUCCESS_STATUS, getRouter } from '@orpc/server';
|
|
8
8
|
import { StandardHandler } from '@orpc/server/standard';
|
|
9
|
-
import {
|
|
9
|
+
import { value, isAsyncIteratorObject, stringifyJSON, mergeHttpPath, NullProtoObj } from '@orpc/shared';
|
|
10
10
|
import { flattenStandardHeader, generateContentDisposition } from '@standardserver/core';
|
|
11
11
|
import { toStandardLazyRequest, toEventStream } from '@standardserver/node';
|
|
12
12
|
import { mergeMap } from 'rxjs';
|
|
@@ -76,56 +76,83 @@ const MethodDecoratorMap = {
|
|
|
76
76
|
};
|
|
77
77
|
function Implement(contract) {
|
|
78
78
|
if (contract instanceof ProcedureContract) {
|
|
79
|
-
const meta = getOpenAPIMeta(contract);
|
|
80
|
-
if (meta?.path === void 0) {
|
|
81
|
-
throw new TypeError(`
|
|
82
|
-
@Implement decorator requires contract to have a 'openapi.path' meta.
|
|
83
|
-
Please define one using '.meta(openapi({ path: '/example' }))'.
|
|
84
|
-
Or use "populateRouterContractOpenAPIPaths" from "@orpc/openapi" utility to automatically fill in any missing paths.
|
|
85
|
-
`);
|
|
86
|
-
}
|
|
87
|
-
const method = meta.method ?? DEFAULT_OPENAPI_METHOD;
|
|
88
|
-
const path = toNestPattern(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
|
|
89
|
-
const successStatus = meta.successStatus ?? DEFAULT_SUCCESS_STATUS;
|
|
90
79
|
return (target, propertyKey, descriptor) => {
|
|
91
80
|
applyDecorators(
|
|
92
|
-
|
|
93
|
-
HttpCode(successStatus),
|
|
81
|
+
toNestRouteDecorator(contract),
|
|
94
82
|
UseInterceptors(ImplementInterceptor)
|
|
95
83
|
)(target, propertyKey, descriptor);
|
|
96
84
|
};
|
|
97
85
|
}
|
|
98
86
|
return (target, propertyKey, descriptor) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
87
|
+
UseInterceptors(ImplementInterceptor)(target, propertyKey, descriptor);
|
|
88
|
+
implementRouterContract(contract, target, propertyKey, descriptor);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function toNestRouteDecorator(contract) {
|
|
92
|
+
const meta = getOpenAPIMeta(contract);
|
|
93
|
+
if (meta?.path === void 0) {
|
|
94
|
+
throw new TypeError(`
|
|
95
|
+
@Implement decorator requires contract to have a 'openapi.path' meta.
|
|
96
|
+
Please define one using '.meta(openapi({ path: '/example' }))'.
|
|
97
|
+
Or use "populateRouterContractOpenAPIPaths" from "@orpc/openapi" utility to automatically fill in any missing paths.
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
const method = meta.method ?? DEFAULT_OPENAPI_METHOD;
|
|
101
|
+
const path = toNestPattern(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
|
|
102
|
+
const successStatus = meta.successStatus ?? DEFAULT_SUCCESS_STATUS;
|
|
103
|
+
if (method === "QUERY") {
|
|
104
|
+
throw new TypeError(`
|
|
105
|
+
@Implement decorator does not support the 'QUERY' HTTP method because NestJS does not support it.
|
|
106
|
+
Use the 'GET' method instead.
|
|
107
|
+
`);
|
|
108
|
+
}
|
|
109
|
+
return applyDecorators(
|
|
110
|
+
MethodDecoratorMap[method](path),
|
|
111
|
+
HttpCode(successStatus)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
function implementRouterContract(contract, target, propertyKey, descriptor) {
|
|
115
|
+
for (const key in contract) {
|
|
116
|
+
let methodName = `${propertyKey}_${key}`;
|
|
117
|
+
let i = 0;
|
|
118
|
+
while (methodName in target) {
|
|
119
|
+
methodName = `${propertyKey}_${key}_${i++}`;
|
|
120
|
+
}
|
|
121
|
+
target[methodName] = async function(...args) {
|
|
122
|
+
const router = await descriptor.value.apply(this, args);
|
|
123
|
+
return getRouter(router, [key]);
|
|
124
|
+
};
|
|
125
|
+
Object.setPrototypeOf(target[methodName], descriptor.value);
|
|
126
|
+
queueMicrotask(() => {
|
|
109
127
|
for (const p of Reflect.getOwnMetadataKeys(target, propertyKey)) {
|
|
110
128
|
Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target, propertyKey), target, methodName);
|
|
111
129
|
}
|
|
112
130
|
for (const p of Reflect.getOwnMetadataKeys(target.constructor, propertyKey)) {
|
|
113
131
|
Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target.constructor, propertyKey), target.constructor, methodName);
|
|
114
132
|
}
|
|
115
|
-
|
|
133
|
+
});
|
|
134
|
+
const childContract = contract[key];
|
|
135
|
+
const childDescriptor = Object.getOwnPropertyDescriptor(target, methodName);
|
|
136
|
+
if (childContract instanceof ProcedureContract) {
|
|
137
|
+
const routeDecorator = toNestRouteDecorator(childContract);
|
|
138
|
+
queueMicrotask(() => {
|
|
139
|
+
routeDecorator(target, methodName, childDescriptor);
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
implementRouterContract(childContract, target, methodName, childDescriptor);
|
|
116
143
|
}
|
|
117
|
-
}
|
|
144
|
+
}
|
|
118
145
|
}
|
|
119
146
|
let ImplementInterceptor = class {
|
|
120
147
|
config;
|
|
121
148
|
codec;
|
|
122
|
-
|
|
149
|
+
toNestStandardLazyRequest;
|
|
123
150
|
httpAdapterHost;
|
|
124
151
|
constructor(config, httpAdapterHost) {
|
|
125
152
|
this.config = config ?? {};
|
|
126
153
|
this.httpAdapterHost = httpAdapterHost;
|
|
127
154
|
this.codec = new OpenAPIHandlerCodecCore(this.config);
|
|
128
|
-
this.
|
|
155
|
+
this.toNestStandardLazyRequest = this.config.toNestStandardLazyRequest ?? ((req, res) => {
|
|
129
156
|
const standardRequest = toStandardLazyRequest(
|
|
130
157
|
"raw" in req ? req.raw : req,
|
|
131
158
|
"raw" in res ? res.raw : res
|
|
@@ -133,6 +160,7 @@ let ImplementInterceptor = class {
|
|
|
133
160
|
if (req.body !== void 0) {
|
|
134
161
|
standardRequest.resolveBody = () => Promise.resolve(req.body);
|
|
135
162
|
}
|
|
163
|
+
standardRequest.params = req.params;
|
|
136
164
|
return standardRequest;
|
|
137
165
|
});
|
|
138
166
|
}
|
|
@@ -147,21 +175,21 @@ let ImplementInterceptor = class {
|
|
|
147
175
|
}
|
|
148
176
|
const req = ctx.switchToHttp().getRequest();
|
|
149
177
|
const res = ctx.switchToHttp().getResponse();
|
|
150
|
-
const standardRequest = this.
|
|
178
|
+
const standardRequest = this.toNestStandardLazyRequest(req, res);
|
|
151
179
|
const handler = new StandardHandler({
|
|
152
180
|
resolveProcedure: () => Promise.resolve({
|
|
153
181
|
path: getPathMeta(procedure) ?? [],
|
|
154
182
|
procedure,
|
|
155
183
|
decodeInput: () => this.codec.decodeInput({
|
|
156
184
|
procedure,
|
|
157
|
-
params: toORPCOpenAPIParams(procedure,
|
|
185
|
+
params: toORPCOpenAPIParams(procedure, standardRequest.params)
|
|
158
186
|
}, standardRequest)
|
|
159
187
|
}),
|
|
160
188
|
encodeError: this.codec.encodeError.bind(this.codec),
|
|
161
189
|
encodeOutput: this.codec.encodeOutput.bind(this.codec)
|
|
162
190
|
}, this.config);
|
|
163
191
|
const result = await handler.handle(standardRequest, {
|
|
164
|
-
context: this.config.context ?? {}
|
|
192
|
+
context: await value(this.config.context ?? {}, ctx)
|
|
165
193
|
});
|
|
166
194
|
if (!result.matched) {
|
|
167
195
|
throw new TypeError(
|
|
@@ -171,15 +199,15 @@ let ImplementInterceptor = class {
|
|
|
171
199
|
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
172
200
|
httpAdapter.status(res, result.response.status);
|
|
173
201
|
for (const key in result.response.headers) {
|
|
174
|
-
const
|
|
175
|
-
if (typeof
|
|
176
|
-
httpAdapter.setHeader(res, key,
|
|
202
|
+
const value2 = result.response.headers[key];
|
|
203
|
+
if (typeof value2 === "string") {
|
|
204
|
+
httpAdapter.setHeader(res, key, value2);
|
|
177
205
|
} else {
|
|
178
|
-
|
|
206
|
+
value2?.forEach((value3, index) => {
|
|
179
207
|
if (index === 0) {
|
|
180
|
-
httpAdapter.setHeader(res, key,
|
|
208
|
+
httpAdapter.setHeader(res, key, value3);
|
|
181
209
|
} else {
|
|
182
|
-
httpAdapter.appendHeader(res, key,
|
|
210
|
+
httpAdapter.appendHeader(res, key, value3);
|
|
183
211
|
}
|
|
184
212
|
});
|
|
185
213
|
}
|
|
@@ -202,7 +230,7 @@ let ImplementInterceptor = class {
|
|
|
202
230
|
type: body.type,
|
|
203
231
|
disposition: flattenStandardHeader(result.response.headers["content-disposition"]) ?? generateContentDisposition(body instanceof File ? body.name : "blob"),
|
|
204
232
|
// BunS3 can use NaN for the size
|
|
205
|
-
length: Number.
|
|
233
|
+
length: Number.isFinite(body.size) ? body.size : void 0
|
|
206
234
|
});
|
|
207
235
|
}
|
|
208
236
|
if (body instanceof FormData) {
|
|
@@ -233,26 +261,31 @@ ImplementInterceptor = __decorateClass([
|
|
|
233
261
|
__decorateParam(0, Optional()),
|
|
234
262
|
__decorateParam(1, Inject(HttpAdapterHost))
|
|
235
263
|
], ImplementInterceptor);
|
|
236
|
-
function flattenParamValue(
|
|
237
|
-
return Array.isArray(
|
|
264
|
+
function flattenParamValue(value2) {
|
|
265
|
+
return Array.isArray(value2) ? value2.join("/") : value2;
|
|
238
266
|
}
|
|
239
267
|
function toORPCOpenAPIParams(contract, params) {
|
|
240
268
|
const meta = getOpenAPIMeta(contract);
|
|
241
|
-
if (!params || meta?.path === void 0) {
|
|
269
|
+
if (!params || meta?.path === void 0 || Object.keys(params).length === 0) {
|
|
242
270
|
return void 0;
|
|
243
271
|
}
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
272
|
+
const orpcParams = new NullProtoObj();
|
|
273
|
+
const restKey = Object.hasOwn(params, "*") ? "*" : "path";
|
|
274
|
+
for (const [key, value2] of Object.entries(params)) {
|
|
275
|
+
if (key === restKey) {
|
|
276
|
+
const restParams = getDynamicPathParams(
|
|
277
|
+
meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path
|
|
278
|
+
)?.filter((c) => c.allowsSlash);
|
|
279
|
+
if (restParams?.length) {
|
|
280
|
+
for (const c of restParams) {
|
|
281
|
+
orpcParams[c.parameterName] = flattenParamValue(value2);
|
|
282
|
+
}
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
252
285
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
286
|
+
orpcParams[key] = flattenParamValue(value2);
|
|
287
|
+
}
|
|
288
|
+
return orpcParams;
|
|
256
289
|
}
|
|
257
290
|
function toNestPattern(path) {
|
|
258
291
|
const params = getDynamicPathParams(path);
|
package/package.json
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/nest",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.30",
|
|
5
|
+
"description": "NestJS integration for oRPC: implement typesafe contracts in NestJS controllers",
|
|
5
6
|
"license": "MIT",
|
|
7
|
+
"funding": [
|
|
8
|
+
"https://github.com/sponsors/dinwwwh",
|
|
9
|
+
"https://opencollective.com/middleapi"
|
|
10
|
+
],
|
|
6
11
|
"homepage": "https://orpc.dev",
|
|
7
12
|
"repository": {
|
|
8
13
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/middleapi/orpc
|
|
14
|
+
"url": "git+https://github.com/middleapi/orpc.git",
|
|
10
15
|
"directory": "packages/nest"
|
|
11
16
|
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"orpc",
|
|
19
|
+
"nestjs",
|
|
20
|
+
"nest",
|
|
21
|
+
"contract-first",
|
|
22
|
+
"rpc",
|
|
23
|
+
"openapi",
|
|
24
|
+
"typescript",
|
|
25
|
+
"typesafe"
|
|
26
|
+
],
|
|
12
27
|
"sideEffects": false,
|
|
13
28
|
"exports": {
|
|
14
29
|
"./package.json": "./package.json",
|
|
@@ -37,23 +52,25 @@
|
|
|
37
52
|
}
|
|
38
53
|
},
|
|
39
54
|
"dependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@orpc/
|
|
43
|
-
"@orpc/
|
|
44
|
-
"@orpc/
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
55
|
+
"@standardserver/core": "^0.8.0",
|
|
56
|
+
"@standardserver/node": "^0.8.0",
|
|
57
|
+
"@orpc/client": "2.0.0-beta.30",
|
|
58
|
+
"@orpc/contract": "2.0.0-beta.30",
|
|
59
|
+
"@orpc/openapi": "2.0.0-beta.30",
|
|
60
|
+
"@orpc/shared": "2.0.0-beta.30",
|
|
61
|
+
"@orpc/server": "2.0.0-beta.30"
|
|
47
62
|
},
|
|
48
63
|
"devDependencies": {
|
|
49
64
|
"@fastify/cookie": "^11.0.2",
|
|
50
|
-
"@nestjs/common": "^11.1
|
|
51
|
-
"@nestjs/core": "^11.1
|
|
52
|
-
"@nestjs/platform-
|
|
65
|
+
"@nestjs/common": "^11.2.1",
|
|
66
|
+
"@nestjs/core": "^11.2.1",
|
|
67
|
+
"@nestjs/platform-express": "^11.2.1",
|
|
68
|
+
"@nestjs/platform-fastify": "^11.2.1",
|
|
69
|
+
"@nestjs/testing": "^11.2.1",
|
|
70
|
+
"@types/express": "^5.0.6",
|
|
53
71
|
"express": "^5.2.1",
|
|
54
|
-
"fastify": "^5.
|
|
55
|
-
"rxjs": "^7.8.2"
|
|
56
|
-
"supertest": "^7.2.2"
|
|
72
|
+
"fastify": "^5.12.1",
|
|
73
|
+
"rxjs": "^7.8.2"
|
|
57
74
|
},
|
|
58
75
|
"scripts": {
|
|
59
76
|
"build": "unbuild",
|