@bool-ts/core 2.3.0 → 2.3.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.
@@ -49,6 +49,7 @@ export type TApplicationOptions<AllowedMethods extends Array<THttpMethods> = Arr
49
49
  port: number;
50
50
  }> & Partial<{
51
51
  config: Record<string | symbol, any> | (() => Record<string | symbol, any>);
52
+ idleTimeoutInSeconds: number;
52
53
  prefix: string;
53
54
  debug: boolean;
54
55
  log: Partial<{
@@ -5,26 +5,26 @@ type AnsiOptions = {
5
5
  underline?: boolean;
6
6
  };
7
7
  declare const ansiColors: Readonly<{
8
- black: 30;
9
- red: 31;
10
- green: 32;
11
- yellow: 33;
12
- blue: 34;
13
- magenta: 35;
14
- cyan: 36;
15
- white: 37;
16
- gray: 90;
8
+ black: "38;5;16";
9
+ red: "38;5;196";
10
+ green: "38;5;46";
11
+ yellow: "38;5;226";
12
+ blue: "38;5;21";
13
+ magenta: "38;5;201";
14
+ cyan: "38;5;51";
15
+ white: "38;5;231";
16
+ gray: "38;5;244";
17
17
  }>;
18
18
  declare const backgroundColors: Readonly<{
19
- black: 40;
20
- red: 41;
21
- green: 42;
22
- yellow: 43;
23
- blue: 44;
24
- magenta: 45;
25
- cyan: 46;
26
- white: 47;
27
- gray: 100;
19
+ black: "48;5;16";
20
+ red: "48;5;196";
21
+ green: "48;5;46";
22
+ yellow: "48;5;226";
23
+ blue: "48;5;21";
24
+ magenta: "48;5;201";
25
+ cyan: "48;5;51";
26
+ white: "48;5;231";
27
+ gray: "48;5;244";
28
28
  }>;
29
29
  export declare const ansiText: (text: string, options?: AnsiOptions) => string;
30
30
  export {};
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "@bool-ts/date-time": "^1.0.0",
8
8
  "qs": "^6.14.1",
9
9
  "reflect-metadata": "^0.2.2",
10
- "zod": "^4.3.4"
10
+ "zod": "^4.3.6"
11
11
  },
12
12
  "description": "Core package for BoolTS framework",
13
13
  "devDependencies": {
@@ -44,5 +44,5 @@
44
44
  "test:socket": "bun --hot run __test/client/socket.ts"
45
45
  },
46
46
  "types": "./dist/index.d.ts",
47
- "version": "2.3.0"
47
+ "version": "2.3.2"
48
48
  }
