@bool-ts/core 1.7.16 → 1.8.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.
Files changed (84) hide show
  1. package/.prettierrc +1 -1
  2. package/__test/controller.ts +1 -1
  3. package/__test/index.ts +4 -1
  4. package/__test/module.ts +3 -1
  5. package/__test/tsconfig.json +109 -0
  6. package/__test/webSocket.ts +37 -0
  7. package/__test/webSocketClient.ts +23 -0
  8. package/dist/decorators/controller.d.ts +3 -3
  9. package/dist/decorators/controller.js +1 -2
  10. package/dist/decorators/dispatcher.d.ts +1 -1
  11. package/dist/decorators/http.d.ts +12 -12
  12. package/dist/decorators/http.js +1 -1
  13. package/dist/decorators/index.d.ts +5 -0
  14. package/dist/decorators/index.js +3 -0
  15. package/dist/decorators/module.d.ts +3 -1
  16. package/dist/decorators/module.js +9 -2
  17. package/dist/decorators/webSocket.d.ts +25 -0
  18. package/dist/decorators/webSocket.js +40 -0
  19. package/dist/decorators/webSocketArguments.d.ts +22 -0
  20. package/dist/decorators/webSocketArguments.js +49 -0
  21. package/dist/decorators/webSocketEvent.d.ts +15 -0
  22. package/dist/decorators/webSocketEvent.js +24 -0
  23. package/dist/decorators/zodSchema.js +3 -3
  24. package/dist/entities/{route.d.ts → httpRoute.d.ts} +12 -12
  25. package/dist/entities/{route.js → httpRoute.js} +27 -25
  26. package/dist/entities/httpRouter.d.ts +10 -0
  27. package/dist/entities/{router.js → httpRouter.js} +7 -5
  28. package/dist/entities/{routerGroup.d.ts → httpRouterGroup.d.ts} +4 -4
  29. package/dist/entities/{routerGroup.js → httpRouterGroup.js} +1 -1
  30. package/dist/entities/index.d.ts +7 -4
  31. package/dist/entities/index.js +6 -3
  32. package/dist/entities/webSocketRoute.d.ts +10 -0
  33. package/dist/entities/webSocketRoute.js +15 -0
  34. package/dist/entities/webSocketRouter.d.ts +31 -0
  35. package/dist/entities/webSocketRouter.js +54 -0
  36. package/dist/entities/webSocketRouterGroup.d.ts +25 -0
  37. package/dist/entities/webSocketRouterGroup.js +51 -0
  38. package/dist/hooks/factory.d.ts +1 -39
  39. package/dist/hooks/factory.js +450 -76
  40. package/dist/hooks/injector.js +2 -2
  41. package/dist/index.d.ts +1 -1
  42. package/dist/interfaces/index.d.ts +1 -0
  43. package/dist/interfaces/webSocket.d.ts +2 -0
  44. package/dist/interfaces/webSocket.js +1 -0
  45. package/dist/keys/index.d.ts +10 -1
  46. package/dist/keys/index.js +21 -12
  47. package/dist/ultils/colors.d.ts +30 -0
  48. package/dist/ultils/colors.js +41 -0
  49. package/dist/ultils/index.d.ts +2 -0
  50. package/dist/ultils/index.js +2 -0
  51. package/dist/ultils/socket.d.ts +1 -0
  52. package/dist/ultils/socket.js +7 -0
  53. package/package.json +8 -7
  54. package/src/decorators/controller.ts +5 -4
  55. package/src/decorators/dispatcher.ts +2 -1
  56. package/src/decorators/guard.ts +1 -0
  57. package/src/decorators/http.ts +3 -3
  58. package/src/decorators/index.ts +10 -0
  59. package/src/decorators/middleware.ts +1 -0
  60. package/src/decorators/module.ts +14 -3
  61. package/src/decorators/webSocket.ts +81 -0
  62. package/src/decorators/webSocketArguments.ts +144 -0
  63. package/src/decorators/webSocketEvent.ts +56 -0
  64. package/src/decorators/zodSchema.ts +5 -3
  65. package/src/entities/{route.ts → httpRoute.ts} +71 -57
  66. package/src/entities/{router.ts → httpRouter.ts} +8 -6
  67. package/src/entities/{routerGroup.ts → httpRouterGroup.ts} +4 -4
  68. package/src/entities/index.ts +7 -4
  69. package/src/entities/webSocketRoute.ts +27 -0
  70. package/src/entities/webSocketRouter.ts +64 -0
  71. package/src/entities/webSocketRouterGroup.ts +64 -0
  72. package/src/hooks/factory.ts +704 -112
  73. package/src/hooks/injector.ts +2 -2
  74. package/src/index.ts +1 -1
  75. package/src/interfaces/index.ts +1 -0
  76. package/src/interfaces/webSocket.ts +1 -0
  77. package/src/keys/index.ts +22 -12
  78. package/src/ultils/colors.ts +56 -0
  79. package/src/ultils/index.ts +3 -1
  80. package/src/ultils/socket.ts +9 -0
  81. package/test.ts +0 -0
  82. package/tsconfig.json +3 -2
  83. package/bun.lockb +0 -0
  84. package/dist/entities/router.d.ts +0 -10
