@bool-ts/core 1.8.0 → 1.8.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 (58) hide show
  1. package/__test/controller.ts +1 -1
  2. package/__test/dispatcher.ts +2 -2
  3. package/__test/firstGuard.ts +3 -1
  4. package/__test/firstMiddleware.ts +3 -2
  5. package/__test/index.ts +1 -1
  6. package/__test/module.ts +1 -1
  7. package/__test/repository.ts +2 -3
  8. package/__test/secondGuard.ts +1 -1
  9. package/__test/secondMiddleware.ts +2 -2
  10. package/__test/service.ts +4 -7
  11. package/__test/tsconfig.json +6 -2
  12. package/__test/webSocket.ts +1 -1
  13. package/dist/entities/webSocketRoute.d.ts +2 -0
  14. package/dist/entities/webSocketRouter.d.ts +1 -1
  15. package/dist/index.js +4995 -6
  16. package/package.json +2 -2
  17. package/src/entities/webSocketRoute.ts +13 -5
  18. package/src/entities/webSocketRouter.ts +2 -2
  19. package/dist/decorators/arguments.js +0 -123
  20. package/dist/decorators/controller.js +0 -9
  21. package/dist/decorators/dispatcher.js +0 -6
  22. package/dist/decorators/guard.js +0 -9
  23. package/dist/decorators/http.js +0 -60
  24. package/dist/decorators/index.js +0 -13
  25. package/dist/decorators/inject.js +0 -9
  26. package/dist/decorators/injectable.js +0 -3
  27. package/dist/decorators/middleware.js +0 -6
  28. package/dist/decorators/module.js +0 -48
  29. package/dist/decorators/webSocket.js +0 -40
  30. package/dist/decorators/webSocketArguments.js +0 -49
  31. package/dist/decorators/webSocketEvent.js +0 -24
  32. package/dist/decorators/zodSchema.js +0 -15
  33. package/dist/entities/httpRoute.js +0 -268
  34. package/dist/entities/httpRouter.js +0 -27
  35. package/dist/entities/httpRouterGroup.js +0 -24
  36. package/dist/entities/index.js +0 -6
  37. package/dist/entities/webSocketRoute.js +0 -15
  38. package/dist/entities/webSocketRouter.js +0 -54
  39. package/dist/entities/webSocketRouterGroup.js +0 -51
  40. package/dist/hooks/factory.js +0 -1072
  41. package/dist/hooks/index.js +0 -2
  42. package/dist/hooks/injector.js +0 -36
  43. package/dist/http/clientError.js +0 -42
  44. package/dist/http/index.js +0 -40
  45. package/dist/http/serverError.js +0 -24
  46. package/dist/interfaces/context.js +0 -1
  47. package/dist/interfaces/controller.js +0 -1
  48. package/dist/interfaces/dispatcher.js +0 -1
  49. package/dist/interfaces/guard.js +0 -1
  50. package/dist/interfaces/index.js +0 -1
  51. package/dist/interfaces/middleware.js +0 -1
  52. package/dist/interfaces/module.js +0 -1
  53. package/dist/interfaces/webSocket.js +0 -1
  54. package/dist/keys/index.js +0 -31
  55. package/dist/ultils/asyncFunction.js +0 -1
  56. package/dist/ultils/colors.js +0 -41
  57. package/dist/ultils/index.js +0 -3
  58. package/dist/ultils/socket.js +0 -7
