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