@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.
@@ -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;