@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 CHANGED
@@ -1,17 +1,16 @@
1
- <div align="center">
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/1.x/graph/badge.svg">
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://github.com/middleapi/orpc/blob/1.x/LICENSE">
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
- <h3 align="center">Typesafe APIs Made Simple 🪄</h3>
24
+ ## Documentation
26
25
 
27
- **oRPC is a powerful combination of RPC and OpenAPI**, makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards
26
+ You can read the documentation [here](https://orpc.dev).
28
27
 
29
- ---
28
+ ## Packages
30
29
 
31
- ## Highlights
30
+ **Core**
32
31
 
33
- - **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
34
- - **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
35
- - **📝 Contract-First Development**: Optionally define your API contract before implementation.
36
- - **🔍 First-Class OpenTelemetry**: Seamlessly integrate with OpenTelemetry for observability.
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
- ## Documentation
37
+ **Schema validation**
47
38
 
48
- You can find the full documentation [here](https://orpc.dev).
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
- ## Packages
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
- - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Build your API contract.
53
- - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build your API or implement API contract.
54
- - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume your API on the client with type-safety.
55
- - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
56
- - [@orpc/otel](https://www.npmjs.com/package/@orpc/otel): [OpenTelemetry](https://opentelemetry.io/) integration for observability.
57
- - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
58
- - [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
59
- - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
60
- - [@orpc/experimental-react-swr](https://www.npmjs.com/package/@orpc/experimental-react-swr): [SWR](https://swr.vercel.app/) integration.
61
- - [@orpc/vue-colada](https://www.npmjs.com/package/@orpc/vue-colada): Integration with [Pinia Colada](https://pinia-colada.esm.dev/).
62
- - [@orpc/hey-api](https://www.npmjs.com/package/@orpc/hey-api): [Hey API](https://heyapi.dev/) integration.
63
- - [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): More schemas that [Zod](https://zod.dev/) doesn't support yet.
64
- - [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): OpenAPI spec generation from [Valibot](https://valibot.dev/).
65
- - [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): OpenAPI spec generation from [ArkType](https://arktype.io/).
66
-
67
- ## `@orpc/nest`
68
-
69
- Deeply integrate oRPC with [NestJS](https://nestjs.com/). Read the [documentation](https://orpc.dev/docs/openapi/integrations/implement-contract-in-nest) for more information.
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
- If you find oRPC valuable and would like to support its development, you can do so here: [GitHub Sponsors](https://github.com/sponsors/dinwwwh).
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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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/1.x/LICENSE) for more information.
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 { AnySchema, ContractRouter, HTTPPath, AnyContractRouter } from '@orpc/contract';
2
- export { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths, populateContractRouterPaths } from '@orpc/contract';
3
- import { CreateProcedureClientOptions, Router, Context, BuilderConfig, Implementer } from '@orpc/server';
4
- export { ImplementedProcedure, Implementer, ImplementerInternal, ImplementerInternalWithMiddlewares, ORPCError, ProcedureImplementer, RouterImplementer, RouterImplementerWithMiddlewares, onError, onFinish, onStart, onSuccess } from '@orpc/server';
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
- * You can extend this interface to add global context properties.
17
- * @example
18
- * ```ts
19
- * declare module '@orpc/nest' {
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
- constructor(config: ORPCModuleConfig | undefined);
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
- declare function toNestPattern(path: HTTPPath): string;
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 { AnySchema, ContractRouter, HTTPPath, AnyContractRouter } from '@orpc/contract';
2
- export { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths, populateContractRouterPaths } from '@orpc/contract';
3
- import { CreateProcedureClientOptions, Router, Context, BuilderConfig, Implementer } from '@orpc/server';
4
- export { ImplementedProcedure, Implementer, ImplementerInternal, ImplementerInternalWithMiddlewares, ORPCError, ProcedureImplementer, RouterImplementer, RouterImplementerWithMiddlewares, onError, onFinish, onStart, onSuccess } from '@orpc/server';
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
- * You can extend this interface to add global context properties.
17
- * @example
18
- * ```ts
19
- * declare module '@orpc/nest' {
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
- constructor(config: ORPCModuleConfig | undefined);
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
- declare function toNestPattern(path: HTTPPath): string;
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 { getRouter, unlazy, isProcedure, implement as implement$1 } from '@orpc/server';
2
- export { ORPCError, onError, onFinish, onStart, onSuccess } from '@orpc/server';
3
- import { Module, applyDecorators, Options, Delete, Patch, Put, Post, Get, Head, HttpCode, UseInterceptors, Injectable, Inject, Optional } from '@nestjs/common';
4
- import { isContractProcedure, fallbackContractConfig } from '@orpc/contract';
5
- export { populateContractRouterPaths } from '@orpc/contract';
6
- import { standardizeHTTPPath, StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer } from '@orpc/openapi-client/standard';
7
- import { StandardOpenAPICodec } from '@orpc/openapi/standard';
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 { get, toArray, intercept } from '@orpc/shared';
10
- import * as StandardServerFastify from '@orpc/standard-server-fastify';
11
- import * as StandardServerFetch from '@orpc/standard-server-fetch';
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("ORPC_MODULE_CONFIG");
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 (isContractProcedure(contract)) {
84
- const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
85
- const path = contract["~orpc"].route.path;
86
- if (path === void 0) {
87
- throw new Error(`
88
- @Implement decorator requires contract to have a 'path'.
89
- Please define one using 'path' property on the '.route' method.
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](toNestPattern(path)),
96
- HttpCode(fallbackContractConfig("defaultSuccessStatus", contract["~orpc"].route.successStatus)),
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(get(contract, [key]))(target, methodName, Object.getOwnPropertyDescriptor(target, methodName));
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
- constructor(config) {
122
+ toNestStandardLazyRequest;
123
+ httpAdapterHost;
124
+ constructor(config, httpAdapterHost) {
126
125
  this.config = config ?? {};
127
- this.codec = new StandardOpenAPICodec(
128
- new StandardOpenAPISerializer(
129
- new StandardOpenAPIJsonSerializer(this.config),
130
- new StandardBracketNotationSerializer(this.config)
131
- ),
132
- this.config
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 (!isProcedure(procedure)) {
140
- throw new Error(`
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 isHono = "finalized" in res && typeof res.newResponse === "function";
147
- const isFastify = "raw" in req && !isHono;
148
- const standardRequest = (() => {
149
- if (isHono) {
150
- return StandardServerFetch.toStandardLazyRequest(req.raw);
151
- }
152
- if (isFastify) {
153
- return StandardServerFastify.toStandardLazyRequest(req, res);
154
- }
155
- return StandardServerNode.toStandardLazyRequest(req, res);
156
- })();
157
- const handler = new StandardHandler(procedure, {
158
- init: () => {
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
- return intercept(
172
- toArray(this.config.sendResponseInterceptors),
173
- { request: req, response: res, standardResponse: result.response },
174
- async ({ response, standardResponse }) => {
175
- if (isHono) {
176
- const fetchResponse = StandardServerFetch.toFetchResponse(standardResponse, this.config);
177
- return response.newResponse(fetchResponse.body, fetchResponse);
178
- } else if (isFastify) {
179
- await StandardServerFastify.sendStandardResponse(response, standardResponse, this.config);
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
- await StandardServerNode.sendStandardResponse(response, standardResponse, this.config);
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 flattenParams(params) {
196
- const flatten = {};
197
- for (const [key, value] of Object.entries(params ?? {})) {
198
- if (Array.isArray(value)) {
199
- flatten[key] = value.join("/");
200
- } else {
201
- flatten[key] = value;
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
- return flatten;
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
- function implement(contract, config = {}) {
208
- return implement$1(contract, config);
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, implement, toNestPattern };
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.9",
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.0.0",
28
- "@nestjs/core": ">=11.0.0",
29
- "express": ">=5.0.0",
30
- "fastify": ">=5.0.0",
31
- "rxjs": ">=7.0.0"
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
- "@orpc/client": "1.14.9",
43
- "@orpc/openapi-client": "1.14.9",
44
- "@orpc/openapi": "1.14.9",
45
- "@orpc/server": "1.14.9",
46
- "@orpc/shared": "1.14.9",
47
- "@orpc/contract": "1.14.9",
48
- "@orpc/standard-server": "1.14.9",
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
- "@hono/node-server": "^1.19.11",
56
- "@mnigos/platform-hono": "^0.1.3",
57
- "@nestjs/common": "^11.1.16",
58
- "@nestjs/core": "^11.1.16",
59
- "@nestjs/platform-express": "^11.1.16",
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.3",
66
- "hono": "^4.10.7",
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
- "build:watch": "pnpm run build --watch",
74
- "type:check": "tsc -b",
75
- "type:check:test": "tsc -p tsconfig.test.json --noEmit"
62
+ "type:check": "tsc -b"
76
63
  }
77
64
  }