@bool-ts/core 1.9.0 → 1.9.2

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