@bool-ts/core 2.2.4 → 2.3.1
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/dist/constants/index.d.ts +3 -0
- package/dist/constants/keys.d.ts +34 -0
- package/dist/constants/objects.d.ts +505 -0
- package/dist/decorators/arguments.d.ts +2 -3
- package/dist/decorators/container.d.ts +5 -1
- package/dist/decorators/controller.d.ts +1 -1
- package/dist/decorators/guard.d.ts +1 -1
- package/dist/decorators/inject.d.ts +1 -1
- package/dist/decorators/injectable.d.ts +1 -1
- package/dist/decorators/interceptor.d.ts +1 -1
- package/dist/decorators/middleware.d.ts +1 -1
- package/dist/decorators/module.d.ts +1 -1
- package/dist/decorators/webSocket.d.ts +1 -1
- package/dist/decorators/webSocketArguments.d.ts +1 -1
- package/dist/entities/application.d.ts +13 -83
- package/dist/entities/httpRoute.d.ts +0 -2
- package/dist/entities/httpRouter.d.ts +29 -3
- package/dist/entities/httpRouterGroup.d.ts +5 -1
- package/dist/entities/injector.d.ts +2 -2
- package/dist/http/clientError.d.ts +5 -35
- package/dist/http/serverError.d.ts +7 -19
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/index.js.map +31 -29
- package/dist/interfaces/@types.d.ts +114 -0
- package/dist/interfaces/guard.d.ts +2 -1
- package/dist/interfaces/index.d.ts +2 -1
- package/dist/producers/factory.d.ts +1 -1
- package/dist/utils/asyncFunction.d.ts +1 -0
- package/dist/utils/colors.d.ts +30 -0
- package/dist/utils/functions.d.ts +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/socket.d.ts +1 -0
- package/package.json +5 -4
- package/src/constants/index.ts +10 -0
- package/src/constants/objects.ts +291 -0
- package/src/decorators/arguments.ts +3 -5
- package/src/decorators/container.ts +40 -20
- package/src/decorators/controller.ts +2 -2
- package/src/decorators/guard.ts +2 -2
- package/src/decorators/http.ts +1 -1
- package/src/decorators/inject.ts +2 -2
- package/src/decorators/injectable.ts +2 -2
- package/src/decorators/interceptor.ts +2 -2
- package/src/decorators/middleware.ts +2 -2
- package/src/decorators/module.ts +2 -2
- package/src/decorators/webSocket.ts +2 -2
- package/src/decorators/webSocketArguments.ts +1 -1
- package/src/decorators/webSocketEvent.ts +1 -1
- package/src/entities/application.ts +1603 -1559
- package/src/entities/httpRoute.ts +1 -4
- package/src/entities/httpRouter.ts +36 -6
- package/src/entities/httpRouterGroup.ts +16 -5
- package/src/entities/injector.ts +3 -3
- package/src/http/clientError.ts +16 -39
- package/src/http/serverError.ts +17 -22
- package/src/index.ts +12 -2
- package/src/interfaces/@types.ts +171 -0
- package/src/interfaces/guard.ts +7 -1
- package/src/interfaces/index.ts +24 -1
- package/src/producers/factory.ts +1 -1
- package/src/utils/colors.ts +50 -0
- package/src/utils/constructor.ts +1 -0
- package/src/utils/functions.ts +13 -0
- package/src/{ultils → utils}/index.ts +1 -0
- package/src/ultils/colors.ts +0 -56
- /package/{src/ultils/constructor.ts → dist/utils/constructor.d.ts} +0 -0
- /package/src/{keys/index.ts → constants/keys.ts} +0 -0
- /package/src/{ultils → utils}/asyncFunction.ts +0 -0
- /package/src/{ultils → utils}/socket.ts +0 -0
|
@@ -1,26 +1,46 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Server, ServerWebSocket, WebSocketHandler } from "bun";
|
|
2
2
|
import type {
|
|
3
3
|
TArgumentsMetadataCollection,
|
|
4
4
|
TContainerMetadata,
|
|
5
5
|
TControllerMetadata,
|
|
6
6
|
TModuleMetadata,
|
|
7
7
|
TWebSocketEventHandlerMetadata,
|
|
8
|
-
TWebSocketMetadata
|
|
8
|
+
TWebSocketMetadata,
|
|
9
|
+
TWebSocketUpgradeData
|
|
9
10
|
} from "../decorators";
|
|
10
11
|
import type { THttpMethods } from "../http";
|
|
11
|
-
import type {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
import type {
|
|
13
|
+
IController,
|
|
14
|
+
ICustomValidator,
|
|
15
|
+
IGuard,
|
|
16
|
+
IInterceptor,
|
|
17
|
+
IMiddleware,
|
|
18
|
+
TApplicationOptions,
|
|
19
|
+
TCloseInterceptorHandlers,
|
|
20
|
+
TCloseInterceptorsPipe,
|
|
21
|
+
TControllerPipe,
|
|
22
|
+
TEndMiddlewareHandlers,
|
|
23
|
+
TEndMiddlewaresPipe,
|
|
24
|
+
TGuardHandlers,
|
|
25
|
+
TGuardReturn,
|
|
26
|
+
TGuardsPipe,
|
|
27
|
+
TOpenInterceptorHandlers,
|
|
28
|
+
TOpenInterceptorsPipe,
|
|
29
|
+
TParamsType,
|
|
30
|
+
TPipesEnforcerUnion,
|
|
31
|
+
TPreLaunch,
|
|
32
|
+
TResolutedOptions,
|
|
33
|
+
TStartMiddlewareHandlers,
|
|
34
|
+
TStartMiddlewaresPipe,
|
|
35
|
+
TStaticMap,
|
|
36
|
+
TValidator
|
|
37
|
+
} from "../interfaces";
|
|
38
|
+
import type { TConstructor } from "../utils";
|
|
14
39
|
|
|
15
40
|
import { ETimeUnit, add as TimeAdd } from "@bool-ts/date-time";
|
|
41
|
+
import { serve } from "bun";
|
|
16
42
|
import { parse as QsParse } from "qs";
|
|
17
|
-
import {
|
|
18
|
-
HttpClientError,
|
|
19
|
-
httpMethods,
|
|
20
|
-
httpMethodsStandardization,
|
|
21
|
-
HttpServerError,
|
|
22
|
-
jsonErrorInfer
|
|
23
|
-
} from "../http";
|
|
43
|
+
import { Objects } from "../constants";
|
|
24
44
|
import {
|
|
25
45
|
argumentsKey,
|
|
26
46
|
configKey,
|
|
@@ -47,8 +67,15 @@ import {
|
|
|
47
67
|
webSocketKey,
|
|
48
68
|
webSocketMessageArgsKey,
|
|
49
69
|
webSocketServerArgsKey
|
|
50
|
-
} from "../keys";
|
|
51
|
-
import {
|
|
70
|
+
} from "../constants/keys";
|
|
71
|
+
import {
|
|
72
|
+
HttpClientError,
|
|
73
|
+
httpMethods,
|
|
74
|
+
httpMethodsStandardization,
|
|
75
|
+
HttpServerError,
|
|
76
|
+
jsonErrorInfer
|
|
77
|
+
} from "../http";
|
|
78
|
+
import { ansiText, inferStatusText, isWebSocketUpgrade } from "../utils";
|
|
52
79
|
import { Context } from "./context";
|
|
53
80
|
import { HttpRouter } from "./httpRouter";
|
|
54
81
|
import { HttpRouterGroup } from "./httpRouterGroup";
|
|
@@ -58,111 +85,29 @@ import { WebSocketRoute } from "./webSocketRoute";
|
|
|
58
85
|
import { WebSocketRouter } from "./webSocketRouter";
|
|
59
86
|
import { WebSocketRouterGroup } from "./webSocketRouterGroup";
|
|
60
87
|
|
|
61
|
-
type TParamsType = Record<string, string>;
|
|
62
|
-
|
|
63
|
-
type TApplicationOptions<AllowedMethods extends Array<THttpMethods> = Array<THttpMethods>> =
|
|
64
|
-
Required<{
|
|
65
|
-
port: number;
|
|
66
|
-
}> &
|
|
67
|
-
Partial<{
|
|
68
|
-
config: Record<string | symbol, any> | (() => Record<string | symbol, any>);
|
|
69
|
-
prefix: string;
|
|
70
|
-
debug: boolean;
|
|
71
|
-
log: Partial<{
|
|
72
|
-
methods: AllowedMethods;
|
|
73
|
-
}>;
|
|
74
|
-
queryParser: Parameters<typeof QsParse>[1];
|
|
75
|
-
static: Required<{
|
|
76
|
-
path: string;
|
|
77
|
-
}> &
|
|
78
|
-
Partial<{
|
|
79
|
-
headers: TParamsType;
|
|
80
|
-
cacheTimeInSeconds: number;
|
|
81
|
-
}>;
|
|
82
|
-
cors: Partial<{
|
|
83
|
-
credentials: boolean;
|
|
84
|
-
origins: string | Array<string>;
|
|
85
|
-
methods: Array<THttpMethods>;
|
|
86
|
-
headers: Array<string>;
|
|
87
|
-
}>;
|
|
88
|
-
}>;
|
|
89
|
-
|
|
90
|
-
type TGroupElementModel<
|
|
91
|
-
TFuncName extends keyof TClass,
|
|
92
|
-
TClass extends Object = Object,
|
|
93
|
-
TFunc = TClass[TFuncName]
|
|
94
|
-
> = Readonly<{
|
|
95
|
-
class: TClass;
|
|
96
|
-
func: TFunc;
|
|
97
|
-
funcName: TFuncName;
|
|
98
|
-
argumentsMetadata: TArgumentsMetadataCollection;
|
|
99
|
-
}>;
|
|
100
|
-
|
|
101
|
-
type TStaticMap = Map<
|
|
102
|
-
string,
|
|
103
|
-
Readonly<{
|
|
104
|
-
expiredAt: Date;
|
|
105
|
-
file: BunFile;
|
|
106
|
-
}>
|
|
107
|
-
>;
|
|
108
|
-
|
|
109
|
-
type TResolutedOptions = Readonly<{
|
|
110
|
-
allowLogsMethods: Array<THttpMethods>;
|
|
111
|
-
allowOrigins: Array<string>;
|
|
112
|
-
allowMethods: Array<THttpMethods>;
|
|
113
|
-
allowHeaders: Array<string>;
|
|
114
|
-
allowCredentials: boolean;
|
|
115
|
-
staticOption?: Required<{
|
|
116
|
-
path: string;
|
|
117
|
-
}> &
|
|
118
|
-
Partial<{
|
|
119
|
-
headers: TParamsType;
|
|
120
|
-
cacheTimeInSeconds: number;
|
|
121
|
-
}>;
|
|
122
|
-
}>;
|
|
123
|
-
|
|
124
|
-
type TWebSocketUpgradeData = {
|
|
125
|
-
pathname: string;
|
|
126
|
-
method: string;
|
|
127
|
-
query: Record<string, unknown>;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
type TPreLaunch =
|
|
131
|
-
| undefined
|
|
132
|
-
| Readonly<{
|
|
133
|
-
containerMetadata: TContainerMetadata;
|
|
134
|
-
modulesConverted: Array<TConstructor<unknown>>;
|
|
135
|
-
resolutedContainer?: Awaited<ReturnType<Application["containerResolution"]>>;
|
|
136
|
-
resolutedModules: Array<Awaited<ReturnType<Application["moduleResolution"]>>>;
|
|
137
|
-
webSocketsMap: Map<string, TWebSocketEventHandlerMetadata>;
|
|
138
|
-
}>;
|
|
139
|
-
|
|
140
|
-
type TValidator = undefined | ICustomValidator;
|
|
141
|
-
|
|
142
88
|
export class Application<TRootClass extends Object = Object> {
|
|
143
89
|
#preLaunchData: TPreLaunch;
|
|
144
|
-
#
|
|
145
|
-
#injector = new Injector();
|
|
90
|
+
#type: "CONTAINER" | "MODULE";
|
|
146
91
|
#staticMap: TStaticMap = new Map();
|
|
147
92
|
#resolutedOptions: TResolutedOptions;
|
|
148
93
|
#staticCacheTimeInSecond: number = 900;
|
|
149
94
|
#customValidator: TValidator;
|
|
95
|
+
#globalContext: Context = new Context();
|
|
150
96
|
|
|
151
97
|
constructor(
|
|
152
98
|
private readonly classConstructor: TConstructor<TRootClass>,
|
|
153
99
|
private readonly options: TApplicationOptions
|
|
154
100
|
) {
|
|
155
|
-
|
|
101
|
+
const metadataKeys = Reflect.getOwnMetadataKeys(classConstructor);
|
|
156
102
|
|
|
157
|
-
if (
|
|
158
|
-
!this.#inputedConstructorKeys.includes(containerKey) &&
|
|
159
|
-
!this.#inputedConstructorKeys.includes(moduleKey)
|
|
160
|
-
) {
|
|
103
|
+
if (!metadataKeys.includes(containerKey) && !metadataKeys.includes(moduleKey)) {
|
|
161
104
|
throw Error(
|
|
162
105
|
`Can not detect! ${classConstructor.name} class is not a container or module.`
|
|
163
106
|
);
|
|
164
107
|
}
|
|
165
108
|
|
|
109
|
+
this.#type = !metadataKeys.includes(containerKey) ? "MODULE" : "CONTAINER";
|
|
110
|
+
|
|
166
111
|
this.#staticCacheTimeInSecond =
|
|
167
112
|
typeof options.static?.cacheTimeInSeconds !== "number"
|
|
168
113
|
? 900
|
|
@@ -183,10 +128,51 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
183
128
|
allowHeaders:
|
|
184
129
|
!this.options.cors?.headers || this.options.cors.headers.includes("*")
|
|
185
130
|
? ["*"]
|
|
186
|
-
: this.options.cors.headers
|
|
131
|
+
: this.options.cors.headers,
|
|
132
|
+
pipelineStrategy: (() => {
|
|
133
|
+
switch (options.pipelineStrategy?.type) {
|
|
134
|
+
case "SIMPLE":
|
|
135
|
+
return Object.freeze({
|
|
136
|
+
startMiddlewares: "FIFO",
|
|
137
|
+
endMiddlewares: options.pipelineStrategy.targets?.middlewares || "FIFO",
|
|
138
|
+
openInterceptors: "FIFO",
|
|
139
|
+
closeInterceptors:
|
|
140
|
+
options.pipelineStrategy.targets?.interceptors || "FIFO"
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
default:
|
|
144
|
+
return Object.freeze({
|
|
145
|
+
startMiddlewares: "FIFO",
|
|
146
|
+
endMiddlewares: "FIFO",
|
|
147
|
+
openInterceptors: "FIFO",
|
|
148
|
+
closeInterceptors: "FIFO"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
})()
|
|
187
152
|
});
|
|
188
153
|
}
|
|
189
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Static method to initialize app and await all reloads.
|
|
157
|
+
* @param classConstructor
|
|
158
|
+
* @param options
|
|
159
|
+
* @returns
|
|
160
|
+
*/
|
|
161
|
+
public static async create<TRootClass extends Object = Object>(
|
|
162
|
+
classConstructor: TConstructor<TRootClass>,
|
|
163
|
+
options: TApplicationOptions
|
|
164
|
+
) {
|
|
165
|
+
const app = new Application(classConstructor, options);
|
|
166
|
+
|
|
167
|
+
await app.preLaunch();
|
|
168
|
+
|
|
169
|
+
return app;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Register app validator to execute all validations process in app.
|
|
174
|
+
* @param validator
|
|
175
|
+
*/
|
|
190
176
|
public useValidator(validator: ICustomValidator) {
|
|
191
177
|
this.#customValidator = validator;
|
|
192
178
|
}
|
|
@@ -200,69 +186,42 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
200
186
|
return this.#preLaunchData;
|
|
201
187
|
}
|
|
202
188
|
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const resolutedModules = await Promise.all(
|
|
222
|
-
modulesConverted.map((moduleConverted) =>
|
|
223
|
-
this.moduleResolution({
|
|
224
|
-
moduleClass: moduleConverted,
|
|
225
|
-
options: this.options,
|
|
226
|
-
extendInjector: !resolutedContainer
|
|
227
|
-
? this.#injector
|
|
228
|
-
: resolutedContainer.injector
|
|
229
|
-
})
|
|
230
|
-
)
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
const prefixs = [
|
|
234
|
-
...new Set(
|
|
235
|
-
resolutedModules.map(
|
|
236
|
-
(availableModuleResolution) => availableModuleResolution.prefix
|
|
237
|
-
)
|
|
238
|
-
)
|
|
239
|
-
];
|
|
240
|
-
|
|
241
|
-
if (prefixs.length !== resolutedModules.length) {
|
|
242
|
-
throw Error("Module prefix should be unique.");
|
|
243
|
-
}
|
|
189
|
+
const {
|
|
190
|
+
startMiddlewareHandlers,
|
|
191
|
+
endMiddlewareHandlers,
|
|
192
|
+
controllerRouterGroup,
|
|
193
|
+
webSocketHttpRouterGroup,
|
|
194
|
+
webSocketRouterGroup
|
|
195
|
+
} =
|
|
196
|
+
this.#type !== "MODULE"
|
|
197
|
+
? await this.#containerResolver({
|
|
198
|
+
containerClass: this.classConstructor,
|
|
199
|
+
prefix: this.options.prefix,
|
|
200
|
+
options: this.options
|
|
201
|
+
})
|
|
202
|
+
: await this.#moduleResolver({
|
|
203
|
+
moduleClass: this.classConstructor,
|
|
204
|
+
prefix: this.options.prefix,
|
|
205
|
+
options: this.options
|
|
206
|
+
});
|
|
244
207
|
|
|
245
208
|
const webSocketsMap = new Map<string, TWebSocketEventHandlerMetadata>();
|
|
209
|
+
const webSocketMap = webSocketRouterGroup.execute();
|
|
246
210
|
|
|
247
|
-
for (const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
for (const [key, metadata] of webSocketMap.entries()) {
|
|
251
|
-
webSocketsMap.set(key, metadata);
|
|
252
|
-
}
|
|
211
|
+
for (const [key, metadata] of webSocketMap.entries()) {
|
|
212
|
+
webSocketsMap.set(key, metadata);
|
|
253
213
|
}
|
|
254
214
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
215
|
+
this.#preLaunchData = Object.freeze({
|
|
216
|
+
startMiddlewareHandlers,
|
|
217
|
+
endMiddlewareHandlers,
|
|
218
|
+
controllerRouterGroup,
|
|
219
|
+
webSocketHttpRouterGroup,
|
|
220
|
+
webSocketRouterGroup,
|
|
221
|
+
webSocketsMap: webSocketsMap
|
|
261
222
|
});
|
|
262
223
|
|
|
263
|
-
this.#preLaunchData
|
|
264
|
-
|
|
265
|
-
return preLaunchData;
|
|
224
|
+
return this.#preLaunchData;
|
|
266
225
|
}
|
|
267
226
|
|
|
268
227
|
/**
|
|
@@ -270,6 +229,22 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
270
229
|
* @param port
|
|
271
230
|
*/
|
|
272
231
|
public async listen() {
|
|
232
|
+
const server = serve<TWebSocketUpgradeData>({
|
|
233
|
+
port: this.options.port,
|
|
234
|
+
fetch: this.#rootFetch.bind(this),
|
|
235
|
+
websocket: await this.#rootWebSocket.bind(this)()
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
this.#globalContext.set(webSocketServerArgsKey, server);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
*
|
|
243
|
+
* @param request
|
|
244
|
+
* @param server
|
|
245
|
+
* @returns
|
|
246
|
+
*/
|
|
247
|
+
async #rootFetch(request: Request, server: Server<TWebSocketUpgradeData>) {
|
|
273
248
|
const {
|
|
274
249
|
allowLogsMethods,
|
|
275
250
|
allowOrigins,
|
|
@@ -279,522 +254,690 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
279
254
|
staticOption
|
|
280
255
|
} = this.#resolutedOptions;
|
|
281
256
|
|
|
282
|
-
const {
|
|
257
|
+
const {
|
|
258
|
+
startMiddlewareHandlers,
|
|
259
|
+
endMiddlewareHandlers,
|
|
260
|
+
controllerRouterGroup,
|
|
261
|
+
webSocketHttpRouterGroup
|
|
262
|
+
} = await this.preLaunch();
|
|
263
|
+
|
|
264
|
+
const start = performance.now(),
|
|
265
|
+
url = new URL(request.url),
|
|
266
|
+
query = QsParse(url.searchParams.toString(), this.options.queryParser),
|
|
267
|
+
origin = request.headers.get("origin") || "*",
|
|
268
|
+
method = request.method.toUpperCase(),
|
|
269
|
+
responseHeaders = new Headers();
|
|
270
|
+
|
|
271
|
+
const context = new Context()
|
|
272
|
+
.setOptions({ isStatic: true })
|
|
273
|
+
.set(httpServerArgsKey, server)
|
|
274
|
+
.set(requestArgsKey, request)
|
|
275
|
+
.set(requestHeaderArgsKey, request.headers)
|
|
276
|
+
.set(responseHeadersArgsKey, responseHeaders)
|
|
277
|
+
.set(queryArgsKey, query);
|
|
283
278
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
279
|
+
try {
|
|
280
|
+
[
|
|
281
|
+
...(!allowCredentials
|
|
282
|
+
? []
|
|
283
|
+
: [
|
|
284
|
+
{
|
|
285
|
+
key: "Access-Control-Allow-Credentials",
|
|
286
|
+
value: "true"
|
|
287
|
+
}
|
|
288
|
+
]),
|
|
289
|
+
{
|
|
290
|
+
key: "Access-Control-Allow-Origin",
|
|
291
|
+
value: allowOrigins.includes("*")
|
|
292
|
+
? "*"
|
|
293
|
+
: !allowOrigins.includes(origin)
|
|
294
|
+
? allowOrigins[0]
|
|
295
|
+
: origin
|
|
296
|
+
},
|
|
297
|
+
{ key: "Access-Control-Allow-Methods", value: allowMethods.join(", ") },
|
|
298
|
+
{ key: "Access-Control-Allow-Headers", value: allowHeaders.join(", ") }
|
|
299
|
+
].forEach(({ key, value }) => responseHeaders.set(key, value));
|
|
301
300
|
|
|
302
|
-
|
|
303
|
-
const validateRequestMethod = httpMethodsStandardization(method);
|
|
304
|
-
|
|
305
|
-
if (!validateRequestMethod) {
|
|
306
|
-
return this.finalizeResponse(
|
|
307
|
-
new Response(
|
|
308
|
-
JSON.stringify({
|
|
309
|
-
httpCode: 405,
|
|
310
|
-
message: "Method Not Allowed.",
|
|
311
|
-
data: undefined
|
|
312
|
-
}),
|
|
313
|
-
{
|
|
314
|
-
status: 405,
|
|
315
|
-
statusText: "Method Not Allowed.",
|
|
316
|
-
headers: responseHeaders
|
|
317
|
-
}
|
|
318
|
-
)
|
|
319
|
-
);
|
|
320
|
-
}
|
|
301
|
+
const validateRequestMethod = httpMethodsStandardization(method);
|
|
321
302
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
>;
|
|
331
|
-
}>;
|
|
332
|
-
|
|
333
|
-
if (isUpgradable) {
|
|
334
|
-
for (const availableModuleResolution of resolutedModules) {
|
|
335
|
-
const routeResult =
|
|
336
|
-
availableModuleResolution.webSocketHttpRouterGroup.find({
|
|
337
|
-
pathname: url.pathname,
|
|
338
|
-
method: method
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
if (routeResult) {
|
|
342
|
-
collection = Object.freeze({
|
|
343
|
-
route: routeResult,
|
|
344
|
-
resolution: availableModuleResolution
|
|
345
|
-
});
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (!collection) {
|
|
351
|
-
return this.finalizeResponse(
|
|
352
|
-
new Response(
|
|
353
|
-
JSON.stringify({
|
|
354
|
-
httpCode: 404,
|
|
355
|
-
message: "Route not found.",
|
|
356
|
-
data: undefined
|
|
357
|
-
}),
|
|
358
|
-
{
|
|
359
|
-
status: 404,
|
|
360
|
-
statusText: "Not found.",
|
|
361
|
-
headers: responseHeaders
|
|
362
|
-
}
|
|
363
|
-
)
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const upgradeResult = await this.webSocketFetcher(
|
|
368
|
-
{
|
|
369
|
-
request,
|
|
370
|
-
server
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
query: query,
|
|
374
|
-
responseHeaders: responseHeaders,
|
|
375
|
-
route: collection.route,
|
|
376
|
-
moduleResolution: collection.resolution
|
|
377
|
-
}
|
|
378
|
-
);
|
|
303
|
+
if (!validateRequestMethod || !allowMethods.includes(method)) {
|
|
304
|
+
return this.finalizeResponse(
|
|
305
|
+
new Response(undefined, {
|
|
306
|
+
...Objects.clientErrorStatuses.METHOD_NOT_ALLOWED,
|
|
307
|
+
headers: responseHeaders
|
|
308
|
+
})
|
|
309
|
+
);
|
|
310
|
+
}
|
|
379
311
|
|
|
380
|
-
|
|
381
|
-
|
|
312
|
+
const isUpgradable = isWebSocketUpgrade(request);
|
|
313
|
+
|
|
314
|
+
if (isUpgradable) {
|
|
315
|
+
return await this.#webSocketFetcher({
|
|
316
|
+
request: request,
|
|
317
|
+
server: server,
|
|
318
|
+
context: context,
|
|
319
|
+
url: url,
|
|
320
|
+
query: query,
|
|
321
|
+
method: method,
|
|
322
|
+
responseHeaders: responseHeaders,
|
|
323
|
+
httpRouterGroup: webSocketHttpRouterGroup,
|
|
324
|
+
startMiddlewareHandlers: startMiddlewareHandlers,
|
|
325
|
+
endMiddlewareHandlers: endMiddlewareHandlers
|
|
326
|
+
});
|
|
327
|
+
}
|
|
382
328
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
: !allowOrigins.includes(origin)
|
|
397
|
-
? allowOrigins[0]
|
|
398
|
-
: origin
|
|
399
|
-
},
|
|
400
|
-
{ key: "Access-Control-Allow-Methods", value: allowMethods.join(", ") },
|
|
401
|
-
{ key: "Access-Control-Allow-Headers", value: allowHeaders.join(", ") }
|
|
402
|
-
].forEach(({ key, value }) => responseHeaders.set(key, value));
|
|
403
|
-
|
|
404
|
-
if (!allowMethods.includes(method)) {
|
|
405
|
-
return this.finalizeResponse(
|
|
406
|
-
new Response(undefined, {
|
|
407
|
-
status: 405,
|
|
408
|
-
statusText: "Method Not Allowed.",
|
|
409
|
-
headers: responseHeaders
|
|
410
|
-
})
|
|
411
|
-
);
|
|
412
|
-
}
|
|
329
|
+
if (request.method.toUpperCase() === "OPTIONS") {
|
|
330
|
+
return this.finalizeResponse(
|
|
331
|
+
allowOrigins.includes("*") || allowOrigins.includes(origin)
|
|
332
|
+
? new Response(undefined, {
|
|
333
|
+
...Objects.successfulStatuses.NO_CONTENT,
|
|
334
|
+
headers: responseHeaders
|
|
335
|
+
})
|
|
336
|
+
: new Response(undefined, {
|
|
337
|
+
...Objects.clientErrorStatuses.EXPECTATION_FAILED,
|
|
338
|
+
headers: responseHeaders
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
}
|
|
413
342
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
: new Response(undefined, {
|
|
423
|
-
status: 417,
|
|
424
|
-
statusText: "Expectation Failed.",
|
|
425
|
-
headers: responseHeaders
|
|
426
|
-
})
|
|
427
|
-
);
|
|
428
|
-
}
|
|
343
|
+
if (staticOption) {
|
|
344
|
+
const staticResult = await this.#staticFetcher({
|
|
345
|
+
url: url,
|
|
346
|
+
responseHeaders: responseHeaders,
|
|
347
|
+
path: staticOption.path,
|
|
348
|
+
headers: staticOption.headers,
|
|
349
|
+
cacheTimeInSeconds: staticOption.cacheTimeInSeconds
|
|
350
|
+
});
|
|
429
351
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
pathname,
|
|
469
|
-
Object.freeze({
|
|
470
|
-
expiredAt: TimeAdd(
|
|
471
|
-
new Date(),
|
|
472
|
-
this.#staticCacheTimeInSecond,
|
|
473
|
-
ETimeUnit.seconds
|
|
474
|
-
),
|
|
475
|
-
file: file
|
|
476
|
-
})
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
if (headers) {
|
|
480
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
481
|
-
responseHeaders.set(key, value);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
responseHeaders.set("Content-Type", file.type);
|
|
486
|
-
|
|
487
|
-
return this.finalizeResponse(
|
|
488
|
-
new Response(await file.arrayBuffer(), {
|
|
489
|
-
status: 200,
|
|
490
|
-
statusText: "SUCCESS",
|
|
491
|
-
headers: responseHeaders
|
|
492
|
-
})
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
352
|
+
if (staticResult instanceof Response) {
|
|
353
|
+
return staticResult;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return await this.#httpFetcher({
|
|
358
|
+
url: url,
|
|
359
|
+
method: method,
|
|
360
|
+
context: context,
|
|
361
|
+
httpRouterGroup: controllerRouterGroup,
|
|
362
|
+
startMiddlewareHandlers: startMiddlewareHandlers,
|
|
363
|
+
endMiddlewareHandlers: endMiddlewareHandlers
|
|
364
|
+
});
|
|
365
|
+
} catch (error) {
|
|
366
|
+
this.options.debug && console.error(error);
|
|
367
|
+
|
|
368
|
+
return this.finalizeResponse(jsonErrorInfer(error, responseHeaders));
|
|
369
|
+
} finally {
|
|
370
|
+
if (allowLogsMethods) {
|
|
371
|
+
const end = performance.now();
|
|
372
|
+
const responseStatus = context.get(responseStatusArgsKey, { isStatic: false });
|
|
373
|
+
const inferedResponseStatus =
|
|
374
|
+
typeof responseStatus !== "number" || !responseStatus ? 0 : responseStatus;
|
|
375
|
+
const pathname = ansiText(url.pathname, { color: "blue" });
|
|
376
|
+
const convertedPID = `${Bun.color("yellow", "ansi")}${process.pid}`;
|
|
377
|
+
const convertedMethod = ansiText(` ${request.method} `, {
|
|
378
|
+
color: "yellow",
|
|
379
|
+
backgroundColor: "blue"
|
|
380
|
+
});
|
|
381
|
+
const convertedReqIp = ansiText(
|
|
382
|
+
`${
|
|
383
|
+
request.headers.get("x-forwarded-for") ||
|
|
384
|
+
request.headers.get("x-real-ip") ||
|
|
385
|
+
server.requestIP(request)?.address ||
|
|
386
|
+
"<Unknown>"
|
|
387
|
+
}`,
|
|
388
|
+
{
|
|
389
|
+
color: "yellow"
|
|
496
390
|
}
|
|
391
|
+
);
|
|
392
|
+
const convertedTime = ansiText(
|
|
393
|
+
` ${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms `,
|
|
394
|
+
{
|
|
395
|
+
color: "yellow",
|
|
396
|
+
backgroundColor: "blue"
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
const convertedResponseStatus = ansiText(
|
|
400
|
+
` ${inferedResponseStatus} (${inferStatusText(inferedResponseStatus)}) `,
|
|
401
|
+
(() => {
|
|
402
|
+
if (inferedResponseStatus >= 100 && inferedResponseStatus < 200)
|
|
403
|
+
return {
|
|
404
|
+
color: "white",
|
|
405
|
+
backgroundColor: "cyan"
|
|
406
|
+
};
|
|
407
|
+
else if (inferedResponseStatus >= 200 && inferedResponseStatus < 300)
|
|
408
|
+
return {
|
|
409
|
+
color: "white",
|
|
410
|
+
backgroundColor: "blue"
|
|
411
|
+
};
|
|
412
|
+
else if (inferedResponseStatus >= 300 && inferedResponseStatus < 400)
|
|
413
|
+
return {
|
|
414
|
+
color: "black",
|
|
415
|
+
backgroundColor: "magenta"
|
|
416
|
+
};
|
|
417
|
+
else if (inferedResponseStatus >= 400 && inferedResponseStatus < 500)
|
|
418
|
+
return {
|
|
419
|
+
color: "black",
|
|
420
|
+
backgroundColor: "yellow"
|
|
421
|
+
};
|
|
422
|
+
else if (inferedResponseStatus >= 500 && inferedResponseStatus < 600)
|
|
423
|
+
return {
|
|
424
|
+
color: "white",
|
|
425
|
+
backgroundColor: "red"
|
|
426
|
+
};
|
|
427
|
+
else
|
|
428
|
+
return {
|
|
429
|
+
color: "black",
|
|
430
|
+
backgroundColor: "gray"
|
|
431
|
+
};
|
|
432
|
+
})()
|
|
433
|
+
);
|
|
497
434
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
435
|
+
allowLogsMethods.includes(
|
|
436
|
+
request.method.toUpperCase() as (typeof allowLogsMethods)[number]
|
|
437
|
+
) &&
|
|
438
|
+
console.info(
|
|
439
|
+
[
|
|
440
|
+
`PID: ${convertedPID}`,
|
|
441
|
+
`Method: ${convertedMethod}`,
|
|
442
|
+
`IP: ${convertedReqIp}`,
|
|
443
|
+
pathname,
|
|
444
|
+
`Time: ${convertedTime}`,
|
|
445
|
+
typeof responseStatus !== "number" || !responseStatus
|
|
446
|
+
? undefined
|
|
447
|
+
: convertedResponseStatus
|
|
448
|
+
]
|
|
449
|
+
.filter((x) => !!x?.trim())
|
|
450
|
+
.join(" - ")
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
*
|
|
458
|
+
* @returns
|
|
459
|
+
*/
|
|
460
|
+
async #rootWebSocket<T extends TWebSocketUpgradeData = TWebSocketUpgradeData>(): Promise<
|
|
461
|
+
WebSocketHandler<T>
|
|
462
|
+
> {
|
|
463
|
+
const { webSocketsMap } = await this.preLaunch();
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
open: (connection: ServerWebSocket<T>) => {
|
|
467
|
+
const pathnameKey = `${connection.data.pathname}:::open`;
|
|
468
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
469
|
+
|
|
470
|
+
if (!handlerMetadata) {
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
503
473
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
474
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
475
|
+
const args: Array<unknown> = [];
|
|
476
|
+
|
|
477
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
478
|
+
switch (argumentMetadata.type) {
|
|
479
|
+
case webSocketConnectionArgsKey:
|
|
480
|
+
args[argumentMetadata.index] = connection;
|
|
481
|
+
break;
|
|
482
|
+
case webSocketServerArgsKey:
|
|
483
|
+
args[argumentMetadata.index] =
|
|
484
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
509
485
|
break;
|
|
510
|
-
}
|
|
511
486
|
}
|
|
487
|
+
}
|
|
512
488
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
injector: resolutedContainer.injector,
|
|
519
|
-
startMiddlewareGroup: resolutedContainer.startMiddlewareGroup,
|
|
520
|
-
guardGroup: resolutedContainer.guardGroup
|
|
521
|
-
},
|
|
522
|
-
options: {
|
|
523
|
-
isContainer: true
|
|
524
|
-
}
|
|
525
|
-
});
|
|
489
|
+
handlerMetadata.descriptor.value(...args);
|
|
490
|
+
},
|
|
491
|
+
close: (connection, code, reason) => {
|
|
492
|
+
const pathnameKey = `${connection.data.pathname}:::close`;
|
|
493
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
526
494
|
|
|
527
|
-
|
|
528
|
-
|
|
495
|
+
if (!handlerMetadata) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
529
498
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
.setOptions({ isStatic: false })
|
|
533
|
-
.set(responseStatusArgsKey, 404)
|
|
534
|
-
.set(responseStatusTextArgsKey, "Not found.")
|
|
535
|
-
.set(
|
|
536
|
-
responseBodyArgsKey,
|
|
537
|
-
JSON.stringify({
|
|
538
|
-
httpCode: 404,
|
|
539
|
-
message: "Route not found.",
|
|
540
|
-
data: undefined
|
|
541
|
-
})
|
|
542
|
-
);
|
|
543
|
-
} else {
|
|
544
|
-
const { context: newContext } = await this.httpFetcher({
|
|
545
|
-
context: context,
|
|
546
|
-
route: collection.route,
|
|
547
|
-
resolutedMap: collection.resolution
|
|
548
|
-
});
|
|
499
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
500
|
+
const args: Array<unknown> = [];
|
|
549
501
|
|
|
550
|
-
|
|
502
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
503
|
+
switch (argumentMetadata.type) {
|
|
504
|
+
case webSocketConnectionArgsKey:
|
|
505
|
+
args[argumentMetadata.index] = connection;
|
|
506
|
+
break;
|
|
507
|
+
case webSocketCloseCodeArgsKey:
|
|
508
|
+
args[argumentMetadata.index] = code;
|
|
509
|
+
break;
|
|
510
|
+
case webSocketCloseReasonArgsKey:
|
|
511
|
+
args[argumentMetadata.index] = reason;
|
|
512
|
+
break;
|
|
513
|
+
case webSocketServerArgsKey:
|
|
514
|
+
args[argumentMetadata.index] =
|
|
515
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
516
|
+
break;
|
|
551
517
|
}
|
|
518
|
+
}
|
|
552
519
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
520
|
+
handlerMetadata.descriptor.value(...args);
|
|
521
|
+
},
|
|
522
|
+
message: (connection: ServerWebSocket<T>, message) => {
|
|
523
|
+
const pathnameKey = `${connection.data.pathname}:::message`;
|
|
524
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
525
|
+
|
|
526
|
+
if (!handlerMetadata) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
531
|
+
const args: Array<unknown> = [];
|
|
564
532
|
|
|
565
|
-
|
|
533
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
534
|
+
switch (argumentMetadata.type) {
|
|
535
|
+
case webSocketConnectionArgsKey:
|
|
536
|
+
args[argumentMetadata.index] = connection;
|
|
537
|
+
break;
|
|
538
|
+
case webSocketMessageArgsKey:
|
|
539
|
+
args[argumentMetadata.index] = message;
|
|
540
|
+
break;
|
|
541
|
+
case webSocketServerArgsKey:
|
|
542
|
+
args[argumentMetadata.index] =
|
|
543
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
544
|
+
break;
|
|
566
545
|
}
|
|
546
|
+
}
|
|
567
547
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
context.get<unknown>(responseBodyArgsKey, { isStatic: false }) ||
|
|
574
|
-
undefined,
|
|
575
|
-
latestResponseStatus = context.get<unknown>(responseStatusArgsKey, {
|
|
576
|
-
isStatic: false
|
|
577
|
-
}),
|
|
578
|
-
latestResponseStatusText = context.get<unknown>(responseStatusTextArgsKey, {
|
|
579
|
-
isStatic: false
|
|
580
|
-
});
|
|
548
|
+
handlerMetadata.descriptor.value(...args);
|
|
549
|
+
},
|
|
550
|
+
drain: (connection: ServerWebSocket<T>) => {
|
|
551
|
+
const pathnameKey = `${connection.data.pathname}:::drain`;
|
|
552
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
581
553
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
? method === "POST"
|
|
586
|
-
? 201
|
|
587
|
-
: undefined
|
|
588
|
-
: latestResponseStatus,
|
|
589
|
-
statusText:
|
|
590
|
-
typeof latestResponseStatusText !== "string"
|
|
591
|
-
? undefined
|
|
592
|
-
: latestResponseStatusText,
|
|
593
|
-
headers: latestResponseHeaders,
|
|
594
|
-
data: latestResponseBody
|
|
595
|
-
});
|
|
596
|
-
} catch (error) {
|
|
597
|
-
this.options.debug && console.error(error);
|
|
598
|
-
|
|
599
|
-
return this.finalizeResponse(jsonErrorInfer(error, responseHeaders));
|
|
600
|
-
} finally {
|
|
601
|
-
if (allowLogsMethods) {
|
|
602
|
-
const end = performance.now();
|
|
603
|
-
const pathname = ansiText(url.pathname, { color: "blue" });
|
|
604
|
-
const convertedPID = `${Bun.color("yellow", "ansi")}${process.pid}`;
|
|
605
|
-
const convertedMethod = ansiText(request.method, {
|
|
606
|
-
color: "yellow",
|
|
607
|
-
backgroundColor: "blue"
|
|
608
|
-
});
|
|
609
|
-
const convertedReqIp = ansiText(
|
|
610
|
-
`${
|
|
611
|
-
request.headers.get("x-forwarded-for") ||
|
|
612
|
-
request.headers.get("x-real-ip") ||
|
|
613
|
-
server.requestIP(request)?.address ||
|
|
614
|
-
"<Unknown>"
|
|
615
|
-
}`,
|
|
616
|
-
{
|
|
617
|
-
color: "yellow"
|
|
618
|
-
}
|
|
619
|
-
);
|
|
620
|
-
const convertedTime = ansiText(
|
|
621
|
-
`${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms`,
|
|
622
|
-
{
|
|
623
|
-
color: "yellow",
|
|
624
|
-
backgroundColor: "blue"
|
|
625
|
-
}
|
|
626
|
-
);
|
|
554
|
+
if (!handlerMetadata) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
627
557
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
558
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
559
|
+
const args: Array<unknown> = [];
|
|
560
|
+
|
|
561
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
562
|
+
switch (argumentMetadata.type) {
|
|
563
|
+
case webSocketConnectionArgsKey:
|
|
564
|
+
args[argumentMetadata.index] = connection;
|
|
565
|
+
break;
|
|
566
|
+
case webSocketServerArgsKey:
|
|
567
|
+
args[argumentMetadata.index] =
|
|
568
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
569
|
+
break;
|
|
634
570
|
}
|
|
635
571
|
}
|
|
572
|
+
|
|
573
|
+
handlerMetadata.descriptor.value(...args);
|
|
636
574
|
},
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
575
|
+
ping: (connection: ServerWebSocket<T>, data) => {
|
|
576
|
+
const pathnameKey = `${connection.data.pathname}:::ping`;
|
|
577
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
641
578
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
579
|
+
if (!handlerMetadata) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
645
582
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
583
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
584
|
+
const args: Array<unknown> = [];
|
|
585
|
+
|
|
586
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
587
|
+
switch (argumentMetadata.type) {
|
|
588
|
+
case webSocketConnectionArgsKey:
|
|
589
|
+
args[argumentMetadata.index] = connection;
|
|
590
|
+
break;
|
|
591
|
+
case webSocketMessageArgsKey:
|
|
592
|
+
args[argumentMetadata.index] = data;
|
|
593
|
+
break;
|
|
594
|
+
case webSocketServerArgsKey:
|
|
595
|
+
args[argumentMetadata.index] =
|
|
596
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
597
|
+
break;
|
|
658
598
|
}
|
|
599
|
+
}
|
|
659
600
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
601
|
+
handlerMetadata.descriptor.value(...args);
|
|
602
|
+
},
|
|
603
|
+
pong: (connection: ServerWebSocket<T>, data) => {
|
|
604
|
+
const pathnameKey = `${connection.data.pathname}:::pong`;
|
|
605
|
+
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
665
606
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
607
|
+
if (!handlerMetadata) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
669
610
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
args[argumentMetadata.index] = reason;
|
|
686
|
-
break;
|
|
687
|
-
}
|
|
611
|
+
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
612
|
+
const args: Array<unknown> = [];
|
|
613
|
+
|
|
614
|
+
for (const [, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
615
|
+
switch (argumentMetadata.type) {
|
|
616
|
+
case webSocketConnectionArgsKey:
|
|
617
|
+
args[argumentMetadata.index] = connection;
|
|
618
|
+
break;
|
|
619
|
+
case webSocketMessageArgsKey:
|
|
620
|
+
args[argumentMetadata.index] = data;
|
|
621
|
+
break;
|
|
622
|
+
case webSocketServerArgsKey:
|
|
623
|
+
args[argumentMetadata.index] =
|
|
624
|
+
this.#globalContext.get(webSocketServerArgsKey);
|
|
625
|
+
break;
|
|
688
626
|
}
|
|
627
|
+
}
|
|
689
628
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
629
|
+
handlerMetadata.descriptor.value(...args);
|
|
630
|
+
}
|
|
631
|
+
} satisfies WebSocketHandler<T>;
|
|
632
|
+
}
|
|
695
633
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
634
|
+
/**
|
|
635
|
+
*
|
|
636
|
+
* @param param0
|
|
637
|
+
* @returns
|
|
638
|
+
*/
|
|
639
|
+
async #webSocketFetcher({
|
|
640
|
+
request,
|
|
641
|
+
server,
|
|
642
|
+
context,
|
|
643
|
+
url,
|
|
644
|
+
query,
|
|
645
|
+
method,
|
|
646
|
+
responseHeaders,
|
|
647
|
+
httpRouterGroup,
|
|
648
|
+
startMiddlewareHandlers,
|
|
649
|
+
endMiddlewareHandlers
|
|
650
|
+
}: Required<{
|
|
651
|
+
server: Server<TWebSocketUpgradeData>;
|
|
652
|
+
request: Request;
|
|
653
|
+
context: Context;
|
|
654
|
+
url: URL;
|
|
655
|
+
query: ReturnType<typeof QsParse>;
|
|
656
|
+
method: THttpMethods;
|
|
657
|
+
responseHeaders: Headers;
|
|
658
|
+
httpRouterGroup: HttpRouterGroup;
|
|
659
|
+
startMiddlewareHandlers: TStartMiddlewareHandlers;
|
|
660
|
+
endMiddlewareHandlers: TEndMiddlewareHandlers;
|
|
661
|
+
}>) {
|
|
662
|
+
try {
|
|
663
|
+
await this.#pipesEnforcer({
|
|
664
|
+
type: "START_MIDDLEWARES",
|
|
665
|
+
handlers: startMiddlewareHandlers,
|
|
666
|
+
context: context
|
|
667
|
+
});
|
|
699
668
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
switch (argumentMetadata.type) {
|
|
705
|
-
case webSocketConnectionArgsKey:
|
|
706
|
-
args[argumentMetadata.index] = connection;
|
|
707
|
-
break;
|
|
708
|
-
case webSocketMessageArgsKey:
|
|
709
|
-
args[argumentMetadata.index] = message;
|
|
710
|
-
break;
|
|
711
|
-
case webSocketServerArgsKey:
|
|
712
|
-
args[argumentMetadata.index] = server;
|
|
713
|
-
break;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
669
|
+
const routeResult = httpRouterGroup.find({
|
|
670
|
+
pathname: url.pathname,
|
|
671
|
+
method: method
|
|
672
|
+
});
|
|
716
673
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
674
|
+
let upgradeResult: Response | undefined = this.finalizeResponse(
|
|
675
|
+
new Response(undefined, {
|
|
676
|
+
...Objects.serverErrorStatuses.INTERNAL_SERVER_ERROR,
|
|
677
|
+
headers: responseHeaders
|
|
678
|
+
})
|
|
679
|
+
);
|
|
722
680
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
681
|
+
if (routeResult) {
|
|
682
|
+
const authResult = await this.#pipesEnforcer({
|
|
683
|
+
type: "GUARDS",
|
|
684
|
+
handlers: routeResult.guardHandlers,
|
|
685
|
+
context: context
|
|
686
|
+
});
|
|
726
687
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
}
|
|
688
|
+
if (authResult !== true) {
|
|
689
|
+
upgradeResult = this.finalizeResponse(
|
|
690
|
+
new Response(undefined, {
|
|
691
|
+
...(!authResult || authResult === "UNAUTHORIZATION"
|
|
692
|
+
? Objects.clientErrorStatuses.UNAUTHORIZED
|
|
693
|
+
: Objects.clientErrorStatuses.FORBIDDEN),
|
|
694
|
+
headers: responseHeaders
|
|
695
|
+
})
|
|
696
|
+
);
|
|
697
|
+
} else {
|
|
698
|
+
context.set(routeModelArgsKey, routeResult.model);
|
|
740
699
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
700
|
+
await this.#pipesEnforcer({
|
|
701
|
+
type: "OPEN_INTERCEPTORS",
|
|
702
|
+
handlers: routeResult.openInterceptorHandlers,
|
|
703
|
+
context: context
|
|
704
|
+
});
|
|
746
705
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
706
|
+
const upgradeExecution = await routeResult.model.func(
|
|
707
|
+
...[server, request, query]
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
await this.#pipesEnforcer({
|
|
711
|
+
type: "CLOSE_INTERCEPTORS",
|
|
712
|
+
handlers: routeResult.closeInterceptorHandlers,
|
|
713
|
+
context: context
|
|
714
|
+
});
|
|
750
715
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
args[argumentMetadata.index] = server;
|
|
761
|
-
break;
|
|
762
|
-
case webSocketMessageArgsKey:
|
|
763
|
-
args[argumentMetadata.index] = data;
|
|
764
|
-
break;
|
|
765
|
-
}
|
|
716
|
+
if (typeof upgradeExecution !== "boolean" || !upgradeExecution) {
|
|
717
|
+
upgradeResult = this.finalizeResponse(
|
|
718
|
+
new Response(undefined, {
|
|
719
|
+
...Objects.serverErrorStatuses.INTERNAL_SERVER_ERROR,
|
|
720
|
+
headers: responseHeaders
|
|
721
|
+
})
|
|
722
|
+
);
|
|
723
|
+
} else {
|
|
724
|
+
upgradeResult = undefined;
|
|
766
725
|
}
|
|
726
|
+
}
|
|
727
|
+
} else {
|
|
728
|
+
}
|
|
767
729
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
730
|
+
await this.#pipesEnforcer({
|
|
731
|
+
type: "END_MIDDLEWARES",
|
|
732
|
+
handlers: endMiddlewareHandlers,
|
|
733
|
+
context: context
|
|
734
|
+
});
|
|
773
735
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
736
|
+
return upgradeResult;
|
|
737
|
+
} catch (error) {
|
|
738
|
+
console.error(error);
|
|
739
|
+
throw error;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
777
742
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
743
|
+
/**
|
|
744
|
+
*
|
|
745
|
+
* @param param0
|
|
746
|
+
* @returns
|
|
747
|
+
*/
|
|
748
|
+
async #staticFetcher({
|
|
749
|
+
url,
|
|
750
|
+
path,
|
|
751
|
+
headers,
|
|
752
|
+
cacheTimeInSeconds,
|
|
753
|
+
responseHeaders
|
|
754
|
+
}: {
|
|
755
|
+
url: URL;
|
|
756
|
+
path: string;
|
|
757
|
+
responseHeaders: Headers;
|
|
758
|
+
headers?: TParamsType;
|
|
759
|
+
cacheTimeInSeconds?: number;
|
|
760
|
+
}) {
|
|
761
|
+
const pathname = `${path}/${url.pathname}`;
|
|
762
|
+
const cachedFile = this.#staticMap.get(pathname);
|
|
763
|
+
|
|
764
|
+
if (!cachedFile) {
|
|
765
|
+
const file = Bun.file(pathname);
|
|
766
|
+
const isFileExists = await file.exists();
|
|
767
|
+
|
|
768
|
+
if (isFileExists) {
|
|
769
|
+
if (headers) {
|
|
770
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
771
|
+
responseHeaders.set(key, value);
|
|
793
772
|
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
responseHeaders.set("Content-Type", file.type);
|
|
776
|
+
|
|
777
|
+
return this.finalizeResponse(
|
|
778
|
+
new Response(await file.arrayBuffer(), {
|
|
779
|
+
...Objects.successfulStatuses.OK,
|
|
780
|
+
headers: responseHeaders
|
|
781
|
+
})
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
} else {
|
|
785
|
+
const isExpired = new Date() > cachedFile.expiredAt;
|
|
786
|
+
|
|
787
|
+
if (isExpired) {
|
|
788
|
+
this.#staticMap.delete(pathname);
|
|
789
|
+
}
|
|
794
790
|
|
|
795
|
-
|
|
791
|
+
const file = !isExpired ? cachedFile.file : Bun.file(pathname);
|
|
792
|
+
const isFileExists = await file.exists();
|
|
793
|
+
|
|
794
|
+
if (isFileExists) {
|
|
795
|
+
this.#staticMap.set(
|
|
796
|
+
pathname,
|
|
797
|
+
Object.freeze({
|
|
798
|
+
expiredAt: TimeAdd(
|
|
799
|
+
new Date(),
|
|
800
|
+
this.#staticCacheTimeInSecond,
|
|
801
|
+
ETimeUnit.seconds
|
|
802
|
+
),
|
|
803
|
+
file: file
|
|
804
|
+
})
|
|
805
|
+
);
|
|
806
|
+
|
|
807
|
+
if (headers) {
|
|
808
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
809
|
+
responseHeaders.set(key, value);
|
|
810
|
+
}
|
|
796
811
|
}
|
|
812
|
+
|
|
813
|
+
responseHeaders.set("Content-Type", file.type);
|
|
814
|
+
|
|
815
|
+
return this.finalizeResponse(
|
|
816
|
+
new Response(await file.arrayBuffer(), {
|
|
817
|
+
...Objects.successfulStatuses.OK,
|
|
818
|
+
headers: responseHeaders
|
|
819
|
+
})
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
*
|
|
827
|
+
* @param param0
|
|
828
|
+
* @returns
|
|
829
|
+
*/
|
|
830
|
+
async #httpFetcher({
|
|
831
|
+
context,
|
|
832
|
+
url,
|
|
833
|
+
method,
|
|
834
|
+
httpRouterGroup,
|
|
835
|
+
startMiddlewareHandlers = [],
|
|
836
|
+
endMiddlewareHandlers = []
|
|
837
|
+
}: {
|
|
838
|
+
context: Context;
|
|
839
|
+
url: URL;
|
|
840
|
+
method: THttpMethods;
|
|
841
|
+
httpRouterGroup: HttpRouterGroup;
|
|
842
|
+
startMiddlewareHandlers?: TStartMiddlewareHandlers;
|
|
843
|
+
endMiddlewareHandlers?: TEndMiddlewareHandlers;
|
|
844
|
+
}) {
|
|
845
|
+
const contextOptions = { isStatic: true };
|
|
846
|
+
|
|
847
|
+
context.setOptions(contextOptions);
|
|
848
|
+
|
|
849
|
+
await this.#pipesEnforcer({
|
|
850
|
+
type: "START_MIDDLEWARES",
|
|
851
|
+
handlers: startMiddlewareHandlers,
|
|
852
|
+
context: context
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
const routeResult = httpRouterGroup.find({
|
|
856
|
+
pathname: url.pathname,
|
|
857
|
+
method: method
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
if (!routeResult) {
|
|
861
|
+
context
|
|
862
|
+
.setOptions({ isStatic: false })
|
|
863
|
+
.set(responseStatusArgsKey, Objects.clientErrorStatuses.NOT_FOUND.status)
|
|
864
|
+
.set(responseStatusTextArgsKey, Objects.clientErrorStatuses.NOT_FOUND.statusText)
|
|
865
|
+
.set(responseBodyArgsKey, undefined);
|
|
866
|
+
} else {
|
|
867
|
+
context.set(routeModelArgsKey, routeResult.model);
|
|
868
|
+
|
|
869
|
+
const authResult = await this.#pipesEnforcer({
|
|
870
|
+
type: "GUARDS",
|
|
871
|
+
handlers: routeResult.guardHandlers,
|
|
872
|
+
context: context
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
if (authResult !== true) {
|
|
876
|
+
context
|
|
877
|
+
.setOptions({ isStatic: false })
|
|
878
|
+
.set(
|
|
879
|
+
responseStatusArgsKey,
|
|
880
|
+
!authResult || authResult === "UNAUTHORIZATION"
|
|
881
|
+
? Objects.clientErrorStatuses.UNAUTHORIZED.status
|
|
882
|
+
: Objects.clientErrorStatuses.FORBIDDEN.status
|
|
883
|
+
)
|
|
884
|
+
.set(
|
|
885
|
+
responseStatusTextArgsKey,
|
|
886
|
+
!authResult || authResult === "UNAUTHORIZATION"
|
|
887
|
+
? Objects.clientErrorStatuses.UNAUTHORIZED.statusText
|
|
888
|
+
: Objects.clientErrorStatuses.FORBIDDEN.statusText
|
|
889
|
+
)
|
|
890
|
+
.set(responseBodyArgsKey, undefined);
|
|
891
|
+
} else {
|
|
892
|
+
await this.#pipesEnforcer({
|
|
893
|
+
type: "OPEN_INTERCEPTORS",
|
|
894
|
+
handlers: routeResult.openInterceptorHandlers,
|
|
895
|
+
context: context
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
await this.#pipesEnforcer({
|
|
899
|
+
type: "CONTROLLER",
|
|
900
|
+
context: context
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
await this.#pipesEnforcer({
|
|
904
|
+
type: "CLOSE_INTERCEPTORS",
|
|
905
|
+
handlers: routeResult.closeInterceptorHandlers,
|
|
906
|
+
context: context
|
|
907
|
+
});
|
|
797
908
|
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
await this.#pipesEnforcer({
|
|
912
|
+
type: "END_MIDDLEWARES",
|
|
913
|
+
handlers: endMiddlewareHandlers,
|
|
914
|
+
context: context
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
const latestResponseHeaders =
|
|
918
|
+
context.get<Headers | null | undefined>(responseHeadersArgsKey, {
|
|
919
|
+
isStatic: true
|
|
920
|
+
}) || new Headers(),
|
|
921
|
+
latestResponseBody =
|
|
922
|
+
context.get<unknown>(responseBodyArgsKey, { isStatic: false }) || undefined,
|
|
923
|
+
latestResponseStatus = context.get<unknown>(responseStatusArgsKey, {
|
|
924
|
+
isStatic: false
|
|
925
|
+
}),
|
|
926
|
+
latestResponseStatusText = context.get<unknown>(responseStatusTextArgsKey, {
|
|
927
|
+
isStatic: false
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
return this.serializeResponse({
|
|
931
|
+
status:
|
|
932
|
+
typeof latestResponseStatus !== "number"
|
|
933
|
+
? method === "POST"
|
|
934
|
+
? 201
|
|
935
|
+
: undefined
|
|
936
|
+
: latestResponseStatus,
|
|
937
|
+
statusText:
|
|
938
|
+
typeof latestResponseStatusText !== "string" ? undefined : latestResponseStatusText,
|
|
939
|
+
headers: latestResponseHeaders,
|
|
940
|
+
data: latestResponseBody
|
|
798
941
|
});
|
|
799
942
|
}
|
|
800
943
|
|
|
@@ -803,20 +946,38 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
803
946
|
* @param param0
|
|
804
947
|
* @returns
|
|
805
948
|
*/
|
|
806
|
-
|
|
949
|
+
async #containerResolver({
|
|
950
|
+
prefix = "",
|
|
951
|
+
startMiddlewareHandlers = [],
|
|
952
|
+
endMiddlewareHandlers = [],
|
|
953
|
+
guardHandlers = [],
|
|
954
|
+
openInterceptorHandlers = [],
|
|
955
|
+
closeInterceptorHandlers = [],
|
|
956
|
+
controllerRouterGroup = new HttpRouterGroup(),
|
|
957
|
+
webSocketHttpRouterGroup = new HttpRouterGroup(),
|
|
958
|
+
webSocketRouterGroup = new WebSocketRouterGroup(),
|
|
807
959
|
containerClass,
|
|
808
960
|
options,
|
|
809
961
|
extendInjector
|
|
810
962
|
}: {
|
|
811
963
|
containerClass: TConstructor<unknown>;
|
|
812
|
-
|
|
813
|
-
|
|
964
|
+
prefix?: string;
|
|
965
|
+
options: Omit<TApplicationOptions, "prefix">;
|
|
966
|
+
extendInjector?: Injector;
|
|
967
|
+
startMiddlewareHandlers?: TStartMiddlewareHandlers;
|
|
968
|
+
endMiddlewareHandlers?: TEndMiddlewareHandlers;
|
|
969
|
+
guardHandlers?: TGuardHandlers;
|
|
970
|
+
openInterceptorHandlers?: TOpenInterceptorHandlers;
|
|
971
|
+
closeInterceptorHandlers?: TCloseInterceptorHandlers;
|
|
972
|
+
controllerRouterGroup?: HttpRouterGroup;
|
|
973
|
+
webSocketHttpRouterGroup?: HttpRouterGroup;
|
|
974
|
+
webSocketRouterGroup?: WebSocketRouterGroup;
|
|
814
975
|
}) {
|
|
815
976
|
if (!Reflect.getOwnMetadataKeys(containerClass).includes(containerKey)) {
|
|
816
|
-
throw Error(
|
|
977
|
+
throw Error(`[${containerClass.name}] is not a container.`);
|
|
817
978
|
}
|
|
818
979
|
|
|
819
|
-
const injector = new Injector(extendInjector);
|
|
980
|
+
const injector = !extendInjector ? new Injector() : new Injector(extendInjector);
|
|
820
981
|
const containerMetadata: TContainerMetadata = Reflect.getOwnMetadata(
|
|
821
982
|
containerKey,
|
|
822
983
|
containerClass
|
|
@@ -825,8 +986,11 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
825
986
|
const {
|
|
826
987
|
loaders,
|
|
827
988
|
middlewares,
|
|
828
|
-
guards,
|
|
829
989
|
dependencies,
|
|
990
|
+
modules,
|
|
991
|
+
guards,
|
|
992
|
+
interceptors,
|
|
993
|
+
prefix: containerPrefix,
|
|
830
994
|
config: containerConfig
|
|
831
995
|
} = containerMetadata || {};
|
|
832
996
|
|
|
@@ -902,28 +1066,38 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
902
1066
|
//#endregion
|
|
903
1067
|
|
|
904
1068
|
//#region [Dependencies]
|
|
905
|
-
|
|
1069
|
+
if (dependencies) {
|
|
1070
|
+
for (const dependency of dependencies) {
|
|
1071
|
+
const registerResult = injector.get(dependency);
|
|
1072
|
+
|
|
1073
|
+
if (!registerResult) {
|
|
1074
|
+
throw new Error(`Can not collect dependency [${dependency.name}].`);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
906
1078
|
//#endregion
|
|
907
1079
|
|
|
908
1080
|
//#region [Middleware(s)]
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
!middlewares ||
|
|
917
|
-
middlewares.forEach((middleware) => {
|
|
1081
|
+
if (middlewares) {
|
|
1082
|
+
const middlwareChecker = (
|
|
1083
|
+
instance: unknown,
|
|
1084
|
+
ofClass: unknown
|
|
1085
|
+
): ofClass is IMiddleware => !!instance;
|
|
1086
|
+
|
|
1087
|
+
for (const middleware of middlewares) {
|
|
918
1088
|
const instance = injector.get<IMiddleware>(middleware);
|
|
919
1089
|
|
|
1090
|
+
if (!instance || !middlwareChecker(instance, middleware)) {
|
|
1091
|
+
throw new Error(`Can not collect middleware [${middleware.name}].`);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
920
1094
|
if (instance.start && typeof instance.start === "function") {
|
|
921
1095
|
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
922
1096
|
Reflect.getOwnMetadata(argumentsKey, middleware, "start") || {};
|
|
923
1097
|
|
|
924
|
-
|
|
1098
|
+
startMiddlewareHandlers.push(
|
|
925
1099
|
Object.freeze({
|
|
926
|
-
class: middleware
|
|
1100
|
+
class: middleware,
|
|
927
1101
|
funcName: "start",
|
|
928
1102
|
func: instance.start.bind(instance),
|
|
929
1103
|
argumentsMetadata: argumentsMetadata
|
|
@@ -935,42 +1109,131 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
935
1109
|
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
936
1110
|
Reflect.getOwnMetadata(argumentsKey, middleware, "end") || {};
|
|
937
1111
|
|
|
938
|
-
|
|
1112
|
+
endMiddlewareHandlers.push(
|
|
939
1113
|
Object.freeze({
|
|
940
|
-
class: middleware
|
|
1114
|
+
class: middleware,
|
|
941
1115
|
funcName: "end",
|
|
942
1116
|
func: instance.end.bind(instance),
|
|
943
1117
|
argumentsMetadata: argumentsMetadata
|
|
944
1118
|
})
|
|
945
1119
|
);
|
|
946
1120
|
}
|
|
947
|
-
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
948
1123
|
//#endregion
|
|
949
1124
|
|
|
950
1125
|
//#region [Guard(s)]
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1126
|
+
if (guards) {
|
|
1127
|
+
const guardChecker = (instance: unknown, ofClass: unknown): ofClass is IGuard =>
|
|
1128
|
+
!!instance;
|
|
1129
|
+
|
|
1130
|
+
for (const guard of guards) {
|
|
1131
|
+
const instance = injector.get<IGuard>(guard);
|
|
1132
|
+
|
|
1133
|
+
if (!instance || !guardChecker(instance, guard)) {
|
|
1134
|
+
throw new Error(`Can not collect guard [${guard.name}].`);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1138
|
+
Reflect.getOwnMetadata(argumentsKey, guard, "enforce") || {};
|
|
1139
|
+
|
|
1140
|
+
guardHandlers.push(
|
|
1141
|
+
Object.freeze({
|
|
1142
|
+
class: guard,
|
|
1143
|
+
funcName: "enforce",
|
|
1144
|
+
func: instance.enforce.bind(instance),
|
|
1145
|
+
argumentsMetadata: argumentsMetadata
|
|
1146
|
+
})
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
//#endregion
|
|
1151
|
+
|
|
1152
|
+
//#region [Interceptor(s)]
|
|
1153
|
+
if (interceptors) {
|
|
1154
|
+
const interceptorChecker = (
|
|
1155
|
+
instance: unknown,
|
|
1156
|
+
ofClass: unknown
|
|
1157
|
+
): ofClass is IInterceptor => !!instance;
|
|
1158
|
+
|
|
1159
|
+
for (const interceptor of interceptors) {
|
|
1160
|
+
const instance = injector.get<IInterceptor>(interceptor);
|
|
1161
|
+
|
|
1162
|
+
if (!instance || !interceptorChecker(instance, interceptor)) {
|
|
1163
|
+
throw new Error(`Can not collect interceptor [${interceptor.name}].`);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
if (instance) {
|
|
1167
|
+
if (instance.open && typeof instance.open === "function") {
|
|
1168
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1169
|
+
Reflect.getOwnMetadata(argumentsKey, interceptor, "open") || {};
|
|
1170
|
+
|
|
1171
|
+
openInterceptorHandlers.push(
|
|
1172
|
+
Object.freeze({
|
|
1173
|
+
class: interceptor,
|
|
1174
|
+
funcName: "open",
|
|
1175
|
+
func: instance.open.bind(instance),
|
|
1176
|
+
argumentsMetadata: argumentsMetadata
|
|
1177
|
+
})
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
if (instance.close && typeof instance.close === "function") {
|
|
1182
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1183
|
+
Reflect.getOwnMetadata(argumentsKey, interceptor, "close") || {};
|
|
1184
|
+
|
|
1185
|
+
closeInterceptorHandlers.push(
|
|
1186
|
+
Object.freeze({
|
|
1187
|
+
class: interceptor,
|
|
1188
|
+
funcName: "close",
|
|
1189
|
+
func: instance.close.bind(instance),
|
|
1190
|
+
argumentsMetadata: argumentsMetadata
|
|
1191
|
+
})
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
//#endregion
|
|
1198
|
+
|
|
1199
|
+
//#region [Module(s)]
|
|
1200
|
+
if (modules) {
|
|
1201
|
+
const fullPrefix = [prefix.trim(), containerPrefix?.trim() || ""]
|
|
1202
|
+
.filter((prefix) => prefix.length > 0)
|
|
1203
|
+
.join("/");
|
|
1204
|
+
|
|
1205
|
+
for (const module of modules) {
|
|
1206
|
+
try {
|
|
1207
|
+
await this.#moduleResolver({
|
|
1208
|
+
prefix: fullPrefix,
|
|
1209
|
+
moduleClass: module,
|
|
1210
|
+
extendInjector: injector,
|
|
1211
|
+
options: options,
|
|
1212
|
+
startMiddlewareHandlers: startMiddlewareHandlers,
|
|
1213
|
+
endMiddlewareHandlers: endMiddlewareHandlers,
|
|
1214
|
+
guardHandlers: [...guardHandlers],
|
|
1215
|
+
openInterceptorHandlers: [...openInterceptorHandlers],
|
|
1216
|
+
closeInterceptorHandlers: [...closeInterceptorHandlers],
|
|
1217
|
+
controllerRouterGroup: controllerRouterGroup,
|
|
1218
|
+
webSocketHttpRouterGroup: webSocketHttpRouterGroup,
|
|
1219
|
+
webSocketRouterGroup: webSocketRouterGroup
|
|
1220
|
+
});
|
|
1221
|
+
} catch (error: unknown) {
|
|
1222
|
+
console.group(`Can not resolve module: [${module.name}].`);
|
|
1223
|
+
console.error(error);
|
|
1224
|
+
console.groupEnd();
|
|
1225
|
+
throw error;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
967
1229
|
//#endregion
|
|
968
1230
|
|
|
969
1231
|
return Object.freeze({
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1232
|
+
startMiddlewareHandlers: startMiddlewareHandlers,
|
|
1233
|
+
endMiddlewareHandlers: endMiddlewareHandlers,
|
|
1234
|
+
controllerRouterGroup: controllerRouterGroup,
|
|
1235
|
+
webSocketHttpRouterGroup: webSocketHttpRouterGroup,
|
|
1236
|
+
webSocketRouterGroup: webSocketRouterGroup
|
|
974
1237
|
});
|
|
975
1238
|
}
|
|
976
1239
|
|
|
@@ -979,20 +1242,38 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
979
1242
|
* @param param0
|
|
980
1243
|
* @returns
|
|
981
1244
|
*/
|
|
982
|
-
|
|
1245
|
+
async #moduleResolver({
|
|
1246
|
+
prefix = "",
|
|
1247
|
+
startMiddlewareHandlers = [],
|
|
1248
|
+
endMiddlewareHandlers = [],
|
|
1249
|
+
guardHandlers = [],
|
|
1250
|
+
openInterceptorHandlers = [],
|
|
1251
|
+
closeInterceptorHandlers = [],
|
|
1252
|
+
controllerRouterGroup = new HttpRouterGroup(),
|
|
1253
|
+
webSocketHttpRouterGroup = new HttpRouterGroup(),
|
|
1254
|
+
webSocketRouterGroup = new WebSocketRouterGroup(),
|
|
983
1255
|
moduleClass,
|
|
984
1256
|
options,
|
|
985
1257
|
extendInjector
|
|
986
1258
|
}: {
|
|
1259
|
+
prefix?: string;
|
|
987
1260
|
moduleClass: TConstructor<unknown>;
|
|
988
|
-
options: TApplicationOptions
|
|
989
|
-
extendInjector
|
|
1261
|
+
options: Omit<TApplicationOptions, "prefix">;
|
|
1262
|
+
extendInjector?: Injector;
|
|
1263
|
+
startMiddlewareHandlers?: TStartMiddlewareHandlers;
|
|
1264
|
+
endMiddlewareHandlers?: TEndMiddlewareHandlers;
|
|
1265
|
+
guardHandlers?: TGuardHandlers;
|
|
1266
|
+
openInterceptorHandlers?: TOpenInterceptorHandlers;
|
|
1267
|
+
closeInterceptorHandlers?: TCloseInterceptorHandlers;
|
|
1268
|
+
controllerRouterGroup?: HttpRouterGroup;
|
|
1269
|
+
webSocketHttpRouterGroup?: HttpRouterGroup;
|
|
1270
|
+
webSocketRouterGroup?: WebSocketRouterGroup;
|
|
990
1271
|
}) {
|
|
991
1272
|
if (!Reflect.getOwnMetadataKeys(moduleClass).includes(moduleKey)) {
|
|
992
|
-
throw Error(
|
|
1273
|
+
throw Error(`[${moduleClass.name}] is not a module.`);
|
|
993
1274
|
}
|
|
994
1275
|
|
|
995
|
-
const injector = new Injector(extendInjector);
|
|
1276
|
+
const injector = !extendInjector ? new Injector() : new Injector(extendInjector);
|
|
996
1277
|
const moduleMetadata: TModuleMetadata = Reflect.getOwnMetadata(moduleKey, moduleClass);
|
|
997
1278
|
|
|
998
1279
|
const {
|
|
@@ -1007,7 +1288,9 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1007
1288
|
config: moduleConfig
|
|
1008
1289
|
} = moduleMetadata || {};
|
|
1009
1290
|
|
|
1010
|
-
const fullPrefix =
|
|
1291
|
+
const fullPrefix = [prefix.trim(), modulePrefix?.trim() || ""]
|
|
1292
|
+
.filter((prefix) => prefix.length > 0)
|
|
1293
|
+
.join("/");
|
|
1011
1294
|
|
|
1012
1295
|
//#region [Configuration(s)]
|
|
1013
1296
|
const { config } = Object.freeze({
|
|
@@ -1087,28 +1370,38 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1087
1370
|
//#endregion
|
|
1088
1371
|
|
|
1089
1372
|
//#region [Dependencies]
|
|
1090
|
-
|
|
1373
|
+
if (dependencies) {
|
|
1374
|
+
for (const dependency of dependencies) {
|
|
1375
|
+
const registerResult = injector.get(dependency);
|
|
1376
|
+
|
|
1377
|
+
if (!registerResult) {
|
|
1378
|
+
throw new Error(`Can not collect dependency [${dependency.name}].`);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1091
1382
|
//#endregion
|
|
1092
1383
|
|
|
1093
1384
|
//#region [Middleware(s)]
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
!middlewares ||
|
|
1102
|
-
middlewares.forEach((middleware) => {
|
|
1385
|
+
if (middlewares) {
|
|
1386
|
+
const middlwareChecker = (
|
|
1387
|
+
instance: unknown,
|
|
1388
|
+
ofClass: unknown
|
|
1389
|
+
): ofClass is IMiddleware => !!instance;
|
|
1390
|
+
|
|
1391
|
+
for (const middleware of middlewares) {
|
|
1103
1392
|
const instance = injector.get<IMiddleware>(middleware);
|
|
1104
1393
|
|
|
1394
|
+
if (!instance || !middlwareChecker(instance, middleware)) {
|
|
1395
|
+
throw new Error(`Can not collect middleware [${middleware.name}].`);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1105
1398
|
if (instance.start && typeof instance.start === "function") {
|
|
1106
1399
|
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1107
1400
|
Reflect.getOwnMetadata(argumentsKey, middleware, "start") || {};
|
|
1108
1401
|
|
|
1109
|
-
|
|
1402
|
+
startMiddlewareHandlers.push(
|
|
1110
1403
|
Object.freeze({
|
|
1111
|
-
class: middleware
|
|
1404
|
+
class: middleware,
|
|
1112
1405
|
funcName: "start",
|
|
1113
1406
|
func: instance.start.bind(instance),
|
|
1114
1407
|
argumentsMetadata: argumentsMetadata
|
|
@@ -1120,200 +1413,159 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1120
1413
|
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1121
1414
|
Reflect.getOwnMetadata(argumentsKey, middleware, "end") || {};
|
|
1122
1415
|
|
|
1123
|
-
|
|
1416
|
+
endMiddlewareHandlers.push(
|
|
1124
1417
|
Object.freeze({
|
|
1125
|
-
class: middleware
|
|
1418
|
+
class: middleware,
|
|
1126
1419
|
funcName: "end",
|
|
1127
1420
|
func: instance.end.bind(instance),
|
|
1128
1421
|
argumentsMetadata: argumentsMetadata
|
|
1129
1422
|
})
|
|
1130
1423
|
);
|
|
1131
1424
|
}
|
|
1132
|
-
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1133
1427
|
//#endregion
|
|
1134
1428
|
|
|
1135
1429
|
//#region [Guard(s)]
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1430
|
+
if (guards) {
|
|
1431
|
+
const guardChecker = (instance: unknown, ofClass: unknown): ofClass is IGuard =>
|
|
1432
|
+
!!instance;
|
|
1433
|
+
|
|
1434
|
+
for (const guard of guards) {
|
|
1435
|
+
const instance = injector.get<IGuard>(guard);
|
|
1436
|
+
|
|
1437
|
+
if (!instance || !guardChecker(instance, guard)) {
|
|
1438
|
+
throw new Error(`Can not collect guard [${guard.name}].`);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1442
|
+
Reflect.getOwnMetadata(argumentsKey, guard, "enforce") || {};
|
|
1443
|
+
|
|
1444
|
+
guardHandlers.push(
|
|
1445
|
+
Object.freeze({
|
|
1446
|
+
class: guard,
|
|
1447
|
+
funcName: "enforce",
|
|
1448
|
+
func: instance.enforce.bind(instance),
|
|
1449
|
+
argumentsMetadata: argumentsMetadata
|
|
1450
|
+
})
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1152
1454
|
//#endregion
|
|
1153
1455
|
|
|
1154
|
-
//#region [
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
> = [];
|
|
1456
|
+
//#region [Interceptor(s)]
|
|
1457
|
+
if (interceptors) {
|
|
1458
|
+
const interceptorChecker = (
|
|
1459
|
+
instance: unknown,
|
|
1460
|
+
ofClass: unknown
|
|
1461
|
+
): ofClass is IInterceptor => !!instance;
|
|
1161
1462
|
|
|
1162
|
-
|
|
1163
|
-
interceptors.forEach((interceptor) => {
|
|
1463
|
+
for (const interceptor of interceptors) {
|
|
1164
1464
|
const instance = injector.get<IInterceptor>(interceptor);
|
|
1165
1465
|
|
|
1166
|
-
if (instance
|
|
1167
|
-
|
|
1168
|
-
Reflect.getOwnMetadata(argumentsKey, interceptor, "open") || {};
|
|
1169
|
-
|
|
1170
|
-
openInterceptorGroup.push(
|
|
1171
|
-
Object.freeze({
|
|
1172
|
-
class: interceptor as IInterceptor,
|
|
1173
|
-
funcName: "open",
|
|
1174
|
-
func: instance.open.bind(instance),
|
|
1175
|
-
argumentsMetadata: argumentsMetadata
|
|
1176
|
-
})
|
|
1177
|
-
);
|
|
1466
|
+
if (!instance || !interceptorChecker(instance, interceptor)) {
|
|
1467
|
+
throw new Error(`Can not collect interceptor [${interceptor.name}].`);
|
|
1178
1468
|
}
|
|
1179
1469
|
|
|
1180
|
-
if (instance
|
|
1181
|
-
|
|
1182
|
-
|
|
1470
|
+
if (instance) {
|
|
1471
|
+
if (instance.open && typeof instance.open === "function") {
|
|
1472
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1473
|
+
Reflect.getOwnMetadata(argumentsKey, interceptor, "open") || {};
|
|
1474
|
+
|
|
1475
|
+
openInterceptorHandlers.push(
|
|
1476
|
+
Object.freeze({
|
|
1477
|
+
class: interceptor,
|
|
1478
|
+
funcName: "open",
|
|
1479
|
+
func: instance.open.bind(instance),
|
|
1480
|
+
argumentsMetadata: argumentsMetadata
|
|
1481
|
+
})
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1183
1484
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1485
|
+
if (instance.close && typeof instance.close === "function") {
|
|
1486
|
+
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
1487
|
+
Reflect.getOwnMetadata(argumentsKey, interceptor, "close") || {};
|
|
1488
|
+
|
|
1489
|
+
closeInterceptorHandlers.push(
|
|
1490
|
+
Object.freeze({
|
|
1491
|
+
class: interceptor,
|
|
1492
|
+
funcName: "close",
|
|
1493
|
+
func: instance.close.bind(instance),
|
|
1494
|
+
argumentsMetadata: argumentsMetadata
|
|
1495
|
+
})
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1192
1498
|
}
|
|
1193
|
-
}
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1194
1501
|
//#endregion
|
|
1195
1502
|
|
|
1196
1503
|
//#region [Controller(s)]
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
controllerConstructor,
|
|
1203
|
-
httpRouterGroup: controllerRouterGroup,
|
|
1504
|
+
if (controllers) {
|
|
1505
|
+
for (const controller of controllers) {
|
|
1506
|
+
this.#controllerResolver({
|
|
1507
|
+
controllerConstructor: controller,
|
|
1508
|
+
prefix: fullPrefix,
|
|
1204
1509
|
injector: injector,
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1510
|
+
httpRouterGroup: controllerRouterGroup,
|
|
1511
|
+
guardHandlers: [...guardHandlers],
|
|
1512
|
+
openInterceptorHandlers: [...openInterceptorHandlers],
|
|
1513
|
+
closeInterceptorHandlers: [...closeInterceptorHandlers]
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1208
1517
|
//#endregion
|
|
1209
1518
|
|
|
1210
1519
|
//#region [WebSocket(s)]
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
webSockets &&
|
|
1215
|
-
webSockets.forEach((webSocket) =>
|
|
1216
|
-
this.initWebSocketInstance({
|
|
1520
|
+
if (webSockets) {
|
|
1521
|
+
for (const webSocket of webSockets) {
|
|
1522
|
+
this.#webSocketResolver({
|
|
1217
1523
|
webSocketConstructor: webSocket,
|
|
1218
|
-
httpRouterGroup: webSocketHttpRouterGroup,
|
|
1219
|
-
webSocketRouterGroup: webSocketRouterGroup,
|
|
1220
1524
|
injector: injector,
|
|
1221
|
-
prefix: fullPrefix
|
|
1222
|
-
|
|
1223
|
-
|
|
1525
|
+
prefix: fullPrefix,
|
|
1526
|
+
webSocketHttpRouterGroup: webSocketHttpRouterGroup,
|
|
1527
|
+
webSocketRouterGroup: webSocketRouterGroup
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1224
1531
|
//#endregion
|
|
1225
1532
|
|
|
1226
1533
|
return Object.freeze({
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
startMiddlewareGroup: startMiddlewareGroup,
|
|
1230
|
-
endMiddlewareGroup: endMiddlewareGroup,
|
|
1231
|
-
guardGroup: guardGroup,
|
|
1232
|
-
openInterceptorGroup: openInterceptorGroup,
|
|
1233
|
-
closeInterceptorGroup: closeInterceptorGroup,
|
|
1534
|
+
startMiddlewareHandlers: startMiddlewareHandlers,
|
|
1535
|
+
endMiddlewareHandlers: endMiddlewareHandlers,
|
|
1234
1536
|
controllerRouterGroup: controllerRouterGroup,
|
|
1235
1537
|
webSocketHttpRouterGroup: webSocketHttpRouterGroup,
|
|
1236
1538
|
webSocketRouterGroup: webSocketRouterGroup
|
|
1237
1539
|
});
|
|
1238
1540
|
}
|
|
1239
1541
|
|
|
1240
|
-
/**
|
|
1241
|
-
*
|
|
1242
|
-
* @param data
|
|
1243
|
-
* @param zodSchema
|
|
1244
|
-
* @param argumentIndex
|
|
1245
|
-
* @param funcName
|
|
1246
|
-
* @returns
|
|
1247
|
-
*/
|
|
1248
|
-
private async argumentsResolution<TValidationSchema = unknown>(
|
|
1249
|
-
data: unknown,
|
|
1250
|
-
validationSchema: TValidationSchema,
|
|
1251
|
-
argumentIndex: number,
|
|
1252
|
-
funcName: string | symbol
|
|
1253
|
-
) {
|
|
1254
|
-
if (!this.#customValidator) {
|
|
1255
|
-
return data;
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
try {
|
|
1259
|
-
const validation = await this.#customValidator.validate(
|
|
1260
|
-
data,
|
|
1261
|
-
validationSchema,
|
|
1262
|
-
argumentIndex,
|
|
1263
|
-
funcName
|
|
1264
|
-
);
|
|
1265
|
-
|
|
1266
|
-
if (!(validation instanceof ValidationFailed)) {
|
|
1267
|
-
return validation;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
throw new HttpClientError({
|
|
1271
|
-
httpCode: 400,
|
|
1272
|
-
message: `Validation at the [${funcName.toString()}] method fails at positional argument [${argumentIndex}].`,
|
|
1273
|
-
data: validation.error
|
|
1274
|
-
});
|
|
1275
|
-
} catch (error) {
|
|
1276
|
-
if (error instanceof HttpClientError) {
|
|
1277
|
-
throw error;
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
throw new HttpServerError({
|
|
1281
|
-
httpCode: 500,
|
|
1282
|
-
message: `Validation at the [${funcName.toString()}] method error at positional argument [${argumentIndex}].`,
|
|
1283
|
-
data: !(error instanceof Error)
|
|
1284
|
-
? error
|
|
1285
|
-
: [
|
|
1286
|
-
{
|
|
1287
|
-
message: error.message,
|
|
1288
|
-
code: error.name,
|
|
1289
|
-
cause: error.cause
|
|
1290
|
-
}
|
|
1291
|
-
]
|
|
1292
|
-
});
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
1542
|
/**
|
|
1297
1543
|
*
|
|
1298
1544
|
* @param param0
|
|
1299
1545
|
* @returns
|
|
1300
1546
|
*/
|
|
1301
|
-
|
|
1547
|
+
#controllerResolver({
|
|
1302
1548
|
controllerConstructor,
|
|
1303
|
-
|
|
1304
|
-
injector,
|
|
1305
|
-
|
|
1549
|
+
prefix = "",
|
|
1550
|
+
injector = new Injector(),
|
|
1551
|
+
httpRouterGroup = new HttpRouterGroup(),
|
|
1552
|
+
guardHandlers = [],
|
|
1553
|
+
openInterceptorHandlers = [],
|
|
1554
|
+
closeInterceptorHandlers = []
|
|
1306
1555
|
}: Readonly<{
|
|
1307
1556
|
controllerConstructor: TConstructor<unknown>;
|
|
1308
|
-
|
|
1309
|
-
injector: Injector;
|
|
1557
|
+
injector?: Injector;
|
|
1310
1558
|
prefix?: string;
|
|
1559
|
+
httpRouterGroup?: HttpRouterGroup;
|
|
1560
|
+
guardHandlers?: TGuardHandlers;
|
|
1561
|
+
openInterceptorHandlers?: TOpenInterceptorHandlers;
|
|
1562
|
+
closeInterceptorHandlers?: TCloseInterceptorHandlers;
|
|
1311
1563
|
}>) {
|
|
1312
1564
|
if (!Reflect.getOwnMetadataKeys(controllerConstructor).includes(controllerKey)) {
|
|
1313
|
-
throw Error(
|
|
1565
|
+
throw Error(`[${controllerConstructor.name}] is not a controller.`);
|
|
1314
1566
|
}
|
|
1315
1567
|
|
|
1316
|
-
const controller = injector.get(controllerConstructor);
|
|
1568
|
+
const controller = injector.get<IController>(controllerConstructor);
|
|
1317
1569
|
|
|
1318
1570
|
if (!controller) {
|
|
1319
1571
|
throw Error("Can not initialize controller.");
|
|
@@ -1327,16 +1579,25 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1327
1579
|
httpMetadata: []
|
|
1328
1580
|
};
|
|
1329
1581
|
|
|
1582
|
+
const fullPrefix = [prefix.trim(), controllerMetadata.prefix.trim()]
|
|
1583
|
+
.filter((prefix) => prefix.length > 0)
|
|
1584
|
+
.join("/");
|
|
1585
|
+
|
|
1330
1586
|
const router = new HttpRouter({
|
|
1331
|
-
alias:
|
|
1587
|
+
alias: fullPrefix,
|
|
1588
|
+
guardHandlers: guardHandlers,
|
|
1589
|
+
openInterceptorHandlers: openInterceptorHandlers,
|
|
1590
|
+
closeInterceptorHandlers: closeInterceptorHandlers
|
|
1332
1591
|
});
|
|
1333
1592
|
|
|
1334
|
-
controllerMetadata.httpMetadata
|
|
1593
|
+
for (const routeMetadata of controllerMetadata.httpMetadata) {
|
|
1335
1594
|
if (typeof routeMetadata.descriptor.value !== "function") {
|
|
1336
|
-
|
|
1595
|
+
continue;
|
|
1337
1596
|
}
|
|
1338
1597
|
|
|
1339
|
-
const route = router.route(
|
|
1598
|
+
const route = router.route({
|
|
1599
|
+
alias: routeMetadata.path
|
|
1600
|
+
});
|
|
1340
1601
|
const handler = routeMetadata.descriptor.value.bind(controller);
|
|
1341
1602
|
const httpRouteModel = Object.freeze({
|
|
1342
1603
|
class: controllerConstructor,
|
|
@@ -1347,21 +1608,85 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1347
1608
|
|
|
1348
1609
|
switch (routeMetadata.httpMethod) {
|
|
1349
1610
|
case "GET":
|
|
1350
|
-
|
|
1611
|
+
route.get({ model: httpRouteModel });
|
|
1612
|
+
break;
|
|
1351
1613
|
case "POST":
|
|
1352
|
-
|
|
1614
|
+
route.post({ model: httpRouteModel });
|
|
1615
|
+
break;
|
|
1353
1616
|
case "PUT":
|
|
1354
|
-
|
|
1617
|
+
route.put({ model: httpRouteModel });
|
|
1618
|
+
break;
|
|
1355
1619
|
case "PATCH":
|
|
1356
|
-
|
|
1620
|
+
route.patch({ model: httpRouteModel });
|
|
1621
|
+
break;
|
|
1357
1622
|
case "DELETE":
|
|
1358
|
-
|
|
1623
|
+
route.delete({ model: httpRouteModel });
|
|
1624
|
+
break;
|
|
1359
1625
|
case "OPTIONS":
|
|
1360
|
-
|
|
1626
|
+
route.options({ model: httpRouteModel });
|
|
1627
|
+
break;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
return httpRouterGroup.add(router);
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
/**
|
|
1635
|
+
*
|
|
1636
|
+
* @param param0
|
|
1637
|
+
* @returns
|
|
1638
|
+
*/
|
|
1639
|
+
async #argumentsResolver<TValidationSchema = unknown>({
|
|
1640
|
+
data,
|
|
1641
|
+
validationSchema,
|
|
1642
|
+
argumentIndex,
|
|
1643
|
+
funcName
|
|
1644
|
+
}: {
|
|
1645
|
+
data: unknown;
|
|
1646
|
+
validationSchema: TValidationSchema;
|
|
1647
|
+
argumentIndex: number;
|
|
1648
|
+
funcName: string | symbol;
|
|
1649
|
+
}) {
|
|
1650
|
+
if (!this.#customValidator) {
|
|
1651
|
+
return data;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
try {
|
|
1655
|
+
const validation = await this.#customValidator.validate(
|
|
1656
|
+
data,
|
|
1657
|
+
validationSchema,
|
|
1658
|
+
argumentIndex,
|
|
1659
|
+
funcName
|
|
1660
|
+
);
|
|
1661
|
+
|
|
1662
|
+
if (!(validation instanceof ValidationFailed)) {
|
|
1663
|
+
return validation;
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
throw new HttpClientError({
|
|
1667
|
+
httpCode: 400,
|
|
1668
|
+
message: `Validation at the [${funcName.toString()}] method fails at positional argument [${argumentIndex}].`,
|
|
1669
|
+
data: validation.error
|
|
1670
|
+
});
|
|
1671
|
+
} catch (error) {
|
|
1672
|
+
if (error instanceof HttpClientError) {
|
|
1673
|
+
throw error;
|
|
1361
1674
|
}
|
|
1362
|
-
});
|
|
1363
1675
|
|
|
1364
|
-
|
|
1676
|
+
throw new HttpServerError({
|
|
1677
|
+
httpCode: 500,
|
|
1678
|
+
message: `Validation at the [${funcName.toString()}] method error at positional argument [${argumentIndex}].`,
|
|
1679
|
+
data: !(error instanceof Error)
|
|
1680
|
+
? error
|
|
1681
|
+
: [
|
|
1682
|
+
{
|
|
1683
|
+
message: error.message,
|
|
1684
|
+
code: error.name,
|
|
1685
|
+
cause: error.cause
|
|
1686
|
+
}
|
|
1687
|
+
]
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1365
1690
|
}
|
|
1366
1691
|
|
|
1367
1692
|
/**
|
|
@@ -1369,24 +1694,30 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1369
1694
|
* @param param0
|
|
1370
1695
|
* @returns
|
|
1371
1696
|
*/
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1697
|
+
#webSocketResolver({
|
|
1698
|
+
webSocketConstructor,
|
|
1699
|
+
prefix = "",
|
|
1700
|
+
injector = new Injector(),
|
|
1701
|
+
webSocketHttpRouterGroup = new HttpRouterGroup(),
|
|
1702
|
+
webSocketRouterGroup = new WebSocketRouterGroup(),
|
|
1703
|
+
guardHandlers = [],
|
|
1704
|
+
openInterceptorHandlers = [],
|
|
1705
|
+
closeInterceptorHandlers = []
|
|
1378
1706
|
}: Readonly<{
|
|
1379
1707
|
webSocketConstructor: TConstructor<unknown>;
|
|
1380
|
-
|
|
1381
|
-
webSocketRouterGroup
|
|
1382
|
-
injector
|
|
1708
|
+
webSocketHttpRouterGroup?: HttpRouterGroup;
|
|
1709
|
+
webSocketRouterGroup?: WebSocketRouterGroup;
|
|
1710
|
+
injector?: Injector;
|
|
1383
1711
|
prefix?: string;
|
|
1712
|
+
guardHandlers?: TGuardHandlers;
|
|
1713
|
+
openInterceptorHandlers?: TOpenInterceptorHandlers;
|
|
1714
|
+
closeInterceptorHandlers?: TCloseInterceptorHandlers;
|
|
1384
1715
|
}>): Readonly<{
|
|
1385
|
-
|
|
1716
|
+
webSocketHttpRouterGroup: HttpRouterGroup;
|
|
1386
1717
|
webSocketRouterGroup: WebSocketRouterGroup;
|
|
1387
1718
|
}> {
|
|
1388
1719
|
if (!Reflect.getOwnMetadataKeys(webSocketConstructor).includes(webSocketKey)) {
|
|
1389
|
-
throw Error(
|
|
1720
|
+
throw Error(`[${webSocketConstructor.name}] is not a websocket route.`);
|
|
1390
1721
|
}
|
|
1391
1722
|
|
|
1392
1723
|
const webSocket = injector.get(webSocketConstructor);
|
|
@@ -1404,11 +1735,14 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1404
1735
|
http: []
|
|
1405
1736
|
};
|
|
1406
1737
|
|
|
1407
|
-
const fullPrefix = `/${prefix
|
|
1738
|
+
const fullPrefix = `/${prefix}/${webSocketMetadata.prefix}`;
|
|
1408
1739
|
|
|
1409
1740
|
//#region [HTTP ROUTER]
|
|
1410
1741
|
const router = new HttpRouter({
|
|
1411
|
-
alias: fullPrefix
|
|
1742
|
+
alias: fullPrefix,
|
|
1743
|
+
guardHandlers: guardHandlers,
|
|
1744
|
+
openInterceptorHandlers: openInterceptorHandlers,
|
|
1745
|
+
closeInterceptorHandlers: closeInterceptorHandlers
|
|
1412
1746
|
});
|
|
1413
1747
|
|
|
1414
1748
|
for (const [_key, httpMetadata] of Object.entries(webSocketMetadata.http)) {
|
|
@@ -1416,7 +1750,9 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1416
1750
|
continue;
|
|
1417
1751
|
}
|
|
1418
1752
|
|
|
1419
|
-
const route = router.route(
|
|
1753
|
+
const route = router.route({
|
|
1754
|
+
alias: httpMetadata.path
|
|
1755
|
+
});
|
|
1420
1756
|
const handler = httpMetadata.descriptor.value.bind(webSocket);
|
|
1421
1757
|
const httpRouteModel = Object.freeze({
|
|
1422
1758
|
class: webSocketConstructor,
|
|
@@ -1435,7 +1771,7 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1435
1771
|
}
|
|
1436
1772
|
}
|
|
1437
1773
|
|
|
1438
|
-
|
|
1774
|
+
webSocketHttpRouterGroup.add(router);
|
|
1439
1775
|
//#endregion
|
|
1440
1776
|
|
|
1441
1777
|
//#region [WEBSOCKET ROUTER]
|
|
@@ -1455,142 +1791,55 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1455
1791
|
//#endregion
|
|
1456
1792
|
|
|
1457
1793
|
return Object.freeze({
|
|
1458
|
-
|
|
1794
|
+
webSocketHttpRouterGroup: webSocketHttpRouterGroup,
|
|
1459
1795
|
webSocketRouterGroup: webSocketRouterGroup
|
|
1460
1796
|
});
|
|
1461
1797
|
}
|
|
1462
1798
|
|
|
1463
1799
|
/**
|
|
1464
1800
|
*
|
|
1465
|
-
* @param
|
|
1466
|
-
* @returns
|
|
1801
|
+
* @param data
|
|
1467
1802
|
*/
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
headers,
|
|
1472
|
-
data
|
|
1473
|
-
}: {
|
|
1474
|
-
status?: number;
|
|
1475
|
-
statusText?: string;
|
|
1476
|
-
headers: Headers;
|
|
1477
|
-
data: unknown;
|
|
1478
|
-
}): Response {
|
|
1479
|
-
const contentType = headers.get("Content-Type") || "text/plain";
|
|
1480
|
-
|
|
1481
|
-
if (contentType.includes("application/json")) {
|
|
1482
|
-
return this.finalizeResponse(
|
|
1483
|
-
new Response(
|
|
1484
|
-
!data
|
|
1485
|
-
? undefined
|
|
1486
|
-
: data instanceof ReadableStream
|
|
1487
|
-
? data
|
|
1488
|
-
: JSON.stringify(data),
|
|
1489
|
-
{
|
|
1490
|
-
status: !data ? 204 : status,
|
|
1491
|
-
statusText: statusText,
|
|
1492
|
-
headers: headers
|
|
1493
|
-
}
|
|
1494
|
-
)
|
|
1495
|
-
);
|
|
1803
|
+
async #pipesEnforcer(
|
|
1804
|
+
data: TStartMiddlewaresPipe & {
|
|
1805
|
+
context: Context;
|
|
1496
1806
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
!data ? undefined : data instanceof ReadableStream ? data : String(data),
|
|
1502
|
-
{
|
|
1503
|
-
status: !data ? 204 : status,
|
|
1504
|
-
statusText: statusText,
|
|
1505
|
-
headers: headers
|
|
1506
|
-
}
|
|
1507
|
-
)
|
|
1508
|
-
);
|
|
1807
|
+
): Promise<undefined>;
|
|
1808
|
+
async #pipesEnforcer(
|
|
1809
|
+
data: TEndMiddlewaresPipe & {
|
|
1810
|
+
context: Context;
|
|
1509
1811
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
data instanceof ArrayBuffer ||
|
|
1515
|
-
data instanceof Blob ||
|
|
1516
|
-
data instanceof ReadableStream
|
|
1517
|
-
) {
|
|
1518
|
-
return this.finalizeResponse(
|
|
1519
|
-
new Response(data as BodyInit, {
|
|
1520
|
-
status: status,
|
|
1521
|
-
statusText: statusText,
|
|
1522
|
-
headers: headers
|
|
1523
|
-
})
|
|
1524
|
-
);
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
throw new Error("Invalid data type for application/octet-stream");
|
|
1812
|
+
): Promise<undefined>;
|
|
1813
|
+
async #pipesEnforcer(
|
|
1814
|
+
data: TOpenInterceptorsPipe & {
|
|
1815
|
+
context: Context;
|
|
1528
1816
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
new Response(data, { status: status, statusText: statusText, headers: headers })
|
|
1534
|
-
);
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
throw new Error("multipart/form-data requires FormData object");
|
|
1817
|
+
): Promise<undefined>;
|
|
1818
|
+
async #pipesEnforcer(
|
|
1819
|
+
data: TCloseInterceptorsPipe & {
|
|
1820
|
+
context: Context;
|
|
1538
1821
|
}
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
response.headers.set("X-Powered-By", "Bool Typescript");
|
|
1556
|
-
|
|
1557
|
-
return response;
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
/**
|
|
1561
|
-
*
|
|
1562
|
-
* @param param0
|
|
1563
|
-
* @returns
|
|
1564
|
-
*/
|
|
1565
|
-
private async httpFetcher({
|
|
1566
|
-
context: outerContext,
|
|
1567
|
-
route,
|
|
1568
|
-
options,
|
|
1569
|
-
resolutedMap
|
|
1570
|
-
}: Partial<{
|
|
1571
|
-
route: NonNullable<ReturnType<HttpRouterGroup["find"]>>;
|
|
1572
|
-
resolutedMap:
|
|
1573
|
-
| Partial<
|
|
1574
|
-
NonNullable<Awaited<ReturnType<Application<TRootClass>["containerResolution"]>>>
|
|
1575
|
-
>
|
|
1576
|
-
| Partial<
|
|
1577
|
-
NonNullable<Awaited<ReturnType<Application<TRootClass>["moduleResolution"]>>>
|
|
1578
|
-
>;
|
|
1822
|
+
): Promise<undefined>;
|
|
1823
|
+
async #pipesEnforcer(
|
|
1824
|
+
data: TGuardsPipe & {
|
|
1825
|
+
context: Context;
|
|
1826
|
+
}
|
|
1827
|
+
): Promise<TGuardReturn>;
|
|
1828
|
+
async #pipesEnforcer(
|
|
1829
|
+
data: TControllerPipe & {
|
|
1830
|
+
context: Context;
|
|
1831
|
+
}
|
|
1832
|
+
): Promise<undefined>;
|
|
1833
|
+
async #pipesEnforcer({
|
|
1834
|
+
type,
|
|
1835
|
+
handlers,
|
|
1836
|
+
context
|
|
1837
|
+
}: TPipesEnforcerUnion & {
|
|
1579
1838
|
context: Context;
|
|
1580
|
-
|
|
1581
|
-
isContainer: boolean;
|
|
1582
|
-
}>;
|
|
1583
|
-
}>) {
|
|
1839
|
+
}): Promise<unknown> {
|
|
1584
1840
|
const contextOptions = { isStatic: true };
|
|
1585
|
-
const context = new Context(...(!outerContext ? [] : [outerContext])).setOptions(
|
|
1586
|
-
contextOptions
|
|
1587
|
-
);
|
|
1588
1841
|
|
|
1589
|
-
|
|
1590
|
-
context
|
|
1591
|
-
.set(paramsArgsKey, route.parameters, { isPassthrough: true })
|
|
1592
|
-
.set(routeModelArgsKey, route.model, { isPassthrough: true });
|
|
1593
|
-
}
|
|
1842
|
+
context.setOptions(contextOptions);
|
|
1594
1843
|
|
|
1595
1844
|
const httpServer =
|
|
1596
1845
|
context.get<Server<TWebSocketUpgradeData> | null | undefined>(
|
|
@@ -1614,313 +1863,285 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1614
1863
|
NonNullable<ReturnType<HttpRouterGroup["find"]>>["model"] | null | undefined
|
|
1615
1864
|
>(routeModelArgsKey, contextOptions) || undefined;
|
|
1616
1865
|
|
|
1617
|
-
if (
|
|
1618
|
-
const
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
for (let i = 0; i < startMiddlewareGroup.length; i++) {
|
|
1623
|
-
const args = [];
|
|
1624
|
-
const {
|
|
1625
|
-
func: handler,
|
|
1626
|
-
funcName: functionName,
|
|
1627
|
-
argumentsMetadata
|
|
1628
|
-
} = startMiddlewareGroup[i];
|
|
1629
|
-
|
|
1630
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1631
|
-
switch (argMetadata.type) {
|
|
1632
|
-
case contextArgsKey:
|
|
1633
|
-
args[argMetadata.index] = !argMetadata.key
|
|
1634
|
-
? context
|
|
1635
|
-
: context.get(argMetadata.key, contextOptions);
|
|
1636
|
-
break;
|
|
1637
|
-
case requestArgsKey:
|
|
1638
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1639
|
-
? request
|
|
1640
|
-
: await this.argumentsResolution(
|
|
1641
|
-
request,
|
|
1642
|
-
argMetadata.validationSchema,
|
|
1643
|
-
argMetadata.index,
|
|
1644
|
-
functionName
|
|
1645
|
-
);
|
|
1646
|
-
break;
|
|
1647
|
-
case requestBodyArgsKey:
|
|
1648
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1649
|
-
? await request?.[argMetadata.parser || "json"]()
|
|
1650
|
-
: await this.argumentsResolution(
|
|
1651
|
-
await request?.[argMetadata.parser || "json"](),
|
|
1652
|
-
argMetadata.validationSchema,
|
|
1653
|
-
argMetadata.index,
|
|
1654
|
-
functionName
|
|
1655
|
-
);
|
|
1656
|
-
break;
|
|
1657
|
-
case requestHeadersArgsKey:
|
|
1658
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1659
|
-
? requestHeaders
|
|
1660
|
-
: await this.argumentsResolution(
|
|
1661
|
-
requestHeaders?.toJSON(),
|
|
1662
|
-
argMetadata.validationSchema,
|
|
1663
|
-
argMetadata.index,
|
|
1664
|
-
functionName
|
|
1665
|
-
);
|
|
1666
|
-
break;
|
|
1667
|
-
case requestHeaderArgsKey:
|
|
1668
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1669
|
-
? requestHeaders?.get(argMetadata.key) || undefined
|
|
1670
|
-
: await this.argumentsResolution(
|
|
1671
|
-
requestHeaders?.get(argMetadata.key) || undefined,
|
|
1672
|
-
argMetadata.validationSchema,
|
|
1673
|
-
argMetadata.index,
|
|
1674
|
-
functionName
|
|
1675
|
-
);
|
|
1676
|
-
break;
|
|
1677
|
-
case paramArgsKey:
|
|
1678
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1679
|
-
? parameters?.[argMetadata.key] || undefined
|
|
1680
|
-
: await this.argumentsResolution(
|
|
1681
|
-
parameters?.[argMetadata.key] || undefined,
|
|
1682
|
-
argMetadata.validationSchema,
|
|
1683
|
-
argMetadata.index,
|
|
1684
|
-
functionName
|
|
1685
|
-
);
|
|
1686
|
-
break;
|
|
1687
|
-
case routeModelArgsKey:
|
|
1688
|
-
args[argMetadata.index] = routeModel;
|
|
1689
|
-
break;
|
|
1690
|
-
case responseHeadersArgsKey:
|
|
1691
|
-
args[argMetadata.index] = responseHeaders;
|
|
1692
|
-
break;
|
|
1693
|
-
case httpServerArgsKey:
|
|
1694
|
-
args[argMetadata.index] = httpServer;
|
|
1695
|
-
break;
|
|
1696
|
-
default:
|
|
1697
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1698
|
-
? !context.has(argMetadata.type, contextOptions)
|
|
1699
|
-
? undefined
|
|
1700
|
-
: context.get(argMetadata.type, contextOptions)
|
|
1701
|
-
: await this.argumentsResolution(
|
|
1702
|
-
!(argMetadata.type in context)
|
|
1703
|
-
? undefined
|
|
1704
|
-
: context.get(argMetadata.type, contextOptions),
|
|
1705
|
-
argMetadata.validationSchema,
|
|
1706
|
-
argMetadata.index,
|
|
1707
|
-
functionName
|
|
1708
|
-
);
|
|
1709
|
-
break;
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1866
|
+
if (type === "START_MIDDLEWARES" || type === "END_MIDDLEWARES") {
|
|
1867
|
+
const strategy =
|
|
1868
|
+
type === "START_MIDDLEWARES"
|
|
1869
|
+
? this.#resolutedOptions.pipelineStrategy.startMiddlewares
|
|
1870
|
+
: this.#resolutedOptions.pipelineStrategy.endMiddlewares;
|
|
1712
1871
|
|
|
1713
|
-
|
|
1872
|
+
for (
|
|
1873
|
+
let i = strategy === "FIFO" ? 0 : handlers.length - 1;
|
|
1874
|
+
strategy === "FIFO" ? i < handlers.length : i > -1;
|
|
1875
|
+
strategy === "FIFO" ? i++ : i--
|
|
1876
|
+
) {
|
|
1877
|
+
const args = [];
|
|
1878
|
+
const { func: handler, funcName: functionName, argumentsMetadata } = handlers[i];
|
|
1879
|
+
|
|
1880
|
+
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1881
|
+
switch (argMetadata.type) {
|
|
1882
|
+
case contextArgsKey:
|
|
1883
|
+
args[argMetadata.index] = !argMetadata.key
|
|
1884
|
+
? context
|
|
1885
|
+
: context.get(argMetadata.key, contextOptions);
|
|
1886
|
+
break;
|
|
1887
|
+
case requestArgsKey:
|
|
1888
|
+
args[argMetadata.index] = request;
|
|
1889
|
+
break;
|
|
1890
|
+
case requestBodyArgsKey:
|
|
1891
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1892
|
+
? await request?.[argMetadata.parser || "json"]()
|
|
1893
|
+
: await this.#argumentsResolver({
|
|
1894
|
+
data: await request?.[argMetadata.parser || "json"](),
|
|
1895
|
+
validationSchema: argMetadata.validationSchema,
|
|
1896
|
+
argumentIndex: argMetadata.index,
|
|
1897
|
+
funcName: functionName
|
|
1898
|
+
});
|
|
1899
|
+
break;
|
|
1900
|
+
case requestHeadersArgsKey:
|
|
1901
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1902
|
+
? requestHeaders
|
|
1903
|
+
: await this.#argumentsResolver({
|
|
1904
|
+
data: requestHeaders?.toJSON(),
|
|
1905
|
+
validationSchema: argMetadata.validationSchema,
|
|
1906
|
+
argumentIndex: argMetadata.index,
|
|
1907
|
+
funcName: functionName
|
|
1908
|
+
});
|
|
1909
|
+
break;
|
|
1910
|
+
case requestHeaderArgsKey:
|
|
1911
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1912
|
+
? requestHeaders?.get(argMetadata.key) || undefined
|
|
1913
|
+
: await this.#argumentsResolver({
|
|
1914
|
+
data: requestHeaders?.get(argMetadata.key) || undefined,
|
|
1915
|
+
validationSchema: argMetadata.validationSchema,
|
|
1916
|
+
argumentIndex: argMetadata.index,
|
|
1917
|
+
funcName: functionName
|
|
1918
|
+
});
|
|
1919
|
+
break;
|
|
1920
|
+
case paramArgsKey:
|
|
1921
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1922
|
+
? parameters?.[argMetadata.key] || undefined
|
|
1923
|
+
: await this.#argumentsResolver({
|
|
1924
|
+
data: parameters?.[argMetadata.key] || undefined,
|
|
1925
|
+
validationSchema: argMetadata.validationSchema,
|
|
1926
|
+
argumentIndex: argMetadata.index,
|
|
1927
|
+
funcName: functionName
|
|
1928
|
+
});
|
|
1929
|
+
break;
|
|
1930
|
+
case routeModelArgsKey:
|
|
1931
|
+
args[argMetadata.index] = undefined;
|
|
1932
|
+
break;
|
|
1933
|
+
case responseHeadersArgsKey:
|
|
1934
|
+
args[argMetadata.index] = responseHeaders;
|
|
1935
|
+
break;
|
|
1936
|
+
case httpServerArgsKey:
|
|
1937
|
+
args[argMetadata.index] = httpServer;
|
|
1938
|
+
break;
|
|
1939
|
+
default:
|
|
1940
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1941
|
+
? context.get(argMetadata.type, contextOptions)
|
|
1942
|
+
: await this.#argumentsResolver({
|
|
1943
|
+
data: context.get(argMetadata.type, contextOptions),
|
|
1944
|
+
validationSchema: argMetadata.validationSchema,
|
|
1945
|
+
argumentIndex: argMetadata.index,
|
|
1946
|
+
funcName: functionName
|
|
1947
|
+
});
|
|
1948
|
+
break;
|
|
1949
|
+
}
|
|
1714
1950
|
}
|
|
1951
|
+
|
|
1952
|
+
await handler(...args);
|
|
1953
|
+
}
|
|
1954
|
+
} else if (type === "GUARDS") {
|
|
1955
|
+
if (!routeModel || handlers.length === 0) {
|
|
1956
|
+
return true;
|
|
1715
1957
|
}
|
|
1716
1958
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
case httpServerArgsKey:
|
|
1791
|
-
args[argMetadata.index] = httpServer;
|
|
1792
|
-
break;
|
|
1793
|
-
default:
|
|
1794
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1795
|
-
? !context.has(argMetadata.type)
|
|
1796
|
-
? undefined
|
|
1797
|
-
: context.get(argMetadata.type)
|
|
1798
|
-
: await this.argumentsResolution(
|
|
1799
|
-
context.get(argMetadata.type),
|
|
1800
|
-
argMetadata.validationSchema,
|
|
1801
|
-
argMetadata.index,
|
|
1802
|
-
functionName
|
|
1803
|
-
);
|
|
1804
|
-
break;
|
|
1805
|
-
}
|
|
1959
|
+
for (let i = 0; i < handlers.length; i++) {
|
|
1960
|
+
const args = [];
|
|
1961
|
+
const { func: handler, funcName: functionName, argumentsMetadata } = handlers[i];
|
|
1962
|
+
|
|
1963
|
+
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1964
|
+
switch (argMetadata.type) {
|
|
1965
|
+
case requestArgsKey:
|
|
1966
|
+
args[argMetadata.index] = request;
|
|
1967
|
+
break;
|
|
1968
|
+
case requestBodyArgsKey:
|
|
1969
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1970
|
+
? await request?.[argMetadata.parser || "json"]()
|
|
1971
|
+
: await this.#argumentsResolver({
|
|
1972
|
+
data: await request?.[argMetadata.parser || "json"](),
|
|
1973
|
+
validationSchema: argMetadata.validationSchema,
|
|
1974
|
+
argumentIndex: argMetadata.index,
|
|
1975
|
+
funcName: functionName
|
|
1976
|
+
});
|
|
1977
|
+
break;
|
|
1978
|
+
case contextArgsKey:
|
|
1979
|
+
args[argMetadata.index] = !argMetadata.key
|
|
1980
|
+
? context
|
|
1981
|
+
: context.get(argMetadata.key);
|
|
1982
|
+
break;
|
|
1983
|
+
case requestHeadersArgsKey:
|
|
1984
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1985
|
+
? requestHeaders
|
|
1986
|
+
: await this.#argumentsResolver({
|
|
1987
|
+
data: requestHeaders?.toJSON(),
|
|
1988
|
+
validationSchema: argMetadata.validationSchema,
|
|
1989
|
+
argumentIndex: argMetadata.index,
|
|
1990
|
+
funcName: functionName
|
|
1991
|
+
});
|
|
1992
|
+
break;
|
|
1993
|
+
case responseHeadersArgsKey:
|
|
1994
|
+
args[argMetadata.index] = responseHeaders;
|
|
1995
|
+
break;
|
|
1996
|
+
case requestHeaderArgsKey:
|
|
1997
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1998
|
+
? requestHeaders?.get(argMetadata.key) || undefined
|
|
1999
|
+
: await this.#argumentsResolver({
|
|
2000
|
+
data: requestHeaders?.get(argMetadata.key) || undefined,
|
|
2001
|
+
validationSchema: argMetadata.validationSchema,
|
|
2002
|
+
argumentIndex: argMetadata.index,
|
|
2003
|
+
funcName: functionName
|
|
2004
|
+
});
|
|
2005
|
+
break;
|
|
2006
|
+
case paramArgsKey:
|
|
2007
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2008
|
+
? parameters?.[argMetadata.key] || undefined
|
|
2009
|
+
: await this.#argumentsResolver({
|
|
2010
|
+
data: parameters?.[argMetadata.key],
|
|
2011
|
+
validationSchema: argMetadata.validationSchema,
|
|
2012
|
+
argumentIndex: argMetadata.index,
|
|
2013
|
+
funcName: functionName
|
|
2014
|
+
});
|
|
2015
|
+
break;
|
|
2016
|
+
case routeModelArgsKey:
|
|
2017
|
+
args[argMetadata.index] = routeModel;
|
|
2018
|
+
break;
|
|
2019
|
+
case httpServerArgsKey:
|
|
2020
|
+
args[argMetadata.index] = httpServer;
|
|
2021
|
+
break;
|
|
2022
|
+
default:
|
|
2023
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2024
|
+
? context.get(argMetadata.type)
|
|
2025
|
+
: await this.#argumentsResolver({
|
|
2026
|
+
data: context.get(argMetadata.type),
|
|
2027
|
+
validationSchema: argMetadata.validationSchema,
|
|
2028
|
+
argumentIndex: argMetadata.index,
|
|
2029
|
+
funcName: functionName
|
|
2030
|
+
});
|
|
2031
|
+
break;
|
|
1806
2032
|
}
|
|
2033
|
+
}
|
|
1807
2034
|
|
|
1808
|
-
|
|
2035
|
+
const guardResult = await handler(...args);
|
|
1809
2036
|
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
httpCode: 401,
|
|
1813
|
-
message: "Unauthorization.",
|
|
1814
|
-
data: undefined
|
|
1815
|
-
});
|
|
1816
|
-
}
|
|
2037
|
+
if (guardResult !== true) {
|
|
2038
|
+
return guardResult;
|
|
1817
2039
|
}
|
|
1818
2040
|
}
|
|
1819
|
-
}
|
|
1820
2041
|
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
2042
|
+
return true;
|
|
2043
|
+
} else if (type === "OPEN_INTERCEPTORS" || type === "CLOSE_INTERCEPTORS") {
|
|
2044
|
+
if (!routeModel) {
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
const strategy =
|
|
2049
|
+
type === "OPEN_INTERCEPTORS"
|
|
2050
|
+
? this.#resolutedOptions.pipelineStrategy.openInterceptors
|
|
2051
|
+
: this.#resolutedOptions.pipelineStrategy.closeInterceptors;
|
|
2052
|
+
|
|
2053
|
+
for (
|
|
2054
|
+
let i = strategy === "FIFO" ? 0 : handlers.length - 1;
|
|
2055
|
+
strategy === "FIFO" ? i < handlers.length : i > -1;
|
|
2056
|
+
strategy === "FIFO" ? i++ : i--
|
|
1826
2057
|
) {
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
// Execute open interceptor(s)
|
|
1830
|
-
for (let i = 0; i < openInterceptorGroup.length; i++) {
|
|
1831
|
-
const args = [];
|
|
1832
|
-
const {
|
|
1833
|
-
func: handler,
|
|
1834
|
-
funcName: functionName,
|
|
1835
|
-
argumentsMetadata
|
|
1836
|
-
} = openInterceptorGroup[i];
|
|
1837
|
-
|
|
1838
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1839
|
-
switch (argMetadata.type) {
|
|
1840
|
-
case requestArgsKey:
|
|
1841
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1842
|
-
? request
|
|
1843
|
-
: await this.argumentsResolution(
|
|
1844
|
-
request,
|
|
1845
|
-
argMetadata.validationSchema,
|
|
1846
|
-
argMetadata.index,
|
|
1847
|
-
functionName
|
|
1848
|
-
);
|
|
1849
|
-
break;
|
|
1850
|
-
case requestBodyArgsKey:
|
|
1851
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1852
|
-
? await request?.[argMetadata.parser || "json"]()
|
|
1853
|
-
: await this.argumentsResolution(
|
|
1854
|
-
await request?.[argMetadata.parser || "json"](),
|
|
1855
|
-
argMetadata.validationSchema,
|
|
1856
|
-
argMetadata.index,
|
|
1857
|
-
functionName
|
|
1858
|
-
);
|
|
1859
|
-
break;
|
|
1860
|
-
case contextArgsKey:
|
|
1861
|
-
args[argMetadata.index] = !argMetadata.key
|
|
1862
|
-
? context
|
|
1863
|
-
: context.get(argMetadata.key);
|
|
1864
|
-
break;
|
|
1865
|
-
case requestHeadersArgsKey:
|
|
1866
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1867
|
-
? requestHeaders
|
|
1868
|
-
: await this.argumentsResolution(
|
|
1869
|
-
requestHeaders?.toJSON(),
|
|
1870
|
-
argMetadata.validationSchema,
|
|
1871
|
-
argMetadata.index,
|
|
1872
|
-
functionName
|
|
1873
|
-
);
|
|
1874
|
-
break;
|
|
1875
|
-
case requestHeaderArgsKey:
|
|
1876
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1877
|
-
? requestHeaders?.get(argMetadata.key) || undefined
|
|
1878
|
-
: await this.argumentsResolution(
|
|
1879
|
-
requestHeaders?.get(argMetadata.key) || undefined,
|
|
1880
|
-
argMetadata.validationSchema,
|
|
1881
|
-
argMetadata.index,
|
|
1882
|
-
functionName
|
|
1883
|
-
);
|
|
1884
|
-
break;
|
|
1885
|
-
case responseHeadersArgsKey:
|
|
1886
|
-
args[argMetadata.index] = responseHeaders;
|
|
1887
|
-
break;
|
|
1888
|
-
case paramArgsKey:
|
|
1889
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1890
|
-
? parameters?.[argMetadata.key] || undefined
|
|
1891
|
-
: await this.argumentsResolution(
|
|
1892
|
-
parameters?.[argMetadata.key] || undefined,
|
|
1893
|
-
argMetadata.validationSchema,
|
|
1894
|
-
argMetadata.index,
|
|
1895
|
-
functionName
|
|
1896
|
-
);
|
|
1897
|
-
break;
|
|
1898
|
-
case routeModelArgsKey:
|
|
1899
|
-
args[argMetadata.index] = routeModel;
|
|
1900
|
-
break;
|
|
1901
|
-
case httpServerArgsKey:
|
|
1902
|
-
args[argMetadata.index] = httpServer;
|
|
1903
|
-
break;
|
|
1904
|
-
default:
|
|
1905
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
1906
|
-
? !context.has(argMetadata.type)
|
|
1907
|
-
? undefined
|
|
1908
|
-
: context.get(argMetadata.type)
|
|
1909
|
-
: await this.argumentsResolution(
|
|
1910
|
-
context.get(argMetadata.type),
|
|
1911
|
-
argMetadata.validationSchema,
|
|
1912
|
-
argMetadata.index,
|
|
1913
|
-
functionName
|
|
1914
|
-
);
|
|
1915
|
-
break;
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
2058
|
+
const args = [];
|
|
2059
|
+
const { func: handler, funcName: functionName, argumentsMetadata } = handlers[i];
|
|
1918
2060
|
|
|
1919
|
-
|
|
2061
|
+
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
2062
|
+
switch (argMetadata.type) {
|
|
2063
|
+
case requestArgsKey:
|
|
2064
|
+
args[argMetadata.index] = request;
|
|
2065
|
+
break;
|
|
2066
|
+
case requestBodyArgsKey:
|
|
2067
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2068
|
+
? await request?.[argMetadata.parser || "json"]()
|
|
2069
|
+
: await this.#argumentsResolver({
|
|
2070
|
+
data: await request?.[argMetadata.parser || "json"](),
|
|
2071
|
+
validationSchema: argMetadata.validationSchema,
|
|
2072
|
+
argumentIndex: argMetadata.index,
|
|
2073
|
+
funcName: functionName
|
|
2074
|
+
});
|
|
2075
|
+
break;
|
|
2076
|
+
case contextArgsKey:
|
|
2077
|
+
args[argMetadata.index] = !argMetadata.key
|
|
2078
|
+
? context
|
|
2079
|
+
: context.get(argMetadata.key);
|
|
2080
|
+
break;
|
|
2081
|
+
case requestHeadersArgsKey:
|
|
2082
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2083
|
+
? requestHeaders
|
|
2084
|
+
: await this.#argumentsResolver({
|
|
2085
|
+
data: requestHeaders?.toJSON(),
|
|
2086
|
+
validationSchema: argMetadata.validationSchema,
|
|
2087
|
+
argumentIndex: argMetadata.index,
|
|
2088
|
+
funcName: functionName
|
|
2089
|
+
});
|
|
2090
|
+
break;
|
|
2091
|
+
case requestHeaderArgsKey:
|
|
2092
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2093
|
+
? requestHeaders?.get(argMetadata.key) || undefined
|
|
2094
|
+
: await this.#argumentsResolver({
|
|
2095
|
+
data: requestHeaders?.get(argMetadata.key) || undefined,
|
|
2096
|
+
validationSchema: argMetadata.validationSchema,
|
|
2097
|
+
argumentIndex: argMetadata.index,
|
|
2098
|
+
funcName: functionName
|
|
2099
|
+
});
|
|
2100
|
+
break;
|
|
2101
|
+
case responseHeadersArgsKey:
|
|
2102
|
+
args[argMetadata.index] = responseHeaders;
|
|
2103
|
+
break;
|
|
2104
|
+
case paramArgsKey:
|
|
2105
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2106
|
+
? parameters?.[argMetadata.key] || undefined
|
|
2107
|
+
: await this.#argumentsResolver({
|
|
2108
|
+
data: parameters?.[argMetadata.key] || undefined,
|
|
2109
|
+
validationSchema: argMetadata.validationSchema,
|
|
2110
|
+
argumentIndex: argMetadata.index,
|
|
2111
|
+
funcName: functionName
|
|
2112
|
+
});
|
|
2113
|
+
break;
|
|
2114
|
+
case routeModelArgsKey:
|
|
2115
|
+
args[argMetadata.index] = routeModel;
|
|
2116
|
+
break;
|
|
2117
|
+
case httpServerArgsKey:
|
|
2118
|
+
args[argMetadata.index] = httpServer;
|
|
2119
|
+
break;
|
|
2120
|
+
default:
|
|
2121
|
+
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2122
|
+
? context.get(argMetadata.type)
|
|
2123
|
+
: await this.#argumentsResolver({
|
|
2124
|
+
data: context.get(argMetadata.type),
|
|
2125
|
+
validationSchema: argMetadata.validationSchema,
|
|
2126
|
+
argumentIndex: argMetadata.index,
|
|
2127
|
+
funcName: functionName
|
|
2128
|
+
});
|
|
2129
|
+
break;
|
|
2130
|
+
}
|
|
1920
2131
|
}
|
|
2132
|
+
|
|
2133
|
+
await handler(...args);
|
|
2134
|
+
}
|
|
2135
|
+
} else if (type === "CONTROLLER") {
|
|
2136
|
+
if (!routeModel) {
|
|
2137
|
+
context
|
|
2138
|
+
.setOptions({ isStatic: false })
|
|
2139
|
+
.set(responseStatusArgsKey, 404)
|
|
2140
|
+
.set(responseStatusTextArgsKey, "Not found.");
|
|
2141
|
+
|
|
2142
|
+
return;
|
|
1921
2143
|
}
|
|
1922
2144
|
|
|
1923
|
-
// Execute controller action
|
|
1924
2145
|
const controllerActionArguments: any[] = [];
|
|
1925
2146
|
const {
|
|
1926
2147
|
func: controllerAction,
|
|
@@ -1931,24 +2152,17 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1931
2152
|
for (const [_key, argMetadata] of Object.entries(controllerActionArgumentsMetadata)) {
|
|
1932
2153
|
switch (argMetadata.type) {
|
|
1933
2154
|
case requestArgsKey:
|
|
1934
|
-
controllerActionArguments[argMetadata.index] =
|
|
1935
|
-
? request
|
|
1936
|
-
: await this.argumentsResolution(
|
|
1937
|
-
request,
|
|
1938
|
-
argMetadata.validationSchema,
|
|
1939
|
-
argMetadata.index,
|
|
1940
|
-
controllerActionName
|
|
1941
|
-
);
|
|
2155
|
+
controllerActionArguments[argMetadata.index] = request;
|
|
1942
2156
|
break;
|
|
1943
2157
|
case requestBodyArgsKey:
|
|
1944
2158
|
controllerActionArguments[argMetadata.index] = !argMetadata.validationSchema
|
|
1945
2159
|
? await request?.[argMetadata.parser || "json"]()
|
|
1946
|
-
: await this
|
|
1947
|
-
await request?.[argMetadata.parser || "json"](),
|
|
1948
|
-
argMetadata.validationSchema,
|
|
1949
|
-
argMetadata.index,
|
|
1950
|
-
controllerActionName
|
|
1951
|
-
);
|
|
2160
|
+
: await this.#argumentsResolver({
|
|
2161
|
+
data: await request?.[argMetadata.parser || "json"](),
|
|
2162
|
+
validationSchema: argMetadata.validationSchema,
|
|
2163
|
+
argumentIndex: argMetadata.index,
|
|
2164
|
+
funcName: controllerActionName
|
|
2165
|
+
});
|
|
1952
2166
|
break;
|
|
1953
2167
|
case contextArgsKey:
|
|
1954
2168
|
controllerActionArguments[argMetadata.index] = !argMetadata.key
|
|
@@ -1958,22 +2172,22 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1958
2172
|
case requestHeadersArgsKey:
|
|
1959
2173
|
controllerActionArguments[argMetadata.index] = !argMetadata.validationSchema
|
|
1960
2174
|
? requestHeaders
|
|
1961
|
-
: await this
|
|
1962
|
-
requestHeaders?.toJSON(),
|
|
1963
|
-
argMetadata.validationSchema,
|
|
1964
|
-
argMetadata.index,
|
|
1965
|
-
controllerActionName
|
|
1966
|
-
);
|
|
2175
|
+
: await this.#argumentsResolver({
|
|
2176
|
+
data: requestHeaders?.toJSON(),
|
|
2177
|
+
validationSchema: argMetadata.validationSchema,
|
|
2178
|
+
argumentIndex: argMetadata.index,
|
|
2179
|
+
funcName: controllerActionName
|
|
2180
|
+
});
|
|
1967
2181
|
break;
|
|
1968
2182
|
case requestHeaderArgsKey:
|
|
1969
2183
|
controllerActionArguments[argMetadata.index] = !argMetadata.validationSchema
|
|
1970
2184
|
? requestHeaders?.get(argMetadata.key) || undefined
|
|
1971
|
-
: await this
|
|
1972
|
-
requestHeaders?.get(argMetadata.key) || undefined,
|
|
1973
|
-
argMetadata.validationSchema,
|
|
1974
|
-
argMetadata.index,
|
|
1975
|
-
controllerActionName
|
|
1976
|
-
);
|
|
2185
|
+
: await this.#argumentsResolver({
|
|
2186
|
+
data: requestHeaders?.get(argMetadata.key) || undefined,
|
|
2187
|
+
validationSchema: argMetadata.validationSchema,
|
|
2188
|
+
argumentIndex: argMetadata.index,
|
|
2189
|
+
funcName: controllerActionName
|
|
2190
|
+
});
|
|
1977
2191
|
break;
|
|
1978
2192
|
case responseHeadersArgsKey:
|
|
1979
2193
|
controllerActionArguments[argMetadata.index] = responseHeaders;
|
|
@@ -1981,12 +2195,12 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1981
2195
|
case paramArgsKey:
|
|
1982
2196
|
controllerActionArguments[argMetadata.index] = !argMetadata.validationSchema
|
|
1983
2197
|
? parameters?.[argMetadata.key] || undefined
|
|
1984
|
-
: await this
|
|
1985
|
-
parameters?.[argMetadata.key] || undefined,
|
|
1986
|
-
argMetadata.validationSchema,
|
|
1987
|
-
argMetadata.index,
|
|
1988
|
-
controllerActionName
|
|
1989
|
-
);
|
|
2198
|
+
: await this.#argumentsResolver({
|
|
2199
|
+
data: parameters?.[argMetadata.key] || undefined,
|
|
2200
|
+
validationSchema: argMetadata.validationSchema,
|
|
2201
|
+
argumentIndex: argMetadata.index,
|
|
2202
|
+
funcName: controllerActionName
|
|
2203
|
+
});
|
|
1990
2204
|
break;
|
|
1991
2205
|
case routeModelArgsKey:
|
|
1992
2206
|
controllerActionArguments[argMetadata.index] = routeModel;
|
|
@@ -1996,15 +2210,13 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1996
2210
|
break;
|
|
1997
2211
|
default:
|
|
1998
2212
|
controllerActionArguments[argMetadata.index] = !argMetadata.validationSchema
|
|
1999
|
-
?
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
controllerActionName
|
|
2007
|
-
);
|
|
2213
|
+
? context.get(argMetadata.type)
|
|
2214
|
+
: await this.#argumentsResolver({
|
|
2215
|
+
data: context.get(argMetadata.type),
|
|
2216
|
+
validationSchema: argMetadata.validationSchema,
|
|
2217
|
+
argumentIndex: argMetadata.index,
|
|
2218
|
+
funcName: controllerActionName
|
|
2219
|
+
});
|
|
2008
2220
|
break;
|
|
2009
2221
|
}
|
|
2010
2222
|
}
|
|
@@ -2012,279 +2224,111 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
2012
2224
|
context.set(responseBodyArgsKey, await controllerAction(...controllerActionArguments), {
|
|
2013
2225
|
isStatic: false
|
|
2014
2226
|
});
|
|
2015
|
-
|
|
2016
|
-
if (
|
|
2017
|
-
resolutedMap &&
|
|
2018
|
-
"closeInterceptorGroup" in resolutedMap &&
|
|
2019
|
-
resolutedMap.closeInterceptorGroup
|
|
2020
|
-
) {
|
|
2021
|
-
const { closeInterceptorGroup } = resolutedMap;
|
|
2022
|
-
|
|
2023
|
-
// Execute close interceptor(s)
|
|
2024
|
-
for (let i = 0; i < closeInterceptorGroup.length; i++) {
|
|
2025
|
-
const args = [];
|
|
2026
|
-
const {
|
|
2027
|
-
func: handler,
|
|
2028
|
-
funcName: functionName,
|
|
2029
|
-
argumentsMetadata
|
|
2030
|
-
} = closeInterceptorGroup[i];
|
|
2031
|
-
|
|
2032
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
2033
|
-
switch (argMetadata.type) {
|
|
2034
|
-
case requestArgsKey:
|
|
2035
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2036
|
-
? request
|
|
2037
|
-
: await this.argumentsResolution(
|
|
2038
|
-
request,
|
|
2039
|
-
argMetadata.validationSchema,
|
|
2040
|
-
argMetadata.index,
|
|
2041
|
-
functionName
|
|
2042
|
-
);
|
|
2043
|
-
break;
|
|
2044
|
-
case requestBodyArgsKey:
|
|
2045
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2046
|
-
? await request?.[argMetadata.parser || "json"]()
|
|
2047
|
-
: await this.argumentsResolution(
|
|
2048
|
-
await request?.[argMetadata.parser || "json"](),
|
|
2049
|
-
argMetadata.validationSchema,
|
|
2050
|
-
argMetadata.index,
|
|
2051
|
-
functionName
|
|
2052
|
-
);
|
|
2053
|
-
break;
|
|
2054
|
-
case contextArgsKey:
|
|
2055
|
-
args[argMetadata.index] = !argMetadata.key
|
|
2056
|
-
? context
|
|
2057
|
-
: context.get(argMetadata.key);
|
|
2058
|
-
break;
|
|
2059
|
-
case requestHeadersArgsKey:
|
|
2060
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2061
|
-
? requestHeaders
|
|
2062
|
-
: await this.argumentsResolution(
|
|
2063
|
-
requestHeaders?.toJSON(),
|
|
2064
|
-
argMetadata.validationSchema,
|
|
2065
|
-
argMetadata.index,
|
|
2066
|
-
functionName
|
|
2067
|
-
);
|
|
2068
|
-
break;
|
|
2069
|
-
case responseHeadersArgsKey:
|
|
2070
|
-
args[argMetadata.index] = context.get(argMetadata.type);
|
|
2071
|
-
break;
|
|
2072
|
-
case requestHeaderArgsKey:
|
|
2073
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2074
|
-
? requestHeaders?.get(argMetadata.key) || undefined
|
|
2075
|
-
: await this.argumentsResolution(
|
|
2076
|
-
requestHeaders?.get(argMetadata.key) || undefined,
|
|
2077
|
-
argMetadata.validationSchema,
|
|
2078
|
-
argMetadata.index,
|
|
2079
|
-
functionName
|
|
2080
|
-
);
|
|
2081
|
-
break;
|
|
2082
|
-
case paramArgsKey:
|
|
2083
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2084
|
-
? parameters?.[argMetadata.key] || undefined
|
|
2085
|
-
: await this.argumentsResolution(
|
|
2086
|
-
parameters?.[argMetadata.key] || undefined,
|
|
2087
|
-
argMetadata.validationSchema,
|
|
2088
|
-
argMetadata.index,
|
|
2089
|
-
functionName
|
|
2090
|
-
);
|
|
2091
|
-
break;
|
|
2092
|
-
case routeModelArgsKey:
|
|
2093
|
-
args[argMetadata.index] = routeModel;
|
|
2094
|
-
break;
|
|
2095
|
-
case httpServerArgsKey:
|
|
2096
|
-
args[argMetadata.index] = httpServer;
|
|
2097
|
-
break;
|
|
2098
|
-
default:
|
|
2099
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2100
|
-
? !context.has(argMetadata.type)
|
|
2101
|
-
? undefined
|
|
2102
|
-
: context.get(argMetadata.type)
|
|
2103
|
-
: await this.argumentsResolution(
|
|
2104
|
-
context.get(argMetadata.type),
|
|
2105
|
-
argMetadata.validationSchema,
|
|
2106
|
-
argMetadata.index,
|
|
2107
|
-
functionName
|
|
2108
|
-
);
|
|
2109
|
-
break;
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
|
-
|
|
2113
|
-
await handler(...args);
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
|
|
2118
|
-
if (resolutedMap) {
|
|
2119
|
-
const { endMiddlewareGroup } = resolutedMap;
|
|
2120
|
-
|
|
2121
|
-
// Execute end middleware(s)
|
|
2122
|
-
if (endMiddlewareGroup) {
|
|
2123
|
-
for (let i = 0; i < endMiddlewareGroup.length; i++) {
|
|
2124
|
-
const args = [];
|
|
2125
|
-
const {
|
|
2126
|
-
func: handler,
|
|
2127
|
-
funcName: functionName,
|
|
2128
|
-
argumentsMetadata
|
|
2129
|
-
} = endMiddlewareGroup[i];
|
|
2130
|
-
|
|
2131
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
2132
|
-
switch (argMetadata.type) {
|
|
2133
|
-
case requestArgsKey:
|
|
2134
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2135
|
-
? request
|
|
2136
|
-
: await this.argumentsResolution(
|
|
2137
|
-
request,
|
|
2138
|
-
argMetadata.validationSchema,
|
|
2139
|
-
argMetadata.index,
|
|
2140
|
-
functionName
|
|
2141
|
-
);
|
|
2142
|
-
break;
|
|
2143
|
-
case requestBodyArgsKey:
|
|
2144
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2145
|
-
? await request?.[argMetadata.parser || "json"]()
|
|
2146
|
-
: await this.argumentsResolution(
|
|
2147
|
-
await request?.[argMetadata.parser || "json"](),
|
|
2148
|
-
argMetadata.validationSchema,
|
|
2149
|
-
argMetadata.index,
|
|
2150
|
-
functionName
|
|
2151
|
-
);
|
|
2152
|
-
break;
|
|
2153
|
-
case contextArgsKey:
|
|
2154
|
-
args[argMetadata.index] = !argMetadata.key
|
|
2155
|
-
? context
|
|
2156
|
-
: context.get(argMetadata.key);
|
|
2157
|
-
break;
|
|
2158
|
-
case requestHeadersArgsKey:
|
|
2159
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2160
|
-
? requestHeaders
|
|
2161
|
-
: await this.argumentsResolution(
|
|
2162
|
-
requestHeaders?.toJSON(),
|
|
2163
|
-
argMetadata.validationSchema,
|
|
2164
|
-
argMetadata.index,
|
|
2165
|
-
functionName
|
|
2166
|
-
);
|
|
2167
|
-
break;
|
|
2168
|
-
case responseHeadersArgsKey:
|
|
2169
|
-
args[argMetadata.index] = context.get(argMetadata.type);
|
|
2170
|
-
break;
|
|
2171
|
-
case requestHeaderArgsKey:
|
|
2172
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2173
|
-
? requestHeaders?.get(argMetadata.key) || undefined
|
|
2174
|
-
: await this.argumentsResolution(
|
|
2175
|
-
requestHeaders?.get(argMetadata.key) || undefined,
|
|
2176
|
-
argMetadata.validationSchema,
|
|
2177
|
-
argMetadata.index,
|
|
2178
|
-
functionName
|
|
2179
|
-
);
|
|
2180
|
-
break;
|
|
2181
|
-
case paramArgsKey:
|
|
2182
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2183
|
-
? parameters?.[argMetadata.key] || undefined
|
|
2184
|
-
: await this.argumentsResolution(
|
|
2185
|
-
parameters?.[argMetadata.key] || undefined,
|
|
2186
|
-
argMetadata.validationSchema,
|
|
2187
|
-
argMetadata.index,
|
|
2188
|
-
functionName
|
|
2189
|
-
);
|
|
2190
|
-
break;
|
|
2191
|
-
case routeModelArgsKey:
|
|
2192
|
-
args[argMetadata.index] = routeModel;
|
|
2193
|
-
break;
|
|
2194
|
-
case httpServerArgsKey:
|
|
2195
|
-
args[argMetadata.index] = httpServer;
|
|
2196
|
-
break;
|
|
2197
|
-
default:
|
|
2198
|
-
args[argMetadata.index] = !argMetadata.validationSchema
|
|
2199
|
-
? !context.has(argMetadata.type)
|
|
2200
|
-
? undefined
|
|
2201
|
-
: context.get(argMetadata.type)
|
|
2202
|
-
: await this.argumentsResolution(
|
|
2203
|
-
!(argMetadata.type in context)
|
|
2204
|
-
? undefined
|
|
2205
|
-
: context.get(argMetadata.type),
|
|
2206
|
-
argMetadata.validationSchema,
|
|
2207
|
-
argMetadata.index,
|
|
2208
|
-
functionName
|
|
2209
|
-
);
|
|
2210
|
-
break;
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
|
|
2214
|
-
await handler(...args);
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
2217
2227
|
}
|
|
2218
2228
|
|
|
2219
|
-
return
|
|
2220
|
-
context: context
|
|
2221
|
-
});
|
|
2229
|
+
return;
|
|
2222
2230
|
}
|
|
2223
2231
|
|
|
2224
2232
|
/**
|
|
2225
2233
|
*
|
|
2226
|
-
* @param
|
|
2227
|
-
* @param bool
|
|
2234
|
+
* @param param0
|
|
2228
2235
|
* @returns
|
|
2229
2236
|
*/
|
|
2230
|
-
private
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
const { request, server } = bun;
|
|
2245
|
-
const {
|
|
2246
|
-
query,
|
|
2247
|
-
responseHeaders,
|
|
2248
|
-
route: { model }
|
|
2249
|
-
} = bool;
|
|
2250
|
-
|
|
2251
|
-
// Execute controller action
|
|
2252
|
-
const isUpgrade = await model.func(...[server, request, query]);
|
|
2237
|
+
private serializeResponse({
|
|
2238
|
+
status,
|
|
2239
|
+
statusText,
|
|
2240
|
+
headers,
|
|
2241
|
+
data
|
|
2242
|
+
}: {
|
|
2243
|
+
status?: number;
|
|
2244
|
+
statusText?: string;
|
|
2245
|
+
headers: Headers;
|
|
2246
|
+
data: unknown;
|
|
2247
|
+
}): Response {
|
|
2248
|
+
const contentType = headers.get("Content-Type") || "text/plain";
|
|
2249
|
+
const inferedStatus = !status ? (!data ? 204 : 200) : status;
|
|
2250
|
+
const inferedStatusText = inferStatusText(inferedStatus);
|
|
2253
2251
|
|
|
2254
|
-
if (
|
|
2252
|
+
if (contentType.includes("application/json")) {
|
|
2255
2253
|
return this.finalizeResponse(
|
|
2256
2254
|
new Response(
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
data
|
|
2261
|
-
|
|
2255
|
+
!data
|
|
2256
|
+
? undefined
|
|
2257
|
+
: data instanceof ReadableStream
|
|
2258
|
+
? data
|
|
2259
|
+
: JSON.stringify(data),
|
|
2262
2260
|
{
|
|
2263
|
-
status:
|
|
2264
|
-
statusText:
|
|
2265
|
-
headers:
|
|
2261
|
+
status: inferedStatus,
|
|
2262
|
+
statusText: inferedStatusText,
|
|
2263
|
+
headers: headers
|
|
2266
2264
|
}
|
|
2267
2265
|
)
|
|
2268
2266
|
);
|
|
2269
2267
|
}
|
|
2270
2268
|
|
|
2271
|
-
if (
|
|
2269
|
+
if (contentType.includes("text/plain") || contentType.includes("text/html")) {
|
|
2272
2270
|
return this.finalizeResponse(
|
|
2273
2271
|
new Response(
|
|
2274
|
-
|
|
2275
|
-
httpCode: 500,
|
|
2276
|
-
message: "Can not upgrade.",
|
|
2277
|
-
data: undefined
|
|
2278
|
-
}),
|
|
2272
|
+
!data ? undefined : data instanceof ReadableStream ? data : String(data),
|
|
2279
2273
|
{
|
|
2280
|
-
status:
|
|
2281
|
-
statusText:
|
|
2282
|
-
headers:
|
|
2274
|
+
status: inferedStatus,
|
|
2275
|
+
statusText: inferedStatusText,
|
|
2276
|
+
headers: headers
|
|
2283
2277
|
}
|
|
2284
2278
|
)
|
|
2285
2279
|
);
|
|
2286
2280
|
}
|
|
2287
2281
|
|
|
2288
|
-
|
|
2282
|
+
if (contentType.includes("application/octet-stream")) {
|
|
2283
|
+
if (
|
|
2284
|
+
data instanceof Uint8Array ||
|
|
2285
|
+
data instanceof ArrayBuffer ||
|
|
2286
|
+
data instanceof Blob ||
|
|
2287
|
+
data instanceof ReadableStream
|
|
2288
|
+
) {
|
|
2289
|
+
return this.finalizeResponse(
|
|
2290
|
+
new Response(data as BodyInit, {
|
|
2291
|
+
status: inferedStatus,
|
|
2292
|
+
statusText: inferedStatusText,
|
|
2293
|
+
headers: headers
|
|
2294
|
+
})
|
|
2295
|
+
);
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
throw new Error("Invalid data type for application/octet-stream");
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
if (contentType.includes("multipart/form-data")) {
|
|
2302
|
+
if (data instanceof FormData) {
|
|
2303
|
+
return this.finalizeResponse(
|
|
2304
|
+
new Response(data, {
|
|
2305
|
+
status: inferedStatus,
|
|
2306
|
+
statusText: inferedStatusText,
|
|
2307
|
+
headers: headers
|
|
2308
|
+
})
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
throw new Error("multipart/form-data requires FormData object");
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
return this.finalizeResponse(
|
|
2316
|
+
new Response(!data ? undefined : String(data), {
|
|
2317
|
+
status: inferedStatus,
|
|
2318
|
+
statusText: inferedStatusText,
|
|
2319
|
+
headers: headers
|
|
2320
|
+
})
|
|
2321
|
+
);
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
/**
|
|
2325
|
+
*
|
|
2326
|
+
* @param response
|
|
2327
|
+
* @returns
|
|
2328
|
+
*/
|
|
2329
|
+
private finalizeResponse(response: Response) {
|
|
2330
|
+
response.headers.set("X-Powered-By", "Bool Typescript");
|
|
2331
|
+
|
|
2332
|
+
return response;
|
|
2289
2333
|
}
|
|
2290
2334
|
}
|