@orpc/nest 0.0.0 → 0.0.2
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 +55 -1
- package/dist/index.d.mts +28 -9
- package/dist/index.d.ts +28 -9
- package/dist/index.mjs +88 -150
- package/package.json +17 -12
package/README.md
CHANGED
@@ -63,7 +63,61 @@ You can find the full documentation [here](https://orpc.unnoq.com).
|
|
63
63
|
|
64
64
|
## `@orpc/nest`
|
65
65
|
|
66
|
-
Deeply integrate oRPC with [NestJS](https://nestjs.com/).
|
66
|
+
Deeply integrate oRPC with [NestJS](https://nestjs.com/). Read the [documentation](https://orpc.unnoq.com/docs/openapi/nest/implement-contract) for more information.
|
67
|
+
|
68
|
+
### Implement Contract
|
69
|
+
|
70
|
+
An overview of how to implement an [oRPC contract](https://orpc.unnoq.com/docs/contract-first/define-contract) in NestJS.
|
71
|
+
|
72
|
+
```ts
|
73
|
+
import { Implement, implement, ORPCError } from '@orpc/nest'
|
74
|
+
|
75
|
+
@Controller()
|
76
|
+
export class PlanetController {
|
77
|
+
/**
|
78
|
+
* Implement a standalone procedure
|
79
|
+
*/
|
80
|
+
@Implement(contract.planet.list)
|
81
|
+
list() {
|
82
|
+
return implement(contract.planet.list).handler(({ input }) => {
|
83
|
+
// Implement logic here
|
84
|
+
|
85
|
+
return []
|
86
|
+
})
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Implement entire a contract
|
91
|
+
*/
|
92
|
+
@Implement(contract.planet)
|
93
|
+
planet() {
|
94
|
+
return {
|
95
|
+
list: implement(contract.planet.list).handler(({ input }) => {
|
96
|
+
// Implement logic here
|
97
|
+
return []
|
98
|
+
}),
|
99
|
+
find: implement(contract.planet.find).handler(({ input }) => {
|
100
|
+
// Implement logic here
|
101
|
+
return {
|
102
|
+
id: 1,
|
103
|
+
name: 'Earth',
|
104
|
+
description: 'The planet Earth',
|
105
|
+
}
|
106
|
+
}),
|
107
|
+
create: implement(contract.planet.create).handler(({ input }) => {
|
108
|
+
// Implement logic here
|
109
|
+
return {
|
110
|
+
id: 1,
|
111
|
+
name: 'Earth',
|
112
|
+
description: 'The planet Earth',
|
113
|
+
}
|
114
|
+
}),
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
// other handlers...
|
119
|
+
}
|
120
|
+
```
|
67
121
|
|
68
122
|
## Sponsors
|
69
123
|
|
package/dist/index.d.mts
CHANGED
@@ -1,17 +1,36 @@
|
|
1
|
-
import { AnyContractProcedure, HTTPPath, AnyContractRouter } from '@orpc/contract';
|
2
|
-
import { BuilderConfig, ImplementerInternal } from '@orpc/server';
|
3
|
-
export { ORPCError } from '@orpc/server';
|
4
1
|
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
2
|
+
import { ContractRouter, HTTPPath, AnyContractRouter, ContractProcedure } from '@orpc/contract';
|
3
|
+
import { Router } from '@orpc/server';
|
4
|
+
export { ImplementedProcedure, Implementer, ImplementerInternal, ImplementerInternalWithMiddlewares, ORPCError, ProcedureImplementer, RouterImplementer, RouterImplementerWithMiddlewares, implement } from '@orpc/server';
|
5
|
+
import { Promisable } from '@orpc/shared';
|
5
6
|
import { Observable } from 'rxjs';
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
/**
|
9
|
+
* Decorator in controller handler to implement a oRPC contract.
|
10
|
+
*
|
11
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/nest/implement-contract#implement-your-contract NestJS Implement Contract Docs}
|
12
|
+
*/
|
13
|
+
declare function Implement<T extends ContractRouter<any>>(contract: T): <U extends Promisable<Router<T, Record<never, never>>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
9
14
|
declare class ImplementInterceptor implements NestInterceptor {
|
10
15
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
11
16
|
}
|
12
17
|
|
13
|
-
declare function
|
14
|
-
|
15
|
-
|
18
|
+
declare function toNestPattern(path: HTTPPath): string;
|
19
|
+
type PopulatedContractRouterPaths<T extends AnyContractRouter> = T extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrors, infer UMeta> ? ContractProcedure<UInputSchema, UOutputSchema, UErrors, UMeta> : {
|
20
|
+
[K in keyof T]: T[K] extends AnyContractRouter ? PopulatedContractRouterPaths<T[K]> : never;
|
21
|
+
};
|
22
|
+
interface PopulateContractRouterPathsOptions {
|
23
|
+
path?: readonly string[];
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* populateContractRouterPaths is completely optional,
|
27
|
+
* because the procedure's path is required for NestJS implementation.
|
28
|
+
* This utility automatically populates any missing paths
|
29
|
+
* Using the router's keys + `/`.
|
30
|
+
*
|
31
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/nest/implement-contract#define-your-contract NestJS Implement Contract Docs}
|
32
|
+
*/
|
33
|
+
declare function populateContractRouterPaths<T extends AnyContractRouter>(router: T, options?: PopulateContractRouterPathsOptions): PopulatedContractRouterPaths<T>;
|
16
34
|
|
17
|
-
export { Implement, ImplementInterceptor,
|
35
|
+
export { Implement as Impl, Implement, ImplementInterceptor, populateContractRouterPaths, toNestPattern };
|
36
|
+
export type { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths };
|
package/dist/index.d.ts
CHANGED
@@ -1,17 +1,36 @@
|
|
1
|
-
import { AnyContractProcedure, HTTPPath, AnyContractRouter } from '@orpc/contract';
|
2
|
-
import { BuilderConfig, ImplementerInternal } from '@orpc/server';
|
3
|
-
export { ORPCError } from '@orpc/server';
|
4
1
|
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
2
|
+
import { ContractRouter, HTTPPath, AnyContractRouter, ContractProcedure } from '@orpc/contract';
|
3
|
+
import { Router } from '@orpc/server';
|
4
|
+
export { ImplementedProcedure, Implementer, ImplementerInternal, ImplementerInternalWithMiddlewares, ORPCError, ProcedureImplementer, RouterImplementer, RouterImplementerWithMiddlewares, implement } from '@orpc/server';
|
5
|
+
import { Promisable } from '@orpc/shared';
|
5
6
|
import { Observable } from 'rxjs';
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
/**
|
9
|
+
* Decorator in controller handler to implement a oRPC contract.
|
10
|
+
*
|
11
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/nest/implement-contract#implement-your-contract NestJS Implement Contract Docs}
|
12
|
+
*/
|
13
|
+
declare function Implement<T extends ContractRouter<any>>(contract: T): <U extends Promisable<Router<T, Record<never, never>>>>(target: Record<PropertyKey, any>, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => U>) => void;
|
9
14
|
declare class ImplementInterceptor implements NestInterceptor {
|
10
15
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
11
16
|
}
|
12
17
|
|
13
|
-
declare function
|
14
|
-
|
15
|
-
|
18
|
+
declare function toNestPattern(path: HTTPPath): string;
|
19
|
+
type PopulatedContractRouterPaths<T extends AnyContractRouter> = T extends ContractProcedure<infer UInputSchema, infer UOutputSchema, infer UErrors, infer UMeta> ? ContractProcedure<UInputSchema, UOutputSchema, UErrors, UMeta> : {
|
20
|
+
[K in keyof T]: T[K] extends AnyContractRouter ? PopulatedContractRouterPaths<T[K]> : never;
|
21
|
+
};
|
22
|
+
interface PopulateContractRouterPathsOptions {
|
23
|
+
path?: readonly string[];
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* populateContractRouterPaths is completely optional,
|
27
|
+
* because the procedure's path is required for NestJS implementation.
|
28
|
+
* This utility automatically populates any missing paths
|
29
|
+
* Using the router's keys + `/`.
|
30
|
+
*
|
31
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/nest/implement-contract#define-your-contract NestJS Implement Contract Docs}
|
32
|
+
*/
|
33
|
+
declare function populateContractRouterPaths<T extends AnyContractRouter>(router: T, options?: PopulateContractRouterPathsOptions): PopulatedContractRouterPaths<T>;
|
16
34
|
|
17
|
-
export { Implement, ImplementInterceptor,
|
35
|
+
export { Implement as Impl, Implement, ImplementInterceptor, populateContractRouterPaths, toNestPattern };
|
36
|
+
export type { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths };
|
package/dist/index.mjs
CHANGED
@@ -1,133 +1,87 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer, standardizeHTTPPath } from '@orpc/openapi-client/standard';
|
1
|
+
import { applyDecorators, Delete, Patch, Put, Post, Get, Head, UseInterceptors } from '@nestjs/common';
|
2
|
+
import { toORPCError } from '@orpc/client';
|
3
|
+
import { isContractProcedure, ContractProcedure, fallbackContractConfig } from '@orpc/contract';
|
4
|
+
import { standardizeHTTPPath, StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer } from '@orpc/openapi-client/standard';
|
6
5
|
import { StandardOpenAPICodec } from '@orpc/openapi/standard';
|
6
|
+
import { getRouter, unlazy, isProcedure, createProcedureClient, ORPCError } from '@orpc/server';
|
7
|
+
export { ORPCError, implement } from '@orpc/server';
|
8
|
+
import { toArray, get } from '@orpc/shared';
|
9
|
+
import { flattenHeader } from '@orpc/standard-server';
|
7
10
|
import { toStandardLazyRequest, sendStandardResponse } from '@orpc/standard-server-node';
|
8
11
|
import { mergeMap } from 'rxjs';
|
9
|
-
import '@orpc/
|
12
|
+
import { toHttpPath } from '@orpc/client/standard';
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
status: 400,
|
14
|
-
message: "Bad Request"
|
15
|
-
},
|
16
|
-
UNAUTHORIZED: {
|
17
|
-
status: 401,
|
18
|
-
message: "Unauthorized"
|
19
|
-
},
|
20
|
-
FORBIDDEN: {
|
21
|
-
status: 403,
|
22
|
-
message: "Forbidden"
|
23
|
-
},
|
24
|
-
NOT_FOUND: {
|
25
|
-
status: 404,
|
26
|
-
message: "Not Found"
|
27
|
-
},
|
28
|
-
METHOD_NOT_SUPPORTED: {
|
29
|
-
status: 405,
|
30
|
-
message: "Method Not Supported"
|
31
|
-
},
|
32
|
-
NOT_ACCEPTABLE: {
|
33
|
-
status: 406,
|
34
|
-
message: "Not Acceptable"
|
35
|
-
},
|
36
|
-
TIMEOUT: {
|
37
|
-
status: 408,
|
38
|
-
message: "Request Timeout"
|
39
|
-
},
|
40
|
-
CONFLICT: {
|
41
|
-
status: 409,
|
42
|
-
message: "Conflict"
|
43
|
-
},
|
44
|
-
PRECONDITION_FAILED: {
|
45
|
-
status: 412,
|
46
|
-
message: "Precondition Failed"
|
47
|
-
},
|
48
|
-
PAYLOAD_TOO_LARGE: {
|
49
|
-
status: 413,
|
50
|
-
message: "Payload Too Large"
|
51
|
-
},
|
52
|
-
UNSUPPORTED_MEDIA_TYPE: {
|
53
|
-
status: 415,
|
54
|
-
message: "Unsupported Media Type"
|
55
|
-
},
|
56
|
-
UNPROCESSABLE_CONTENT: {
|
57
|
-
status: 422,
|
58
|
-
message: "Unprocessable Content"
|
59
|
-
},
|
60
|
-
TOO_MANY_REQUESTS: {
|
61
|
-
status: 429,
|
62
|
-
message: "Too Many Requests"
|
63
|
-
},
|
64
|
-
CLIENT_CLOSED_REQUEST: {
|
65
|
-
status: 499,
|
66
|
-
message: "Client Closed Request"
|
67
|
-
},
|
68
|
-
INTERNAL_SERVER_ERROR: {
|
69
|
-
status: 500,
|
70
|
-
message: "Internal Server Error"
|
71
|
-
},
|
72
|
-
NOT_IMPLEMENTED: {
|
73
|
-
status: 501,
|
74
|
-
message: "Not Implemented"
|
75
|
-
},
|
76
|
-
BAD_GATEWAY: {
|
77
|
-
status: 502,
|
78
|
-
message: "Bad Gateway"
|
79
|
-
},
|
80
|
-
SERVICE_UNAVAILABLE: {
|
81
|
-
status: 503,
|
82
|
-
message: "Service Unavailable"
|
83
|
-
},
|
84
|
-
GATEWAY_TIMEOUT: {
|
85
|
-
status: 504,
|
86
|
-
message: "Gateway Timeout"
|
87
|
-
}
|
88
|
-
};
|
89
|
-
function fallbackORPCErrorStatus(code, status) {
|
90
|
-
return status ?? COMMON_ORPC_ERROR_DEFS[code]?.status ?? 500;
|
91
|
-
}
|
92
|
-
function fallbackORPCErrorMessage(code, message) {
|
93
|
-
return message || COMMON_ORPC_ERROR_DEFS[code]?.message || code;
|
14
|
+
function toNestPattern(path) {
|
15
|
+
return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/*$1").replace(/\/\{([^}]+)\}/g, "/:$1");
|
94
16
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
17
|
+
function populateContractRouterPaths(router, options = {}) {
|
18
|
+
const path = toArray(options.path);
|
19
|
+
if (isContractProcedure(router)) {
|
20
|
+
if (router["~orpc"].route.path === void 0) {
|
21
|
+
return new ContractProcedure({
|
22
|
+
...router["~orpc"],
|
23
|
+
route: {
|
24
|
+
...router["~orpc"].route,
|
25
|
+
path: toHttpPath(path)
|
26
|
+
}
|
27
|
+
});
|
103
28
|
}
|
104
|
-
|
105
|
-
super(message, options);
|
106
|
-
this.code = code;
|
107
|
-
this.status = fallbackORPCErrorStatus(code, options?.status);
|
108
|
-
this.defined = options?.defined ?? false;
|
109
|
-
this.data = options?.data;
|
29
|
+
return router;
|
110
30
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
code: this.code,
|
115
|
-
status: this.status,
|
116
|
-
message: this.message,
|
117
|
-
data: this.data
|
118
|
-
};
|
31
|
+
const populated = {};
|
32
|
+
for (const key in router) {
|
33
|
+
populated[key] = populateContractRouterPaths(router[key], { ...options, path: [...path, key] });
|
119
34
|
}
|
120
|
-
|
121
|
-
function toORPCError(error) {
|
122
|
-
return error instanceof ORPCError ? error : new ORPCError("INTERNAL_SERVER_ERROR", {
|
123
|
-
message: "Internal server error",
|
124
|
-
cause: error
|
125
|
-
});
|
126
|
-
}
|
127
|
-
function isORPCErrorStatus(status) {
|
128
|
-
return status < 200 || status >= 400;
|
35
|
+
return populated;
|
129
36
|
}
|
130
37
|
|
38
|
+
const MethodDecoratorMap = {
|
39
|
+
HEAD: Head,
|
40
|
+
GET: Get,
|
41
|
+
POST: Post,
|
42
|
+
PUT: Put,
|
43
|
+
PATCH: Patch,
|
44
|
+
DELETE: Delete
|
45
|
+
};
|
46
|
+
function Implement(contract) {
|
47
|
+
if (isContractProcedure(contract)) {
|
48
|
+
const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
|
49
|
+
const path = contract["~orpc"].route.path;
|
50
|
+
if (path === void 0) {
|
51
|
+
throw new Error(`
|
52
|
+
@Implement decorator requires contract to have a 'path'.
|
53
|
+
Please define one using 'path' property on the '.route' method.
|
54
|
+
Or use "populateContractRouterPaths" utility to automatically fill in any missing paths.
|
55
|
+
`);
|
56
|
+
}
|
57
|
+
return (target, propertyKey, descriptor) => {
|
58
|
+
applyDecorators(
|
59
|
+
MethodDecoratorMap[method](toNestPattern(path)),
|
60
|
+
UseInterceptors(ImplementInterceptor)
|
61
|
+
)(target, propertyKey, descriptor);
|
62
|
+
};
|
63
|
+
}
|
64
|
+
return (target, propertyKey, descriptor) => {
|
65
|
+
for (const key in contract) {
|
66
|
+
let methodName = `${propertyKey}_${key}`;
|
67
|
+
let i = 0;
|
68
|
+
while (methodName in target) {
|
69
|
+
methodName = `${propertyKey}_${key}_${i++}`;
|
70
|
+
}
|
71
|
+
target[methodName] = async function(...args) {
|
72
|
+
const router = await descriptor.value.apply(this, args);
|
73
|
+
return getRouter(router, [key]);
|
74
|
+
};
|
75
|
+
for (const p of Reflect.getOwnMetadataKeys(target, propertyKey)) {
|
76
|
+
Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target, propertyKey), target, methodName);
|
77
|
+
}
|
78
|
+
for (const p of Reflect.getOwnMetadataKeys(target.constructor, propertyKey)) {
|
79
|
+
Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target.constructor, propertyKey), target.constructor, methodName);
|
80
|
+
}
|
81
|
+
Implement(get(contract, [key]))(target, methodName, Object.getOwnPropertyDescriptor(target, methodName));
|
82
|
+
}
|
83
|
+
};
|
84
|
+
}
|
131
85
|
const codec = new StandardOpenAPICodec(
|
132
86
|
new StandardOpenAPISerializer(
|
133
87
|
new StandardOpenAPIJsonSerializer(),
|
@@ -137,7 +91,13 @@ const codec = new StandardOpenAPICodec(
|
|
137
91
|
class ImplementInterceptor {
|
138
92
|
intercept(ctx, next) {
|
139
93
|
return next.handle().pipe(
|
140
|
-
mergeMap(async (
|
94
|
+
mergeMap(async (impl) => {
|
95
|
+
const { default: procedure } = await unlazy(impl);
|
96
|
+
if (!isProcedure(procedure)) {
|
97
|
+
throw new Error(`
|
98
|
+
The return value of the @Implement controller handler must be a corresponding implemented router or procedure.
|
99
|
+
`);
|
100
|
+
}
|
141
101
|
const req = ctx.switchToHttp().getRequest();
|
142
102
|
const res = ctx.switchToHttp().getResponse();
|
143
103
|
const nodeReq = "raw" in req ? req.raw : req;
|
@@ -148,13 +108,17 @@ class ImplementInterceptor {
|
|
148
108
|
const standardResponse = await (async () => {
|
149
109
|
let isDecoding = false;
|
150
110
|
try {
|
111
|
+
const client = createProcedureClient(procedure);
|
151
112
|
isDecoding = true;
|
152
113
|
const input = await codec.decode(standardRequest, flattenParams(req.params), procedure);
|
153
114
|
isDecoding = false;
|
154
|
-
const output = await
|
115
|
+
const output = await client(input, {
|
116
|
+
signal: standardRequest.signal,
|
117
|
+
lastEventId: flattenHeader(standardRequest.headers["last-event-id"])
|
118
|
+
});
|
155
119
|
return codec.encode(output, procedure);
|
156
120
|
} catch (e) {
|
157
|
-
const error = isDecoding && !(e instanceof ORPCError
|
121
|
+
const error = isDecoding && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
|
158
122
|
message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
|
159
123
|
cause: e
|
160
124
|
}) : toORPCError(e);
|
@@ -178,30 +142,4 @@ function flattenParams(params) {
|
|
178
142
|
return flatten;
|
179
143
|
}
|
180
144
|
|
181
|
-
|
182
|
-
return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/*$1").replace(/\/\{([^}]+)\}/g, "/:$1");
|
183
|
-
}
|
184
|
-
|
185
|
-
function Implement(contract) {
|
186
|
-
const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
|
187
|
-
const path = contract["~orpc"].route.path;
|
188
|
-
if (path === void 0) {
|
189
|
-
throw new Error(`
|
190
|
-
oRPC Fastify integration requires procedure to have a 'path'.
|
191
|
-
Please define one using 'path' property on the '.route' method.
|
192
|
-
`);
|
193
|
-
}
|
194
|
-
return (target, propertyKey, descriptor) => {
|
195
|
-
const MethodDecorator = method === "GET" ? Get : method === "HEAD" ? Head : method === "PUT" ? Put : method === "PATCH" ? Patch : method === "DELETE" ? Delete : Post;
|
196
|
-
applyDecorators(
|
197
|
-
MethodDecorator(toFastifyPattern(path)),
|
198
|
-
UseInterceptors(ImplementInterceptor)
|
199
|
-
)(target, propertyKey, descriptor);
|
200
|
-
};
|
201
|
-
}
|
202
|
-
|
203
|
-
function implement(contract, config = {}) {
|
204
|
-
return implementerInternal(contract, config, []);
|
205
|
-
}
|
206
|
-
|
207
|
-
export { Implement, ImplementInterceptor, implement, toFastifyPattern };
|
145
|
+
export { Implement as Impl, Implement, ImplementInterceptor, populateContractRouterPaths, toNestPattern };
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orpc/nest",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.0.
|
4
|
+
"version": "0.0.2",
|
5
5
|
"license": "MIT",
|
6
6
|
"homepage": "https://orpc.unnoq.com",
|
7
7
|
"repository": {
|
@@ -28,8 +28,7 @@
|
|
28
28
|
"@nestjs/core": ">=11.0.0",
|
29
29
|
"express": ">=5.0.0",
|
30
30
|
"fastify": ">=5.0.0",
|
31
|
-
"rxjs": ">=7.0.0"
|
32
|
-
"@orpc/contract": "1.2.0"
|
31
|
+
"rxjs": ">=7.0.0"
|
33
32
|
},
|
34
33
|
"peerDependenciesMeta": {
|
35
34
|
"express": {
|
@@ -40,27 +39,33 @@
|
|
40
39
|
}
|
41
40
|
},
|
42
41
|
"dependencies": {
|
43
|
-
"@orpc/openapi-client": "1.2.0",
|
44
|
-
"@orpc/server": "1.2.0",
|
45
42
|
"@orpc/client": "1.2.0",
|
43
|
+
"@orpc/openapi": "1.2.0",
|
46
44
|
"@orpc/shared": "1.2.0",
|
45
|
+
"@orpc/contract": "1.2.0",
|
46
|
+
"@orpc/openapi-client": "1.2.0",
|
47
|
+
"@orpc/server": "1.2.0",
|
47
48
|
"@orpc/standard-server": "1.2.0",
|
48
|
-
"@orpc/standard-server-node": "1.2.0"
|
49
|
-
"@orpc/openapi": "1.2.0"
|
49
|
+
"@orpc/standard-server-node": "1.2.0"
|
50
50
|
},
|
51
51
|
"devDependencies": {
|
52
|
-
"@nestjs/common": "^11.
|
52
|
+
"@nestjs/common": "^11.1.0",
|
53
53
|
"@nestjs/core": "^11.0.0",
|
54
|
-
"@nestjs/platform-express": "^11.
|
55
|
-
"@nestjs/platform-fastify": "^11.
|
54
|
+
"@nestjs/platform-express": "^11.1.0",
|
55
|
+
"@nestjs/platform-fastify": "^11.1.0",
|
56
|
+
"@nestjs/testing": "^11.1.0",
|
57
|
+
"@ts-rest/core": "^3.52.1",
|
56
58
|
"@types/express": "^5.0.1",
|
57
59
|
"express": "^5.0.0",
|
58
60
|
"fastify": "^5.0.0",
|
59
|
-
"rxjs": "^7.0.0"
|
61
|
+
"rxjs": "^7.0.0",
|
62
|
+
"supertest": "^7.1.0",
|
63
|
+
"zod": "^3.24.4"
|
60
64
|
},
|
61
65
|
"scripts": {
|
62
66
|
"build": "unbuild",
|
63
67
|
"build:watch": "pnpm run build --watch",
|
64
|
-
"type:check": "tsc -b"
|
68
|
+
"type:check": "tsc -b",
|
69
|
+
"type:check:test": "tsc -p tsconfig.test.json --noEmit"
|
65
70
|
}
|
66
71
|
}
|