@orpc/nest 1.14.9 → 1.14.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/README.md +52 -102
- package/dist/index.d.mts +40 -47
- package/dist/index.d.ts +40 -47
- package/dist/index.mjs +146 -86
- package/package.json +22 -35
package/README.md
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
<
|
|
2
|
-
<image align="center" src="https://orpc.dev/logo.webp" width=280 alt="oRPC logo" />
|
|
3
|
-
</div>
|
|
4
|
-
|
|
5
|
-
<h1></h1>
|
|
1
|
+
<h1 align="center">oRPC - Typesafe APIs Made Simple 🪄</h1>
|
|
6
2
|
|
|
7
3
|
<div align="center">
|
|
8
4
|
<a href="https://codecov.io/gh/middleapi/orpc">
|
|
9
|
-
<img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/
|
|
5
|
+
<img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg">
|
|
10
6
|
</a>
|
|
11
7
|
<a href="https://www.npmjs.com/package/@orpc/nest">
|
|
12
8
|
<img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fnest?logo=npm" />
|
|
13
9
|
</a>
|
|
14
|
-
<a href="https://
|
|
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">
|
|
15
14
|
<img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" />
|
|
16
15
|
</a>
|
|
17
16
|
<a href="https://discord.gg/TXEbwRBvQn">
|
|
@@ -22,109 +21,53 @@
|
|
|
22
21
|
</a>
|
|
23
22
|
</div>
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
## Documentation
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
You can read the documentation [here](https://orpc.dev).
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
## Packages
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
**Core**
|
|
32
31
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), SWR, Pinia Colada, and more.
|
|
38
|
-
- **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
|
|
39
|
-
- **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
|
|
40
|
-
- **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
|
|
41
|
-
- **⏱️ Lazy Router**: Enhance cold start times with our lazy routing feature.
|
|
42
|
-
- **📡 SSE & Streaming**: Enjoy full type-safe support for SSE and streaming.
|
|
43
|
-
- **🌍 Multi-Runtime Support**: Fast and lightweight on Cloudflare, Deno, Bun, Node.js, and beyond.
|
|
44
|
-
- **🔌 Extendability**: Easily extend functionality with plugins, middleware, and interceptors.
|
|
32
|
+
- [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Define API contract as the single source of truth.
|
|
33
|
+
- [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build APIs or implement contracts.
|
|
34
|
+
- [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume APIs with end-to-end type safety.
|
|
35
|
+
- [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Add OpenAPI compatibility to APIs.
|
|
45
36
|
|
|
46
|
-
|
|
37
|
+
**Schema validation**
|
|
47
38
|
|
|
48
|
-
|
|
39
|
+
- [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): Integrate with [Zod](https://zod.dev/).
|
|
40
|
+
- [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): Integrate with [Valibot](https://valibot.dev/).
|
|
41
|
+
- [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): Integrate with [ArkType](https://arktype.io/).
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
**Built-in features**
|
|
44
|
+
|
|
45
|
+
- [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
|
|
46
|
+
- [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
|
|
47
|
+
- [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- [@orpc/
|
|
55
|
-
- [@orpc/
|
|
56
|
-
- [@orpc/
|
|
57
|
-
- [@orpc/
|
|
58
|
-
- [@orpc/
|
|
59
|
-
- [@orpc/
|
|
60
|
-
- [@orpc/
|
|
61
|
-
- [@orpc/
|
|
62
|
-
- [@orpc/
|
|
63
|
-
- [@orpc/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
### Implement Contract
|
|
72
|
-
|
|
73
|
-
An overview of how to implement an [oRPC contract](https://orpc.dev/docs/contract-first/define-contract) in NestJS.
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
import { Implement, implement, ORPCError } from '@orpc/nest'
|
|
77
|
-
|
|
78
|
-
@Controller()
|
|
79
|
-
export class PlanetController {
|
|
80
|
-
/**
|
|
81
|
-
* Implement a standalone procedure
|
|
82
|
-
*/
|
|
83
|
-
@Implement(contract.planet.list)
|
|
84
|
-
list() {
|
|
85
|
-
return implement(contract.planet.list).handler(({ input }) => {
|
|
86
|
-
// Implement logic here
|
|
87
|
-
|
|
88
|
-
return []
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Implement entire contract
|
|
94
|
-
*/
|
|
95
|
-
@Implement(contract.planet)
|
|
96
|
-
planet() {
|
|
97
|
-
return {
|
|
98
|
-
list: implement(contract.planet.list).handler(({ input }) => {
|
|
99
|
-
// Implement logic here
|
|
100
|
-
return []
|
|
101
|
-
}),
|
|
102
|
-
find: implement(contract.planet.find).handler(({ input }) => {
|
|
103
|
-
// Implement logic here
|
|
104
|
-
return {
|
|
105
|
-
id: 1,
|
|
106
|
-
name: 'Earth',
|
|
107
|
-
description: 'The planet Earth',
|
|
108
|
-
}
|
|
109
|
-
}),
|
|
110
|
-
create: implement(contract.planet.create).handler(({ input }) => {
|
|
111
|
-
// Implement logic here
|
|
112
|
-
return {
|
|
113
|
-
id: 1,
|
|
114
|
-
name: 'Earth',
|
|
115
|
-
description: 'The planet Earth',
|
|
116
|
-
}
|
|
117
|
-
}),
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// other handlers...
|
|
122
|
-
}
|
|
123
|
-
```
|
|
49
|
+
**Framework & ecosystem integrations**
|
|
50
|
+
|
|
51
|
+
- [@orpc/next](https://www.npmjs.com/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
|
|
52
|
+
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
|
|
53
|
+
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
|
|
54
|
+
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
|
|
55
|
+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
|
|
56
|
+
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
|
|
57
|
+
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
|
|
58
|
+
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
|
|
59
|
+
- [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
|
|
60
|
+
- [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
|
|
61
|
+
|
|
62
|
+
**Observability**
|
|
63
|
+
|
|
64
|
+
- [@orpc/opentelemetry](https://www.npmjs.com/package/@orpc/opentelemetry): Integrate with [OpenTelemetry](https://opentelemetry.io/) for distributed tracing.
|
|
65
|
+
- [@orpc/pino](https://www.npmjs.com/package/@orpc/pino): Integrate with [Pino](https://getpino.io/) for logging.
|
|
66
|
+
- [@orpc/evlog](https://www.npmjs.com/package/@orpc/evlog): Integrate with [Evlog](https://evlog.dev/) for logging.
|
|
124
67
|
|
|
125
68
|
## Sponsors
|
|
126
69
|
|
|
127
|
-
|
|
70
|
+
Like what we build over at [middleapi](https://github.com/middleapi)? You can help keep it going here: [GitHub Sponsors](https://github.com/sponsors/dinwwwh). Every bit helps! 🚀
|
|
128
71
|
|
|
129
72
|
### 🏆 Platinum Sponsor
|
|
130
73
|
|
|
@@ -166,11 +109,10 @@ If you find oRPC valuable and would like to support its development, you can do
|
|
|
166
109
|
<td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" 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>
|
|
167
110
|
<td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" 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>
|
|
168
111
|
<td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" 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>
|
|
169
|
-
<td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="139" alt="Ryan Vogel"/><br />Ryan Vogel</a></td>
|
|
170
112
|
<td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
|
|
113
|
+
<td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" 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>
|
|
171
114
|
</tr>
|
|
172
115
|
<tr>
|
|
173
|
-
<td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" 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>
|
|
174
116
|
<td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td>
|
|
175
117
|
</tr>
|
|
176
118
|
</table>
|
|
@@ -230,6 +172,7 @@ If you find oRPC valuable and would like to support its development, you can do
|
|
|
230
172
|
<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>
|
|
231
173
|
<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>
|
|
232
174
|
<a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
|
|
175
|
+
<a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="32" height="32" alt="Ryan Vogel" /></a>
|
|
233
176
|
<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>
|
|
234
177
|
<a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="32" height="32" alt="Peter Adam" /></a>
|
|
235
178
|
<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>
|
|
@@ -244,6 +187,13 @@ If you find oRPC valuable and would like to support its development, you can do
|
|
|
244
187
|
<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>
|
|
245
188
|
</p>
|
|
246
189
|
|
|
190
|
+
## References
|
|
191
|
+
|
|
192
|
+
oRPC is inspired by existing solutions that prioritize type safety and developer experience. Special acknowledgments to:
|
|
193
|
+
|
|
194
|
+
- [tRPC](https://trpc.io): For pioneering the concept of end-to-end type-safe RPC and influencing the development of type-safe APIs.
|
|
195
|
+
- [ts-rest](https://ts-rest.com): For its emphasis on contract-first development and OpenAPI integration, which have greatly inspired oRPC's feature set.
|
|
196
|
+
|
|
247
197
|
## License
|
|
248
198
|
|
|
249
|
-
Distributed under the MIT License. See [LICENSE](https://github.com/middleapi/orpc/blob/
|
|
199
|
+
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,38 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
6
|
-
import { StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
|
|
7
|
-
import { StandardOpenAPICodecOptions } from '@orpc/openapi/standard';
|
|
8
|
-
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
9
|
-
import { Interceptor, Promisable } from '@orpc/shared';
|
|
10
|
-
import { StandardResponse } from '@orpc/standard-server';
|
|
11
|
-
import { SendStandardResponseOptions } from '@orpc/standard-server-node';
|
|
1
|
+
import { ExecutionContext, DynamicModule, NestInterceptor, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { RouterContract } from '@orpc/contract';
|
|
3
|
+
import { DefaultInitialContext, ContractedRouter } from '@orpc/server';
|
|
4
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
12
5
|
import { Observable } from 'rxjs';
|
|
6
|
+
import { OpenAPIHandlerCodecCoreOptions } from '@orpc/openapi/standard';
|
|
7
|
+
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
8
|
+
import { StandardLazyRequest } from '@standardserver/core';
|
|
9
|
+
import { ToEventStreamOptions } from '@standardserver/node';
|
|
10
|
+
import { HttpAdapterHost } from '@nestjs/core';
|
|
13
11
|
|
|
14
12
|
declare const ORPC_MODULE_CONFIG_SYMBOL: unique symbol;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* interface ORPCGlobalContext {
|
|
21
|
-
* user: { id: string; name: string }
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
interface ORPCGlobalContext {
|
|
27
|
-
}
|
|
28
|
-
interface ORPCModuleConfig extends CreateProcedureClientOptions<ORPCGlobalContext, AnySchema, object, object, object>, SendStandardResponseOptions, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPICodecOptions {
|
|
29
|
-
plugins?: StandardHandlerOptions<ORPCGlobalContext>['plugins'];
|
|
30
|
-
sendResponseInterceptors?: Interceptor<{
|
|
31
|
-
request: any;
|
|
32
|
-
response: any;
|
|
33
|
-
standardResponse: StandardResponse;
|
|
34
|
-
}, unknown>[];
|
|
13
|
+
interface NestStandardLazyRequest extends StandardLazyRequest {
|
|
14
|
+
/**
|
|
15
|
+
* Route parameters extracted from the request path.
|
|
16
|
+
*/
|
|
17
|
+
params?: undefined | Record<string, string | string[]>;
|
|
35
18
|
}
|
|
19
|
+
type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> & StandardHandlerOptions<DefaultInitialContext> & (object extends DefaultInitialContext ? {
|
|
20
|
+
context?: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
21
|
+
} : {
|
|
22
|
+
context: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
23
|
+
}) & {
|
|
24
|
+
/**
|
|
25
|
+
* Customize how to convert NestJS `req` and `res` to {@link NestStandardLazyRequest}.
|
|
26
|
+
* You might need to define this if you are not using express or fastify adapters.
|
|
27
|
+
*/
|
|
28
|
+
toNestStandardLazyRequest?: undefined | ((req: any, res: any) => NestStandardLazyRequest);
|
|
29
|
+
/**
|
|
30
|
+
* Options for how to convert the Standard Response to a Nest Response (returning value), like event stream options, etc.
|
|
31
|
+
*/
|
|
32
|
+
toNestResponse?: undefined | {
|
|
33
|
+
/**
|
|
34
|
+
* Options for the event stream, like keep-alive settings, initial comment, etc.
|
|
35
|
+
*/
|
|
36
|
+
eventStream?: undefined | ToEventStreamOptions;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
36
39
|
declare class ORPCModule {
|
|
37
40
|
static forRoot(config: ORPCModuleConfig): DynamicModule;
|
|
38
41
|
static forRootAsync(options: {
|
|
@@ -42,25 +45,15 @@ declare class ORPCModule {
|
|
|
42
45
|
}): DynamicModule;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
* Decorator in controller handler to implement a oRPC contract.
|
|
47
|
-
*
|
|
48
|
-
* @see {@link https://orpc.dev/docs/openapi/integrations/implement-contract-in-nest#implement-your-contract NestJS Implement Contract Docs}
|
|
49
|
-
*/
|
|
50
|
-
declare function Implement<T extends ContractRouter<any>>(contract: T): <U extends Promisable<Router<T, ORPCGlobalContext>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
|
48
|
+
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;
|
|
51
49
|
declare class ImplementInterceptor implements NestInterceptor {
|
|
52
50
|
private readonly config;
|
|
53
51
|
private readonly codec;
|
|
54
|
-
|
|
52
|
+
private readonly toNestStandardLazyRequest;
|
|
53
|
+
private readonly httpAdapterHost;
|
|
54
|
+
constructor(config: ORPCModuleConfig | undefined, httpAdapterHost: HttpAdapterHost);
|
|
55
55
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Alias for `implement` from `@orpc/server` with default context set to `ORPCGlobalContext`
|
|
62
|
-
*/
|
|
63
|
-
declare function implement<T extends AnyContractRouter, TContext extends Context = ORPCGlobalContext>(contract: T, config?: BuilderConfig): Implementer<T, TContext, TContext>;
|
|
64
|
-
|
|
65
|
-
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL, implement, toNestPattern };
|
|
66
|
-
export type { ORPCGlobalContext, ORPCModuleConfig };
|
|
58
|
+
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL };
|
|
59
|
+
export type { NestStandardLazyRequest, ORPCModuleConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
6
|
-
import { StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
|
|
7
|
-
import { StandardOpenAPICodecOptions } from '@orpc/openapi/standard';
|
|
8
|
-
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
9
|
-
import { Interceptor, Promisable } from '@orpc/shared';
|
|
10
|
-
import { StandardResponse } from '@orpc/standard-server';
|
|
11
|
-
import { SendStandardResponseOptions } from '@orpc/standard-server-node';
|
|
1
|
+
import { ExecutionContext, DynamicModule, NestInterceptor, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { RouterContract } from '@orpc/contract';
|
|
3
|
+
import { DefaultInitialContext, ContractedRouter } from '@orpc/server';
|
|
4
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
12
5
|
import { Observable } from 'rxjs';
|
|
6
|
+
import { OpenAPIHandlerCodecCoreOptions } from '@orpc/openapi/standard';
|
|
7
|
+
import { StandardHandlerOptions } from '@orpc/server/standard';
|
|
8
|
+
import { StandardLazyRequest } from '@standardserver/core';
|
|
9
|
+
import { ToEventStreamOptions } from '@standardserver/node';
|
|
10
|
+
import { HttpAdapterHost } from '@nestjs/core';
|
|
13
11
|
|
|
14
12
|
declare const ORPC_MODULE_CONFIG_SYMBOL: unique symbol;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* interface ORPCGlobalContext {
|
|
21
|
-
* user: { id: string; name: string }
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
interface ORPCGlobalContext {
|
|
27
|
-
}
|
|
28
|
-
interface ORPCModuleConfig extends CreateProcedureClientOptions<ORPCGlobalContext, AnySchema, object, object, object>, SendStandardResponseOptions, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPICodecOptions {
|
|
29
|
-
plugins?: StandardHandlerOptions<ORPCGlobalContext>['plugins'];
|
|
30
|
-
sendResponseInterceptors?: Interceptor<{
|
|
31
|
-
request: any;
|
|
32
|
-
response: any;
|
|
33
|
-
standardResponse: StandardResponse;
|
|
34
|
-
}, unknown>[];
|
|
13
|
+
interface NestStandardLazyRequest extends StandardLazyRequest {
|
|
14
|
+
/**
|
|
15
|
+
* Route parameters extracted from the request path.
|
|
16
|
+
*/
|
|
17
|
+
params?: undefined | Record<string, string | string[]>;
|
|
35
18
|
}
|
|
19
|
+
type ORPCModuleConfig = OpenAPIHandlerCodecCoreOptions<DefaultInitialContext> & StandardHandlerOptions<DefaultInitialContext> & (object extends DefaultInitialContext ? {
|
|
20
|
+
context?: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
21
|
+
} : {
|
|
22
|
+
context: Value<Promisable<DefaultInitialContext>, [ctx: ExecutionContext]>;
|
|
23
|
+
}) & {
|
|
24
|
+
/**
|
|
25
|
+
* Customize how to convert NestJS `req` and `res` to {@link NestStandardLazyRequest}.
|
|
26
|
+
* You might need to define this if you are not using express or fastify adapters.
|
|
27
|
+
*/
|
|
28
|
+
toNestStandardLazyRequest?: undefined | ((req: any, res: any) => NestStandardLazyRequest);
|
|
29
|
+
/**
|
|
30
|
+
* Options for how to convert the Standard Response to a Nest Response (returning value), like event stream options, etc.
|
|
31
|
+
*/
|
|
32
|
+
toNestResponse?: undefined | {
|
|
33
|
+
/**
|
|
34
|
+
* Options for the event stream, like keep-alive settings, initial comment, etc.
|
|
35
|
+
*/
|
|
36
|
+
eventStream?: undefined | ToEventStreamOptions;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
36
39
|
declare class ORPCModule {
|
|
37
40
|
static forRoot(config: ORPCModuleConfig): DynamicModule;
|
|
38
41
|
static forRootAsync(options: {
|
|
@@ -42,25 +45,15 @@ declare class ORPCModule {
|
|
|
42
45
|
}): DynamicModule;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
* Decorator in controller handler to implement a oRPC contract.
|
|
47
|
-
*
|
|
48
|
-
* @see {@link https://orpc.dev/docs/openapi/integrations/implement-contract-in-nest#implement-your-contract NestJS Implement Contract Docs}
|
|
49
|
-
*/
|
|
50
|
-
declare function Implement<T extends ContractRouter<any>>(contract: T): <U extends Promisable<Router<T, ORPCGlobalContext>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
|
48
|
+
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;
|
|
51
49
|
declare class ImplementInterceptor implements NestInterceptor {
|
|
52
50
|
private readonly config;
|
|
53
51
|
private readonly codec;
|
|
54
|
-
|
|
52
|
+
private readonly toNestStandardLazyRequest;
|
|
53
|
+
private readonly httpAdapterHost;
|
|
54
|
+
constructor(config: ORPCModuleConfig | undefined, httpAdapterHost: HttpAdapterHost);
|
|
55
55
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Alias for `implement` from `@orpc/server` with default context set to `ORPCGlobalContext`
|
|
62
|
-
*/
|
|
63
|
-
declare function implement<T extends AnyContractRouter, TContext extends Context = ORPCGlobalContext>(contract: T, config?: BuilderConfig): Implementer<T, TContext, TContext>;
|
|
64
|
-
|
|
65
|
-
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL, implement, toNestPattern };
|
|
66
|
-
export type { ORPCGlobalContext, ORPCModuleConfig };
|
|
58
|
+
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL };
|
|
59
|
+
export type { NestStandardLazyRequest, ORPCModuleConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { Module, applyDecorators, Options, Delete, Patch, Put, Post, Get, Head, HttpCode, UseInterceptors, StreamableFile, HttpException, Injectable, Inject, Optional } from '@nestjs/common';
|
|
3
|
+
import { HttpAdapterHost } from '@nestjs/core';
|
|
4
|
+
import { ProcedureContract, getPathMeta } from '@orpc/contract';
|
|
5
|
+
import { getOpenAPIMeta, DEFAULT_OPENAPI_METHOD, getDynamicPathParams } from '@orpc/openapi';
|
|
6
|
+
import { OpenAPIHandlerCodecCore } from '@orpc/openapi/standard';
|
|
7
|
+
import { DEFAULT_SUCCESS_STATUS, getRouter, unlazy, Procedure } from '@orpc/server';
|
|
8
8
|
import { StandardHandler } from '@orpc/server/standard';
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import * as StandardServerNode from '@orpc/standard-server-node';
|
|
9
|
+
import { mergeHttpPath, value, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
|
|
10
|
+
import { flattenStandardHeader, generateContentDisposition } from '@standardserver/core';
|
|
11
|
+
import { toStandardLazyRequest, toEventStream } from '@standardserver/node';
|
|
13
12
|
import { mergeMap } from 'rxjs';
|
|
14
13
|
|
|
15
14
|
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
@@ -20,7 +19,7 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
|
20
19
|
result = (decorator(result)) || result;
|
|
21
20
|
return result;
|
|
22
21
|
};
|
|
23
|
-
const ORPC_MODULE_CONFIG_SYMBOL = Symbol("
|
|
22
|
+
const ORPC_MODULE_CONFIG_SYMBOL = Symbol.for("ORPC_NEST_MODULE_CONFIG");
|
|
24
23
|
let ORPCModule = class {
|
|
25
24
|
static forRoot(config) {
|
|
26
25
|
return {
|
|
@@ -57,10 +56,6 @@ ORPCModule = __decorateClass$1([
|
|
|
57
56
|
Module({})
|
|
58
57
|
], ORPCModule);
|
|
59
58
|
|
|
60
|
-
function toNestPattern(path) {
|
|
61
|
-
return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/*$1").replace(/\/\{([^}]+)\}/g, "/:$1");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
59
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
65
60
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
66
61
|
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
@@ -80,20 +75,22 @@ const MethodDecoratorMap = {
|
|
|
80
75
|
OPTIONS: Options
|
|
81
76
|
};
|
|
82
77
|
function Implement(contract) {
|
|
83
|
-
if (
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
Or use "populateContractRouterPaths" from "@orpc/contract" utility to automatically fill in any missing paths.
|
|
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.
|
|
91
85
|
`);
|
|
92
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;
|
|
93
90
|
return (target, propertyKey, descriptor) => {
|
|
94
91
|
applyDecorators(
|
|
95
|
-
MethodDecoratorMap[method](
|
|
96
|
-
HttpCode(
|
|
92
|
+
MethodDecoratorMap[method](path),
|
|
93
|
+
HttpCode(successStatus),
|
|
97
94
|
UseInterceptors(ImplementInterceptor)
|
|
98
95
|
)(target, propertyKey, descriptor);
|
|
99
96
|
};
|
|
@@ -115,74 +112,118 @@ function Implement(contract) {
|
|
|
115
112
|
for (const p of Reflect.getOwnMetadataKeys(target.constructor, propertyKey)) {
|
|
116
113
|
Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target.constructor, propertyKey), target.constructor, methodName);
|
|
117
114
|
}
|
|
118
|
-
Implement(
|
|
115
|
+
Implement(contract[key])(target, methodName, Object.getOwnPropertyDescriptor(target, methodName));
|
|
119
116
|
}
|
|
120
117
|
};
|
|
121
118
|
}
|
|
122
119
|
let ImplementInterceptor = class {
|
|
123
120
|
config;
|
|
124
121
|
codec;
|
|
125
|
-
|
|
122
|
+
toNestStandardLazyRequest;
|
|
123
|
+
httpAdapterHost;
|
|
124
|
+
constructor(config, httpAdapterHost) {
|
|
126
125
|
this.config = config ?? {};
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
126
|
+
this.httpAdapterHost = httpAdapterHost;
|
|
127
|
+
this.codec = new OpenAPIHandlerCodecCore(this.config);
|
|
128
|
+
this.toNestStandardLazyRequest = this.config.toNestStandardLazyRequest ?? ((req, res) => {
|
|
129
|
+
const standardRequest = toStandardLazyRequest(
|
|
130
|
+
"raw" in req ? req.raw : req,
|
|
131
|
+
"raw" in res ? res.raw : res
|
|
132
|
+
);
|
|
133
|
+
if (req.body !== void 0) {
|
|
134
|
+
standardRequest.resolveBody = () => Promise.resolve(req.body);
|
|
135
|
+
}
|
|
136
|
+
standardRequest.params = req.params;
|
|
137
|
+
return standardRequest;
|
|
138
|
+
});
|
|
134
139
|
}
|
|
135
140
|
intercept(ctx, next) {
|
|
136
141
|
return next.handle().pipe(
|
|
137
142
|
mergeMap(async (impl) => {
|
|
138
143
|
const { default: procedure } = await unlazy(impl);
|
|
139
|
-
if (!
|
|
140
|
-
throw new
|
|
144
|
+
if (!(procedure instanceof Procedure)) {
|
|
145
|
+
throw new TypeError(`
|
|
141
146
|
The return value of the @Implement controller handler must be a corresponding implemented router or procedure.
|
|
142
147
|
`);
|
|
143
148
|
}
|
|
144
149
|
const req = ctx.switchToHttp().getRequest();
|
|
145
150
|
const res = ctx.switchToHttp().getResponse();
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
},
|
|
160
|
-
match: () => Promise.resolve({ path: toArray(this.config.path), procedure, params: flattenParams(req.params) })
|
|
161
|
-
}, this.codec, {
|
|
162
|
-
// Since plugins can modify options directly, so we need to clone to avoid affecting other handlers/requests
|
|
163
|
-
// TODO: improve plugins system to avoid this cloning
|
|
164
|
-
clientInterceptors: [...toArray(this.config.interceptors)],
|
|
165
|
-
plugins: [...toArray(this.config.plugins)]
|
|
166
|
-
});
|
|
151
|
+
const standardRequest = this.toNestStandardLazyRequest(req, res);
|
|
152
|
+
const handler = new StandardHandler({
|
|
153
|
+
resolveProcedure: () => Promise.resolve({
|
|
154
|
+
path: getPathMeta(procedure) ?? [],
|
|
155
|
+
procedure,
|
|
156
|
+
decodeInput: () => this.codec.decodeInput({
|
|
157
|
+
procedure,
|
|
158
|
+
params: toORPCOpenAPIParams(procedure, standardRequest.params)
|
|
159
|
+
}, standardRequest)
|
|
160
|
+
}),
|
|
161
|
+
encodeError: this.codec.encodeError.bind(this.codec),
|
|
162
|
+
encodeOutput: this.codec.encodeOutput.bind(this.codec)
|
|
163
|
+
}, this.config);
|
|
167
164
|
const result = await handler.handle(standardRequest, {
|
|
168
|
-
context: this.config.context
|
|
165
|
+
context: await value(this.config.context ?? {}, ctx)
|
|
169
166
|
});
|
|
170
|
-
if (result.matched) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
167
|
+
if (!result.matched) {
|
|
168
|
+
throw new TypeError(
|
|
169
|
+
"oRPC NestJS handler returned an unmatched result, which should never happen. Please check your plugins/interceptors or report a bug."
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
173
|
+
httpAdapter.status(res, result.response.status);
|
|
174
|
+
for (const key in result.response.headers) {
|
|
175
|
+
const value2 = result.response.headers[key];
|
|
176
|
+
if (typeof value2 === "string") {
|
|
177
|
+
httpAdapter.setHeader(res, key, value2);
|
|
178
|
+
} else {
|
|
179
|
+
value2?.forEach((value3, index) => {
|
|
180
|
+
if (index === 0) {
|
|
181
|
+
httpAdapter.setHeader(res, key, value3);
|
|
180
182
|
} else {
|
|
181
|
-
|
|
183
|
+
httpAdapter.appendHeader(res, key, value3);
|
|
182
184
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const body = result.response.body;
|
|
189
|
+
if (body instanceof ReadableStream) {
|
|
190
|
+
httpAdapter.setHeader(res, "standard-server", "octet-stream");
|
|
191
|
+
return new StreamableFile(Readable.fromWeb(body), {
|
|
192
|
+
type: flattenStandardHeader(result.response.headers["content-type"]) ?? "application/octet-stream"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (isAsyncIteratorObject(body)) {
|
|
196
|
+
return new StreamableFile(toEventStream(body, this.config.toNestResponse?.eventStream), {
|
|
197
|
+
type: "text/event-stream"
|
|
198
|
+
});
|
|
185
199
|
}
|
|
200
|
+
if (body instanceof Blob) {
|
|
201
|
+
httpAdapter.setHeader(res, "standard-server", "file");
|
|
202
|
+
return new StreamableFile(Readable.fromWeb(body.stream()), {
|
|
203
|
+
type: body.type,
|
|
204
|
+
disposition: flattenStandardHeader(result.response.headers["content-disposition"]) ?? generateContentDisposition(body instanceof File ? body.name : "blob"),
|
|
205
|
+
// BunS3 can use NaN for the size
|
|
206
|
+
length: Number.isFinite(body.size) ? body.size : void 0
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (body instanceof FormData) {
|
|
210
|
+
const response = new Response(body);
|
|
211
|
+
return new StreamableFile(Readable.fromWeb(response.body), {
|
|
212
|
+
type: response.headers.get("content-type")
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (body instanceof URLSearchParams) {
|
|
216
|
+
httpAdapter.setHeader(res, "content-type", "application/x-www-form-urlencoded");
|
|
217
|
+
return body.toString();
|
|
218
|
+
}
|
|
219
|
+
if (body === void 0) {
|
|
220
|
+
return body;
|
|
221
|
+
}
|
|
222
|
+
if (result.response.status >= 300 && typeof body === "object" && body !== null && !Array.isArray(body)) {
|
|
223
|
+
throw new HttpException(body, result.response.status);
|
|
224
|
+
}
|
|
225
|
+
httpAdapter.setHeader(res, "content-type", "application/json");
|
|
226
|
+
return typeof body === "string" || body === null ? stringifyJSON(body) : body;
|
|
186
227
|
})
|
|
187
228
|
);
|
|
188
229
|
}
|
|
@@ -190,22 +231,41 @@ let ImplementInterceptor = class {
|
|
|
190
231
|
ImplementInterceptor = __decorateClass([
|
|
191
232
|
Injectable(),
|
|
192
233
|
__decorateParam(0, Inject(ORPC_MODULE_CONFIG_SYMBOL)),
|
|
193
|
-
__decorateParam(0, Optional())
|
|
234
|
+
__decorateParam(0, Optional()),
|
|
235
|
+
__decorateParam(1, Inject(HttpAdapterHost))
|
|
194
236
|
], ImplementInterceptor);
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
237
|
+
function flattenParamValue(value2) {
|
|
238
|
+
return Array.isArray(value2) ? value2.join("/") : value2;
|
|
239
|
+
}
|
|
240
|
+
function toORPCOpenAPIParams(contract, params) {
|
|
241
|
+
const meta = getOpenAPIMeta(contract);
|
|
242
|
+
if (!params || meta?.path === void 0) {
|
|
243
|
+
return void 0;
|
|
203
244
|
}
|
|
204
|
-
|
|
245
|
+
const dynamicParams = getDynamicPathParams(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
|
|
246
|
+
if (!dynamicParams) {
|
|
247
|
+
return void 0;
|
|
248
|
+
}
|
|
249
|
+
return dynamicParams.reduce((acc, config) => {
|
|
250
|
+
const value2 = config.allowsSlash ? flattenParamValue(params?.["*"] ?? params?.path) : flattenParamValue(params?.[config.parameterName]);
|
|
251
|
+
if (value2 === void 0) {
|
|
252
|
+
return acc;
|
|
253
|
+
}
|
|
254
|
+
acc[config.parameterName] = value2;
|
|
255
|
+
return acc;
|
|
256
|
+
}, {});
|
|
205
257
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
258
|
+
function toNestPattern(path) {
|
|
259
|
+
const params = getDynamicPathParams(path);
|
|
260
|
+
if (!params?.length) {
|
|
261
|
+
return path;
|
|
262
|
+
}
|
|
263
|
+
for (let i = params.length - 1; i >= 0; i--) {
|
|
264
|
+
const param = params[i];
|
|
265
|
+
const pattern = param.allowsSlash ? `*` : `:${param.parameterName}`;
|
|
266
|
+
path = path.slice(0, param.startIndex) + pattern + path.slice(param.startIndex + param.segment.length);
|
|
267
|
+
}
|
|
268
|
+
return path;
|
|
209
269
|
}
|
|
210
270
|
|
|
211
|
-
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL
|
|
271
|
+
export { Implement as Impl, Implement, ImplementInterceptor, ORPCModule, ORPC_MODULE_CONFIG_SYMBOL };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/nest",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.14.
|
|
4
|
+
"version": "1.14.11",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://orpc.dev",
|
|
7
7
|
"repository": {
|
|
@@ -9,11 +9,9 @@
|
|
|
9
9
|
"url": "git+https://github.com/middleapi/orpc.git",
|
|
10
10
|
"directory": "packages/nest"
|
|
11
11
|
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"orpc"
|
|
14
|
-
],
|
|
15
12
|
"sideEffects": false,
|
|
16
13
|
"exports": {
|
|
14
|
+
"./package.json": "./package.json",
|
|
17
15
|
".": {
|
|
18
16
|
"types": "./dist/index.d.mts",
|
|
19
17
|
"import": "./dist/index.mjs",
|
|
@@ -24,11 +22,11 @@
|
|
|
24
22
|
"dist"
|
|
25
23
|
],
|
|
26
24
|
"peerDependencies": {
|
|
27
|
-
"@nestjs/common": ">=11.
|
|
28
|
-
"@nestjs/core": ">=11.
|
|
29
|
-
"express": ">=5.
|
|
30
|
-
"fastify": ">=5.
|
|
31
|
-
"rxjs": ">=7.
|
|
25
|
+
"@nestjs/common": ">=11.1.27",
|
|
26
|
+
"@nestjs/core": ">=11.1.27",
|
|
27
|
+
"express": ">=5.2.1",
|
|
28
|
+
"fastify": ">=5.8.5",
|
|
29
|
+
"rxjs": ">=7.8.2"
|
|
32
30
|
},
|
|
33
31
|
"peerDependenciesMeta": {
|
|
34
32
|
"express": {
|
|
@@ -39,39 +37,28 @@
|
|
|
39
37
|
}
|
|
40
38
|
},
|
|
41
39
|
"dependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@orpc/
|
|
45
|
-
"@orpc/
|
|
46
|
-
"@orpc/
|
|
47
|
-
"@orpc/
|
|
48
|
-
"@orpc/
|
|
49
|
-
"@orpc/standard-server-fastify": "1.14.9",
|
|
50
|
-
"@orpc/standard-server-fetch": "1.14.9",
|
|
51
|
-
"@orpc/standard-server-node": "1.14.9"
|
|
40
|
+
"@standardserver/core": "^0.5.0",
|
|
41
|
+
"@standardserver/node": "^0.5.0",
|
|
42
|
+
"@orpc/client": "1.14.11",
|
|
43
|
+
"@orpc/openapi": "1.14.11",
|
|
44
|
+
"@orpc/contract": "1.14.11",
|
|
45
|
+
"@orpc/server": "1.14.11",
|
|
46
|
+
"@orpc/shared": "1.14.11"
|
|
52
47
|
},
|
|
53
48
|
"devDependencies": {
|
|
54
49
|
"@fastify/cookie": "^11.0.2",
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@nestjs/
|
|
58
|
-
"@nestjs/
|
|
59
|
-
"@nestjs/
|
|
60
|
-
"@nestjs/platform-fastify": "^11.1.16",
|
|
61
|
-
"@nestjs/testing": "^11.1.16",
|
|
62
|
-
"@ts-rest/core": "^3.52.1",
|
|
50
|
+
"@nestjs/common": "^11.1.27",
|
|
51
|
+
"@nestjs/core": "^11.1.27",
|
|
52
|
+
"@nestjs/platform-express": "^11.1.27",
|
|
53
|
+
"@nestjs/platform-fastify": "^11.1.27",
|
|
54
|
+
"@nestjs/testing": "^11.1.27",
|
|
63
55
|
"@types/express": "^5.0.6",
|
|
64
56
|
"express": "^5.2.1",
|
|
65
|
-
"fastify": "^5.8.
|
|
66
|
-
"
|
|
67
|
-
"rxjs": "^7.8.2",
|
|
68
|
-
"supertest": "^7.1.4",
|
|
69
|
-
"zod": "^4.3.6"
|
|
57
|
+
"fastify": "^5.8.5",
|
|
58
|
+
"rxjs": "^7.8.2"
|
|
70
59
|
},
|
|
71
60
|
"scripts": {
|
|
72
61
|
"build": "unbuild",
|
|
73
|
-
"
|
|
74
|
-
"type:check": "tsc -b",
|
|
75
|
-
"type:check:test": "tsc -p tsconfig.test.json --noEmit"
|
|
62
|
+
"type:check": "tsc -b"
|
|
76
63
|
}
|
|
77
64
|
}
|