@@ -1,5 +1,5 @@
1
1
  import "reflect-metadata";
2
- import { controllerKey, dispatcherKey, guardKey, injectableKey, injectKey, middlewareKey } from "../keys";
2
+ import { controllerKey, dispatcherKey, guardKey, injectableKey, injectKey, middlewareKey, webSocketKey } from "../keys";
3
3
  export class Injector {
4
4
  _mapper = new Map();
5
5
  /**
@@ -14,7 +14,7 @@ export class Injector {
14
14
  return undefined;
15
15
  }
16
16
  const ownMetadataKeys = Reflect.getMetadataKeys(definition);
17
- if (![injectableKey, controllerKey, middlewareKey, guardKey, dispatcherKey].some((value) => ownMetadataKeys.includes(value))) {
17
+ if (![injectableKey, controllerKey, middlewareKey, guardKey, dispatcherKey, webSocketKey].some((value) => ownMetadataKeys.includes(value))) {
18
18
  throw Error("Missing dependency declaration, please check @Injectable() used on dependency(ies).");
19
19
  }
20
20
  // Initialize dependencies injection
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import "reflect-metadata";
2
- export type { TRouteModel } from "./entities";
2
+ export type { THttpRouteModel } from "./entities";
3
3
  export * from "./decorators";
4
4
  export * from "./hooks";
5
5
  export * from "./http";
@@ -4,3 +4,4 @@ export type { IDispatcher } from "./dispatcher";
4
4
  export type { IGuard } from "./guard";
5
5
  export type { IMiddleware } from "./middleware";
6
6
  export type { IModule } from "./module";
7
+ export type { IWebSocket } from "./webSocket";
@@ -0,0 +1,2 @@
1
+ export interface IWebSocket<T = any> {
2
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  export declare const argumentsKey: unique symbol;
2
+ export declare const webSocketEventArgumentsKey: unique symbol;
2
3
  export declare const configKey: unique symbol;
3
4
  export declare const controllerKey: unique symbol;
4
5
  export declare const dispatcherKey: unique symbol;
@@ -8,7 +9,15 @@ export declare const injectKey: unique symbol;
8
9
  export declare const injectableKey: unique symbol;
9
10
  export declare const middlewareKey: unique symbol;
10
11
  export declare const moduleKey: unique symbol;
11
- export declare const controllerRouteZodSchemaKey: unique symbol;
12
+ export declare const zodSchemaKey: unique symbol;
13
+ export declare const webSocketKey: unique symbol;
14
+ export declare const webSocketEventKey: unique symbol;
15
+ export declare const webSocketServerArgsKey: unique symbol;
16
+ export declare const webSocketConnectionArgsKey: unique symbol;
17
+ export declare const webSocketMessageArgsKey: unique symbol;
18
+ export declare const webSocketCloseCodeArgsKey: unique symbol;
19
+ export declare const webSocketCloseReasonArgsKey: unique symbol;
20
+ export declare const httpServerArgsKey: unique symbol;
12
21
  export declare const requestHeadersArgsKey: unique symbol;
13
22
  export declare const requestHeaderArgsKey: unique symbol;
14
23
  export declare const requestBodyArgsKey: unique symbol;
@@ -1,4 +1,5 @@
1
1
  export const argumentsKey = Symbol("__bool:arguments__");
2
+ export const webSocketEventArgumentsKey = Symbol("__bool:webSocketEventArguments__");
2
3
  export const configKey = Symbol("__bool:config__");
3
4
  export const controllerKey = Symbol("__bool:controller__");
4
5
  export const dispatcherKey = Symbol("__bool:dispatcher__");
@@ -8,15 +9,23 @@ export const injectKey = Symbol("__bool:inject__");
8
9
  export const injectableKey = Symbol("__bool:injectable__");
9
10
  export const middlewareKey = Symbol("__bool:middleware__");
10
11
  export const moduleKey = Symbol("__bool:module__");
11
- export const controllerRouteZodSchemaKey = Symbol("__bool:controller.route.zodSchema__");
12
- export const requestHeadersArgsKey = Symbol("__bool:arguments:requestHeaders__");
13
- export const requestHeaderArgsKey = Symbol("__bool:arguments:requestHeader__");
14
- export const requestBodyArgsKey = Symbol("__bool:arguments:requestBody__");
15
- export const paramsArgsKey = Symbol("__bool:arguments:params__");
16
- export const paramArgsKey = Symbol("__bool:arguments:param__");
17
- export const queryArgsKey = Symbol("__bool:arguments:query__");
18
- export const requestArgsKey = Symbol("__bool:arguments:request__");
19
- export const responseHeadersArgsKey = Symbol("__bool:arguments:responseHeaders__");
20
- export const contextArgsKey = Symbol("__bool:arguments:context__");
21
- export const routeModelArgsKey = Symbol("__bool:arguments:routeModel__");
22
- export const responseBodyArgsKey = Symbol("__bool:arguments:responseBody__");
12
+ export const zodSchemaKey = Symbol("__bool:zodSchema__");
13
+ export const webSocketKey = Symbol("__bool:webSocket__");
14
+ export const webSocketEventKey = Symbol("__bool:webSocket:event__");
15
+ export const webSocketServerArgsKey = Symbol("__bool:webSocketArguments:server__");
16
+ export const webSocketConnectionArgsKey = Symbol("__bool:webSocketArguments:connection__");
17
+ export const webSocketMessageArgsKey = Symbol("__bool:webSocketArguments:message__");
18
+ export const webSocketCloseCodeArgsKey = Symbol("__bool:webSocketArguments:closeCode__");
19
+ export const webSocketCloseReasonArgsKey = Symbol("__bool:webSocketArguments:closeReason__");
20
+ export const httpServerArgsKey = Symbol("__bool:httpArguments:server__");
21
+ export const requestHeadersArgsKey = Symbol("__bool:httpArguments:requestHeaders__");
22
+ export const requestHeaderArgsKey = Symbol("__bool:httpArguments:requestHeader__");
23
+ export const requestBodyArgsKey = Symbol("__bool:httpArguments:requestBody__");
24
+ export const paramsArgsKey = Symbol("__bool:httpArguments:params__");
25
+ export const paramArgsKey = Symbol("__bool:httpArguments:param__");
26
+ export const queryArgsKey = Symbol("__bool:httpArguments:query__");
27
+ export const requestArgsKey = Symbol("__bool:httpArguments:request__");
28
+ export const responseHeadersArgsKey = Symbol("__bool:httpArguments:responseHeaders__");
29
+ export const contextArgsKey = Symbol("__bool:httpArguments:context__");
30
+ export const routeModelArgsKey = Symbol("__bool:httpArguments:routeModel__");
31
+ export const responseBodyArgsKey = Symbol("__bool:httpArguments:responseBody__");
@@ -0,0 +1,30 @@
1
+ type AnsiOptions = {
2
+ color?: keyof typeof ansiColors;
3
+ backgroundColor?: keyof typeof backgroundColors;
4
+ bold?: boolean;
5
+ underline?: boolean;
6
+ };
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;
17
+ }>;
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;
28
+ }>;
29
+ export declare const ansiText: (text: string, options?: AnsiOptions) => string;
30
+ export {};
@@ -0,0 +1,41 @@
1
+ const ansiColors = Object.freeze({
2
+ black: 30,
3
+ red: 31,
4
+ green: 32,
5
+ yellow: 33,
6
+ blue: 34,
7
+ magenta: 35,
8
+ cyan: 36,
9
+ white: 37,
10
+ gray: 90
11
+ });
12
+ const backgroundColors = Object.freeze({
13
+ black: 40,
14
+ red: 41,
15
+ green: 42,
16
+ yellow: 43,
17
+ blue: 44,
18
+ magenta: 45,
19
+ cyan: 46,
20
+ white: 47,
21
+ gray: 100
22
+ });
23
+ export const ansiText = (text, options = {}) => {
24
+ const { color, backgroundColor, bold, underline } = options;
25
+ let ansiCode = "";
26
+ if (bold) {
27
+ ansiCode += "\x1b[1m"; // Mã ANSI cho in đậm
28
+ }
29
+ if (underline) {
30
+ ansiCode += "\x1b[4m"; // Mã ANSI cho gạch chân
31
+ }
32
+ if (color && ansiColors[color]) {
33
+ ansiCode += `\x1b[${ansiColors[color]}m`;
34
+ }
35
+ // Màu nền
36
+ if (backgroundColor && backgroundColors[backgroundColor]) {
37
+ ansiCode += `\x1b[${backgroundColors[backgroundColor]}m`;
38
+ }
39
+ // Kết quả với reset
40
+ return `${ansiCode}${text}\x1b[0m`;
41
+ };
@@ -1 +1,3 @@
1
1
  export * from "./asyncFunction";
2
+ export * from "./colors";
3
+ export * from "./socket";
@@ -1 +1,3 @@
1
1
  export * from "./asyncFunction";
2
+ export * from "./colors";
3
+ export * from "./socket";
@@ -0,0 +1 @@
1
+ export declare const isWebSocketUpgrade: (request: Request) => boolean;
@@ -0,0 +1,7 @@
1
+ export const isWebSocketUpgrade = (request) => {
2
+ const headers = request.headers;
3
+ const method = request.method;
4
+ const upgrade = headers.get("upgrade")?.toLowerCase() || "";
5
+ const connection = headers.get("connection")?.toLowerCase() || "";
6
+ return method === "GET" && upgrade?.toLowerCase() === "websocket" && connection?.toLowerCase().includes("upgrade");
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bool-ts/core",
3
- "version": "1.7.16",
3
+ "version": "1.8.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -18,14 +18,15 @@
18
18
  },
19
19
  "homepage": "https://github.com/BoolTS/core#readme",
20
20
  "dependencies": {
21
- "colors": "^1.4.0",
22
- "qs": "^6.13.0",
21
+ "@bool-ts/date-time": "^1.0.0",
22
+ "qs": "^6.13.1",
23
23
  "reflect-metadata": "^0.2.2",
24
- "zod": "^3.23.8"
24
+ "zod": "^3.24.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/bun": "latest",
28
- "@types/qs": "^6.9.16",
29
- "typescript": "^5.6.2"
30
- }
28
+ "@types/qs": "^6.9.17",
29
+ "typescript": "^5.7.2"
30
+ },
31
+ "private": "false"
31
32
  }
@@ -1,6 +1,7 @@
1
- import type { IController } from "../interfaces/controller";
1
+ import type { IController } from "../interfaces";
2
+ import type { THttpMetadata } from "./http";
3
+
2
4
  import { controllerHttpKey, controllerKey } from "../keys";
3
- import { type THttpMetadata } from "./http";
4
5
 
5
6
  export type TControllerMetadata = Required<{
6
7
  prefix: string;
@@ -8,10 +9,10 @@ export type TControllerMetadata = Required<{
8
9
  }>;
9
10
 
10
11
  export const Controller =
11
- (prefix: string) =>
12
+ (prefix?: string) =>
12
13
  <T extends { new (...args: any[]): IController }>(target: T) => {
13
14
  const metadata: TControllerMetadata = {
14
- prefix: !prefix.startsWith("/") ? `/${prefix}` : prefix,
15
+ prefix: !prefix?.startsWith("/") ? `/${prefix || ""}` : prefix,
15
16
  httpMetadata: [...(Reflect.getOwnMetadata(controllerHttpKey, target.constructor) || [])]
16
17
  };
17
18
 
@@ -1,4 +1,5 @@
1
- import type { IDispatcher } from "../interfaces/dispatcher";
1
+ import type { IDispatcher } from "../interfaces";
2
+
2
3
  import { dispatcherKey } from "../keys";
3
4
 
4
5
  export type TDispatcherMetadata = undefined;
@@ -1,4 +1,5 @@
1
1
  import type { IGuard } from "../interfaces";
2
+
2
3
  import { guardKey } from "../keys";
3
4
 
4
5
  export type TGuardMetadata = undefined;
@@ -4,15 +4,15 @@ export type TRoute = {
4
4
  path: string;
5
5
  httpMethod: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
6
6
  methodName: string;
7
- descriptor: PropertyDescriptor;
7
+ descriptor: TypedPropertyDescriptor<any>;
8
8
  };
9
9
 
10
10
  export type THttpMetadata = Array<TRoute>;
11
11
 
12
12
  const defaultDecorator =
13
13
  (path: string, method: "Get" | "Post" | "Put" | "Patch" | "Delete" | "Options") =>
14
- (target: Object, methodName: string, descriptor: PropertyDescriptor) => {
15
- if (!(descriptor.value instanceof Function)) {
14
+ (target: Object, methodName: string | symbol, descriptor: TypedPropertyDescriptor<any>) => {
15
+ if (!(descriptor?.value instanceof Function)) {
16
16
  throw Error(`${method} decorator only use for class method.`);
17
17
  }
18
18
 
@@ -18,6 +18,14 @@ export { Inject } from "./inject";
18
18
  export { Injectable } from "./injectable";
19
19
  export { Middleware } from "./middleware";
20
20
  export { Module } from "./module";
21
+ export { WebSocket } from "./webSocket";
22
+ export {
23
+ WebSocketCloseCode,
24
+ WebSocketCloseReason,
25
+ WebSocketConnection,
26
+ WebSocketServer
27
+ } from "./webSocketArguments";
28
+ export { WebSocketEvent } from "./webSocketEvent";
21
29
  export { ZodSchema } from "./zodSchema";
22
30
 
23
31
  export type { TArgumentsMetadata } from "./arguments";
@@ -27,3 +35,5 @@ export type { TGuardMetadata } from "./guard";
27
35
  export type { THttpMetadata } from "./http";
28
36
  export type { TMiddlewareMetadata } from "./middleware";
29
37
  export type { TModuleMetadata, TModuleOptions } from "./module";
38
+ export type { TWebSocketMetadata } from "./webSocket";
39
+ export type { TWebSocketEventHandlerMetadata, TWebSocketEventMetadata } from "./webSocketEvent";
@@ -1,4 +1,5 @@
1
1
  import type { IMiddleware } from "../interfaces";
2
+
2
3
  import { middlewareKey } from "../keys";
3
4
 
4
5
  export type TMiddlewareMetadata = undefined;
@@ -1,5 +1,6 @@
1
- import type { IModule } from "../interfaces/module";
2
- import { controllerKey, dispatcherKey, guardKey, injectableKey, middlewareKey, moduleKey } from "../keys";
1
+ import type { IModule } from "../interfaces";
2
+
3
+ import { controllerKey, dispatcherKey, guardKey, injectableKey, middlewareKey, moduleKey, webSocketKey } from "../keys";
3
4
 
4
5
  type TInstances = Array<new (...args: any[]) => any>;
5
6
  type TLoaders<TConfig extends {} = {}> = Record<
@@ -17,6 +18,7 @@ export type TModuleOptions<TConfig extends {} = {}> =
17
18
  guards: TInstances;
18
19
  controllers: TInstances;
19
20
  dispatchers: TInstances;
21
+ webSockets: TInstances;
20
22
  }>
21
23
  | undefined;
22
24
 
@@ -30,13 +32,14 @@ export type TModuleMetadata<TConfig extends {} = {}> =
30
32
  guards: TInstances;
31
33
  controllers: TInstances;
32
34
  dispatchers: TInstances;
35
+ webSockets: TInstances;
33
36
  }>
34
37
  | undefined;
35
38
 
36
39
  export const Module =
37
40
  <TConfig extends {} = {}>(args?: TModuleOptions<TConfig>) =>
38
41
  <T extends { new (...args: any[]): IModule }>(target: T) => {
39
- const { middlewares, guards, dispatchers, controllers, dependencies } = args || {};
42
+ const { middlewares, guards, dispatchers, controllers, dependencies, webSockets } = args || {};
40
43
 
41
44
  if (middlewares) {
42
45
  for (let i = 0; i < middlewares.length; i++) {
@@ -78,6 +81,14 @@ export const Module =
78
81
  }
79
82
  }
80
83
 
84
+ if (webSockets) {
85
+ for (let i = 0; i < webSockets.length; i++) {
86
+ if (!Reflect.getOwnMetadataKeys(webSockets[i]).includes(webSocketKey)) {
87
+ throw Error(`${webSockets[i].name} is not a websocket gateway.`);
88
+ }
89
+ }
90
+ }
91
+
81
92
  Reflect.defineMetadata(moduleKey, args, target);
82
93
  };
83
94
 
@@ -0,0 +1,81 @@
1
+ import type { Server } from "bun";
2
+ import type { IWebSocket } from "../interfaces";
3
+ import type { TWebSocketEventMetadata } from "./webSocketEvent";
4
+
5
+ import { webSocketEventKey, webSocketKey } from "../keys";
6
+
7
+ export type TWebSocketHttpRouteMetadata = {
8
+ path: string;
9
+ httpMethod: "GET" | "POST";
10
+ methodName: symbol;
11
+ descriptor: PropertyDescriptor;
12
+ };
13
+
14
+ export type TWebSocketUpgradeData = {
15
+ pathname: string;
16
+ method: string;
17
+ query: Record<string, unknown>;
18
+ };
19
+
20
+ export type TWebSocketHttpMetadata = TWebSocketHttpRouteMetadata[];
21
+
22
+ export type TWebSocketMetadata = Required<{
23
+ prefix: string;
24
+ events: TWebSocketEventMetadata;
25
+ http: TWebSocketHttpMetadata;
26
+ }>;
27
+
28
+ const upgradeHandlerSymbol = Symbol("__bool:webSocket.upgrade__");
29
+
30
+ const upgradeHandler = (server: Server, request: Request, query: Record<string, unknown>) => {
31
+ const url = new URL(request.url);
32
+
33
+ return server.upgrade<TWebSocketUpgradeData>(request, {
34
+ data: {
35
+ method: request.method.toUpperCase(),
36
+ pathname: url.pathname,
37
+ query: query
38
+ }
39
+ });
40
+ };
41
+
42
+ export const WebSocket =
43
+ (
44
+ args?: Partial<{
45
+ prefix: string;
46
+ }>
47
+ ) =>
48
+ <T extends { new (...args: any[]): IWebSocket }>(target: T) => {
49
+ const { prefix } = args || {};
50
+
51
+ target.prototype[upgradeHandlerSymbol] = upgradeHandler;
52
+
53
+ const descriptor = Object.getOwnPropertyDescriptor(target.prototype, upgradeHandlerSymbol);
54
+
55
+ const httpMetadata: TWebSocketHttpMetadata = !descriptor
56
+ ? []
57
+ : [
58
+ {
59
+ path: "/",
60
+ httpMethod: "GET",
61
+ methodName: upgradeHandlerSymbol,
62
+ descriptor: descriptor
63
+ },
64
+ {
65
+ path: "/",
66
+ httpMethod: "POST",
67
+ methodName: upgradeHandlerSymbol,
68
+ descriptor: descriptor
69
+ }
70
+ ];
71
+
72
+ const metadata: TWebSocketMetadata = {
73
+ prefix: !prefix?.startsWith("/") ? `/${prefix || ""}` : prefix,
74
+ events: Reflect.getOwnMetadata(webSocketEventKey, target) || {},
75
+ http: httpMetadata
76
+ };
77
+
78
+ Reflect.defineMetadata(webSocketKey, metadata, target);
79
+ };
80
+
81
+ export default WebSocket;
@@ -0,0 +1,144 @@
1
+ import {
2
+ webSocketCloseCodeArgsKey,
3
+ webSocketCloseReasonArgsKey,
4
+ webSocketConnectionArgsKey,
5
+ webSocketEventArgumentsKey,
6
+ webSocketMessageArgsKey,
7
+ webSocketServerArgsKey
8
+ } from "../keys";
9
+
10
+ export type TWebsocketArgumentsMetadata =
11
+ | {
12
+ index: number;
13
+ type: typeof webSocketConnectionArgsKey;
14
+ }
15
+ | {
16
+ index: number;
17
+ type: typeof webSocketMessageArgsKey;
18
+ }
19
+ | {
20
+ index: number;
21
+ type: typeof webSocketServerArgsKey;
22
+ }
23
+ | {
24
+ index: number;
25
+ type: typeof webSocketCloseCodeArgsKey;
26
+ }
27
+ | {
28
+ index: number;
29
+ type: typeof webSocketCloseReasonArgsKey;
30
+ };
31
+
32
+ export type TWebsocketArgumentsMetadataGroup = Record<string, TWebsocketArgumentsMetadata>;
33
+
34
+ export const WebSocketConnection =
35
+ () => (target: Object, methodName: string | symbol | undefined, parameterIndex: number) => {
36
+ if (!methodName) {
37
+ return;
38
+ }
39
+
40
+ const webSocketEventArgumentsMetadata: TWebsocketArgumentsMetadataGroup =
41
+ Reflect.getOwnMetadata(webSocketEventArgumentsKey, target.constructor, methodName) ||
42
+ {};
43
+
44
+ webSocketEventArgumentsMetadata[`argumentIndexes.${parameterIndex}`] = {
45
+ index: parameterIndex,
46
+ type: webSocketConnectionArgsKey
47
+ } satisfies Extract<
48
+ TWebsocketArgumentsMetadata,
49
+ {
50
+ type: typeof webSocketConnectionArgsKey;
51
+ }
52
+ >;
53
+
54
+ Reflect.defineMetadata(
55
+ webSocketEventArgumentsKey,
56
+ webSocketEventArgumentsMetadata,
57
+ target.constructor,
58
+ methodName
59
+ );
60
+ };
61
+
62
+ export const WebSocketServer =
63
+ () => (target: Object, methodName: string | symbol | undefined, parameterIndex: number) => {
64
+ if (!methodName) {
65
+ return;
66
+ }
67
+
68
+ const webSocketEventArgumentsMetadata: TWebsocketArgumentsMetadataGroup =
69
+ Reflect.getOwnMetadata(webSocketEventArgumentsKey, target.constructor, methodName) ||
70
+ {};
71
+
72
+ webSocketEventArgumentsMetadata[`argumentIndexes.${parameterIndex}`] = {
73
+ index: parameterIndex,
74
+ type: webSocketServerArgsKey
75
+ } satisfies Extract<
76
+ TWebsocketArgumentsMetadata,
77
+ {
78
+ type: typeof webSocketServerArgsKey;
79
+ }
80
+ >;
81
+
82
+ Reflect.defineMetadata(
83
+ webSocketEventArgumentsKey,
84
+ webSocketEventArgumentsMetadata,
85
+ target.constructor,
86
+ methodName
87
+ );
88
+ };
89
+
90
+ export const WebSocketCloseCode =
91
+ () => (target: Object, methodName: string | symbol | undefined, parameterIndex: number) => {
92
+ if (!methodName) {
93
+ return;
94
+ }
95
+
96
+ const webSocketEventArgumentsMetadata: TWebsocketArgumentsMetadataGroup =
97
+ Reflect.getOwnMetadata(webSocketEventArgumentsKey, target.constructor, methodName) ||
98
+ {};
99
+
100
+ webSocketEventArgumentsMetadata[`argumentIndexes.${parameterIndex}`] = {
101
+ index: parameterIndex,
102
+ type: webSocketCloseCodeArgsKey
103
+ } satisfies Extract<
104
+ TWebsocketArgumentsMetadata,
105
+ {
106
+ type: typeof webSocketCloseCodeArgsKey;
107
+ }
108
+ >;
109
+
110
+ Reflect.defineMetadata(
111
+ webSocketEventArgumentsKey,
112
+ webSocketEventArgumentsMetadata,
113
+ target.constructor,
114
+ methodName
115
+ );
116
+ };
117
+
118
+ export const WebSocketCloseReason =
119
+ () => (target: Object, methodName: string | symbol | undefined, parameterIndex: number) => {
120
+ if (!methodName) {
121
+ return;
122
+ }
123
+
124
+ const webSocketEventArgumentsMetadata: TWebsocketArgumentsMetadataGroup =
125
+ Reflect.getOwnMetadata(webSocketEventArgumentsKey, target.constructor, methodName) ||
126
+ {};
127
+
128
+ webSocketEventArgumentsMetadata[`argumentIndexes.${parameterIndex}`] = {
129
+ index: parameterIndex,
130
+ type: webSocketCloseReasonArgsKey
131
+ } satisfies Extract<
132
+ TWebsocketArgumentsMetadata,
133
+ {
134
+ type: typeof webSocketCloseReasonArgsKey;
135
+ }
136
+ >;
137
+
138
+ Reflect.defineMetadata(
139
+ webSocketEventArgumentsKey,
140
+ webSocketEventArgumentsMetadata,
141
+ target.constructor,
142
+ methodName
143
+ );
144
+ };
@@ -0,0 +1,56 @@
1
+ import type {
2
+ TWebsocketArgumentsMetadata,
3
+ TWebsocketArgumentsMetadataGroup
4
+ } from "./webSocketArguments";
5
+
6
+ import { webSocketEventArgumentsKey, webSocketEventKey } from "../keys";
7
+
8
+ export type TWebSocketEventHandlerMetadata = Required<{
9
+ methodName: string;
10
+ descriptor: PropertyDescriptor;
11
+ }> &
12
+ Partial<{
13
+ arguments: Record<string, TWebsocketArgumentsMetadata>;
14
+ }>;
15
+
16
+ export type TWebSocketEventMetadata = Record<
17
+ "open" | "close" | "message" | "drain" | "ping" | "pong",
18
+ TWebSocketEventHandlerMetadata
19
+ >;
20
+
21
+ /**
22
+ *
23
+ * @param path
24
+ * @returns
25
+ */
26
+ export const WebSocketEvent =
27
+ (eventName: "open" | "close" | "message" | "drain" | "ping" | "pong") =>
28
+ (target: Object, methodName: string, descriptor: PropertyDescriptor) => {
29
+ if (!(descriptor.value instanceof Function)) {
30
+ throw Error("WebSocketEvent decorator only use for class's method.");
31
+ }
32
+
33
+ const webSocketEventArgumentsMetadata: TWebsocketArgumentsMetadataGroup | undefined =
34
+ Reflect.getOwnMetadata(webSocketEventArgumentsKey, target.constructor, methodName);
35
+
36
+ const webSocketEventMetadata: TWebSocketEventHandlerMetadata = Object.freeze({
37
+ methodName: methodName,
38
+ descriptor: descriptor,
39
+ arguments: webSocketEventArgumentsMetadata
40
+ });
41
+
42
+ const webSocketMetadata: TWebSocketEventMetadata = {
43
+ ...(Reflect.getOwnMetadata(webSocketEventKey, target.constructor) || undefined),
44
+ [eventName]: webSocketEventMetadata
45
+ };
46
+
47
+ Reflect.defineMetadata(
48
+ webSocketEventKey,
49
+ webSocketEventMetadata,
50
+ target.constructor,
51
+ methodName
52
+ );
53
+ Reflect.defineMetadata(webSocketEventKey, webSocketMetadata, target.constructor);
54
+ };
55
+
56
+ export default WebSocket;