@orpc/nest 0.0.0-next.d888fab → 0.0.0
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 +1 -55
- package/dist/index.d.mts +9 -28
- package/dist/index.d.ts +9 -28
- package/dist/index.mjs +150 -88
- package/package.json +15 -20
package/README.md
CHANGED
@@ -63,61 +63,7 @@ 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/).
|
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
|
-
```
|
66
|
+
Deeply integrate oRPC with [NestJS](https://nestjs.com/).
|
121
67
|
|
122
68
|
## Sponsors
|
123
69
|
|
package/dist/index.d.mts
CHANGED
@@ -1,36 +1,17 @@
|
|
1
|
+
import { AnyContractProcedure, HTTPPath, AnyContractRouter } from '@orpc/contract';
|
2
|
+
import { BuilderConfig, ImplementerInternal } from '@orpc/server';
|
3
|
+
export { ORPCError } from '@orpc/server';
|
1
4
|
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';
|
6
5
|
import { Observable } from 'rxjs';
|
7
6
|
|
8
|
-
|
9
|
-
|
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;
|
7
|
+
declare function Implement(contract: AnyContractProcedure): MethodDecorator;
|
8
|
+
|
14
9
|
declare class ImplementInterceptor implements NestInterceptor {
|
15
10
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
16
11
|
}
|
17
12
|
|
18
|
-
declare function
|
19
|
-
|
20
|
-
|
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>;
|
13
|
+
declare function toFastifyPattern(path: HTTPPath): string;
|
14
|
+
|
15
|
+
declare function implement<T extends AnyContractRouter>(contract: T, config?: BuilderConfig): ImplementerInternal<T, Record<never, never>, Record<never, never>>;
|
34
16
|
|
35
|
-
export { Implement
|
36
|
-
export type { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths };
|
17
|
+
export { Implement, ImplementInterceptor, implement, toFastifyPattern };
|
package/dist/index.d.ts
CHANGED
@@ -1,36 +1,17 @@
|
|
1
|
+
import { AnyContractProcedure, HTTPPath, AnyContractRouter } from '@orpc/contract';
|
2
|
+
import { BuilderConfig, ImplementerInternal } from '@orpc/server';
|
3
|
+
export { ORPCError } from '@orpc/server';
|
1
4
|
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';
|
6
5
|
import { Observable } from 'rxjs';
|
7
6
|
|
8
|
-
|
9
|
-
|
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;
|
7
|
+
declare function Implement(contract: AnyContractProcedure): MethodDecorator;
|
8
|
+
|
14
9
|
declare class ImplementInterceptor implements NestInterceptor {
|
15
10
|
intercept(ctx: ExecutionContext, next: CallHandler<any>): Observable<any>;
|
16
11
|
}
|
17
12
|
|
18
|
-
declare function
|
19
|
-
|
20
|
-
|
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>;
|
13
|
+
declare function toFastifyPattern(path: HTTPPath): string;
|
14
|
+
|
15
|
+
declare function implement<T extends AnyContractRouter>(contract: T, config?: BuilderConfig): ImplementerInternal<T, Record<never, never>, Record<never, never>>;
|
34
16
|
|
35
|
-
export { Implement
|
36
|
-
export type { PopulateContractRouterPathsOptions, PopulatedContractRouterPaths };
|
17
|
+
export { Implement, ImplementInterceptor, implement, toFastifyPattern };
|
package/dist/index.mjs
CHANGED
@@ -1,87 +1,133 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import {
|
4
|
-
import {
|
1
|
+
import { call, ORPCError as ORPCError$1, implementerInternal } from '@orpc/server';
|
2
|
+
export { ORPCError } from '@orpc/server';
|
3
|
+
import { applyDecorators, Get, Head, Put, Patch, Delete, Post, UseInterceptors } from '@nestjs/common';
|
4
|
+
import { fallbackContractConfig } from '@orpc/contract';
|
5
|
+
import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer, standardizeHTTPPath } from '@orpc/openapi-client/standard';
|
5
6
|
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';
|
10
7
|
import { toStandardLazyRequest, sendStandardResponse } from '@orpc/standard-server-node';
|
11
8
|
import { mergeMap } from 'rxjs';
|
12
|
-
import
|
9
|
+
import '@orpc/shared';
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
}
|
31
|
-
|
32
|
-
|
33
|
-
|
11
|
+
const COMMON_ORPC_ERROR_DEFS = {
|
12
|
+
BAD_REQUEST: {
|
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"
|
34
87
|
}
|
35
|
-
return populated;
|
36
|
-
}
|
37
|
-
|
38
|
-
const MethodDecoratorMap = {
|
39
|
-
HEAD: Head,
|
40
|
-
GET: Get,
|
41
|
-
POST: Post,
|
42
|
-
PUT: Put,
|
43
|
-
PATCH: Patch,
|
44
|
-
DELETE: Delete
|
45
88
|
};
|
46
|
-
function
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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;
|
94
|
+
}
|
95
|
+
class ORPCError extends Error {
|
96
|
+
defined;
|
97
|
+
code;
|
98
|
+
status;
|
99
|
+
data;
|
100
|
+
constructor(code, ...[options]) {
|
101
|
+
if (options?.status && !isORPCErrorStatus(options.status)) {
|
102
|
+
throw new Error("[ORPCError] Invalid error status code.");
|
56
103
|
}
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
104
|
+
const message = fallbackORPCErrorMessage(code, options?.message);
|
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;
|
110
|
+
}
|
111
|
+
toJSON() {
|
112
|
+
return {
|
113
|
+
defined: this.defined,
|
114
|
+
code: this.code,
|
115
|
+
status: this.status,
|
116
|
+
message: this.message,
|
117
|
+
data: this.data
|
62
118
|
};
|
63
119
|
}
|
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
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;
|
129
|
+
}
|
130
|
+
|
85
131
|
const codec = new StandardOpenAPICodec(
|
86
132
|
new StandardOpenAPISerializer(
|
87
133
|
new StandardOpenAPIJsonSerializer(),
|
@@ -91,13 +137,7 @@ const codec = new StandardOpenAPICodec(
|
|
91
137
|
class ImplementInterceptor {
|
92
138
|
intercept(ctx, next) {
|
93
139
|
return next.handle().pipe(
|
94
|
-
mergeMap(async (
|
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
|
-
}
|
140
|
+
mergeMap(async (procedure) => {
|
101
141
|
const req = ctx.switchToHttp().getRequest();
|
102
142
|
const res = ctx.switchToHttp().getResponse();
|
103
143
|
const nodeReq = "raw" in req ? req.raw : req;
|
@@ -108,17 +148,13 @@ class ImplementInterceptor {
|
|
108
148
|
const standardResponse = await (async () => {
|
109
149
|
let isDecoding = false;
|
110
150
|
try {
|
111
|
-
const client = createProcedureClient(procedure);
|
112
151
|
isDecoding = true;
|
113
152
|
const input = await codec.decode(standardRequest, flattenParams(req.params), procedure);
|
114
153
|
isDecoding = false;
|
115
|
-
const output = await
|
116
|
-
signal: standardRequest.signal,
|
117
|
-
lastEventId: flattenHeader(standardRequest.headers["last-event-id"])
|
118
|
-
});
|
154
|
+
const output = await call(procedure, input);
|
119
155
|
return codec.encode(output, procedure);
|
120
156
|
} catch (e) {
|
121
|
-
const error = isDecoding && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
|
157
|
+
const error = isDecoding && !(e instanceof ORPCError$1) ? new ORPCError$1("BAD_REQUEST", {
|
122
158
|
message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
|
123
159
|
cause: e
|
124
160
|
}) : toORPCError(e);
|
@@ -142,4 +178,30 @@ function flattenParams(params) {
|
|
142
178
|
return flatten;
|
143
179
|
}
|
144
180
|
|
145
|
-
|
181
|
+
function toFastifyPattern(path) {
|
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 };
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orpc/nest",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.0.0
|
4
|
+
"version": "0.0.0",
|
5
5
|
"license": "MIT",
|
6
6
|
"homepage": "https://orpc.unnoq.com",
|
7
7
|
"repository": {
|
@@ -28,7 +28,8 @@
|
|
28
28
|
"@nestjs/core": ">=11.0.0",
|
29
29
|
"express": ">=5.0.0",
|
30
30
|
"fastify": ">=5.0.0",
|
31
|
-
"rxjs": ">=7.0.0"
|
31
|
+
"rxjs": ">=7.0.0",
|
32
|
+
"@orpc/contract": "1.2.0"
|
32
33
|
},
|
33
34
|
"peerDependenciesMeta": {
|
34
35
|
"express": {
|
@@ -39,33 +40,27 @@
|
|
39
40
|
}
|
40
41
|
},
|
41
42
|
"dependencies": {
|
42
|
-
"@orpc/client": "
|
43
|
-
"@orpc/
|
44
|
-
"@orpc/
|
45
|
-
"@orpc/
|
46
|
-
"@orpc/server": "
|
47
|
-
"@orpc/
|
48
|
-
"@orpc/
|
49
|
-
"@orpc/standard-server-node": "0.0.0-next.d888fab"
|
43
|
+
"@orpc/openapi-client": "1.2.0",
|
44
|
+
"@orpc/server": "1.2.0",
|
45
|
+
"@orpc/client": "1.2.0",
|
46
|
+
"@orpc/shared": "1.2.0",
|
47
|
+
"@orpc/standard-server": "1.2.0",
|
48
|
+
"@orpc/standard-server-node": "1.2.0",
|
49
|
+
"@orpc/openapi": "1.2.0"
|
50
50
|
},
|
51
51
|
"devDependencies": {
|
52
|
-
"@nestjs/common": "^11.
|
52
|
+
"@nestjs/common": "^11.0.0",
|
53
53
|
"@nestjs/core": "^11.0.0",
|
54
|
-
"@nestjs/platform-express": "^11.
|
55
|
-
"@nestjs/platform-fastify": "^11.
|
56
|
-
"@nestjs/testing": "^11.1.0",
|
57
|
-
"@ts-rest/core": "^3.52.1",
|
54
|
+
"@nestjs/platform-express": "^11.0.0",
|
55
|
+
"@nestjs/platform-fastify": "^11.0.0",
|
58
56
|
"@types/express": "^5.0.1",
|
59
57
|
"express": "^5.0.0",
|
60
58
|
"fastify": "^5.0.0",
|
61
|
-
"rxjs": "^7.0.0"
|
62
|
-
"supertest": "^7.1.0",
|
63
|
-
"zod": "^3.24.4"
|
59
|
+
"rxjs": "^7.0.0"
|
64
60
|
},
|
65
61
|
"scripts": {
|
66
62
|
"build": "unbuild",
|
67
63
|
"build:watch": "pnpm run build --watch",
|
68
|
-
"type:check": "tsc -b"
|
69
|
-
"type:check:test": "tsc -p tsconfig.test.json --noEmit"
|
64
|
+
"type:check": "tsc -b"
|
70
65
|
}
|
71
66
|
}
|