@bool-ts/core 1.9.1 → 1.9.3
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/__test/_constants.ts +1 -0
- package/__test/container.ts +28 -0
- package/__test/controller.ts +1 -1
- package/__test/{module.ts → firstModule.ts} +4 -6
- package/__test/index.ts +2 -4
- package/__test/secondModule.ts +29 -0
- package/__test/tsconfig.json +1 -1
- package/dist/decorators/arguments.d.ts +5 -1
- package/dist/decorators/container.d.ts +10 -10
- package/dist/decorators/index.d.ts +4 -2
- package/dist/decorators/module.d.ts +6 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/interfaces/context.d.ts +8 -2
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/keys/index.d.ts +2 -0
- package/dist/producers/context.d.ts +13 -0
- package/dist/{hooks → producers}/factory.d.ts +3 -2
- package/dist/{hooks → producers}/injector.d.ts +7 -1
- package/package.json +3 -3
- package/src/decorators/arguments.ts +27 -0
- package/src/decorators/container.ts +45 -30
- package/src/decorators/index.ts +4 -1
- package/src/decorators/module.ts +16 -2
- package/src/index.ts +1 -1
- package/src/interfaces/context.ts +9 -2
- package/src/interfaces/index.ts +1 -1
- package/src/keys/index.ts +2 -0
- package/src/producers/context.ts +63 -0
- package/src/producers/factory.ts +2076 -0
- package/src/{hooks → producers}/injector.ts +41 -6
- package/src/hooks/factory.ts +0 -1703
- /package/dist/{hooks → producers}/index.d.ts +0 -0
- /package/src/{hooks → producers}/index.ts +0 -0
package/src/hooks/factory.ts
DELETED
|
@@ -1,1703 +0,0 @@
|
|
|
1
|
-
import type { BunFile, Server } from "bun";
|
|
2
|
-
import type {
|
|
3
|
-
TControllerMetadata,
|
|
4
|
-
TModuleMetadata,
|
|
5
|
-
TWebSocketEventHandlerMetadata,
|
|
6
|
-
TWebSocketMetadata
|
|
7
|
-
} from "../decorators";
|
|
8
|
-
import type { TArgumentsMetadataCollection } from "../decorators/arguments";
|
|
9
|
-
import type { TWebSocketUpgradeData } from "../decorators/webSocket";
|
|
10
|
-
import type { IContext, IGuard, IMiddleware } from "../interfaces";
|
|
11
|
-
import type { IDispatcher } from "../interfaces/dispatcher";
|
|
12
|
-
|
|
13
|
-
import "reflect-metadata";
|
|
14
|
-
|
|
15
|
-
import Qs from "qs";
|
|
16
|
-
import * as Zod from "zod";
|
|
17
|
-
|
|
18
|
-
import { ETimeUnit, add as TimeAdd } from "@bool-ts/date-time";
|
|
19
|
-
import {
|
|
20
|
-
HttpRouter,
|
|
21
|
-
HttpRouterGroup,
|
|
22
|
-
WebSocketRoute,
|
|
23
|
-
WebSocketRouter,
|
|
24
|
-
WebSocketRouterGroup
|
|
25
|
-
} from "../entities";
|
|
26
|
-
import { HttpClientError, HttpServerError, jsonErrorInfer, type THttpMethods } from "../http";
|
|
27
|
-
import {
|
|
28
|
-
argumentsKey,
|
|
29
|
-
configKey,
|
|
30
|
-
contextArgsKey,
|
|
31
|
-
controllerKey,
|
|
32
|
-
moduleKey,
|
|
33
|
-
paramArgsKey,
|
|
34
|
-
paramsArgsKey,
|
|
35
|
-
queryArgsKey,
|
|
36
|
-
requestArgsKey,
|
|
37
|
-
requestBodyArgsKey,
|
|
38
|
-
requestHeaderArgsKey,
|
|
39
|
-
requestHeadersArgsKey,
|
|
40
|
-
responseBodyArgsKey,
|
|
41
|
-
responseHeadersArgsKey,
|
|
42
|
-
routeModelArgsKey,
|
|
43
|
-
webSocketCloseCodeArgsKey,
|
|
44
|
-
webSocketCloseReasonArgsKey,
|
|
45
|
-
webSocketConnectionArgsKey,
|
|
46
|
-
webSocketKey,
|
|
47
|
-
webSocketMessageArgsKey,
|
|
48
|
-
webSocketServerArgsKey
|
|
49
|
-
} from "../keys";
|
|
50
|
-
import { ansiText, isWebSocketUpgrade } from "../ultils";
|
|
51
|
-
import { Injector } from "./injector";
|
|
52
|
-
|
|
53
|
-
export type TGroupElementModel<
|
|
54
|
-
TFuncName extends keyof TClass,
|
|
55
|
-
TClass extends Object = Object,
|
|
56
|
-
TFunc = TClass[TFuncName]
|
|
57
|
-
> = Readonly<{
|
|
58
|
-
class: TClass;
|
|
59
|
-
func: TFunc;
|
|
60
|
-
funcName: TFuncName;
|
|
61
|
-
argumentsMetadata: TArgumentsMetadataCollection;
|
|
62
|
-
}>;
|
|
63
|
-
|
|
64
|
-
export type TBoolFactoryOptions = 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: Array<"GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS">;
|
|
73
|
-
}>;
|
|
74
|
-
queryParser: Parameters<typeof Qs.parse>[1];
|
|
75
|
-
static: Required<{
|
|
76
|
-
path: string;
|
|
77
|
-
}> &
|
|
78
|
-
Partial<{
|
|
79
|
-
headers: Record<string, string>;
|
|
80
|
-
cacheTimeInSeconds: number;
|
|
81
|
-
}>;
|
|
82
|
-
cors: Partial<{
|
|
83
|
-
credentials: boolean;
|
|
84
|
-
origins: string | Array<string>;
|
|
85
|
-
methods: Array<"GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS">;
|
|
86
|
-
headers: Array<string>;
|
|
87
|
-
}>;
|
|
88
|
-
}>;
|
|
89
|
-
|
|
90
|
-
const DEFAULT_STATIC_CACHE_TIME_IN_SECONDS = 900;
|
|
91
|
-
|
|
92
|
-
const responseConverter = (response: Response) => {
|
|
93
|
-
response.headers.set("X-Powered-By", "Bool Typescript");
|
|
94
|
-
|
|
95
|
-
return response;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const controllerCreator = ({
|
|
99
|
-
controllerConstructor,
|
|
100
|
-
httpRouterGroup,
|
|
101
|
-
injector,
|
|
102
|
-
prefix
|
|
103
|
-
}: Readonly<{
|
|
104
|
-
controllerConstructor: new (...args: any[]) => unknown;
|
|
105
|
-
httpRouterGroup: HttpRouterGroup;
|
|
106
|
-
injector: Injector;
|
|
107
|
-
prefix?: string;
|
|
108
|
-
}>) => {
|
|
109
|
-
if (!Reflect.getOwnMetadataKeys(controllerConstructor).includes(controllerKey)) {
|
|
110
|
-
throw Error(`${controllerConstructor.name} is not a controller.`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const controller = injector.get(controllerConstructor);
|
|
114
|
-
|
|
115
|
-
if (!controller) {
|
|
116
|
-
throw Error("Can not initialize controller.");
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const controllerMetadata: TControllerMetadata = Reflect.getOwnMetadata(
|
|
120
|
-
controllerKey,
|
|
121
|
-
controllerConstructor
|
|
122
|
-
) || {
|
|
123
|
-
prefix: "/",
|
|
124
|
-
httpMetadata: []
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const router = new HttpRouter(`/${prefix || ""}/${controllerMetadata.prefix}`);
|
|
128
|
-
|
|
129
|
-
controllerMetadata.httpMetadata.forEach((routeMetadata) => {
|
|
130
|
-
if (typeof routeMetadata.descriptor.value !== "function") {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const route = router.route(routeMetadata.path);
|
|
135
|
-
const handler = routeMetadata.descriptor.value.bind(controller);
|
|
136
|
-
const routeArgument = Object.freeze({
|
|
137
|
-
class: controllerConstructor,
|
|
138
|
-
funcName: routeMetadata.methodName,
|
|
139
|
-
func: handler,
|
|
140
|
-
argumentsMetadata: routeMetadata.argumentsMetadata
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
switch (routeMetadata.httpMethod) {
|
|
144
|
-
case "GET":
|
|
145
|
-
return route.get(routeArgument);
|
|
146
|
-
case "POST":
|
|
147
|
-
return route.post(routeArgument);
|
|
148
|
-
case "PUT":
|
|
149
|
-
return route.put(routeArgument);
|
|
150
|
-
case "PATCH":
|
|
151
|
-
return route.patch(routeArgument);
|
|
152
|
-
case "DELETE":
|
|
153
|
-
return route.delete(routeArgument);
|
|
154
|
-
case "OPTIONS":
|
|
155
|
-
return route.options(routeArgument);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return httpRouterGroup.add(router);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const webSocketCreator = ({
|
|
163
|
-
injector,
|
|
164
|
-
httpRouterGroup,
|
|
165
|
-
prefix,
|
|
166
|
-
webSocketRouterGroup,
|
|
167
|
-
webSocketConstructor
|
|
168
|
-
}: Readonly<{
|
|
169
|
-
webSocketConstructor: new (...args: any[]) => unknown;
|
|
170
|
-
httpRouterGroup: HttpRouterGroup;
|
|
171
|
-
webSocketRouterGroup: WebSocketRouterGroup;
|
|
172
|
-
injector: Injector;
|
|
173
|
-
prefix?: string;
|
|
174
|
-
}>): Readonly<{
|
|
175
|
-
httpRouterGroup: HttpRouterGroup;
|
|
176
|
-
webSocketRouterGroup: WebSocketRouterGroup;
|
|
177
|
-
}> => {
|
|
178
|
-
if (!Reflect.getOwnMetadataKeys(webSocketConstructor).includes(webSocketKey)) {
|
|
179
|
-
throw Error(`${webSocketConstructor.name} is not a controller.`);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const webSocket = injector.get(webSocketConstructor);
|
|
183
|
-
|
|
184
|
-
if (!webSocket) {
|
|
185
|
-
throw Error("Can not initialize webSocket.");
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const webSocketMetadata: TWebSocketMetadata = Reflect.getOwnMetadata(
|
|
189
|
-
webSocketKey,
|
|
190
|
-
webSocketConstructor
|
|
191
|
-
) || {
|
|
192
|
-
prefix: "/",
|
|
193
|
-
events: [],
|
|
194
|
-
http: []
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
const fullPrefix = `/${prefix || ""}/${webSocketMetadata.prefix}`;
|
|
198
|
-
|
|
199
|
-
//#region [HTTP ROUTER]
|
|
200
|
-
const router = new HttpRouter(fullPrefix);
|
|
201
|
-
|
|
202
|
-
for (const [_key, httpMetadata] of Object.entries(webSocketMetadata.http)) {
|
|
203
|
-
if (typeof httpMetadata.descriptor?.value !== "function") {
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const route = router.route(httpMetadata.path);
|
|
208
|
-
const handler = httpMetadata.descriptor.value.bind(webSocket);
|
|
209
|
-
const routeArgument = Object.freeze({
|
|
210
|
-
class: webSocketConstructor,
|
|
211
|
-
funcName: httpMetadata.methodName,
|
|
212
|
-
func: handler,
|
|
213
|
-
argumentsMetadata: httpMetadata.argumentsMetadata
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
switch (httpMetadata.httpMethod) {
|
|
217
|
-
case "GET":
|
|
218
|
-
route.get(routeArgument);
|
|
219
|
-
break;
|
|
220
|
-
case "POST":
|
|
221
|
-
route.post(routeArgument);
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
httpRouterGroup.add(router);
|
|
227
|
-
//#endregion
|
|
228
|
-
|
|
229
|
-
//#region [WEBSOCKET ROUTER]
|
|
230
|
-
const webSocketRouter = new WebSocketRouter(fullPrefix);
|
|
231
|
-
|
|
232
|
-
for (const [key, event] of Object.entries(webSocketMetadata.events)) {
|
|
233
|
-
const webSocketRoute = new WebSocketRoute({
|
|
234
|
-
eventName: key,
|
|
235
|
-
metadata: event
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
webSocketRouter.addRoutes(webSocketRoute);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
webSocketRouter.bind(webSocket);
|
|
242
|
-
webSocketRouterGroup.addRouters(webSocketRouter);
|
|
243
|
-
//#endregion
|
|
244
|
-
|
|
245
|
-
return Object.freeze({
|
|
246
|
-
httpRouterGroup: httpRouterGroup,
|
|
247
|
-
webSocketRouterGroup: webSocketRouterGroup
|
|
248
|
-
});
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
const argumentsResolution = async (
|
|
252
|
-
data: unknown,
|
|
253
|
-
zodSchema: Zod.Schema,
|
|
254
|
-
argumentIndex: number,
|
|
255
|
-
funcName: string | symbol
|
|
256
|
-
) => {
|
|
257
|
-
try {
|
|
258
|
-
const validation = await zodSchema.safeParseAsync(data);
|
|
259
|
-
|
|
260
|
-
if (!validation.success) {
|
|
261
|
-
throw new HttpClientError({
|
|
262
|
-
httpCode: 400,
|
|
263
|
-
message: `Validation at the [${funcName.toString()}] method fails at positional argument [${argumentIndex}].`,
|
|
264
|
-
data: validation.error.issues
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return validation.data;
|
|
269
|
-
} catch (error) {
|
|
270
|
-
if (error instanceof HttpClientError) {
|
|
271
|
-
throw error;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
throw new HttpServerError({
|
|
275
|
-
httpCode: 500,
|
|
276
|
-
message: `Validation at the [${funcName.toString()}] method error at positional argument [${argumentIndex}].`,
|
|
277
|
-
data: !(error instanceof Error)
|
|
278
|
-
? error
|
|
279
|
-
: [
|
|
280
|
-
{
|
|
281
|
-
message: error.message,
|
|
282
|
-
code: error.name,
|
|
283
|
-
cause: error.cause
|
|
284
|
-
}
|
|
285
|
-
]
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const moduleResolution = async (
|
|
291
|
-
module: new (...args: any[]) => unknown,
|
|
292
|
-
options: TBoolFactoryOptions
|
|
293
|
-
) => {
|
|
294
|
-
if (!Reflect.getOwnMetadataKeys(module).includes(moduleKey)) {
|
|
295
|
-
throw Error(`${module.name} is not a module.`);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const injector = new Injector();
|
|
299
|
-
const moduleMetadata = Reflect.getOwnMetadata(moduleKey, module) as TModuleMetadata;
|
|
300
|
-
|
|
301
|
-
if (!moduleMetadata) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const {
|
|
306
|
-
loaders,
|
|
307
|
-
middlewares,
|
|
308
|
-
guards,
|
|
309
|
-
dispatchers,
|
|
310
|
-
controllers,
|
|
311
|
-
dependencies,
|
|
312
|
-
webSockets,
|
|
313
|
-
prefix: modulePrefix,
|
|
314
|
-
config: moduleConfig
|
|
315
|
-
} = moduleMetadata;
|
|
316
|
-
|
|
317
|
-
const fullPrefix = `${options.prefix || ""}/${modulePrefix || ""}`;
|
|
318
|
-
|
|
319
|
-
//#region [Configuration(s)]
|
|
320
|
-
const { config } = Object.freeze({
|
|
321
|
-
config: {
|
|
322
|
-
...(typeof options.config !== "function" ? options.config : await options.config()),
|
|
323
|
-
...(typeof moduleConfig !== "function"
|
|
324
|
-
? typeof moduleConfig !== "object"
|
|
325
|
-
? undefined
|
|
326
|
-
: moduleConfig
|
|
327
|
-
: await moduleConfig())
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
//#endregion
|
|
331
|
-
|
|
332
|
-
//#region [Register config like an injection]
|
|
333
|
-
injector.set(configKey, config);
|
|
334
|
-
//#endregion
|
|
335
|
-
|
|
336
|
-
//#region [Run loader(s)]
|
|
337
|
-
if (loaders) {
|
|
338
|
-
const loaderFunctions = [];
|
|
339
|
-
|
|
340
|
-
for (const [key, func] of Object.entries(loaders)) {
|
|
341
|
-
loaderFunctions.push(async () => {
|
|
342
|
-
try {
|
|
343
|
-
const result = await func({ config });
|
|
344
|
-
|
|
345
|
-
console.info(
|
|
346
|
-
`${ansiText(" INFO ", {
|
|
347
|
-
color: "white",
|
|
348
|
-
backgroundColor: "blue",
|
|
349
|
-
bold: true
|
|
350
|
-
})} Loader [${key}] initialized successfully.`
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
return result;
|
|
354
|
-
} catch (error) {
|
|
355
|
-
console.error(
|
|
356
|
-
`${ansiText(" WARN ", {
|
|
357
|
-
color: "yellow",
|
|
358
|
-
backgroundColor: "red",
|
|
359
|
-
bold: true
|
|
360
|
-
})} Loader [${key}] initialization failed.`
|
|
361
|
-
);
|
|
362
|
-
options.debug && console.error(error);
|
|
363
|
-
throw error;
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const results = await Promise.all(loaderFunctions.map((func) => func()));
|
|
369
|
-
|
|
370
|
-
for (let i = 0; i < results.length; i++) {
|
|
371
|
-
const [key, value] = results[i];
|
|
372
|
-
injector.set(key, value);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
//#endregion
|
|
376
|
-
|
|
377
|
-
//#region [Dependencies]
|
|
378
|
-
!dependencies || dependencies.map((dependency) => injector.get(dependency));
|
|
379
|
-
//#endregion
|
|
380
|
-
|
|
381
|
-
//#region [Middleware(s)]
|
|
382
|
-
const startMiddlewareGroup: Array<
|
|
383
|
-
TGroupElementModel<"start", IMiddleware, NonNullable<IMiddleware["start"]>>
|
|
384
|
-
> = [];
|
|
385
|
-
const endMiddlewareGroup: Array<
|
|
386
|
-
TGroupElementModel<"end", IMiddleware, NonNullable<IMiddleware["end"]>>
|
|
387
|
-
> = [];
|
|
388
|
-
|
|
389
|
-
middlewares &&
|
|
390
|
-
middlewares.forEach((middleware) => {
|
|
391
|
-
const instance = injector.get<IMiddleware>(middleware);
|
|
392
|
-
|
|
393
|
-
if (instance.start && typeof instance.start === "function") {
|
|
394
|
-
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
395
|
-
Reflect.getOwnMetadata(argumentsKey, middleware, "start") || {};
|
|
396
|
-
|
|
397
|
-
startMiddlewareGroup.push(
|
|
398
|
-
Object.freeze({
|
|
399
|
-
class: middleware as IMiddleware,
|
|
400
|
-
funcName: "start",
|
|
401
|
-
func: instance.start.bind(instance),
|
|
402
|
-
argumentsMetadata: argumentsMetadata
|
|
403
|
-
})
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (instance.end && typeof instance.end === "function") {
|
|
408
|
-
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
409
|
-
Reflect.getOwnMetadata(argumentsKey, middleware, "start") || {};
|
|
410
|
-
|
|
411
|
-
endMiddlewareGroup.push(
|
|
412
|
-
Object.freeze({
|
|
413
|
-
class: middleware as IMiddleware,
|
|
414
|
-
funcName: "end",
|
|
415
|
-
func: instance.end.bind(instance),
|
|
416
|
-
argumentsMetadata: argumentsMetadata
|
|
417
|
-
})
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
//#endregion
|
|
422
|
-
|
|
423
|
-
//#region [Guard(s)]
|
|
424
|
-
const guardGroup: Array<TGroupElementModel<"enforce", IGuard, NonNullable<IGuard["enforce"]>>> =
|
|
425
|
-
!guards
|
|
426
|
-
? []
|
|
427
|
-
: guards.map((guard) => {
|
|
428
|
-
const guardInstance = injector.get<IGuard>(guard);
|
|
429
|
-
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
430
|
-
Reflect.getOwnMetadata(argumentsKey, guard, "enforce") || {};
|
|
431
|
-
|
|
432
|
-
return Object.freeze({
|
|
433
|
-
class: guard as unknown as IGuard,
|
|
434
|
-
funcName: "enforce",
|
|
435
|
-
func: guardInstance.enforce.bind(guardInstance),
|
|
436
|
-
argumentsMetadata: argumentsMetadata
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
//#endregion
|
|
440
|
-
|
|
441
|
-
//#region [Before dispatcher(s)]
|
|
442
|
-
const openDispatcherGroup: Array<
|
|
443
|
-
TGroupElementModel<"open", IDispatcher, NonNullable<IDispatcher["open"]>>
|
|
444
|
-
> = [];
|
|
445
|
-
const closeDispatcherGroup: Array<
|
|
446
|
-
TGroupElementModel<"close", IDispatcher, NonNullable<IDispatcher["close"]>>
|
|
447
|
-
> = [];
|
|
448
|
-
|
|
449
|
-
dispatchers &&
|
|
450
|
-
dispatchers.forEach((dispatcher) => {
|
|
451
|
-
const instance = injector.get<IDispatcher>(dispatcher);
|
|
452
|
-
|
|
453
|
-
if (instance.open && typeof instance.open === "function") {
|
|
454
|
-
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
455
|
-
Reflect.getOwnMetadata(argumentsKey, dispatcher, "open") || {};
|
|
456
|
-
|
|
457
|
-
openDispatcherGroup.push(
|
|
458
|
-
Object.freeze({
|
|
459
|
-
class: dispatcher as IDispatcher,
|
|
460
|
-
funcName: "open",
|
|
461
|
-
func: instance.open.bind(instance),
|
|
462
|
-
argumentsMetadata: argumentsMetadata
|
|
463
|
-
})
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (instance.close && typeof instance.close === "function") {
|
|
468
|
-
const argumentsMetadata: TArgumentsMetadataCollection =
|
|
469
|
-
Reflect.getOwnMetadata(argumentsKey, dispatcher, "close") || {};
|
|
470
|
-
|
|
471
|
-
closeDispatcherGroup.push(
|
|
472
|
-
Object.freeze({
|
|
473
|
-
class: dispatcher as IDispatcher,
|
|
474
|
-
funcName: "close",
|
|
475
|
-
func: instance.close.bind(instance),
|
|
476
|
-
argumentsMetadata: argumentsMetadata
|
|
477
|
-
})
|
|
478
|
-
);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
//#endregion
|
|
482
|
-
|
|
483
|
-
//#region [Controller(s)]
|
|
484
|
-
const controllerRouterGroup = new HttpRouterGroup();
|
|
485
|
-
|
|
486
|
-
controllers &&
|
|
487
|
-
controllers.forEach((controllerConstructor) =>
|
|
488
|
-
controllerCreator({
|
|
489
|
-
controllerConstructor,
|
|
490
|
-
httpRouterGroup: controllerRouterGroup,
|
|
491
|
-
injector: injector,
|
|
492
|
-
prefix: fullPrefix
|
|
493
|
-
})
|
|
494
|
-
);
|
|
495
|
-
//#endregion
|
|
496
|
-
|
|
497
|
-
//#region [WebSocket(s)]
|
|
498
|
-
const webSocketHttpRouterGroup = new HttpRouterGroup();
|
|
499
|
-
const webSocketRouterGroup = new WebSocketRouterGroup();
|
|
500
|
-
|
|
501
|
-
webSockets &&
|
|
502
|
-
webSockets.forEach((webSocket) =>
|
|
503
|
-
webSocketCreator({
|
|
504
|
-
webSocketConstructor: webSocket,
|
|
505
|
-
httpRouterGroup: webSocketHttpRouterGroup,
|
|
506
|
-
webSocketRouterGroup: webSocketRouterGroup,
|
|
507
|
-
injector,
|
|
508
|
-
prefix: fullPrefix
|
|
509
|
-
})
|
|
510
|
-
);
|
|
511
|
-
//#endregion
|
|
512
|
-
|
|
513
|
-
return Object.freeze({
|
|
514
|
-
prefix: moduleMetadata.prefix,
|
|
515
|
-
injector: injector,
|
|
516
|
-
startMiddlewareGroup,
|
|
517
|
-
endMiddlewareGroup,
|
|
518
|
-
guardGroup,
|
|
519
|
-
openDispatcherGroup,
|
|
520
|
-
closeDispatcherGroup,
|
|
521
|
-
controllerRouterGroup,
|
|
522
|
-
webSocketHttpRouterGroup,
|
|
523
|
-
webSocketRouterGroup
|
|
524
|
-
});
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
const webSocketFetcher = async (
|
|
528
|
-
bun: Required<{
|
|
529
|
-
request: Request;
|
|
530
|
-
server: Server;
|
|
531
|
-
}>,
|
|
532
|
-
bool: Required<{
|
|
533
|
-
responseHeaders: Headers;
|
|
534
|
-
query: Record<string, unknown>;
|
|
535
|
-
route: NonNullable<ReturnType<HttpRouterGroup["find"]>>;
|
|
536
|
-
moduleResolution: NonNullable<Awaited<ReturnType<typeof moduleResolution>>>;
|
|
537
|
-
}>
|
|
538
|
-
) => {
|
|
539
|
-
const { request, server } = bun;
|
|
540
|
-
const {
|
|
541
|
-
query,
|
|
542
|
-
responseHeaders,
|
|
543
|
-
route: { model }
|
|
544
|
-
} = bool;
|
|
545
|
-
|
|
546
|
-
// Execute controller action
|
|
547
|
-
const isUpgrade = await model.func(...[server, request, query]);
|
|
548
|
-
|
|
549
|
-
if (typeof isUpgrade !== "boolean") {
|
|
550
|
-
return responseConverter(
|
|
551
|
-
new Response(
|
|
552
|
-
JSON.stringify({
|
|
553
|
-
httpCode: 500,
|
|
554
|
-
message: "Can not detect webSocket upgrade result.",
|
|
555
|
-
data: undefined
|
|
556
|
-
}),
|
|
557
|
-
{
|
|
558
|
-
status: 500,
|
|
559
|
-
statusText: "Internal server error.",
|
|
560
|
-
headers: responseHeaders
|
|
561
|
-
}
|
|
562
|
-
)
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (!isUpgrade) {
|
|
567
|
-
return responseConverter(
|
|
568
|
-
new Response(
|
|
569
|
-
JSON.stringify({
|
|
570
|
-
httpCode: 500,
|
|
571
|
-
message: "Can not upgrade.",
|
|
572
|
-
data: undefined
|
|
573
|
-
}),
|
|
574
|
-
{
|
|
575
|
-
status: 500,
|
|
576
|
-
statusText: "Internal server error.",
|
|
577
|
-
headers: responseHeaders
|
|
578
|
-
}
|
|
579
|
-
)
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
return isUpgrade;
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
const httpFetcher = async (
|
|
587
|
-
bun: Required<{
|
|
588
|
-
request: Request;
|
|
589
|
-
server: Server;
|
|
590
|
-
}>,
|
|
591
|
-
bool: Required<{
|
|
592
|
-
responseHeaders: Headers;
|
|
593
|
-
query: Record<string, unknown>;
|
|
594
|
-
route: NonNullable<ReturnType<HttpRouterGroup["find"]>>;
|
|
595
|
-
moduleResolution: NonNullable<Awaited<ReturnType<typeof moduleResolution>>>;
|
|
596
|
-
}>
|
|
597
|
-
) => {
|
|
598
|
-
const { request, server: _server } = bun;
|
|
599
|
-
const {
|
|
600
|
-
query,
|
|
601
|
-
responseHeaders,
|
|
602
|
-
route: { parameters, model },
|
|
603
|
-
moduleResolution: {
|
|
604
|
-
startMiddlewareGroup,
|
|
605
|
-
endMiddlewareGroup,
|
|
606
|
-
guardGroup,
|
|
607
|
-
openDispatcherGroup,
|
|
608
|
-
closeDispatcherGroup
|
|
609
|
-
}
|
|
610
|
-
} = bool;
|
|
611
|
-
|
|
612
|
-
const context: Record<symbol, any> = {
|
|
613
|
-
[requestHeadersArgsKey]: request.headers,
|
|
614
|
-
[responseHeadersArgsKey]: responseHeaders,
|
|
615
|
-
[queryArgsKey]: query,
|
|
616
|
-
[paramsArgsKey]: parameters,
|
|
617
|
-
[routeModelArgsKey]: model
|
|
618
|
-
};
|
|
619
|
-
|
|
620
|
-
const contextHook = {
|
|
621
|
-
get(key) {
|
|
622
|
-
return context[key];
|
|
623
|
-
},
|
|
624
|
-
set(key, value) {
|
|
625
|
-
if (key in context) {
|
|
626
|
-
throw Error(`${String(key)} already exists in context.`);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
context[key] = value;
|
|
630
|
-
}
|
|
631
|
-
} satisfies IContext;
|
|
632
|
-
|
|
633
|
-
// Execute start middleware(s)
|
|
634
|
-
for (let i = 0; i < startMiddlewareGroup.length; i++) {
|
|
635
|
-
const args = [];
|
|
636
|
-
const {
|
|
637
|
-
func: handler,
|
|
638
|
-
funcName: functionName,
|
|
639
|
-
argumentsMetadata
|
|
640
|
-
} = startMiddlewareGroup[i];
|
|
641
|
-
|
|
642
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
643
|
-
switch (argMetadata.type) {
|
|
644
|
-
case requestArgsKey:
|
|
645
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
646
|
-
? request
|
|
647
|
-
: await argumentsResolution(
|
|
648
|
-
request,
|
|
649
|
-
argMetadata.zodSchema,
|
|
650
|
-
argMetadata.index,
|
|
651
|
-
functionName
|
|
652
|
-
);
|
|
653
|
-
break;
|
|
654
|
-
case requestBodyArgsKey:
|
|
655
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
656
|
-
? await request[argMetadata.parser || "json"]()
|
|
657
|
-
: await argumentsResolution(
|
|
658
|
-
await request[argMetadata.parser || "json"](),
|
|
659
|
-
argMetadata.zodSchema,
|
|
660
|
-
argMetadata.index,
|
|
661
|
-
functionName
|
|
662
|
-
);
|
|
663
|
-
break;
|
|
664
|
-
case contextArgsKey:
|
|
665
|
-
args[argMetadata.index] = !argMetadata.key
|
|
666
|
-
? contextHook
|
|
667
|
-
: contextHook.get(argMetadata.key);
|
|
668
|
-
break;
|
|
669
|
-
case requestHeadersArgsKey:
|
|
670
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
671
|
-
? request.headers
|
|
672
|
-
: await argumentsResolution(
|
|
673
|
-
request.headers.toJSON(),
|
|
674
|
-
argMetadata.zodSchema,
|
|
675
|
-
argMetadata.index,
|
|
676
|
-
functionName
|
|
677
|
-
);
|
|
678
|
-
break;
|
|
679
|
-
case responseHeadersArgsKey:
|
|
680
|
-
args[argMetadata.index] = context[argMetadata.type];
|
|
681
|
-
break;
|
|
682
|
-
case requestHeaderArgsKey:
|
|
683
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
684
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
685
|
-
: await argumentsResolution(
|
|
686
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
687
|
-
argMetadata.zodSchema,
|
|
688
|
-
argMetadata.index,
|
|
689
|
-
functionName
|
|
690
|
-
);
|
|
691
|
-
break;
|
|
692
|
-
case paramArgsKey:
|
|
693
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
694
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
695
|
-
: await argumentsResolution(
|
|
696
|
-
context[paramsArgsKey][argMetadata.key],
|
|
697
|
-
argMetadata.zodSchema,
|
|
698
|
-
argMetadata.index,
|
|
699
|
-
functionName
|
|
700
|
-
);
|
|
701
|
-
break;
|
|
702
|
-
case routeModelArgsKey:
|
|
703
|
-
args[argMetadata.index] = context[routeModelArgsKey];
|
|
704
|
-
break;
|
|
705
|
-
default:
|
|
706
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
707
|
-
? !(argMetadata.type in context)
|
|
708
|
-
? undefined
|
|
709
|
-
: context[argMetadata.type]
|
|
710
|
-
: await argumentsResolution(
|
|
711
|
-
!(argMetadata.type in context)
|
|
712
|
-
? undefined
|
|
713
|
-
: context[argMetadata.type],
|
|
714
|
-
argMetadata.zodSchema,
|
|
715
|
-
argMetadata.index,
|
|
716
|
-
functionName
|
|
717
|
-
);
|
|
718
|
-
break;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
context[responseBodyArgsKey] = await handler(...args);
|
|
723
|
-
|
|
724
|
-
if (context[responseBodyArgsKey] instanceof Response) {
|
|
725
|
-
return responseConverter(context[responseBodyArgsKey]);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
// Execute guard(s)
|
|
730
|
-
for (let i = 0; i < guardGroup.length; i++) {
|
|
731
|
-
const args = [];
|
|
732
|
-
const { func: handler, funcName: functionName, argumentsMetadata } = guardGroup[i];
|
|
733
|
-
|
|
734
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
735
|
-
switch (argMetadata.type) {
|
|
736
|
-
case requestArgsKey:
|
|
737
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
738
|
-
? request
|
|
739
|
-
: await argumentsResolution(
|
|
740
|
-
request,
|
|
741
|
-
argMetadata.zodSchema,
|
|
742
|
-
argMetadata.index,
|
|
743
|
-
functionName
|
|
744
|
-
);
|
|
745
|
-
break;
|
|
746
|
-
case requestBodyArgsKey:
|
|
747
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
748
|
-
? await request[argMetadata.parser || "json"]()
|
|
749
|
-
: await argumentsResolution(
|
|
750
|
-
await request[argMetadata.parser || "json"](),
|
|
751
|
-
argMetadata.zodSchema,
|
|
752
|
-
argMetadata.index,
|
|
753
|
-
functionName
|
|
754
|
-
);
|
|
755
|
-
break;
|
|
756
|
-
case contextArgsKey:
|
|
757
|
-
args[argMetadata.index] = !argMetadata.key
|
|
758
|
-
? contextHook
|
|
759
|
-
: contextHook.get(argMetadata.key);
|
|
760
|
-
break;
|
|
761
|
-
case requestHeadersArgsKey:
|
|
762
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
763
|
-
? request.headers
|
|
764
|
-
: await argumentsResolution(
|
|
765
|
-
request.headers.toJSON(),
|
|
766
|
-
argMetadata.zodSchema,
|
|
767
|
-
argMetadata.index,
|
|
768
|
-
functionName
|
|
769
|
-
);
|
|
770
|
-
break;
|
|
771
|
-
case responseHeadersArgsKey:
|
|
772
|
-
args[argMetadata.index] = context[argMetadata.type];
|
|
773
|
-
break;
|
|
774
|
-
case requestHeaderArgsKey:
|
|
775
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
776
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
777
|
-
: await argumentsResolution(
|
|
778
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
779
|
-
argMetadata.zodSchema,
|
|
780
|
-
argMetadata.index,
|
|
781
|
-
functionName
|
|
782
|
-
);
|
|
783
|
-
break;
|
|
784
|
-
case paramArgsKey:
|
|
785
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
786
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
787
|
-
: await argumentsResolution(
|
|
788
|
-
context[paramsArgsKey][argMetadata.key],
|
|
789
|
-
argMetadata.zodSchema,
|
|
790
|
-
argMetadata.index,
|
|
791
|
-
functionName
|
|
792
|
-
);
|
|
793
|
-
break;
|
|
794
|
-
case routeModelArgsKey:
|
|
795
|
-
args[argMetadata.index] = context[routeModelArgsKey];
|
|
796
|
-
break;
|
|
797
|
-
default:
|
|
798
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
799
|
-
? context[argMetadata.type]
|
|
800
|
-
: await argumentsResolution(
|
|
801
|
-
context[argMetadata.type],
|
|
802
|
-
argMetadata.zodSchema,
|
|
803
|
-
argMetadata.index,
|
|
804
|
-
functionName
|
|
805
|
-
);
|
|
806
|
-
break;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
const guardResult = await handler(...args);
|
|
811
|
-
|
|
812
|
-
if (typeof guardResult !== "boolean" || !guardResult) {
|
|
813
|
-
throw new HttpClientError({
|
|
814
|
-
httpCode: 401,
|
|
815
|
-
message: "Unauthorization.",
|
|
816
|
-
data: undefined
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
// Execute open dispatcher(s)
|
|
822
|
-
for (let i = 0; i < openDispatcherGroup.length; i++) {
|
|
823
|
-
const args = [];
|
|
824
|
-
const { func: handler, funcName: functionName, argumentsMetadata } = openDispatcherGroup[i];
|
|
825
|
-
|
|
826
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
827
|
-
switch (argMetadata.type) {
|
|
828
|
-
case requestArgsKey:
|
|
829
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
830
|
-
? request
|
|
831
|
-
: await argumentsResolution(
|
|
832
|
-
request,
|
|
833
|
-
argMetadata.zodSchema,
|
|
834
|
-
argMetadata.index,
|
|
835
|
-
functionName
|
|
836
|
-
);
|
|
837
|
-
break;
|
|
838
|
-
case requestBodyArgsKey:
|
|
839
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
840
|
-
? await request[argMetadata.parser || "json"]()
|
|
841
|
-
: await argumentsResolution(
|
|
842
|
-
await request[argMetadata.parser || "json"](),
|
|
843
|
-
argMetadata.zodSchema,
|
|
844
|
-
argMetadata.index,
|
|
845
|
-
functionName
|
|
846
|
-
);
|
|
847
|
-
break;
|
|
848
|
-
case contextArgsKey:
|
|
849
|
-
args[argMetadata.index] = !argMetadata.key
|
|
850
|
-
? contextHook
|
|
851
|
-
: contextHook.get(argMetadata.key);
|
|
852
|
-
break;
|
|
853
|
-
case requestHeadersArgsKey:
|
|
854
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
855
|
-
? request.headers
|
|
856
|
-
: await argumentsResolution(
|
|
857
|
-
request.headers.toJSON(),
|
|
858
|
-
argMetadata.zodSchema,
|
|
859
|
-
argMetadata.index,
|
|
860
|
-
functionName
|
|
861
|
-
);
|
|
862
|
-
break;
|
|
863
|
-
case responseHeadersArgsKey:
|
|
864
|
-
args[argMetadata.index] = context[argMetadata.type];
|
|
865
|
-
break;
|
|
866
|
-
case requestHeaderArgsKey:
|
|
867
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
868
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
869
|
-
: await argumentsResolution(
|
|
870
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
871
|
-
argMetadata.zodSchema,
|
|
872
|
-
argMetadata.index,
|
|
873
|
-
functionName
|
|
874
|
-
);
|
|
875
|
-
break;
|
|
876
|
-
case paramArgsKey:
|
|
877
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
878
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
879
|
-
: await argumentsResolution(
|
|
880
|
-
context[paramsArgsKey][argMetadata.key],
|
|
881
|
-
argMetadata.zodSchema,
|
|
882
|
-
argMetadata.index,
|
|
883
|
-
functionName
|
|
884
|
-
);
|
|
885
|
-
break;
|
|
886
|
-
case routeModelArgsKey:
|
|
887
|
-
args[argMetadata.index] = context[routeModelArgsKey];
|
|
888
|
-
break;
|
|
889
|
-
default:
|
|
890
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
891
|
-
? context[argMetadata.type]
|
|
892
|
-
: await argumentsResolution(
|
|
893
|
-
context[argMetadata.type],
|
|
894
|
-
argMetadata.zodSchema,
|
|
895
|
-
argMetadata.index,
|
|
896
|
-
functionName
|
|
897
|
-
);
|
|
898
|
-
break;
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
context[responseBodyArgsKey] = await handler(...args);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// Execute controller action
|
|
906
|
-
const controllerActionArguments: any[] = [];
|
|
907
|
-
const {
|
|
908
|
-
func: controllerAction,
|
|
909
|
-
funcName: controllerActionName,
|
|
910
|
-
argumentsMetadata: controllerActionArgumentsMetadata
|
|
911
|
-
} = model;
|
|
912
|
-
|
|
913
|
-
for (const [_key, argMetadata] of Object.entries(controllerActionArgumentsMetadata)) {
|
|
914
|
-
switch (argMetadata.type) {
|
|
915
|
-
case requestArgsKey:
|
|
916
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
917
|
-
? request
|
|
918
|
-
: await argumentsResolution(
|
|
919
|
-
request,
|
|
920
|
-
argMetadata.zodSchema,
|
|
921
|
-
argMetadata.index,
|
|
922
|
-
controllerActionName
|
|
923
|
-
);
|
|
924
|
-
break;
|
|
925
|
-
case requestBodyArgsKey:
|
|
926
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
927
|
-
? await request[argMetadata.parser || "json"]()
|
|
928
|
-
: await argumentsResolution(
|
|
929
|
-
await request[argMetadata.parser || "json"](),
|
|
930
|
-
argMetadata.zodSchema,
|
|
931
|
-
argMetadata.index,
|
|
932
|
-
controllerActionName
|
|
933
|
-
);
|
|
934
|
-
break;
|
|
935
|
-
case contextArgsKey:
|
|
936
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.key
|
|
937
|
-
? contextHook
|
|
938
|
-
: contextHook.get(argMetadata.key);
|
|
939
|
-
break;
|
|
940
|
-
case requestHeadersArgsKey:
|
|
941
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
942
|
-
? request.headers
|
|
943
|
-
: await argumentsResolution(
|
|
944
|
-
request.headers.toJSON(),
|
|
945
|
-
argMetadata.zodSchema,
|
|
946
|
-
argMetadata.index,
|
|
947
|
-
controllerActionName
|
|
948
|
-
);
|
|
949
|
-
break;
|
|
950
|
-
case responseHeadersArgsKey:
|
|
951
|
-
controllerActionArguments[argMetadata.index] = context[argMetadata.type];
|
|
952
|
-
break;
|
|
953
|
-
case requestHeaderArgsKey:
|
|
954
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
955
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
956
|
-
: await argumentsResolution(
|
|
957
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
958
|
-
argMetadata.zodSchema,
|
|
959
|
-
argMetadata.index,
|
|
960
|
-
controllerActionName
|
|
961
|
-
);
|
|
962
|
-
break;
|
|
963
|
-
case paramArgsKey:
|
|
964
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
965
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
966
|
-
: await argumentsResolution(
|
|
967
|
-
context[paramsArgsKey][argMetadata.key],
|
|
968
|
-
argMetadata.zodSchema,
|
|
969
|
-
argMetadata.index,
|
|
970
|
-
controllerActionName
|
|
971
|
-
);
|
|
972
|
-
break;
|
|
973
|
-
case routeModelArgsKey:
|
|
974
|
-
controllerActionArguments[argMetadata.index] = context[routeModelArgsKey];
|
|
975
|
-
break;
|
|
976
|
-
default:
|
|
977
|
-
controllerActionArguments[argMetadata.index] = !argMetadata.zodSchema
|
|
978
|
-
? context[argMetadata.type]
|
|
979
|
-
: await argumentsResolution(
|
|
980
|
-
context[argMetadata.type],
|
|
981
|
-
argMetadata.zodSchema,
|
|
982
|
-
argMetadata.index,
|
|
983
|
-
controllerActionName
|
|
984
|
-
);
|
|
985
|
-
break;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
context[responseBodyArgsKey] = await controllerAction(...controllerActionArguments);
|
|
990
|
-
|
|
991
|
-
// Execute close dispatcher(s)
|
|
992
|
-
for (let i = 0; i < closeDispatcherGroup.length; i++) {
|
|
993
|
-
const args = [];
|
|
994
|
-
const {
|
|
995
|
-
func: handler,
|
|
996
|
-
funcName: functionName,
|
|
997
|
-
argumentsMetadata
|
|
998
|
-
} = closeDispatcherGroup[i];
|
|
999
|
-
|
|
1000
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1001
|
-
switch (argMetadata.type) {
|
|
1002
|
-
case requestArgsKey:
|
|
1003
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1004
|
-
? request
|
|
1005
|
-
: await argumentsResolution(
|
|
1006
|
-
request,
|
|
1007
|
-
argMetadata.zodSchema,
|
|
1008
|
-
argMetadata.index,
|
|
1009
|
-
functionName
|
|
1010
|
-
);
|
|
1011
|
-
break;
|
|
1012
|
-
case requestBodyArgsKey:
|
|
1013
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1014
|
-
? await request[argMetadata.parser || "json"]()
|
|
1015
|
-
: await argumentsResolution(
|
|
1016
|
-
await request[argMetadata.parser || "json"](),
|
|
1017
|
-
argMetadata.zodSchema,
|
|
1018
|
-
argMetadata.index,
|
|
1019
|
-
functionName
|
|
1020
|
-
);
|
|
1021
|
-
break;
|
|
1022
|
-
case contextArgsKey:
|
|
1023
|
-
args[argMetadata.index] = !argMetadata.key
|
|
1024
|
-
? contextHook
|
|
1025
|
-
: contextHook.get(argMetadata.key);
|
|
1026
|
-
break;
|
|
1027
|
-
case requestHeadersArgsKey:
|
|
1028
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1029
|
-
? request.headers
|
|
1030
|
-
: await argumentsResolution(
|
|
1031
|
-
request.headers.toJSON(),
|
|
1032
|
-
argMetadata.zodSchema,
|
|
1033
|
-
argMetadata.index,
|
|
1034
|
-
functionName
|
|
1035
|
-
);
|
|
1036
|
-
break;
|
|
1037
|
-
case responseHeadersArgsKey:
|
|
1038
|
-
args[argMetadata.index] = context[argMetadata.type];
|
|
1039
|
-
break;
|
|
1040
|
-
case requestHeaderArgsKey:
|
|
1041
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1042
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
1043
|
-
: await argumentsResolution(
|
|
1044
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
1045
|
-
argMetadata.zodSchema,
|
|
1046
|
-
argMetadata.index,
|
|
1047
|
-
functionName
|
|
1048
|
-
);
|
|
1049
|
-
break;
|
|
1050
|
-
case paramArgsKey:
|
|
1051
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1052
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
1053
|
-
: await argumentsResolution(
|
|
1054
|
-
context[paramsArgsKey][argMetadata.key],
|
|
1055
|
-
argMetadata.zodSchema,
|
|
1056
|
-
argMetadata.index,
|
|
1057
|
-
functionName
|
|
1058
|
-
);
|
|
1059
|
-
break;
|
|
1060
|
-
case routeModelArgsKey:
|
|
1061
|
-
args[argMetadata.index] = context[routeModelArgsKey];
|
|
1062
|
-
break;
|
|
1063
|
-
default:
|
|
1064
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1065
|
-
? context[argMetadata.type]
|
|
1066
|
-
: await argumentsResolution(
|
|
1067
|
-
context[argMetadata.type],
|
|
1068
|
-
argMetadata.zodSchema,
|
|
1069
|
-
argMetadata.index,
|
|
1070
|
-
functionName
|
|
1071
|
-
);
|
|
1072
|
-
break;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
await handler(...args);
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
if (context[responseBodyArgsKey] instanceof Response) {
|
|
1080
|
-
return responseConverter(context[responseBodyArgsKey]);
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// Execute end middleware(s)
|
|
1084
|
-
for (let i = 0; i < endMiddlewareGroup.length; i++) {
|
|
1085
|
-
const args = [];
|
|
1086
|
-
const { func: handler, funcName: functionName, argumentsMetadata } = endMiddlewareGroup[i];
|
|
1087
|
-
|
|
1088
|
-
for (const [_key, argMetadata] of Object.entries(argumentsMetadata)) {
|
|
1089
|
-
switch (argMetadata.type) {
|
|
1090
|
-
case requestArgsKey:
|
|
1091
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1092
|
-
? request
|
|
1093
|
-
: await argumentsResolution(
|
|
1094
|
-
request,
|
|
1095
|
-
argMetadata.zodSchema,
|
|
1096
|
-
argMetadata.index,
|
|
1097
|
-
functionName
|
|
1098
|
-
);
|
|
1099
|
-
break;
|
|
1100
|
-
case requestBodyArgsKey:
|
|
1101
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1102
|
-
? await request[argMetadata.parser || "json"]()
|
|
1103
|
-
: await argumentsResolution(
|
|
1104
|
-
await request[argMetadata.parser || "json"](),
|
|
1105
|
-
argMetadata.zodSchema,
|
|
1106
|
-
argMetadata.index,
|
|
1107
|
-
functionName
|
|
1108
|
-
);
|
|
1109
|
-
break;
|
|
1110
|
-
case contextArgsKey:
|
|
1111
|
-
args[argMetadata.index] = !argMetadata.key
|
|
1112
|
-
? contextHook
|
|
1113
|
-
: contextHook.get(argMetadata.key);
|
|
1114
|
-
break;
|
|
1115
|
-
case requestHeadersArgsKey:
|
|
1116
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1117
|
-
? request.headers
|
|
1118
|
-
: await argumentsResolution(
|
|
1119
|
-
request.headers.toJSON(),
|
|
1120
|
-
argMetadata.zodSchema,
|
|
1121
|
-
argMetadata.index,
|
|
1122
|
-
functionName
|
|
1123
|
-
);
|
|
1124
|
-
break;
|
|
1125
|
-
case responseHeadersArgsKey:
|
|
1126
|
-
args[argMetadata.index] = context[argMetadata.type];
|
|
1127
|
-
break;
|
|
1128
|
-
case requestHeaderArgsKey:
|
|
1129
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1130
|
-
? request.headers.get(argMetadata.key) || undefined
|
|
1131
|
-
: await argumentsResolution(
|
|
1132
|
-
request.headers.get(argMetadata.key) || undefined,
|
|
1133
|
-
argMetadata.zodSchema,
|
|
1134
|
-
argMetadata.index,
|
|
1135
|
-
functionName
|
|
1136
|
-
);
|
|
1137
|
-
break;
|
|
1138
|
-
case paramArgsKey:
|
|
1139
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1140
|
-
? context[paramsArgsKey][argMetadata.key] || undefined
|
|
1141
|
-
: await argumentsResolution(
|
|
1142
|
-
context[paramsArgsKey][argMetadata.key],
|
|
1143
|
-
argMetadata.zodSchema,
|
|
1144
|
-
argMetadata.index,
|
|
1145
|
-
functionName
|
|
1146
|
-
);
|
|
1147
|
-
break;
|
|
1148
|
-
case routeModelArgsKey:
|
|
1149
|
-
args[argMetadata.index] = context[routeModelArgsKey];
|
|
1150
|
-
break;
|
|
1151
|
-
default:
|
|
1152
|
-
args[argMetadata.index] = !argMetadata.zodSchema
|
|
1153
|
-
? !(argMetadata.type in context)
|
|
1154
|
-
? undefined
|
|
1155
|
-
: context[argMetadata.type]
|
|
1156
|
-
: await argumentsResolution(
|
|
1157
|
-
!(argMetadata.type in context)
|
|
1158
|
-
? undefined
|
|
1159
|
-
: context[argMetadata.type],
|
|
1160
|
-
argMetadata.zodSchema,
|
|
1161
|
-
argMetadata.index,
|
|
1162
|
-
functionName
|
|
1163
|
-
);
|
|
1164
|
-
break;
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
context[responseBodyArgsKey] = await handler(...args);
|
|
1169
|
-
|
|
1170
|
-
if (context[responseBodyArgsKey] instanceof Response) {
|
|
1171
|
-
return responseConverter(context[responseBodyArgsKey]);
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
return responseConverter(
|
|
1176
|
-
new Response(
|
|
1177
|
-
!context[responseBodyArgsKey]
|
|
1178
|
-
? undefined
|
|
1179
|
-
: JSON.stringify({
|
|
1180
|
-
httpCode: 200,
|
|
1181
|
-
message: "SUCCESS",
|
|
1182
|
-
data: context[responseBodyArgsKey]
|
|
1183
|
-
}),
|
|
1184
|
-
{
|
|
1185
|
-
status: !context[responseBodyArgsKey] ? 204 : 200,
|
|
1186
|
-
statusText: "SUCCESS",
|
|
1187
|
-
headers: context[responseHeadersArgsKey]
|
|
1188
|
-
}
|
|
1189
|
-
)
|
|
1190
|
-
);
|
|
1191
|
-
};
|
|
1192
|
-
|
|
1193
|
-
export const BoolFactory = async (
|
|
1194
|
-
modules: Object | Array<Object>,
|
|
1195
|
-
options: TBoolFactoryOptions
|
|
1196
|
-
) => {
|
|
1197
|
-
try {
|
|
1198
|
-
const staticMap: Map<
|
|
1199
|
-
string,
|
|
1200
|
-
Readonly<{
|
|
1201
|
-
expiredAt: Date;
|
|
1202
|
-
file: BunFile;
|
|
1203
|
-
}>
|
|
1204
|
-
> = new Map();
|
|
1205
|
-
|
|
1206
|
-
const modulesConverted = !Array.isArray(modules) ? [modules] : modules;
|
|
1207
|
-
|
|
1208
|
-
const {
|
|
1209
|
-
allowLogsMethods,
|
|
1210
|
-
staticOption,
|
|
1211
|
-
allowOrigins,
|
|
1212
|
-
allowMethods,
|
|
1213
|
-
allowCredentials,
|
|
1214
|
-
allowHeaders
|
|
1215
|
-
} = Object.freeze({
|
|
1216
|
-
allowLogsMethods: options?.log?.methods,
|
|
1217
|
-
staticOption: options.static,
|
|
1218
|
-
allowOrigins: !options.cors?.origins
|
|
1219
|
-
? ["*"]
|
|
1220
|
-
: typeof options.cors.origins !== "string"
|
|
1221
|
-
? options.cors.origins.includes("*") || options.cors.origins.length < 1
|
|
1222
|
-
? ["*"]
|
|
1223
|
-
: options.cors.origins
|
|
1224
|
-
: [options.cors.origins !== "*" ? options.cors.origins : "*"],
|
|
1225
|
-
allowMethods: options.cors?.methods || [
|
|
1226
|
-
"GET",
|
|
1227
|
-
"POST",
|
|
1228
|
-
"PUT",
|
|
1229
|
-
"PATCH",
|
|
1230
|
-
"DELETE",
|
|
1231
|
-
"OPTIONS"
|
|
1232
|
-
],
|
|
1233
|
-
allowCredentials: !options.cors?.credentials ? false : true,
|
|
1234
|
-
allowHeaders:
|
|
1235
|
-
!options.cors?.headers || options.cors.headers.includes("*")
|
|
1236
|
-
? ["*"]
|
|
1237
|
-
: options.cors.headers
|
|
1238
|
-
});
|
|
1239
|
-
|
|
1240
|
-
const moduleResolutions = await Promise.all(
|
|
1241
|
-
modulesConverted.map((moduleConverted) => moduleResolution(moduleConverted, options))
|
|
1242
|
-
);
|
|
1243
|
-
|
|
1244
|
-
const availableModuleResolutions = moduleResolutions.filter(
|
|
1245
|
-
(moduleResolution) => typeof moduleResolution !== "undefined"
|
|
1246
|
-
);
|
|
1247
|
-
|
|
1248
|
-
const prefixs = [
|
|
1249
|
-
...new Set(
|
|
1250
|
-
availableModuleResolutions.map(
|
|
1251
|
-
(availableModuleResolution) => availableModuleResolution.prefix
|
|
1252
|
-
)
|
|
1253
|
-
)
|
|
1254
|
-
];
|
|
1255
|
-
|
|
1256
|
-
if (prefixs.length !== availableModuleResolutions.length) {
|
|
1257
|
-
throw Error("Module prefix should be unique.");
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
const webSocketsMap = new Map<string, TWebSocketEventHandlerMetadata>();
|
|
1261
|
-
|
|
1262
|
-
for (const availableModuleResolution of availableModuleResolutions) {
|
|
1263
|
-
const webSocketMap = availableModuleResolution.webSocketRouterGroup.execute();
|
|
1264
|
-
|
|
1265
|
-
for (const [key, metadata] of webSocketMap.entries()) {
|
|
1266
|
-
webSocketsMap.set(key, metadata);
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
const server = Bun.serve<TWebSocketUpgradeData>({
|
|
1271
|
-
port: options.port,
|
|
1272
|
-
fetch: async (request, server) => {
|
|
1273
|
-
const start = performance.now();
|
|
1274
|
-
const url = new URL(request.url);
|
|
1275
|
-
const query = Qs.parse(url.searchParams.toString(), options.queryParser);
|
|
1276
|
-
const origin = request.headers.get("origin") || "*";
|
|
1277
|
-
const method = request.method.toUpperCase();
|
|
1278
|
-
const responseHeaders = new Headers();
|
|
1279
|
-
|
|
1280
|
-
try {
|
|
1281
|
-
const isUpgradable = isWebSocketUpgrade(request);
|
|
1282
|
-
|
|
1283
|
-
let collection:
|
|
1284
|
-
| undefined
|
|
1285
|
-
| Required<{
|
|
1286
|
-
route: NonNullable<ReturnType<HttpRouterGroup["find"]>>;
|
|
1287
|
-
resolution: NonNullable<Awaited<ReturnType<typeof moduleResolution>>>;
|
|
1288
|
-
}>;
|
|
1289
|
-
|
|
1290
|
-
if (isUpgradable) {
|
|
1291
|
-
for (const availableModuleResolution of availableModuleResolutions) {
|
|
1292
|
-
const routeResult =
|
|
1293
|
-
availableModuleResolution.webSocketHttpRouterGroup.find(
|
|
1294
|
-
url.pathname,
|
|
1295
|
-
request.method as keyof THttpMethods
|
|
1296
|
-
);
|
|
1297
|
-
|
|
1298
|
-
if (routeResult) {
|
|
1299
|
-
collection = Object.freeze({
|
|
1300
|
-
route: routeResult,
|
|
1301
|
-
resolution: availableModuleResolution
|
|
1302
|
-
});
|
|
1303
|
-
break;
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
if (!collection) {
|
|
1308
|
-
return responseConverter(
|
|
1309
|
-
new Response(
|
|
1310
|
-
JSON.stringify({
|
|
1311
|
-
httpCode: 404,
|
|
1312
|
-
message: "Route not found",
|
|
1313
|
-
data: undefined
|
|
1314
|
-
}),
|
|
1315
|
-
{
|
|
1316
|
-
status: 404,
|
|
1317
|
-
statusText: "Not found.",
|
|
1318
|
-
headers: responseHeaders
|
|
1319
|
-
}
|
|
1320
|
-
)
|
|
1321
|
-
);
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
const upgradeResult = await webSocketFetcher(
|
|
1325
|
-
{
|
|
1326
|
-
request,
|
|
1327
|
-
server
|
|
1328
|
-
},
|
|
1329
|
-
{
|
|
1330
|
-
query: query,
|
|
1331
|
-
responseHeaders: responseHeaders,
|
|
1332
|
-
route: collection.route,
|
|
1333
|
-
moduleResolution: collection.resolution
|
|
1334
|
-
}
|
|
1335
|
-
);
|
|
1336
|
-
|
|
1337
|
-
return upgradeResult instanceof Response ? upgradeResult : undefined;
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
allowCredentials &&
|
|
1341
|
-
responseHeaders.set("Access-Control-Allow-Credentials", "true");
|
|
1342
|
-
|
|
1343
|
-
responseHeaders.set("Access-Control-Allow-Methods", allowMethods.join(", "));
|
|
1344
|
-
responseHeaders.set("Access-Control-Allow-Headers", allowHeaders.join(", "));
|
|
1345
|
-
responseHeaders.set(
|
|
1346
|
-
"Access-Control-Allow-Origin",
|
|
1347
|
-
allowOrigins.includes("*")
|
|
1348
|
-
? "*"
|
|
1349
|
-
: !allowOrigins.includes(origin)
|
|
1350
|
-
? allowOrigins[0]
|
|
1351
|
-
: origin
|
|
1352
|
-
);
|
|
1353
|
-
|
|
1354
|
-
if (!allowMethods.includes(method)) {
|
|
1355
|
-
return responseConverter(
|
|
1356
|
-
new Response(undefined, {
|
|
1357
|
-
status: 405,
|
|
1358
|
-
statusText: "Method Not Allowed.",
|
|
1359
|
-
headers: responseHeaders
|
|
1360
|
-
})
|
|
1361
|
-
);
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
if (request.method.toUpperCase() === "OPTIONS") {
|
|
1365
|
-
return responseConverter(
|
|
1366
|
-
allowOrigins.includes("*") || allowOrigins.includes(origin)
|
|
1367
|
-
? new Response(undefined, {
|
|
1368
|
-
status: 204,
|
|
1369
|
-
statusText: "No Content.",
|
|
1370
|
-
headers: responseHeaders
|
|
1371
|
-
})
|
|
1372
|
-
: new Response(undefined, {
|
|
1373
|
-
status: 417,
|
|
1374
|
-
statusText: "Expectation Failed.",
|
|
1375
|
-
headers: responseHeaders
|
|
1376
|
-
})
|
|
1377
|
-
);
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
if (staticOption) {
|
|
1381
|
-
const { path, headers, cacheTimeInSeconds } = staticOption;
|
|
1382
|
-
const pathname = `${path}/${url.pathname}`;
|
|
1383
|
-
const cachedFile = staticMap.get(pathname);
|
|
1384
|
-
|
|
1385
|
-
if (!cachedFile) {
|
|
1386
|
-
const file = Bun.file(pathname);
|
|
1387
|
-
const isFileExists = await file.exists();
|
|
1388
|
-
|
|
1389
|
-
if (isFileExists) {
|
|
1390
|
-
if (headers) {
|
|
1391
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
1392
|
-
responseHeaders.set(key, value);
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
responseHeaders.set("Content-Type", file.type);
|
|
1397
|
-
|
|
1398
|
-
return responseConverter(
|
|
1399
|
-
new Response(await file.arrayBuffer(), {
|
|
1400
|
-
status: 200,
|
|
1401
|
-
statusText: "SUCCESS",
|
|
1402
|
-
headers: responseHeaders
|
|
1403
|
-
})
|
|
1404
|
-
);
|
|
1405
|
-
}
|
|
1406
|
-
} else {
|
|
1407
|
-
const isExpired = new Date() > cachedFile.expiredAt;
|
|
1408
|
-
|
|
1409
|
-
if (isExpired) {
|
|
1410
|
-
staticMap.delete(pathname);
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
const file = !isExpired ? cachedFile.file : Bun.file(pathname);
|
|
1414
|
-
const isFileExists = await file.exists();
|
|
1415
|
-
|
|
1416
|
-
if (isFileExists) {
|
|
1417
|
-
staticMap.set(
|
|
1418
|
-
pathname,
|
|
1419
|
-
Object.freeze({
|
|
1420
|
-
expiredAt: TimeAdd(
|
|
1421
|
-
new Date(),
|
|
1422
|
-
typeof cacheTimeInSeconds !== "number"
|
|
1423
|
-
? DEFAULT_STATIC_CACHE_TIME_IN_SECONDS
|
|
1424
|
-
: cacheTimeInSeconds,
|
|
1425
|
-
ETimeUnit.seconds
|
|
1426
|
-
),
|
|
1427
|
-
file: file
|
|
1428
|
-
})
|
|
1429
|
-
);
|
|
1430
|
-
|
|
1431
|
-
if (headers) {
|
|
1432
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
1433
|
-
responseHeaders.set(key, value);
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
responseHeaders.set("Content-Type", file.type);
|
|
1438
|
-
|
|
1439
|
-
return responseConverter(
|
|
1440
|
-
new Response(await file.arrayBuffer(), {
|
|
1441
|
-
status: 200,
|
|
1442
|
-
statusText: "SUCCESS",
|
|
1443
|
-
headers: responseHeaders
|
|
1444
|
-
})
|
|
1445
|
-
);
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
for (const availableModuleResolution of availableModuleResolutions) {
|
|
1451
|
-
const routeResult = availableModuleResolution.controllerRouterGroup.find(
|
|
1452
|
-
url.pathname,
|
|
1453
|
-
request.method as keyof THttpMethods
|
|
1454
|
-
);
|
|
1455
|
-
|
|
1456
|
-
if (routeResult) {
|
|
1457
|
-
collection = Object.freeze({
|
|
1458
|
-
route: routeResult,
|
|
1459
|
-
resolution: availableModuleResolution
|
|
1460
|
-
});
|
|
1461
|
-
break;
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
if (!collection) {
|
|
1466
|
-
return responseConverter(
|
|
1467
|
-
new Response(
|
|
1468
|
-
JSON.stringify({
|
|
1469
|
-
httpCode: 404,
|
|
1470
|
-
message: "Route not found",
|
|
1471
|
-
data: undefined
|
|
1472
|
-
}),
|
|
1473
|
-
{
|
|
1474
|
-
status: 404,
|
|
1475
|
-
statusText: "Not found.",
|
|
1476
|
-
headers: responseHeaders
|
|
1477
|
-
}
|
|
1478
|
-
)
|
|
1479
|
-
);
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
return await httpFetcher(
|
|
1483
|
-
{
|
|
1484
|
-
request,
|
|
1485
|
-
server
|
|
1486
|
-
},
|
|
1487
|
-
{
|
|
1488
|
-
query: query,
|
|
1489
|
-
responseHeaders: responseHeaders,
|
|
1490
|
-
route: collection.route,
|
|
1491
|
-
moduleResolution: collection.resolution
|
|
1492
|
-
}
|
|
1493
|
-
);
|
|
1494
|
-
} catch (error) {
|
|
1495
|
-
options.debug && console.error(error);
|
|
1496
|
-
|
|
1497
|
-
return responseConverter(jsonErrorInfer(error, responseHeaders));
|
|
1498
|
-
} finally {
|
|
1499
|
-
if (allowLogsMethods) {
|
|
1500
|
-
const end = performance.now();
|
|
1501
|
-
const pathname = ansiText(url.pathname, { color: "blue" });
|
|
1502
|
-
const convertedPID = `${Bun.color("yellow", "ansi")}${process.pid}`;
|
|
1503
|
-
const convertedMethod = ansiText(request.method, {
|
|
1504
|
-
color: "yellow",
|
|
1505
|
-
backgroundColor: "blue"
|
|
1506
|
-
});
|
|
1507
|
-
const convertedReqIp = ansiText(
|
|
1508
|
-
`${
|
|
1509
|
-
request.headers.get("x-forwarded-for") ||
|
|
1510
|
-
request.headers.get("x-real-ip") ||
|
|
1511
|
-
server.requestIP(request)?.address ||
|
|
1512
|
-
"<Unknown>"
|
|
1513
|
-
}`,
|
|
1514
|
-
{
|
|
1515
|
-
color: "yellow"
|
|
1516
|
-
}
|
|
1517
|
-
);
|
|
1518
|
-
const convertedTime = ansiText(
|
|
1519
|
-
`${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms`,
|
|
1520
|
-
{
|
|
1521
|
-
color: "yellow",
|
|
1522
|
-
backgroundColor: "blue"
|
|
1523
|
-
}
|
|
1524
|
-
);
|
|
1525
|
-
|
|
1526
|
-
allowLogsMethods.includes(
|
|
1527
|
-
request.method.toUpperCase() as (typeof allowLogsMethods)[number]
|
|
1528
|
-
) &&
|
|
1529
|
-
console.info(
|
|
1530
|
-
`PID: ${convertedPID} - Method: ${convertedMethod} - IP: ${convertedReqIp} - ${pathname} - Time: ${convertedTime}`
|
|
1531
|
-
);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
},
|
|
1535
|
-
websocket: {
|
|
1536
|
-
open: (connection) => {
|
|
1537
|
-
const pathnameKey = `${connection.data.pathname}:::open`;
|
|
1538
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1539
|
-
|
|
1540
|
-
if (!handlerMetadata) {
|
|
1541
|
-
return;
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1545
|
-
const args: Array<unknown> = [];
|
|
1546
|
-
|
|
1547
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1548
|
-
switch (argumentMetadata.type) {
|
|
1549
|
-
case webSocketConnectionArgsKey:
|
|
1550
|
-
args[argumentMetadata.index] = connection;
|
|
1551
|
-
break;
|
|
1552
|
-
case webSocketServerArgsKey:
|
|
1553
|
-
args[argumentMetadata.index] = server;
|
|
1554
|
-
break;
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
handlerMetadata.descriptor.value(...args);
|
|
1559
|
-
},
|
|
1560
|
-
close: (connection, code: number, reason: string) => {
|
|
1561
|
-
const pathnameKey = `${connection.data.pathname}:::close`;
|
|
1562
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1563
|
-
|
|
1564
|
-
if (!handlerMetadata) {
|
|
1565
|
-
return;
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1569
|
-
const args: Array<unknown> = [];
|
|
1570
|
-
|
|
1571
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1572
|
-
switch (argumentMetadata.type) {
|
|
1573
|
-
case webSocketConnectionArgsKey:
|
|
1574
|
-
args[argumentMetadata.index] = connection;
|
|
1575
|
-
break;
|
|
1576
|
-
case webSocketServerArgsKey:
|
|
1577
|
-
args[argumentMetadata.index] = server;
|
|
1578
|
-
break;
|
|
1579
|
-
case webSocketCloseCodeArgsKey:
|
|
1580
|
-
args[argumentMetadata.index] = code;
|
|
1581
|
-
break;
|
|
1582
|
-
case webSocketCloseReasonArgsKey:
|
|
1583
|
-
args[argumentMetadata.index] = reason;
|
|
1584
|
-
break;
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
handlerMetadata.descriptor.value(...args);
|
|
1589
|
-
},
|
|
1590
|
-
message: (connection, message) => {
|
|
1591
|
-
const pathnameKey = `${connection.data.pathname}:::message`;
|
|
1592
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1593
|
-
|
|
1594
|
-
if (!handlerMetadata) {
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1599
|
-
const args: Array<unknown> = [];
|
|
1600
|
-
|
|
1601
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1602
|
-
switch (argumentMetadata.type) {
|
|
1603
|
-
case webSocketConnectionArgsKey:
|
|
1604
|
-
args[argumentMetadata.index] = connection;
|
|
1605
|
-
break;
|
|
1606
|
-
case webSocketMessageArgsKey:
|
|
1607
|
-
args[argumentMetadata.index] = message;
|
|
1608
|
-
break;
|
|
1609
|
-
case webSocketServerArgsKey:
|
|
1610
|
-
args[argumentMetadata.index] = server;
|
|
1611
|
-
break;
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
handlerMetadata.descriptor.value(...args);
|
|
1616
|
-
},
|
|
1617
|
-
drain: (connection) => {
|
|
1618
|
-
const pathnameKey = `${connection.data.pathname}:::drain`;
|
|
1619
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1620
|
-
|
|
1621
|
-
if (!handlerMetadata) {
|
|
1622
|
-
return;
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1626
|
-
const args: Array<unknown> = [];
|
|
1627
|
-
|
|
1628
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1629
|
-
switch (argumentMetadata.type) {
|
|
1630
|
-
case webSocketConnectionArgsKey:
|
|
1631
|
-
args[argumentMetadata.index] = connection;
|
|
1632
|
-
break;
|
|
1633
|
-
case webSocketServerArgsKey:
|
|
1634
|
-
args[argumentMetadata.index] = server;
|
|
1635
|
-
break;
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
handlerMetadata.descriptor.value(...args);
|
|
1640
|
-
},
|
|
1641
|
-
ping: (connection, data) => {
|
|
1642
|
-
const pathnameKey = `${connection.data.pathname}:::ping`;
|
|
1643
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1644
|
-
|
|
1645
|
-
if (!handlerMetadata) {
|
|
1646
|
-
return;
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1650
|
-
const args: Array<unknown> = [];
|
|
1651
|
-
|
|
1652
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1653
|
-
switch (argumentMetadata.type) {
|
|
1654
|
-
case webSocketConnectionArgsKey:
|
|
1655
|
-
args[argumentMetadata.index] = connection;
|
|
1656
|
-
break;
|
|
1657
|
-
case webSocketServerArgsKey:
|
|
1658
|
-
args[argumentMetadata.index] = server;
|
|
1659
|
-
break;
|
|
1660
|
-
case webSocketMessageArgsKey:
|
|
1661
|
-
args[argumentMetadata.index] = data;
|
|
1662
|
-
break;
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
handlerMetadata.descriptor.value(...args);
|
|
1667
|
-
},
|
|
1668
|
-
pong: (connection, data) => {
|
|
1669
|
-
const pathnameKey = `${connection.data.pathname}:::pong`;
|
|
1670
|
-
const handlerMetadata = webSocketsMap.get(pathnameKey);
|
|
1671
|
-
|
|
1672
|
-
if (!handlerMetadata) {
|
|
1673
|
-
return;
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1676
|
-
const argumentsMetadata = handlerMetadata.arguments || {};
|
|
1677
|
-
const args: Array<unknown> = [];
|
|
1678
|
-
|
|
1679
|
-
for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
|
|
1680
|
-
switch (argumentMetadata.type) {
|
|
1681
|
-
case webSocketConnectionArgsKey:
|
|
1682
|
-
args[argumentMetadata.index] = connection;
|
|
1683
|
-
break;
|
|
1684
|
-
case webSocketServerArgsKey:
|
|
1685
|
-
args[argumentMetadata.index] = server;
|
|
1686
|
-
break;
|
|
1687
|
-
case webSocketMessageArgsKey:
|
|
1688
|
-
args[argumentMetadata.index] = data;
|
|
1689
|
-
break;
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
|
|
1693
|
-
handlerMetadata.descriptor.value(...args);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
});
|
|
1697
|
-
} catch (error) {
|
|
1698
|
-
options.debug && console.error(error);
|
|
1699
|
-
throw error;
|
|
1700
|
-
}
|
|
1701
|
-
};
|
|
1702
|
-
|
|
1703
|
-
export default BoolFactory;
|