@@ -119,10 +119,10 @@ export class Application<TRootClass extends Object = Object> {
119
119
  allowOrigins: !this.options.cors?.origins
120
120
  ? ["*"]
121
121
  : typeof this.options.cors.origins !== "string"
122
- ? this.options.cors.origins.includes("*") || this.options.cors.origins.length < 1
123
- ? ["*"]
124
- : this.options.cors.origins
125
- : [this.options.cors.origins !== "*" ? this.options.cors.origins : "*"],
122
+ ? this.options.cors.origins.includes("*") || this.options.cors.origins.length < 1
123
+ ? ["*"]
124
+ : this.options.cors.origins
125
+ : [this.options.cors.origins !== "*" ? this.options.cors.origins : "*"],
126
126
  allowMethods: this.options.cors?.methods || httpMethods,
127
127
  allowCredentials: !this.options.cors?.credentials ? false : true,
128
128
  allowHeaders:
@@ -231,6 +231,11 @@ export class Application<TRootClass extends Object = Object> {
231
231
  public async listen() {
232
232
  const server = serve<TWebSocketUpgradeData>({
233
233
  port: this.options.port,
234
+ idleTimeout:
235
+ typeof this.options.idleTimeoutInSeconds !== "number" ||
236
+ this.options.idleTimeoutInSeconds <= 0
237
+ ? undefined
238
+ : this.options.idleTimeoutInSeconds,
234
239
  fetch: this.#rootFetch.bind(this),
235
240
  websocket: await this.#rootWebSocket.bind(this)()
236
241
  });
@@ -268,15 +273,15 @@ export class Application<TRootClass extends Object = Object> {
268
273
  method = request.method.toUpperCase(),
269
274
  responseHeaders = new Headers();
270
275
 
271
- try {
272
- const context = new Context()
273
- .setOptions({ isStatic: true })
274
- .set(httpServerArgsKey, server)
275
- .set(requestArgsKey, request)
276
- .set(requestHeaderArgsKey, request.headers)
277
- .set(responseHeadersArgsKey, responseHeaders)
278
- .set(queryArgsKey, query);
276
+ const context = new Context()
277
+ .setOptions({ isStatic: true })
278
+ .set(httpServerArgsKey, server)
279
+ .set(requestArgsKey, request)
280
+ .set(requestHeaderArgsKey, request.headers)
281
+ .set(responseHeadersArgsKey, responseHeaders)
282
+ .set(queryArgsKey, query);
279
283
 
284
+ try {
280
285
  [
281
286
  ...(!allowCredentials
282
287
  ? []
@@ -291,8 +296,8 @@ export class Application<TRootClass extends Object = Object> {
291
296
  value: allowOrigins.includes("*")
292
297
  ? "*"
293
298
  : !allowOrigins.includes(origin)
294
- ? allowOrigins[0]
295
- : origin
299
+ ? allowOrigins[0]
300
+ : origin
296
301
  },
297
302
  { key: "Access-Control-Allow-Methods", value: allowMethods.join(", ") },
298
303
  { key: "Access-Control-Allow-Headers", value: allowHeaders.join(", ") }
@@ -369,9 +374,12 @@ export class Application<TRootClass extends Object = Object> {
369
374
  } finally {
370
375
  if (allowLogsMethods) {
371
376
  const end = performance.now();
377
+ const responseStatus = context.get(responseStatusArgsKey, { isStatic: false });
378
+ const inferedResponseStatus =
379
+ typeof responseStatus !== "number" || !responseStatus ? 0 : responseStatus;
372
380
  const pathname = ansiText(url.pathname, { color: "blue" });
373
381
  const convertedPID = `${Bun.color("yellow", "ansi")}${process.pid}`;
374
- const convertedMethod = ansiText(request.method, {
382
+ const convertedMethod = ansiText(` ${request.method} `, {
375
383
  color: "yellow",
376
384
  backgroundColor: "blue"
377
385
  });
@@ -387,18 +395,64 @@ export class Application<TRootClass extends Object = Object> {
387
395
  }
388
396
  );
389
397
  const convertedTime = ansiText(
390
- `${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms`,
398
+ ` ${Math.round((end - start + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms `,
391
399
  {
392
400
  color: "yellow",
393
401
  backgroundColor: "blue"
394
402
  }
395
403
  );
404
+ const convertedResponseStatus = ansiText(
405
+ ` ${inferedResponseStatus} (${inferStatusText(inferedResponseStatus)}) `,
406
+ (() => {
407
+ if (inferedResponseStatus >= 100 && inferedResponseStatus < 200)
408
+ return {
409
+ color: "white",
410
+ backgroundColor: "cyan"
411
+ };
412
+ else if (inferedResponseStatus >= 200 && inferedResponseStatus < 300)
413
+ return {
414
+ color: "white",
415
+ backgroundColor: "blue"
416
+ };
417
+ else if (inferedResponseStatus >= 300 && inferedResponseStatus < 400)
418
+ return {
419
+ color: "black",
420
+ backgroundColor: "magenta"
421
+ };
422
+ else if (inferedResponseStatus >= 400 && inferedResponseStatus < 500)
423
+ return {
424
+ color: "black",
425
+ backgroundColor: "yellow"
426
+ };
427
+ else if (inferedResponseStatus >= 500 && inferedResponseStatus < 600)
428
+ return {
429
+ color: "white",
430
+ backgroundColor: "red"
431
+ };
432
+ else
433
+ return {
434
+ color: "black",
435
+ backgroundColor: "gray"
436
+ };
437
+ })()
438
+ );
396
439
 
397
440
  allowLogsMethods.includes(
398
441
  request.method.toUpperCase() as (typeof allowLogsMethods)[number]
399
442
  ) &&
400
443
  console.info(
401
- `PID: ${convertedPID} - Method: ${convertedMethod} - IP: ${convertedReqIp} - ${pathname} - Time: ${convertedTime}`
444
+ [
445
+ `PID: ${convertedPID}`,
446
+ `Method: ${convertedMethod}`,
447
+ `IP: ${convertedReqIp}`,
448
+ pathname,
449
+ `Time: ${convertedTime}`,
450
+ typeof responseStatus !== "number" || !responseStatus
451
+ ? undefined
452
+ : convertedResponseStatus
453
+ ]
454
+ .filter((x) => !!x?.trim())
455
+ .join(" - ")
402
456
  );
403
457
  }
404
458
  }
@@ -953,12 +1007,12 @@ export class Application<TRootClass extends Object = Object> {
953
1007
  ? typeof containerConfig !== "object"
954
1008
  ? undefined
955
1009
  : "key" in containerConfig &&
956
- "value" in containerConfig &&
957
- typeof containerConfig.key === "symbol"
958
- ? typeof containerConfig.value !== "function"
959
- ? containerConfig.value
960
- : await containerConfig.value()
961
- : containerConfig
1010
+ "value" in containerConfig &&
1011
+ typeof containerConfig.key === "symbol"
1012
+ ? typeof containerConfig.value !== "function"
1013
+ ? containerConfig.value
1014
+ : await containerConfig.value()
1015
+ : containerConfig
962
1016
  : await containerConfig())
963
1017
  }
964
1018
  });
@@ -1255,12 +1309,12 @@ export class Application<TRootClass extends Object = Object> {
1255
1309
  ? typeof moduleConfig !== "object"
1256
1310
  ? undefined
1257
1311
  : "key" in moduleConfig &&
1258
- "value" in moduleConfig &&
1259
- typeof moduleConfig.key === "symbol"
1260
- ? typeof moduleConfig.value !== "function"
1261
- ? moduleConfig.value
1262
- : await moduleConfig.value()
1263
- : moduleConfig
1312
+ "value" in moduleConfig &&
1313
+ typeof moduleConfig.key === "symbol"
1314
+ ? typeof moduleConfig.value !== "function"
1315
+ ? moduleConfig.value
1316
+ : await moduleConfig.value()
1317
+ : moduleConfig
1264
1318
  : await moduleConfig())
1265
1319
  }
1266
1320
  });
@@ -2206,8 +2260,8 @@ export class Application<TRootClass extends Object = Object> {
2206
2260
  !data
2207
2261
  ? undefined
2208
2262
  : data instanceof ReadableStream
2209
- ? data
2210
- : JSON.stringify(data),
2263
+ ? data
2264
+ : JSON.stringify(data),
2211
2265
  {
2212
2266
  status: inferedStatus,
2213
2267
  statusText: inferedStatusText,
@@ -94,6 +94,7 @@ export type TApplicationOptions<AllowedMethods extends Array<THttpMethods> = Arr
94
94
  }> &
95
95
  Partial<{
96
96
  config: Record<string | symbol, any> | (() => Record<string | symbol, any>);
97
+ idleTimeoutInSeconds: number;
97
98
  prefix: string;
98
99
  debug: boolean;
99
100
  log: Partial<{
@@ -6,51 +6,45 @@ type AnsiOptions = {
6
6
  };
7
7
 
8
8
  const ansiColors = Object.freeze({
9
- black: 30,
10
- red: 31,
11
- green: 32,
12
- yellow: 33,
13
- blue: 34,
14
- magenta: 35,
15
- cyan: 36,
16
- white: 37,
17
- gray: 90
9
+ black: "38;5;16",
10
+ red: "38;5;196",
11
+ green: "38;5;46",
12
+ yellow: "38;5;226",
13
+ blue: "38;5;21",
14
+ magenta: "38;5;201",
15
+ cyan: "38;5;51",
16
+ white: "38;5;231",
17
+ gray: "38;5;244"
18
18
  });
19
19
 
20
20
  const backgroundColors = Object.freeze({
21
- black: 40,
22
- red: 41,
23
- green: 42,
24
- yellow: 43,
25
- blue: 44,
26
- magenta: 45,
27
- cyan: 46,
28
- white: 47,
29
- gray: 100
21
+ black: "48;5;16",
22
+ red: "48;5;196",
23
+ green: "48;5;46",
24
+ yellow: "48;5;226",
25
+ blue: "48;5;21",
26
+ magenta: "48;5;201",
27
+ cyan: "48;5;51",
28
+ white: "48;5;231",
29
+ gray: "48;5;244"
30
30
  });
31
31
 
32
32
  export const ansiText = (text: string, options: AnsiOptions = {}) => {
33
33
  const { color, backgroundColor, bold, underline } = options;
34
+ const codes: string[] = [];
34
35
 
35
- let ansiCode = "";
36
-
37
- if (bold) {
38
- ansiCode += "\x1b[1m"; // Mã ANSI cho in đậm
39
- }
40
-
41
- if (underline) {
42
- ansiCode += "\x1b[4m"; // Mã ANSI cho gạch chân
43
- }
36
+ if (bold) codes.push("1");
37
+ if (underline) codes.push("4");
44
38
 
45
39
  if (color && ansiColors[color]) {
46
- ansiCode += `\x1b[${ansiColors[color]}m`;
40
+ codes.push(ansiColors[color]);
47
41
  }
48
42
 
49
- // Màu nền
50
43
  if (backgroundColor && backgroundColors[backgroundColor]) {
51
- ansiCode += `\x1b[${backgroundColors[backgroundColor]}m`;
44
+ codes.push(backgroundColors[backgroundColor]);
52
45
  }
53
46
 
54
- // Kết quả với reset
55
- return `${ansiCode}${text}\x1b[0m`;
47
+ if (codes.length === 0) return text;
48
+
49
+ return `\x1b[${codes.join(";")}m${text}\x1b[0m`;
56
50
  };