@@ -1,1072 +0,0 @@
1
- import "reflect-metadata";
2
- import Qs from "qs";
3
- import * as Zod from "zod";
4
- import { ETimeUnit, add as TimeAdd } from "@bool-ts/date-time";
5
- import { HttpRouter, HttpRouterGroup, WebSocketRoute, WebSocketRouter, WebSocketRouterGroup } from "../entities";
6
- import { HttpClientError, HttpServerError, jsonErrorInfer } from "../http";
7
- import { argumentsKey, configKey, contextArgsKey, controllerHttpKey, controllerKey, moduleKey, paramArgsKey, paramsArgsKey, queryArgsKey, requestArgsKey, requestBodyArgsKey, requestHeaderArgsKey, requestHeadersArgsKey, responseBodyArgsKey, responseHeadersArgsKey, routeModelArgsKey, webSocketCloseCodeArgsKey, webSocketCloseReasonArgsKey, webSocketConnectionArgsKey, webSocketKey, webSocketMessageArgsKey, webSocketServerArgsKey } from "../keys";
8
- import { ansiText, isWebSocketUpgrade } from "../ultils";
9
- import { Injector } from "./injector";
10
- const DEFAULT_STATIC_CACHE_TIME_IN_SECONDS = 900;
11
- const responseConverter = (response) => {
12
- response.headers.set("X-Powered-By", "Bool Typescript");
13
- return response;
14
- };
15
- const controllerCreator = ({ controllerConstructor, httpRouterGroup, injector, prefix }) => {
16
- if (!Reflect.getOwnMetadataKeys(controllerConstructor).includes(controllerKey)) {
17
- throw Error(`${controllerConstructor.name} is not a controller.`);
18
- }
19
- const controller = injector.get(controllerConstructor);
20
- if (!controller) {
21
- throw Error("Can not initialize controller.");
22
- }
23
- const controllerMetadata = Reflect.getOwnMetadata(controllerKey, controllerConstructor) || {
24
- prefix: "/",
25
- httpMetadata: []
26
- };
27
- const routesMetadata = (Reflect.getOwnMetadata(controllerHttpKey, controllerConstructor) ||
28
- []);
29
- const router = new HttpRouter(`/${prefix || ""}/${controllerMetadata.prefix}`);
30
- routesMetadata.forEach((routeMetadata) => {
31
- if (typeof routeMetadata.descriptor.value !== "function") {
32
- return;
33
- }
34
- const route = router.route(routeMetadata.path);
35
- const handler = routeMetadata.descriptor.value.bind(controller);
36
- const routeArgument = Object.freeze({
37
- class: controllerConstructor,
38
- funcName: routeMetadata.methodName,
39
- func: handler
40
- });
41
- switch (routeMetadata.httpMethod) {
42
- case "GET":
43
- return route.get(routeArgument);
44
- case "POST":
45
- return route.post(routeArgument);
46
- case "PUT":
47
- return route.put(routeArgument);
48
- case "PATCH":
49
- return route.patch(routeArgument);
50
- case "DELETE":
51
- return route.delete(routeArgument);
52
- case "OPTIONS":
53
- return route.options(routeArgument);
54
- }
55
- });
56
- return httpRouterGroup.add(router);
57
- };
58
- const webSocketCreator = ({ injector, httpRouterGroup, prefix, webSocketRouterGroup, webSocketConstructor }) => {
59
- if (!Reflect.getOwnMetadataKeys(webSocketConstructor).includes(webSocketKey)) {
60
- throw Error(`${webSocketConstructor.name} is not a controller.`);
61
- }
62
- const webSocket = injector.get(webSocketConstructor);
63
- if (!webSocket) {
64
- throw Error("Can not initialize webSocket.");
65
- }
66
- const webSocketMetadata = Reflect.getOwnMetadata(webSocketKey, webSocketConstructor) || {
67
- prefix: "/",
68
- events: [],
69
- http: []
70
- };
71
- const fullPrefix = `/${prefix || ""}/${webSocketMetadata.prefix}`;
72
- //#region [HTTP ROUTER]
73
- const router = new HttpRouter(fullPrefix);
74
- for (const [_key, httpMetadata] of Object.entries(webSocketMetadata.http)) {
75
- if (typeof httpMetadata.descriptor?.value !== "function") {
76
- continue;
77
- }
78
- const route = router.route(httpMetadata.path);
79
- const handler = httpMetadata.descriptor.value.bind(webSocket);
80
- const routeArgument = Object.freeze({
81
- class: webSocketConstructor,
82
- funcName: httpMetadata.methodName,
83
- func: handler
84
- });
85
- switch (httpMetadata.httpMethod) {
86
- case "GET":
87
- route.get(routeArgument);
88
- break;
89
- case "POST":
90
- route.post(routeArgument);
91
- break;
92
- }
93
- }
94
- httpRouterGroup.add(router);
95
- //#endregion
96
- //#region [WEBSOCKET ROUTER]
97
- const webSocketRouter = new WebSocketRouter(fullPrefix);
98
- for (const [key, event] of Object.entries(webSocketMetadata.events)) {
99
- const webSocketRoute = new WebSocketRoute({
100
- eventName: key,
101
- metadata: event
102
- });
103
- webSocketRouter.addRoutes(webSocketRoute);
104
- }
105
- webSocketRouter.bind(webSocket);
106
- webSocketRouterGroup.addRouters(webSocketRouter);
107
- //#endregion
108
- return Object.freeze({
109
- httpRouterGroup: httpRouterGroup,
110
- webSocketRouterGroup: webSocketRouterGroup
111
- });
112
- };
113
- const argumentsResolution = async (data, zodSchema, argumentIndex, funcName) => {
114
- try {
115
- const validation = await zodSchema.safeParseAsync(data);
116
- if (!validation.success) {
117
- throw new HttpClientError({
118
- httpCode: 400,
119
- message: `Validation at the [${funcName.toString()}] method fails at positional argument [${argumentIndex}].`,
120
- data: validation.error.issues
121
- });
122
- }
123
- return validation.data;
124
- }
125
- catch (error) {
126
- if (error instanceof HttpClientError) {
127
- throw error;
128
- }
129
- throw new HttpServerError({
130
- httpCode: 500,
131
- message: `Validation at the [${funcName.toString()}] method error at positional argument [${argumentIndex}].`,
132
- data: !(error instanceof Error)
133
- ? error
134
- : [
135
- {
136
- message: error.message,
137
- code: error.name,
138
- cause: error.cause
139
- }
140
- ]
141
- });
142
- }
143
- };
144
- const moduleResolution = async (module, options) => {
145
- if (!Reflect.getOwnMetadataKeys(module).includes(moduleKey)) {
146
- throw Error(`${module.name} is not a module.`);
147
- }
148
- const injector = new Injector();
149
- const moduleMetadata = Reflect.getOwnMetadata(moduleKey, module);
150
- if (!moduleMetadata) {
151
- return;
152
- }
153
- const { loaders, middlewares, guards, dispatchers, controllers, dependencies, webSockets, prefix: modulePrefix, config: moduleConfig } = moduleMetadata;
154
- const fullPrefix = `${options.prefix || ""}/${modulePrefix || ""}`;
155
- //#region [Configuration(s)]
156
- const { config } = Object.freeze({
157
- config: {
158
- ...(typeof options.config !== "function" ? options.config : await options.config()),
159
- ...(typeof moduleConfig !== "function"
160
- ? typeof moduleConfig !== "object"
161
- ? undefined
162
- : moduleConfig
163
- : await moduleConfig())
164
- }
165
- });
166
- //#endregion
167
- //#region [Register config like an injection]
168
- injector.set(configKey, config);
169
- //#endregion
170
- //#region [Run loader(s)]
171
- if (loaders) {
172
- const loaderFunctions = [];
173
- for (const [key, func] of Object.entries(loaders)) {
174
- loaderFunctions.push(async () => {
175
- try {
176
- const result = await func({ config });
177
- console.info(`${ansiText(" INFO ", {
178
- color: "white",
179
- backgroundColor: "blue",
180
- bold: true
181
- })} Loader [${key}] initialized successfully.`);
182
- return result;
183
- }
184
- catch (error) {
185
- console.error(`${ansiText(" WARN ", {
186
- color: "yellow",
187
- backgroundColor: "red",
188
- bold: true
189
- })} Loader [${key}] initialization failed.`);
190
- options.debug && console.error(error);
191
- throw error;
192
- }
193
- });
194
- }
195
- const results = await Promise.all(loaderFunctions.map((func) => func()));
196
- for (let i = 0; i < results.length; i++) {
197
- const [key, value] = results[i];
198
- injector.set(key, value);
199
- }
200
- }
201
- //#endregion
202
- //#region [Dependencies]
203
- !dependencies || dependencies.map((dependency) => injector.get(dependency));
204
- //#endregion
205
- //#region [Middleware(s)]
206
- const startMiddlewareGroup = [];
207
- const endMiddlewareGroup = [];
208
- middlewares &&
209
- middlewares.forEach((middleware) => {
210
- const instance = injector.get(middleware);
211
- if (instance.start && typeof instance.start === "function") {
212
- startMiddlewareGroup.push(Object.freeze({
213
- class: middleware,
214
- funcName: "start",
215
- func: instance.start.bind(instance)
216
- }));
217
- }
218
- if (instance.end && typeof instance.end === "function") {
219
- endMiddlewareGroup.push(Object.freeze({
220
- class: middleware,
221
- funcName: "end",
222
- func: instance.end.bind(instance)
223
- }));
224
- }
225
- });
226
- //#endregion
227
- //#region [Guard(s)]
228
- const guardGroup = !guards
229
- ? []
230
- : guards.map((guard) => {
231
- const guardInstance = injector.get(guard);
232
- return Object.freeze({
233
- class: guard,
234
- funcName: "enforce",
235
- func: guardInstance.enforce.bind(guardInstance)
236
- });
237
- });
238
- //#endregion
239
- //#region [Before dispatcher(s)]
240
- const openDispatcherGroup = [];
241
- const closeDispatcherGroup = [];
242
- dispatchers &&
243
- dispatchers.forEach((dispatcher) => {
244
- const instance = injector.get(dispatcher);
245
- if (instance.open && typeof instance.open === "function") {
246
- openDispatcherGroup.push(Object.freeze({
247
- class: dispatcher,
248
- funcName: "open",
249
- func: instance.open.bind(instance)
250
- }));
251
- }
252
- if (instance.close && typeof instance.close === "function") {
253
- closeDispatcherGroup.push(Object.freeze({
254
- class: dispatcher,
255
- funcName: "close",
256
- func: instance.close.bind(instance)
257
- }));
258
- }
259
- });
260
- //#endregion
261
- //#region [Controller(s)]
262
- const controllerRouterGroup = new HttpRouterGroup();
263
- controllers &&
264
- controllers.forEach((controllerConstructor) => controllerCreator({
265
- controllerConstructor,
266
- httpRouterGroup: controllerRouterGroup,
267
- injector: injector,
268
- prefix: fullPrefix
269
- }));
270
- //#endregion
271
- //#region [WebSocket(s)]
272
- const webSocketHttpRouterGroup = new HttpRouterGroup();
273
- const webSocketRouterGroup = new WebSocketRouterGroup();
274
- webSockets &&
275
- webSockets.forEach((webSocket) => webSocketCreator({
276
- webSocketConstructor: webSocket,
277
- httpRouterGroup: webSocketHttpRouterGroup,
278
- webSocketRouterGroup: webSocketRouterGroup,
279
- injector,
280
- prefix: fullPrefix
281
- }));
282
- //#endregion
283
- return Object.freeze({
284
- prefix: moduleMetadata.prefix,
285
- injector: injector,
286
- startMiddlewareGroup,
287
- endMiddlewareGroup,
288
- guardGroup,
289
- openDispatcherGroup,
290
- closeDispatcherGroup,
291
- controllerRouterGroup,
292
- webSocketHttpRouterGroup,
293
- webSocketRouterGroup
294
- });
295
- };
296
- const webSocketFetcher = async (bun, bool) => {
297
- const { request, server } = bun;
298
- const { query, responseHeaders, route: { model } } = bool;
299
- // Execute controller action
300
- const isUpgrade = await model.func(...[server, request, query]);
301
- if (typeof isUpgrade !== "boolean") {
302
- return responseConverter(new Response(JSON.stringify({
303
- httpCode: 500,
304
- message: "Can not detect webSocket upgrade result.",
305
- data: undefined
306
- }), {
307
- status: 500,
308
- statusText: "Internal server error.",
309
- headers: responseHeaders
310
- }));
311
- }
312
- if (!isUpgrade) {
313
- return responseConverter(new Response(JSON.stringify({
314
- httpCode: 500,
315
- message: "Can not upgrade.",
316
- data: undefined
317
- }), {
318
- status: 500,
319
- statusText: "Internal server error.",
320
- headers: responseHeaders
321
- }));
322
- }
323
- return isUpgrade;
324
- };
325
- const httpFetcher = async (bun, bool) => {
326
- const { request, server: _server } = bun;
327
- const { query, responseHeaders, route: { parameters, model }, moduleResolution: { startMiddlewareGroup, endMiddlewareGroup, guardGroup, openDispatcherGroup, closeDispatcherGroup } } = bool;
328
- const context = {
329
- [requestHeadersArgsKey]: request.headers,
330
- [responseHeadersArgsKey]: responseHeaders,
331
- [queryArgsKey]: query,
332
- [paramsArgsKey]: parameters,
333
- [routeModelArgsKey]: model
334
- };
335
- const contextHook = {
336
- get(key) {
337
- return context[key];
338
- },
339
- set(key, value) {
340
- if (key in context) {
341
- throw Error(`${String(key)} already exists in context.`);
342
- }
343
- context[key] = value;
344
- }
345
- };
346
- // Execute start middleware(s)
347
- for (let i = 0; i < startMiddlewareGroup.length; i++) {
348
- const args = [];
349
- const collection = startMiddlewareGroup[i];
350
- const metadata = Reflect.getOwnMetadata(argumentsKey, collection.class, collection.funcName) || {};
351
- if (metadata) {
352
- for (const [_key, argsMetadata] of Object.entries(metadata)) {
353
- switch (argsMetadata.type) {
354
- case requestArgsKey:
355
- args[argsMetadata.index] = !argsMetadata.zodSchema
356
- ? request
357
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
358
- break;
359
- case requestBodyArgsKey:
360
- args[argsMetadata.index] = !argsMetadata.zodSchema
361
- ? await request[argsMetadata.parser || "json"]()
362
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
363
- break;
364
- case contextArgsKey:
365
- args[argsMetadata.index] = !argsMetadata.key
366
- ? contextHook
367
- : contextHook.get(argsMetadata.key);
368
- break;
369
- case requestHeadersArgsKey:
370
- args[argsMetadata.index] = !argsMetadata.zodSchema
371
- ? request.headers
372
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
373
- break;
374
- case responseHeadersArgsKey:
375
- args[argsMetadata.index] = context[argsMetadata.type];
376
- break;
377
- case requestHeaderArgsKey:
378
- args[argsMetadata.index] = !argsMetadata.zodSchema
379
- ? request.headers.get(argsMetadata.key) || undefined
380
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
381
- break;
382
- case paramArgsKey:
383
- args[argsMetadata.index] = !argsMetadata.zodSchema
384
- ? context[paramsArgsKey][argsMetadata.key] || undefined
385
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
386
- break;
387
- case routeModelArgsKey:
388
- args[argsMetadata.index] = context[routeModelArgsKey];
389
- break;
390
- default:
391
- args[argsMetadata.index] = !argsMetadata.zodSchema
392
- ? !(argsMetadata.type in context)
393
- ? undefined
394
- : context[argsMetadata.type]
395
- : await argumentsResolution(!(argsMetadata.type in context)
396
- ? undefined
397
- : context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
398
- break;
399
- }
400
- }
401
- }
402
- context[responseBodyArgsKey] = await collection.func(...args);
403
- if (context[responseBodyArgsKey] instanceof Response) {
404
- return responseConverter(context[responseBodyArgsKey]);
405
- }
406
- }
407
- // Execute guard(s)
408
- for (let i = 0; i < guardGroup.length; i++) {
409
- const args = [];
410
- const collection = guardGroup[i];
411
- const metadata = Reflect.getOwnMetadata(argumentsKey, collection.class, collection.funcName) || {};
412
- if (metadata) {
413
- for (const [_key, argsMetadata] of Object.entries(metadata)) {
414
- switch (argsMetadata.type) {
415
- case requestArgsKey:
416
- args[argsMetadata.index] = !argsMetadata.zodSchema
417
- ? request
418
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
419
- break;
420
- case requestBodyArgsKey:
421
- args[argsMetadata.index] = !argsMetadata.zodSchema
422
- ? await request[argsMetadata.parser || "json"]()
423
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
424
- break;
425
- case contextArgsKey:
426
- args[argsMetadata.index] = !argsMetadata.key
427
- ? contextHook
428
- : contextHook.get(argsMetadata.key);
429
- break;
430
- case requestHeadersArgsKey:
431
- args[argsMetadata.index] = !argsMetadata.zodSchema
432
- ? request.headers
433
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
434
- break;
435
- case responseHeadersArgsKey:
436
- args[argsMetadata.index] = context[argsMetadata.type];
437
- break;
438
- case requestHeaderArgsKey:
439
- args[argsMetadata.index] = !argsMetadata.zodSchema
440
- ? request.headers.get(argsMetadata.key) || undefined
441
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
442
- break;
443
- case paramArgsKey:
444
- args[argsMetadata.index] = !argsMetadata.zodSchema
445
- ? context[paramsArgsKey][argsMetadata.key] || undefined
446
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
447
- break;
448
- case routeModelArgsKey:
449
- args[argsMetadata.index] = context[routeModelArgsKey];
450
- break;
451
- default:
452
- args[argsMetadata.index] = !argsMetadata.zodSchema
453
- ? context[argsMetadata.type]
454
- : await argumentsResolution(context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
455
- break;
456
- }
457
- }
458
- }
459
- const guardResult = await collection.func(...args);
460
- if (typeof guardResult !== "boolean" || !guardResult) {
461
- throw new HttpClientError({
462
- httpCode: 401,
463
- message: "Unauthorization.",
464
- data: undefined
465
- });
466
- }
467
- }
468
- // Execute open dispatcher(s)
469
- for (let i = 0; i < openDispatcherGroup.length; i++) {
470
- const args = [];
471
- const collection = openDispatcherGroup[i];
472
- const metadata = Reflect.getOwnMetadata(argumentsKey, collection.class, collection.funcName) || {};
473
- if (metadata) {
474
- for (const [_key, argsMetadata] of Object.entries(metadata)) {
475
- switch (argsMetadata.type) {
476
- case requestArgsKey:
477
- args[argsMetadata.index] = !argsMetadata.zodSchema
478
- ? request
479
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
480
- break;
481
- case requestBodyArgsKey:
482
- args[argsMetadata.index] = !argsMetadata.zodSchema
483
- ? await request[argsMetadata.parser || "json"]()
484
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
485
- break;
486
- case contextArgsKey:
487
- args[argsMetadata.index] = !argsMetadata.key
488
- ? contextHook
489
- : contextHook.get(argsMetadata.key);
490
- break;
491
- case requestHeadersArgsKey:
492
- args[argsMetadata.index] = !argsMetadata.zodSchema
493
- ? request.headers
494
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
495
- break;
496
- case responseHeadersArgsKey:
497
- args[argsMetadata.index] = context[argsMetadata.type];
498
- break;
499
- case requestHeaderArgsKey:
500
- args[argsMetadata.index] = !argsMetadata.zodSchema
501
- ? request.headers.get(argsMetadata.key) || undefined
502
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
503
- break;
504
- case paramArgsKey:
505
- args[argsMetadata.index] = !argsMetadata.zodSchema
506
- ? context[paramsArgsKey][argsMetadata.key] || undefined
507
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
508
- break;
509
- case routeModelArgsKey:
510
- args[argsMetadata.index] = context[routeModelArgsKey];
511
- break;
512
- default:
513
- args[argsMetadata.index] = !argsMetadata.zodSchema
514
- ? context[argsMetadata.type]
515
- : await argumentsResolution(context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
516
- break;
517
- }
518
- }
519
- }
520
- context[responseBodyArgsKey] = await collection.func(...args);
521
- }
522
- // Execute controller action
523
- const controllerActionArguments = [];
524
- const controllerActionCollection = model;
525
- const controllerActionMetadata = Reflect.getOwnMetadata(argumentsKey, controllerActionCollection.class, controllerActionCollection.funcName) || {};
526
- if (controllerActionMetadata) {
527
- for (const [_key, argsMetadata] of Object.entries(controllerActionMetadata)) {
528
- switch (argsMetadata.type) {
529
- case requestArgsKey:
530
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
531
- ? request
532
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
533
- break;
534
- case requestBodyArgsKey:
535
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
536
- ? await request[argsMetadata.parser || "json"]()
537
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
538
- break;
539
- case contextArgsKey:
540
- controllerActionArguments[argsMetadata.index] = !argsMetadata.key
541
- ? contextHook
542
- : contextHook.get(argsMetadata.key);
543
- break;
544
- case requestHeadersArgsKey:
545
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
546
- ? request.headers
547
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
548
- break;
549
- case responseHeadersArgsKey:
550
- controllerActionArguments[argsMetadata.index] = context[argsMetadata.type];
551
- break;
552
- case requestHeaderArgsKey:
553
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
554
- ? request.headers.get(argsMetadata.key) || undefined
555
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
556
- break;
557
- case paramArgsKey:
558
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
559
- ? context[paramsArgsKey][argsMetadata.key] || undefined
560
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
561
- break;
562
- case routeModelArgsKey:
563
- controllerActionArguments[argsMetadata.index] = context[routeModelArgsKey];
564
- break;
565
- default:
566
- controllerActionArguments[argsMetadata.index] = !argsMetadata.zodSchema
567
- ? context[argsMetadata.type]
568
- : await argumentsResolution(context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, controllerActionCollection.funcName);
569
- break;
570
- }
571
- }
572
- }
573
- context[responseBodyArgsKey] = await controllerActionCollection.func(...controllerActionArguments);
574
- // Execute close dispatcher(s)
575
- for (let i = 0; i < closeDispatcherGroup.length; i++) {
576
- const args = [];
577
- const collection = closeDispatcherGroup[i];
578
- const metadata = Reflect.getOwnMetadata(argumentsKey, collection.class, collection.funcName) || {};
579
- if (metadata) {
580
- for (const [_key, argsMetadata] of Object.entries(metadata)) {
581
- switch (argsMetadata.type) {
582
- case requestArgsKey:
583
- args[argsMetadata.index] = !argsMetadata.zodSchema
584
- ? request
585
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
586
- break;
587
- case requestBodyArgsKey:
588
- args[argsMetadata.index] = !argsMetadata.zodSchema
589
- ? await request[argsMetadata.parser || "json"]()
590
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
591
- break;
592
- case contextArgsKey:
593
- args[argsMetadata.index] = !argsMetadata.key
594
- ? contextHook
595
- : contextHook.get(argsMetadata.key);
596
- break;
597
- case requestHeadersArgsKey:
598
- args[argsMetadata.index] = !argsMetadata.zodSchema
599
- ? request.headers
600
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
601
- break;
602
- case responseHeadersArgsKey:
603
- args[argsMetadata.index] = context[argsMetadata.type];
604
- break;
605
- case requestHeaderArgsKey:
606
- args[argsMetadata.index] = !argsMetadata.zodSchema
607
- ? request.headers.get(argsMetadata.key) || undefined
608
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
609
- break;
610
- case paramArgsKey:
611
- args[argsMetadata.index] = !argsMetadata.zodSchema
612
- ? context[paramsArgsKey][argsMetadata.key] || undefined
613
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
614
- break;
615
- case routeModelArgsKey:
616
- args[argsMetadata.index] = context[routeModelArgsKey];
617
- break;
618
- default:
619
- args[argsMetadata.index] = !argsMetadata.zodSchema
620
- ? context[argsMetadata.type]
621
- : await argumentsResolution(context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
622
- break;
623
- }
624
- }
625
- }
626
- await collection.func(...args);
627
- }
628
- if (context[responseBodyArgsKey] instanceof Response) {
629
- return responseConverter(context[responseBodyArgsKey]);
630
- }
631
- // Execute end middleware(s)
632
- for (let i = 0; i < endMiddlewareGroup.length; i++) {
633
- const args = [];
634
- const collection = endMiddlewareGroup[i];
635
- const metadata = Reflect.getOwnMetadata(argumentsKey, collection.class, collection.funcName) || {};
636
- if (metadata) {
637
- for (const [_key, argsMetadata] of Object.entries(metadata)) {
638
- switch (argsMetadata.type) {
639
- case requestArgsKey:
640
- args[argsMetadata.index] = !argsMetadata.zodSchema
641
- ? request
642
- : await argumentsResolution(request, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
643
- break;
644
- case requestBodyArgsKey:
645
- args[argsMetadata.index] = !argsMetadata.zodSchema
646
- ? await request[argsMetadata.parser || "json"]()
647
- : await argumentsResolution(await request[argsMetadata.parser || "json"](), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
648
- break;
649
- case contextArgsKey:
650
- args[argsMetadata.index] = !argsMetadata.key
651
- ? contextHook
652
- : contextHook.get(argsMetadata.key);
653
- break;
654
- case requestHeadersArgsKey:
655
- args[argsMetadata.index] = !argsMetadata.zodSchema
656
- ? request.headers
657
- : await argumentsResolution(request.headers.toJSON(), argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
658
- break;
659
- case responseHeadersArgsKey:
660
- args[argsMetadata.index] = context[argsMetadata.type];
661
- break;
662
- case requestHeaderArgsKey:
663
- args[argsMetadata.index] = !argsMetadata.zodSchema
664
- ? request.headers.get(argsMetadata.key) || undefined
665
- : await argumentsResolution(request.headers.get(argsMetadata.key) || undefined, argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
666
- break;
667
- case paramArgsKey:
668
- args[argsMetadata.index] = !argsMetadata.zodSchema
669
- ? context[paramsArgsKey][argsMetadata.key] || undefined
670
- : await argumentsResolution(context[paramsArgsKey][argsMetadata.key], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
671
- break;
672
- case routeModelArgsKey:
673
- args[argsMetadata.index] = context[routeModelArgsKey];
674
- break;
675
- default:
676
- args[argsMetadata.index] = !argsMetadata.zodSchema
677
- ? !(argsMetadata.type in context)
678
- ? undefined
679
- : context[argsMetadata.type]
680
- : await argumentsResolution(!(argsMetadata.type in context)
681
- ? undefined
682
- : context[argsMetadata.type], argsMetadata.zodSchema, argsMetadata.index, collection.funcName);
683
- break;
684
- }
685
- }
686
- }
687
- context[responseBodyArgsKey] = await collection.func(...args);
688
- if (context[responseBodyArgsKey] instanceof Response) {
689
- return responseConverter(context[responseBodyArgsKey]);
690
- }
691
- }
692
- return responseConverter(new Response(!context[responseBodyArgsKey]
693
- ? undefined
694
- : JSON.stringify({
695
- httpCode: 200,
696
- message: "SUCCESS",
697
- data: context[responseBodyArgsKey]
698
- }), {
699
- status: !context[responseBodyArgsKey] ? 204 : 200,
700
- statusText: "SUCCESS",
701
- headers: context[responseHeadersArgsKey]
702
- }));
703
- };
704
- export const BoolFactory = async (modules, options) => {
705
- try {
706
- const staticMap = new Map();
707
- const modulesConverted = !Array.isArray(modules) ? [modules] : modules;
708
- const { allowLogsMethods, staticOption, allowOrigins, allowMethods, allowCredentials, allowHeaders } = Object.freeze({
709
- allowLogsMethods: options?.log?.methods,
710
- staticOption: options.static,
711
- allowOrigins: !options.cors?.origins
712
- ? ["*"]
713
- : typeof options.cors.origins !== "string"
714
- ? options.cors.origins.includes("*") || options.cors.origins.length < 1
715
- ? ["*"]
716
- : options.cors.origins
717
- : [options.cors.origins !== "*" ? options.cors.origins : "*"],
718
- allowMethods: options.cors?.methods || [
719
- "GET",
720
- "POST",
721
- "PUT",
722
- "PATCH",
723
- "DELETE",
724
- "OPTIONS"
725
- ],
726
- allowCredentials: !options.cors?.credentials ? false : true,
727
- allowHeaders: !options.cors?.headers || options.cors.headers.includes("*")
728
- ? ["*"]
729
- : options.cors.headers
730
- });
731
- const moduleResolutions = await Promise.all(modulesConverted.map((moduleConverted) => moduleResolution(moduleConverted, options)));
732
- const availableModuleResolutions = moduleResolutions.filter((moduleResolution) => typeof moduleResolution !== "undefined");
733
- const prefixs = [
734
- ...new Set(availableModuleResolutions.map((availableModuleResolution) => availableModuleResolution.prefix))
735
- ];
736
- if (prefixs.length !== availableModuleResolutions.length) {
737
- throw Error("Module prefix should be unique.");
738
- }
739
- const webSocketsMap = new Map();
740
- for (const availableModuleResolution of availableModuleResolutions) {
741
- const webSocketMap = availableModuleResolution.webSocketRouterGroup.execute();
742
- for (const [key, metadata] of webSocketMap.entries()) {
743
- webSocketsMap.set(key, metadata);
744
- }
745
- }
746
- const server = Bun.serve({
747
- port: options.port,
748
- fetch: async (request, server) => {
749
- const start = performance.now();
750
- const url = new URL(request.url);
751
- const query = Qs.parse(url.searchParams.toString(), options.queryParser);
752
- const origin = request.headers.get("origin") || "*";
753
- const method = request.method.toUpperCase();
754
- const responseHeaders = new Headers();
755
- try {
756
- const isUpgradable = isWebSocketUpgrade(request);
757
- let collection;
758
- if (isUpgradable) {
759
- for (const availableModuleResolution of availableModuleResolutions) {
760
- const routeResult = availableModuleResolution.webSocketHttpRouterGroup.find(url.pathname, request.method);
761
- if (routeResult) {
762
- collection = Object.freeze({
763
- route: routeResult,
764
- resolution: availableModuleResolution
765
- });
766
- break;
767
- }
768
- }
769
- if (!collection) {
770
- return responseConverter(new Response(JSON.stringify({
771
- httpCode: 404,
772
- message: "Route not found",
773
- data: undefined
774
- }), {
775
- status: 404,
776
- statusText: "Not found.",
777
- headers: responseHeaders
778
- }));
779
- }
780
- const upgradeResult = await webSocketFetcher({
781
- request,
782
- server
783
- }, {
784
- query: query,
785
- responseHeaders: responseHeaders,
786
- route: collection.route,
787
- moduleResolution: collection.resolution
788
- });
789
- return upgradeResult instanceof Response ? upgradeResult : undefined;
790
- }
791
- allowCredentials &&
792
- responseHeaders.set("Access-Control-Allow-Credentials", "true");
793
- responseHeaders.set("Access-Control-Allow-Methods", allowMethods.join(", "));
794
- responseHeaders.set("Access-Control-Allow-Headers", allowHeaders.join(", "));
795
- responseHeaders.set("Access-Control-Allow-Origin", allowOrigins.includes("*")
796
- ? "*"
797
- : !allowOrigins.includes(origin)
798
- ? allowOrigins[0]
799
- : origin);
800
- if (!allowMethods.includes(method)) {
801
- return responseConverter(new Response(undefined, {
802
- status: 405,
803
- statusText: "Method Not Allowed.",
804
- headers: responseHeaders
805
- }));
806
- }
807
- if (request.method.toUpperCase() === "OPTIONS") {
808
- return responseConverter(allowOrigins.includes("*") || allowOrigins.includes(origin)
809
- ? new Response(undefined, {
810
- status: 204,
811
- statusText: "No Content.",
812
- headers: responseHeaders
813
- })
814
- : new Response(undefined, {
815
- status: 417,
816
- statusText: "Expectation Failed.",
817
- headers: responseHeaders
818
- }));
819
- }
820
- if (staticOption) {
821
- const { path, headers, cacheTimeInSeconds } = staticOption;
822
- const pathname = `${path}/${url.pathname}`;
823
- const cachedFile = staticMap.get(pathname);
824
- if (!cachedFile) {
825
- const file = Bun.file(pathname);
826
- const isFileExists = await file.exists();
827
- if (isFileExists) {
828
- if (headers) {
829
- for (const [key, value] of Object.entries(headers)) {
830
- responseHeaders.set(key, value);
831
- }
832
- }
833
- responseHeaders.set("Content-Type", file.type);
834
- return responseConverter(new Response(await file.arrayBuffer(), {
835
- status: 200,
836
- statusText: "SUCCESS",
837
- headers: responseHeaders
838
- }));
839
- }
840
- }
841
- else {
842
- const isExpired = new Date() > cachedFile.expiredAt;
843
- if (isExpired) {
844
- staticMap.delete(pathname);
845
- }
846
- const file = !isExpired ? cachedFile.file : Bun.file(pathname);
847
- const isFileExists = await file.exists();
848
- if (isFileExists) {
849
- staticMap.set(pathname, Object.freeze({
850
- expiredAt: TimeAdd(new Date(), typeof cacheTimeInSeconds !== "number"
851
- ? DEFAULT_STATIC_CACHE_TIME_IN_SECONDS
852
- : cacheTimeInSeconds, ETimeUnit.seconds),
853
- file: file
854
- }));
855
- if (headers) {
856
- for (const [key, value] of Object.entries(headers)) {
857
- responseHeaders.set(key, value);
858
- }
859
- }
860
- responseHeaders.set("Content-Type", file.type);
861
- return responseConverter(new Response(await file.arrayBuffer(), {
862
- status: 200,
863
- statusText: "SUCCESS",
864
- headers: responseHeaders
865
- }));
866
- }
867
- }
868
- }
869
- for (const availableModuleResolution of availableModuleResolutions) {
870
- const routeResult = availableModuleResolution.controllerRouterGroup.find(url.pathname, request.method);
871
- if (routeResult) {
872
- collection = Object.freeze({
873
- route: routeResult,
874
- resolution: availableModuleResolution
875
- });
876
- break;
877
- }
878
- }
879
- if (!collection) {
880
- return responseConverter(new Response(JSON.stringify({
881
- httpCode: 404,
882
- message: "Route not found",
883
- data: undefined
884
- }), {
885
- status: 404,
886
- statusText: "Not found.",
887
- headers: responseHeaders
888
- }));
889
- }
890
- return await httpFetcher({
891
- request,
892
- server
893
- }, {
894
- query: query,
895
- responseHeaders: responseHeaders,
896
- route: collection.route,
897
- moduleResolution: collection.resolution
898
- });
899
- }
900
- catch (error) {
901
- options.debug && console.error(error);
902
- return responseConverter(jsonErrorInfer(error, responseHeaders));
903
- }
904
- finally {
905
- if (allowLogsMethods) {
906
- const end = performance.now();
907
- const pathname = ansiText(url.pathname, { color: "blue" });
908
- const convertedPID = `${Bun.color("yellow", "ansi")}${process.pid}`;
909
- const convertedMethod = ansiText(request.method, {
910
- color: "yellow",
911
- backgroundColor: "blue"
912
- });
913
- const convertedReqIp = ansiText(`${request.headers.get("x-forwarded-for") ||
914
- request.headers.get("x-real-ip") ||
915
- server.requestIP(request)?.address ||
916
- "<Unknown>"}`, {
917
- color: "yellow"
918
- });
919
- const convertedTime = ansiText(`${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms`, {
920
- color: "yellow",
921
- backgroundColor: "blue"
922
- });
923
- allowLogsMethods.includes(request.method.toUpperCase()) &&
924
- console.info(`PID: ${convertedPID} - Method: ${convertedMethod} - IP: ${convertedReqIp} - ${pathname} - Time: ${convertedTime}`);
925
- }
926
- }
927
- },
928
- websocket: {
929
- open: (connection) => {
930
- const pathnameKey = `${connection.data.pathname}:::open`;
931
- const handlerMetadata = webSocketsMap.get(pathnameKey);
932
- if (!handlerMetadata) {
933
- return;
934
- }
935
- const argumentsMetadata = handlerMetadata.arguments || {};
936
- const args = [];
937
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
938
- switch (argumentMetadata.type) {
939
- case webSocketConnectionArgsKey:
940
- args[argumentMetadata.index] = connection;
941
- break;
942
- case webSocketServerArgsKey:
943
- args[argumentMetadata.index] = server;
944
- break;
945
- }
946
- }
947
- handlerMetadata.descriptor.value(...args);
948
- },
949
- close: (connection, code, reason) => {
950
- const pathnameKey = `${connection.data.pathname}:::close`;
951
- const handlerMetadata = webSocketsMap.get(pathnameKey);
952
- if (!handlerMetadata) {
953
- return;
954
- }
955
- const argumentsMetadata = handlerMetadata.arguments || {};
956
- const args = [];
957
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
958
- switch (argumentMetadata.type) {
959
- case webSocketConnectionArgsKey:
960
- args[argumentMetadata.index] = connection;
961
- break;
962
- case webSocketServerArgsKey:
963
- args[argumentMetadata.index] = server;
964
- break;
965
- case webSocketCloseCodeArgsKey:
966
- args[argumentMetadata.index] = code;
967
- break;
968
- case webSocketCloseReasonArgsKey:
969
- args[argumentMetadata.index] = reason;
970
- break;
971
- }
972
- }
973
- handlerMetadata.descriptor.value(...args);
974
- },
975
- message: (connection, message) => {
976
- const pathnameKey = `${connection.data.pathname}:::message`;
977
- const handlerMetadata = webSocketsMap.get(pathnameKey);
978
- if (!handlerMetadata) {
979
- return;
980
- }
981
- const argumentsMetadata = handlerMetadata.arguments || {};
982
- const args = [];
983
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
984
- switch (argumentMetadata.type) {
985
- case webSocketConnectionArgsKey:
986
- args[argumentMetadata.index] = connection;
987
- break;
988
- case webSocketMessageArgsKey:
989
- args[argumentMetadata.index] = message;
990
- break;
991
- case webSocketServerArgsKey:
992
- args[argumentMetadata.index] = server;
993
- break;
994
- }
995
- }
996
- handlerMetadata.descriptor.value(...args);
997
- },
998
- drain: (connection) => {
999
- const pathnameKey = `${connection.data.pathname}:::drain`;
1000
- const handlerMetadata = webSocketsMap.get(pathnameKey);
1001
- if (!handlerMetadata) {
1002
- return;
1003
- }
1004
- const argumentsMetadata = handlerMetadata.arguments || {};
1005
- const args = [];
1006
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
1007
- switch (argumentMetadata.type) {
1008
- case webSocketConnectionArgsKey:
1009
- args[argumentMetadata.index] = connection;
1010
- break;
1011
- case webSocketServerArgsKey:
1012
- args[argumentMetadata.index] = server;
1013
- break;
1014
- }
1015
- }
1016
- handlerMetadata.descriptor.value(...args);
1017
- },
1018
- ping: (connection, data) => {
1019
- const pathnameKey = `${connection.data.pathname}:::ping`;
1020
- const handlerMetadata = webSocketsMap.get(pathnameKey);
1021
- if (!handlerMetadata) {
1022
- return;
1023
- }
1024
- const argumentsMetadata = handlerMetadata.arguments || {};
1025
- const args = [];
1026
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
1027
- switch (argumentMetadata.type) {
1028
- case webSocketConnectionArgsKey:
1029
- args[argumentMetadata.index] = connection;
1030
- break;
1031
- case webSocketServerArgsKey:
1032
- args[argumentMetadata.index] = server;
1033
- break;
1034
- case webSocketMessageArgsKey:
1035
- args[argumentMetadata.index] = data;
1036
- break;
1037
- }
1038
- }
1039
- handlerMetadata.descriptor.value(...args);
1040
- },
1041
- pong: (connection, data) => {
1042
- const pathnameKey = `${connection.data.pathname}:::pong`;
1043
- const handlerMetadata = webSocketsMap.get(pathnameKey);
1044
- if (!handlerMetadata) {
1045
- return;
1046
- }
1047
- const argumentsMetadata = handlerMetadata.arguments || {};
1048
- const args = [];
1049
- for (const [_key, argumentMetadata] of Object.entries(argumentsMetadata)) {
1050
- switch (argumentMetadata.type) {
1051
- case webSocketConnectionArgsKey:
1052
- args[argumentMetadata.index] = connection;
1053
- break;
1054
- case webSocketServerArgsKey:
1055
- args[argumentMetadata.index] = server;
1056
- break;
1057
- case webSocketMessageArgsKey:
1058
- args[argumentMetadata.index] = data;
1059
- break;
1060
- }
1061
- }
1062
- handlerMetadata.descriptor.value(...args);
1063
- }
1064
- }
1065
- });
1066
- }
1067
- catch (error) {
1068
- options.debug && console.error(error);
1069
- throw error;
1070
- }
1071
- };
1072
- export default BoolFactory;