@bool-ts/core 2.1.3 → 2.2.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/README.md +1 -1
- package/dist/entities/application.d.ts +5 -4
- package/dist/entities/httpRoute.d.ts +46 -29
- package/dist/entities/httpRouter.d.ts +3 -1
- package/dist/entities/httpRouterGroup.d.ts +9 -5
- package/dist/http/clientError.d.ts +3 -3
- package/dist/http/index.d.ts +3 -11
- package/dist/http/serverError.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/index.js.map +10 -10
- package/package.json +1 -1
- package/src/entities/application.ts +108 -70
- package/src/entities/httpRoute.ts +73 -166
- package/src/entities/httpRouter.ts +2 -4
- package/src/entities/httpRouterGroup.ts +16 -6
- package/src/http/clientError.ts +6 -3
- package/src/http/index.ts +26 -11
- package/src/http/serverError.ts +6 -3
package/package.json
CHANGED
|
@@ -7,13 +7,20 @@ import type {
|
|
|
7
7
|
TWebSocketEventHandlerMetadata,
|
|
8
8
|
TWebSocketMetadata
|
|
9
9
|
} from "../decorators";
|
|
10
|
-
import {
|
|
10
|
+
import type { THttpMethods } from "../http";
|
|
11
11
|
import type { IGuard, IInterceptor, IMiddleware } from "../interfaces";
|
|
12
|
+
import type { ICustomValidator } from "../interfaces/customValidator";
|
|
12
13
|
import type { TConstructor } from "../ultils";
|
|
13
14
|
|
|
14
15
|
import { ETimeUnit, add as TimeAdd } from "@bool-ts/date-time";
|
|
15
16
|
import { parse as QsParse } from "qs";
|
|
16
|
-
import
|
|
17
|
+
import {
|
|
18
|
+
HttpClientError,
|
|
19
|
+
httpMethods,
|
|
20
|
+
httpMethodsStandardization,
|
|
21
|
+
HttpServerError,
|
|
22
|
+
jsonErrorInfer
|
|
23
|
+
} from "../http";
|
|
17
24
|
import {
|
|
18
25
|
argumentsKey,
|
|
19
26
|
configKey,
|
|
@@ -46,38 +53,39 @@ import { Context } from "./context";
|
|
|
46
53
|
import { HttpRouter } from "./httpRouter";
|
|
47
54
|
import { HttpRouterGroup } from "./httpRouterGroup";
|
|
48
55
|
import { Injector } from "./injector";
|
|
49
|
-
import ValidationFailed from "./validationFailed";
|
|
56
|
+
import { ValidationFailed } from "./validationFailed";
|
|
50
57
|
import { WebSocketRoute } from "./webSocketRoute";
|
|
51
58
|
import { WebSocketRouter } from "./webSocketRouter";
|
|
52
59
|
import { WebSocketRouterGroup } from "./webSocketRouterGroup";
|
|
53
60
|
|
|
54
61
|
type TParamsType = Record<string, string>;
|
|
55
62
|
|
|
56
|
-
type TApplicationOptions =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
type TApplicationOptions<AllowedMethods extends Array<THttpMethods> = Array<THttpMethods>> =
|
|
64
|
+
Required<{
|
|
65
|
+
port: number;
|
|
66
|
+
}> &
|
|
67
|
+
Partial<{
|
|
68
|
+
config: Record<string | symbol, any> | (() => Record<string | symbol, any>);
|
|
69
|
+
prefix: string;
|
|
70
|
+
debug: boolean;
|
|
71
|
+
log: Partial<{
|
|
72
|
+
methods: AllowedMethods;
|
|
73
|
+
}>;
|
|
74
|
+
queryParser: Parameters<typeof QsParse>[1];
|
|
75
|
+
static: Required<{
|
|
76
|
+
path: string;
|
|
77
|
+
}> &
|
|
78
|
+
Partial<{
|
|
79
|
+
headers: TParamsType;
|
|
80
|
+
cacheTimeInSeconds: number;
|
|
81
|
+
}>;
|
|
82
|
+
cors: Partial<{
|
|
83
|
+
credentials: boolean;
|
|
84
|
+
origins: string | Array<string>;
|
|
85
|
+
methods: Array<THttpMethods>;
|
|
86
|
+
headers: Array<string>;
|
|
73
87
|
}>;
|
|
74
|
-
cors: Partial<{
|
|
75
|
-
credentials: boolean;
|
|
76
|
-
origins: string | Array<string>;
|
|
77
|
-
methods: Array<"GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS">;
|
|
78
|
-
headers: Array<string>;
|
|
79
88
|
}>;
|
|
80
|
-
}>;
|
|
81
89
|
|
|
82
90
|
type TGroupElementModel<
|
|
83
91
|
TFuncName extends keyof TClass,
|
|
@@ -99,10 +107,10 @@ type TStaticMap = Map<
|
|
|
99
107
|
>;
|
|
100
108
|
|
|
101
109
|
type TResolutedOptions = Readonly<{
|
|
102
|
-
allowLogsMethods:
|
|
103
|
-
allowOrigins: string
|
|
104
|
-
allowMethods:
|
|
105
|
-
allowHeaders: string
|
|
110
|
+
allowLogsMethods: Array<THttpMethods>;
|
|
111
|
+
allowOrigins: Array<string>;
|
|
112
|
+
allowMethods: Array<THttpMethods>;
|
|
113
|
+
allowHeaders: Array<string>;
|
|
106
114
|
allowCredentials: boolean;
|
|
107
115
|
staticOption?: Required<{
|
|
108
116
|
path: string;
|
|
@@ -133,7 +141,7 @@ type TValidator = undefined | ICustomValidator;
|
|
|
133
141
|
|
|
134
142
|
export class Application<TRootClass extends Object = Object> {
|
|
135
143
|
#preLaunchData: TPreLaunch;
|
|
136
|
-
#inputedConstructorKeys: any
|
|
144
|
+
#inputedConstructorKeys: Array<any>;
|
|
137
145
|
#injector = new Injector();
|
|
138
146
|
#staticMap: TStaticMap = new Map();
|
|
139
147
|
#resolutedOptions: TResolutedOptions;
|
|
@@ -170,14 +178,7 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
170
178
|
? ["*"]
|
|
171
179
|
: this.options.cors.origins
|
|
172
180
|
: [this.options.cors.origins !== "*" ? this.options.cors.origins : "*"],
|
|
173
|
-
allowMethods: this.options.cors?.methods ||
|
|
174
|
-
"GET",
|
|
175
|
-
"POST",
|
|
176
|
-
"PUT",
|
|
177
|
-
"PATCH",
|
|
178
|
-
"DELETE",
|
|
179
|
-
"OPTIONS"
|
|
180
|
-
],
|
|
181
|
+
allowMethods: this.options.cors?.methods || httpMethods,
|
|
181
182
|
allowCredentials: !this.options.cors?.credentials ? false : true,
|
|
182
183
|
allowHeaders:
|
|
183
184
|
!this.options.cors?.headers || this.options.cors.headers.includes("*")
|
|
@@ -299,6 +300,25 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
299
300
|
.set(queryArgsKey, query);
|
|
300
301
|
|
|
301
302
|
try {
|
|
303
|
+
const validateRequestMethod = httpMethodsStandardization(method);
|
|
304
|
+
|
|
305
|
+
if (!validateRequestMethod) {
|
|
306
|
+
return this.finalizeResponse(
|
|
307
|
+
new Response(
|
|
308
|
+
JSON.stringify({
|
|
309
|
+
httpCode: 405,
|
|
310
|
+
message: "Method Not Allowed.",
|
|
311
|
+
data: undefined
|
|
312
|
+
}),
|
|
313
|
+
{
|
|
314
|
+
status: 405,
|
|
315
|
+
statusText: "Method Not Allowed.",
|
|
316
|
+
headers: responseHeaders
|
|
317
|
+
}
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
302
322
|
const isUpgradable = isWebSocketUpgrade(request);
|
|
303
323
|
|
|
304
324
|
let collection:
|
|
@@ -313,10 +333,10 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
313
333
|
if (isUpgradable) {
|
|
314
334
|
for (const availableModuleResolution of resolutedModules) {
|
|
315
335
|
const routeResult =
|
|
316
|
-
availableModuleResolution.webSocketHttpRouterGroup.find(
|
|
317
|
-
url.pathname,
|
|
318
|
-
|
|
319
|
-
);
|
|
336
|
+
availableModuleResolution.webSocketHttpRouterGroup.find({
|
|
337
|
+
pathname: url.pathname,
|
|
338
|
+
method: method
|
|
339
|
+
});
|
|
320
340
|
|
|
321
341
|
if (routeResult) {
|
|
322
342
|
collection = Object.freeze({
|
|
@@ -492,10 +512,10 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
492
512
|
}
|
|
493
513
|
|
|
494
514
|
for (const availableModuleResolution of resolutedModules) {
|
|
495
|
-
const routeResult = availableModuleResolution.controllerRouterGroup.find(
|
|
496
|
-
url.pathname,
|
|
497
|
-
method
|
|
498
|
-
);
|
|
515
|
+
const routeResult = availableModuleResolution.controllerRouterGroup.find({
|
|
516
|
+
pathname: url.pathname,
|
|
517
|
+
method: method
|
|
518
|
+
});
|
|
499
519
|
|
|
500
520
|
if (routeResult) {
|
|
501
521
|
collection = Object.freeze({
|
|
@@ -1304,7 +1324,9 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1304
1324
|
httpMetadata: []
|
|
1305
1325
|
};
|
|
1306
1326
|
|
|
1307
|
-
const router = new HttpRouter(
|
|
1327
|
+
const router = new HttpRouter({
|
|
1328
|
+
alias: `/${prefix || ""}/${controllerMetadata.prefix}`
|
|
1329
|
+
});
|
|
1308
1330
|
|
|
1309
1331
|
controllerMetadata.httpMetadata.forEach((routeMetadata) => {
|
|
1310
1332
|
if (typeof routeMetadata.descriptor.value !== "function") {
|
|
@@ -1313,7 +1335,7 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1313
1335
|
|
|
1314
1336
|
const route = router.route(routeMetadata.path);
|
|
1315
1337
|
const handler = routeMetadata.descriptor.value.bind(controller);
|
|
1316
|
-
const
|
|
1338
|
+
const httpRouteModel = Object.freeze({
|
|
1317
1339
|
class: controllerConstructor,
|
|
1318
1340
|
funcName: routeMetadata.methodName,
|
|
1319
1341
|
func: handler,
|
|
@@ -1322,17 +1344,17 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1322
1344
|
|
|
1323
1345
|
switch (routeMetadata.httpMethod) {
|
|
1324
1346
|
case "GET":
|
|
1325
|
-
return route.get(
|
|
1347
|
+
return route.get({ model: httpRouteModel });
|
|
1326
1348
|
case "POST":
|
|
1327
|
-
return route.post(
|
|
1349
|
+
return route.post({ model: httpRouteModel });
|
|
1328
1350
|
case "PUT":
|
|
1329
|
-
return route.put(
|
|
1351
|
+
return route.put({ model: httpRouteModel });
|
|
1330
1352
|
case "PATCH":
|
|
1331
|
-
return route.patch(
|
|
1353
|
+
return route.patch({ model: httpRouteModel });
|
|
1332
1354
|
case "DELETE":
|
|
1333
|
-
return route.delete(
|
|
1355
|
+
return route.delete({ model: httpRouteModel });
|
|
1334
1356
|
case "OPTIONS":
|
|
1335
|
-
return route.options(
|
|
1357
|
+
return route.options({ model: httpRouteModel });
|
|
1336
1358
|
}
|
|
1337
1359
|
});
|
|
1338
1360
|
|
|
@@ -1382,7 +1404,9 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1382
1404
|
const fullPrefix = `/${prefix || ""}/${webSocketMetadata.prefix}`;
|
|
1383
1405
|
|
|
1384
1406
|
//#region [HTTP ROUTER]
|
|
1385
|
-
const router = new HttpRouter(
|
|
1407
|
+
const router = new HttpRouter({
|
|
1408
|
+
alias: fullPrefix
|
|
1409
|
+
});
|
|
1386
1410
|
|
|
1387
1411
|
for (const [_key, httpMetadata] of Object.entries(webSocketMetadata.http)) {
|
|
1388
1412
|
if (typeof httpMetadata.descriptor?.value !== "function") {
|
|
@@ -1391,7 +1415,7 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1391
1415
|
|
|
1392
1416
|
const route = router.route(httpMetadata.path);
|
|
1393
1417
|
const handler = httpMetadata.descriptor.value.bind(webSocket);
|
|
1394
|
-
const
|
|
1418
|
+
const httpRouteModel = Object.freeze({
|
|
1395
1419
|
class: webSocketConstructor,
|
|
1396
1420
|
funcName: httpMetadata.methodName,
|
|
1397
1421
|
func: handler,
|
|
@@ -1400,10 +1424,10 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1400
1424
|
|
|
1401
1425
|
switch (httpMetadata.httpMethod) {
|
|
1402
1426
|
case "GET":
|
|
1403
|
-
route.get(
|
|
1427
|
+
route.get({ model: httpRouteModel });
|
|
1404
1428
|
break;
|
|
1405
1429
|
case "POST":
|
|
1406
|
-
route.post(
|
|
1430
|
+
route.post({ model: httpRouteModel });
|
|
1407
1431
|
break;
|
|
1408
1432
|
}
|
|
1409
1433
|
}
|
|
@@ -1453,21 +1477,31 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1453
1477
|
|
|
1454
1478
|
if (contentType.includes("application/json")) {
|
|
1455
1479
|
return this.finalizeResponse(
|
|
1456
|
-
new Response(
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1480
|
+
new Response(
|
|
1481
|
+
!data
|
|
1482
|
+
? undefined
|
|
1483
|
+
: data instanceof ReadableStream
|
|
1484
|
+
? data
|
|
1485
|
+
: JSON.stringify(data),
|
|
1486
|
+
{
|
|
1487
|
+
status: !data ? 204 : status,
|
|
1488
|
+
statusText: statusText,
|
|
1489
|
+
headers: headers
|
|
1490
|
+
}
|
|
1491
|
+
)
|
|
1461
1492
|
);
|
|
1462
1493
|
}
|
|
1463
1494
|
|
|
1464
1495
|
if (contentType.includes("text/plain") || contentType.includes("text/html")) {
|
|
1465
1496
|
return this.finalizeResponse(
|
|
1466
|
-
new Response(
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1497
|
+
new Response(
|
|
1498
|
+
!data ? undefined : data instanceof ReadableStream ? data : String(data),
|
|
1499
|
+
{
|
|
1500
|
+
status: !data ? 204 : status,
|
|
1501
|
+
statusText: statusText,
|
|
1502
|
+
headers: headers
|
|
1503
|
+
}
|
|
1504
|
+
)
|
|
1471
1505
|
);
|
|
1472
1506
|
}
|
|
1473
1507
|
|
|
@@ -1501,7 +1535,11 @@ export class Application<TRootClass extends Object = Object> {
|
|
|
1501
1535
|
}
|
|
1502
1536
|
|
|
1503
1537
|
return this.finalizeResponse(
|
|
1504
|
-
new Response(
|
|
1538
|
+
new Response(!data ? undefined : String(data), {
|
|
1539
|
+
status: !data ? 204 : status,
|
|
1540
|
+
statusText: statusText,
|
|
1541
|
+
headers: headers
|
|
1542
|
+
})
|
|
1505
1543
|
);
|
|
1506
1544
|
}
|
|
1507
1545
|
|