@dooboostore/simple-boot-http-server 1.0.22 → 1.0.24

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 (181) hide show
  1. package/README.MD +27 -3
  2. package/dist/cjs/SimpleBootHttpServer.js +93 -36
  3. package/dist/cjs/SimpleBootHttpServer.js.map +3 -3
  4. package/dist/cjs/codes/HttpHeaders.js +14 -3
  5. package/dist/cjs/codes/HttpHeaders.js.map +2 -2
  6. package/dist/cjs/codes/HttpStatus.js +1 -0
  7. package/dist/cjs/codes/HttpStatus.js.map +2 -2
  8. package/dist/cjs/codes/Mimes.js +2 -0
  9. package/dist/cjs/codes/Mimes.js.map +2 -2
  10. package/dist/cjs/decorators/MethodMapping.js +8 -6
  11. package/dist/cjs/decorators/MethodMapping.js.map +3 -3
  12. package/dist/cjs/endpoints/WebSocketEndPoint.js +16 -0
  13. package/dist/cjs/endpoints/WebSocketEndPoint.js.map +7 -0
  14. package/dist/cjs/filters/CacheFilter.js +75 -35
  15. package/dist/cjs/filters/CacheFilter.js.map +3 -3
  16. package/dist/cjs/filters/IntentSchemeFilter.js +98 -0
  17. package/dist/cjs/filters/IntentSchemeFilter.js.map +7 -0
  18. package/dist/cjs/filters/ResourceFilter.js +4 -1
  19. package/dist/cjs/filters/ResourceFilter.js.map +2 -2
  20. package/dist/cjs/filters/TopicProtocolFilter.js +343 -0
  21. package/dist/cjs/filters/TopicProtocolFilter.js.map +7 -0
  22. package/dist/cjs/filters/index.js +2 -0
  23. package/dist/cjs/filters/index.js.map +2 -2
  24. package/dist/cjs/index.js +28 -0
  25. package/dist/cjs/index.js.map +2 -2
  26. package/dist/cjs/models/RequestResponse.js +56 -89
  27. package/dist/cjs/models/RequestResponse.js.map +3 -3
  28. package/dist/cjs/models/datas/body/ReqPathData.js +29 -0
  29. package/dist/cjs/models/datas/body/ReqPathData.js.map +7 -0
  30. package/dist/cjs/models/datas/search/ReqSearchParamsObj.js +29 -0
  31. package/dist/cjs/models/datas/search/ReqSearchParamsObj.js.map +7 -0
  32. package/dist/cjs/option/HttpServerOption.js +25 -5
  33. package/dist/cjs/option/HttpServerOption.js.map +2 -2
  34. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +141 -0
  35. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +7 -0
  36. package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js +35 -0
  37. package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js.map +7 -0
  38. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js +324 -0
  39. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js.map +7 -0
  40. package/dist/cjs/proxy/index.js +26 -0
  41. package/dist/cjs/proxy/index.js.map +7 -0
  42. package/dist/cjs/resolvers/ResourceResolver.js +2 -2
  43. package/dist/cjs/resolvers/ResourceResolver.js.map +2 -2
  44. package/dist/cjs/session/SessionManager.js +2 -2
  45. package/dist/cjs/session/SessionManager.js.map +2 -2
  46. package/dist/cjs/websocket/WebSocketClient.js +554 -0
  47. package/dist/cjs/websocket/WebSocketClient.js.map +7 -0
  48. package/dist/cjs/websocket/WebSocketManager.js +652 -0
  49. package/dist/cjs/websocket/WebSocketManager.js.map +7 -0
  50. package/dist/cjs/websocket/index.js +24 -0
  51. package/dist/cjs/websocket/index.js.map +7 -0
  52. package/dist/esm/SimpleBootHttpServer.js +76 -19
  53. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  54. package/dist/esm/codes/HttpHeaders.js +12 -2
  55. package/dist/esm/codes/HttpHeaders.js.map +2 -2
  56. package/dist/esm/codes/HttpStatus.js +1 -0
  57. package/dist/esm/codes/HttpStatus.js.map +2 -2
  58. package/dist/esm/codes/Mimes.js +2 -0
  59. package/dist/esm/codes/Mimes.js.map +2 -2
  60. package/dist/esm/decorators/MethodMapping.js +3 -1
  61. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  62. package/dist/esm/endpoints/WebSocketEndPoint.js +1 -0
  63. package/dist/esm/endpoints/WebSocketEndPoint.js.map +7 -0
  64. package/dist/esm/filters/CacheFilter.js +67 -27
  65. package/dist/esm/filters/CacheFilter.js.map +2 -2
  66. package/dist/esm/filters/IntentSchemeFilter.js +75 -0
  67. package/dist/esm/filters/IntentSchemeFilter.js.map +7 -0
  68. package/dist/esm/filters/ResourceFilter.js +4 -1
  69. package/dist/esm/filters/ResourceFilter.js.map +2 -2
  70. package/dist/esm/filters/TopicProtocolFilter.js +310 -0
  71. package/dist/esm/filters/TopicProtocolFilter.js.map +7 -0
  72. package/dist/esm/filters/index.js +1 -0
  73. package/dist/esm/filters/index.js.map +2 -2
  74. package/dist/esm/index.js +12 -0
  75. package/dist/esm/index.js.map +2 -2
  76. package/dist/esm/models/RequestResponse.js +52 -85
  77. package/dist/esm/models/RequestResponse.js.map +2 -2
  78. package/dist/esm/models/datas/body/ReqPathData.js +6 -0
  79. package/dist/esm/models/datas/body/ReqPathData.js.map +7 -0
  80. package/dist/esm/models/datas/search/ReqSearchParamsObj.js +6 -0
  81. package/dist/esm/models/datas/search/ReqSearchParamsObj.js.map +7 -0
  82. package/dist/esm/option/HttpServerOption.js +24 -4
  83. package/dist/esm/option/HttpServerOption.js.map +2 -2
  84. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +118 -0
  85. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +7 -0
  86. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js +12 -0
  87. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js.map +7 -0
  88. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js +301 -0
  89. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js.map +7 -0
  90. package/dist/esm/proxy/index.js +4 -0
  91. package/dist/esm/proxy/index.js.map +7 -0
  92. package/dist/esm/resolvers/ResourceResolver.js +1 -1
  93. package/dist/esm/resolvers/ResourceResolver.js.map +1 -1
  94. package/dist/esm/session/SessionManager.js +1 -1
  95. package/dist/esm/session/SessionManager.js.map +1 -1
  96. package/dist/esm/websocket/WebSocketClient.js +529 -0
  97. package/dist/esm/websocket/WebSocketClient.js.map +7 -0
  98. package/dist/esm/websocket/WebSocketManager.js +622 -0
  99. package/dist/esm/websocket/WebSocketManager.js.map +7 -0
  100. package/dist/esm/websocket/index.js +3 -0
  101. package/dist/esm/websocket/index.js.map +7 -0
  102. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +13563 -5071
  103. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  104. package/dist/types/SimpleBootHttpServer.d.ts +5 -3
  105. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  106. package/dist/types/codes/HttpHeaders.d.ts +3 -0
  107. package/dist/types/codes/HttpHeaders.d.ts.map +1 -1
  108. package/dist/types/codes/HttpStatus.d.ts +13 -1
  109. package/dist/types/codes/HttpStatus.d.ts.map +1 -1
  110. package/dist/types/codes/Mimes.d.ts +3 -1
  111. package/dist/types/codes/Mimes.d.ts.map +1 -1
  112. package/dist/types/decorators/MethodMapping.d.ts +4 -2
  113. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  114. package/dist/types/endpoints/WebSocketEndPoint.d.ts +17 -0
  115. package/dist/types/endpoints/WebSocketEndPoint.d.ts.map +1 -0
  116. package/dist/types/filters/CacheFilter.d.ts +6 -0
  117. package/dist/types/filters/CacheFilter.d.ts.map +1 -1
  118. package/dist/types/filters/IntentSchemeFilter.d.ts +20 -0
  119. package/dist/types/filters/IntentSchemeFilter.d.ts.map +1 -0
  120. package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
  121. package/dist/types/filters/TopicProtocolFilter.d.ts +34 -0
  122. package/dist/types/filters/TopicProtocolFilter.d.ts.map +1 -0
  123. package/dist/types/filters/index.d.ts +1 -0
  124. package/dist/types/filters/index.d.ts.map +1 -1
  125. package/dist/types/index.d.ts +12 -0
  126. package/dist/types/index.d.ts.map +1 -1
  127. package/dist/types/models/RequestResponse.d.ts +10 -6
  128. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  129. package/dist/types/models/datas/body/ReqPathData.d.ts +4 -0
  130. package/dist/types/models/datas/body/ReqPathData.d.ts.map +1 -0
  131. package/dist/types/models/datas/search/ReqSearchParamsObj.d.ts +4 -0
  132. package/dist/types/models/datas/search/ReqSearchParamsObj.d.ts.map +1 -0
  133. package/dist/types/option/HttpServerOption.d.ts +30 -20
  134. package/dist/types/option/HttpServerOption.d.ts.map +1 -1
  135. package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts +18 -0
  136. package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts.map +1 -0
  137. package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts +5 -0
  138. package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts.map +1 -0
  139. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts +28 -0
  140. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts.map +1 -0
  141. package/dist/types/proxy/index.d.ts +4 -0
  142. package/dist/types/proxy/index.d.ts.map +1 -0
  143. package/dist/types/session/SessionManager.d.ts +2 -17
  144. package/dist/types/session/SessionManager.d.ts.map +1 -1
  145. package/dist/types/websocket/WebSocketClient.d.ts +88 -0
  146. package/dist/types/websocket/WebSocketClient.d.ts.map +1 -0
  147. package/dist/types/websocket/WebSocketManager.d.ts +163 -0
  148. package/dist/types/websocket/WebSocketManager.d.ts.map +1 -0
  149. package/dist/types/websocket/index.d.ts +3 -0
  150. package/dist/types/websocket/index.d.ts.map +1 -0
  151. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +13638 -5146
  152. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  153. package/dist/umd-bundle/websocket-client.umd.js +11194 -0
  154. package/dist/umd-bundle/websocket-client.umd.js.map +7 -0
  155. package/package.json +24 -15
  156. package/src/SimpleBootHttpServer.ts +367 -296
  157. package/src/codes/HttpHeaders.ts +13 -2
  158. package/src/codes/HttpStatus.ts +19 -1
  159. package/src/codes/Mimes.ts +27 -25
  160. package/src/decorators/MethodMapping.ts +6 -3
  161. package/src/endpoints/WebSocketEndPoint.ts +12 -0
  162. package/src/filters/CacheFilter.ts +112 -67
  163. package/src/filters/IntentSchemeFilter.ts +69 -0
  164. package/src/filters/ResourceFilter.ts +7 -1
  165. package/src/filters/TopicProtocolFilter.ts +349 -0
  166. package/src/filters/index.ts +1 -0
  167. package/src/index.ts +12 -12
  168. package/src/models/RequestResponse.ts +113 -240
  169. package/src/models/datas/body/ReqPathData.ts +3 -0
  170. package/src/models/datas/search/ReqSearchParamsObj.ts +3 -0
  171. package/src/option/HttpServerOption.ts +73 -23
  172. package/src/proxy/SymbolIntentApiServiceProxy.ts +120 -0
  173. package/src/proxy/SymbolIntentApiServiceProxyBase.ts +16 -0
  174. package/src/proxy/TopicProtocolApiServiceProxy.ts +328 -0
  175. package/src/proxy/index.ts +3 -0
  176. package/src/resolvers/ResourceResolver.ts +1 -1
  177. package/src/session/SessionManager.ts +3 -3
  178. package/src/websocket/WebSocketClient.ts +637 -0
  179. package/src/websocket/WebSocketManager.ts +713 -0
  180. package/src/websocket/index.ts +2 -0
  181. package/tsconfig.json +3 -1
@@ -1,329 +1,400 @@
1
- import { SimpleApplication } from '@dooboostore/simple-boot/SimpleApplication';
2
- import { HttpServerOption } from './option/HttpServerOption';
3
- import { ConstructorType } from '@dooboostore/core/types';
4
- import { IncomingMessage, Server as HttpServer, ServerResponse } from 'http'
5
- import { Server as HttpsServer } from 'https'; // Add HTTPS support
6
- import { RequestResponse } from './models/RequestResponse';
7
- import { getUrlMapping, getUrlMappings, SaveMappingConfig, UrlMappingSituationType } from './decorators/MethodMapping';
8
- import { HttpStatus } from './codes/HttpStatus';
9
- import { HttpHeaders } from './codes/HttpHeaders';
10
- import { Mimes } from './codes/Mimes';
11
- import { Filter } from './filters/Filter';
12
- import { ExceptionHandlerSituationType, targetExceptionHandler } from '@dooboostore/simple-boot/decorators/exception/ExceptionDecorator';
13
- import { getInject, SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';
14
- import { EndPoint } from './endpoints/EndPoint';
15
- import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';
16
- import { ReqFormUrlBody } from './models/datas/body/ReqFormUrlBody';
17
- import { ReqJsonBody } from './models/datas/body/ReqJsonBody';
18
- import { ReqHeader } from './models/datas/ReqHeader';
19
- import { RouterModule } from '@dooboostore/simple-boot/route/RouterModule';
20
- import { ReqMultipartFormBody } from './models/datas/body/ReqMultipartFormBody';
21
- import { execValidationInValid, getValidIndex } from '@dooboostore/simple-boot/decorators/validate/Validation';
22
- import { ValidException } from '@dooboostore/simple-boot/errors/ValidException';
23
- import { HttpError } from './errors/HttpError';
24
- import { getRoute } from '@dooboostore/simple-boot/decorators/route/Router';
25
- import { OnInit } from './lifecycle/OnInit';
26
- import { URLSearchParams } from 'url';
27
- import { HttpMethod } from './codes/HttpMethod';
28
- import { SessionManager } from './session/SessionManager';
29
- import { InjectSituationType } from './inject/InjectSituationType';
1
+ import {SimpleApplication} from '@dooboostore/simple-boot';
2
+ import {HttpServerOption} from './option/HttpServerOption';
3
+ import {ConstructorType} from '@dooboostore/core';
4
+ import {IncomingMessage, Server as HttpServer, ServerResponse} from 'http'
5
+ import {Server as HttpsServer} from 'https'; // Add HTTPS support
6
+ import {WebSocketServer, WebSocket} from 'ws';
7
+ import {RequestResponse} from './models/RequestResponse';
8
+ import {getUrlMapping, getUrlMappings, SaveMappingConfig, UrlMappingSituationType} from './decorators/MethodMapping';
9
+ import {HttpStatus} from './codes/HttpStatus';
10
+ import {HttpHeaders} from './codes/HttpHeaders';
11
+ import {Mimes} from './codes/Mimes';
12
+ import {Filter} from './filters/Filter';
13
+ import {ExceptionHandlerSituationType, targetExceptionHandler} from '@dooboostore/simple-boot';
14
+ import {getInject, SituationTypeContainer, SituationTypeContainers} from '@dooboostore/simple-boot';
15
+ import {EndPoint} from './endpoints/EndPoint';
16
+ import {ReflectUtils} from '@dooboostore/core';
17
+ import {ReqFormUrlBody} from './models/datas/body/ReqFormUrlBody';
18
+ import {ReqJsonBody} from './models/datas/body/ReqJsonBody';
19
+ import {ReqHeader} from './models/datas/ReqHeader';
20
+ import {RouterModule} from '@dooboostore/simple-boot';
21
+ import {ReqMultipartFormBody} from './models/datas/body/ReqMultipartFormBody';
22
+ import {execValidationInValid, getValidIndex} from '@dooboostore/simple-boot';
23
+ import {ValidException} from '@dooboostore/simple-boot';
24
+ import {HttpError} from './errors/HttpError';
25
+ import {getRoute} from '@dooboostore/simple-boot';
26
+ import {OnInit} from './lifecycle/OnInit';
27
+ import {URLSearchParams} from 'url';
28
+ import {HttpMethod} from './codes/HttpMethod';
29
+ import {SessionManager} from './session/SessionManager';
30
+ import {InjectSituationType} from './inject/InjectSituationType';
31
+ import {ReqSearchParamsObj} from "./models/datas/search/ReqSearchParamsObj";
32
+ import {SimConfig} from '@dooboostore/simple-boot';
33
+ import {ReqPathData} from './models/datas/body/ReqPathData';
34
+ import {WebSocketEndPoint} from './endpoints/WebSocketEndPoint';
30
35
 
31
36
  export class SimpleBootHttpServer extends SimpleApplication {
32
- public server?: HttpServer | HttpsServer;
33
- private sessionManager: SessionManager;
34
- constructor(public option: HttpServerOption = new HttpServerOption()) {
35
- super(option);
36
- this.sessionManager = new SessionManager(this.option);
37
- }
38
-
37
+ public server?: HttpServer | HttpsServer;
38
+ private sessionManager: SessionManager;
39
+ private webSocketClients = new Map<WebSocket, { request: IncomingMessage }>();
39
40
 
40
- public run(otherInstanceSim?: Map<ConstructorType<any>, any>) {
41
- super.run(otherInstanceSim);
42
- const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];
43
- Promise.all(targets.map(it => (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it as ConstructorType<any>}) : it) as OnInit).map(it => it.onInit(this))).then(it => {
44
- this.startServer();
45
- });
46
- return this;
47
- }
41
+ constructor(public option: HttpServerOption = new HttpServerOption()) {
42
+ super(option);
43
+ this.sessionManager = new SessionManager(this.option);
44
+ }
48
45
 
49
- private startServer() {
50
46
 
51
- // const a = this.option.serverOption as HttpsServerOption;
52
- // this.option.serverOption?.
53
-
54
- if (this.option.serverOption && 'key' in this.option.serverOption && 'cert' in this.option.serverOption) {
55
- this.server = new HttpsServer(this.option.serverOption);
56
- const httpServer = new HttpServer();
57
- httpServer.on('request', (req: IncomingMessage, res: ServerResponse) => {
58
- res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });
59
- res.end();
60
- });
61
- httpServer.listen(80, this.option.listen.hostname, () => {
62
- console.log('HTTP redirect server running on port 80');
63
- });
64
- } else if (this.option.serverOption) {
65
- this.server = new HttpServer(this.option.serverOption);
66
- } else {
67
- this.server = new HttpServer();
68
- }
69
- // const thisRef = this;
70
- this.server.on('request', async (req: IncomingMessage, res: ServerResponse) => {
71
- // console.log('request', req.url);
72
- const transactionManager = this.option.transactionManagerFactory ? await this.option.transactionManagerFactory() : undefined;
73
- res.on('close', async () => {
74
- if (this.option.closeEndPoints) {
75
- for (const it of this.option.closeEndPoints) {
76
- try {
77
- const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;
78
- const endPoint = execute?.endPoint(rr, this);
79
- if (endPoint instanceof Promise) {
80
- await endPoint;
81
- }
82
- } catch (e) {
83
- }
84
- }
85
- }
47
+ public run(otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | Symbol, any>) {
48
+ otherInstanceSim ??= new Map<ConstructorType<any> | Function | SimConfig | Symbol, any>();
49
+ otherInstanceSim.set(SimpleBootHttpServer, this);
50
+ super.run(otherInstanceSim);
51
+ const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];
52
+ Promise.all(targets.map(it => (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target: it as ConstructorType<any>}) : it) as OnInit).map(it => it.onInit(this))).then(it => {
53
+ this.startServer();
54
+ });
55
+ return this;
56
+ }
86
57
 
87
- if (!rr.resIsDone()) {
88
- rr.resEnd();
89
- }
90
- });
91
- res.on('error', async () => {
92
- if (this.option.errorEndPoints) {
93
- for (const it of this.option.errorEndPoints) {
94
- try {
95
- const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;
96
- const endPoint = execute?.endPoint(rr, this);
97
- if (endPoint instanceof Promise) {
98
- await endPoint;
99
- }
100
- } catch (e) {
101
- }
102
- }
103
- }
58
+ private startServer() {
104
59
 
105
- if (!rr.resIsDone()) {
106
- rr.resEnd();
107
- }
108
- });
60
+ // const a = this.option.serverOption as HttpsServerOption;
61
+ // this.option.serverOption?.
109
62
 
110
- const rr = new RequestResponse(req, res,{sessionManager: this.sessionManager, option: this.option});
111
- /*
112
- default setting first
113
- */
114
- rr.resSetHeader(HttpHeaders.Server, 'simple-boot-http-server');
115
- const cookie = rr.reqCookieGet(this.option.sessionOption.key);
116
- if (!cookie) {
117
- const session = await this.sessionManager.session();
118
- rr.resSetHeader(HttpHeaders.SetCookie, `${this.option.sessionOption.key}=${session.uuid}; Path=/; HttpOnly`);
63
+ if (this.option.serverOption && 'key' in this.option.serverOption && 'cert' in this.option.serverOption) {
64
+ this.server = new HttpsServer(this.option.serverOption);
65
+ const httpServer = new HttpServer();
66
+ httpServer.on('request', (req: IncomingMessage, res: ServerResponse) => {
67
+ res.writeHead(301, {Location: `https://${req.headers.host}${req.url}`});
68
+ res.end();
69
+ });
70
+ httpServer.listen(80, this.option.listen.hostname, () => {
71
+ console.log('HTTP redirect server running on port 80');
72
+ });
73
+ } else if (this.option.serverOption) {
74
+ this.server = new HttpServer(this.option.serverOption);
75
+ } else {
76
+ this.server = new HttpServer();
77
+ }
78
+ // const thisRef = this;
79
+ this.server.on('request', async (req: IncomingMessage, res: ServerResponse) => {
80
+ // console.log('request', req.url);
81
+ const transactionManager = this.option.transactionManagerFactory ? await this.option.transactionManagerFactory() : undefined;
82
+ res.on('close', async () => {
83
+ if (this.option.closeEndPoints) {
84
+ for (const it of this.option.closeEndPoints) {
85
+ try {
86
+ const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target: it}) : it) as EndPoint;
87
+ const endPoint = execute?.endPoint(rr, this);
88
+ if (endPoint instanceof Promise) {
89
+ await endPoint;
90
+ }
91
+ } catch (e) {
119
92
  }
93
+ }
94
+ }
120
95
 
121
- const otherStorage = new Map<ConstructorType<any>, any>();
122
- otherStorage.set(RequestResponse, rr);
123
- otherStorage.set(IncomingMessage, req);
124
- otherStorage.set(ServerResponse, res);
96
+ if (!rr.resIsDone()) {
97
+ rr.resEnd();
98
+ }
99
+ });
100
+ res.on('error', async () => {
101
+ if (this.option.errorEndPoints) {
102
+ for (const it of this.option.errorEndPoints) {
125
103
  try {
126
- transactionManager?.try();
127
- if (this.option.requestEndPoints) {
128
- for (const it of this.option.requestEndPoints) {
129
- try {
130
- const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim<EndPoint>({target:it}) : it) as EndPoint;
131
- execute?.endPoint(rr, this);
132
- } catch (e) {
133
- }
134
- }
135
- }
104
+ const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target: it}) : it) as EndPoint;
105
+ const endPoint = execute?.endPoint(rr, this);
106
+ if (endPoint instanceof Promise) {
107
+ await endPoint;
108
+ }
109
+ } catch (e) {
110
+ }
111
+ }
112
+ }
136
113
 
137
- const filter = {
138
- carrier: new Map<string, any>(),
139
- filters: [] as { filter: Filter, sw: boolean }[]
140
- };
141
- for (let i = 0; this.option.filters && i < this.option.filters.length; i++) {
142
- const it = this.option.filters[i];
143
- const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as Filter;
144
- let sw = true;
145
- if (execute?.proceedBefore) {
146
- sw = await execute.proceedBefore({rr, app: this, carrier: filter.carrier});
147
- filter.filters.push({filter: execute, sw});
148
- }
149
- if (!sw) {
150
- break;
151
- }
152
- }
114
+ if (!rr.resIsDone()) {
115
+ rr.resEnd();
116
+ }
117
+ });
153
118
 
154
- // body.. something..
155
- if (!rr.resIsDone()) {
156
- const routerModule = await super.routing(rr.reqIntent);
157
- otherStorage.set(RouterModule, routerModule);
158
- const moduleInstance = routerModule?.getModuleInstance?.();
159
- let methods: SaveMappingConfig[] = [];
160
- if (routerModule && moduleInstance) {
161
- // router 클래스 내부에서 선언된 Route일때
162
- if (routerModule.propertyKeys) {
163
- const map = routerModule.propertyKeys?.map((it: string | symbol) => {
164
- return {propertyKey: it, config: getUrlMapping(moduleInstance, it)} as SaveMappingConfig
165
- });
166
- methods.push(...(map ?? []));
167
- } else {
168
- methods.push(...(getUrlMappings(moduleInstance).filter(it => !getRoute(moduleInstance, it.propertyKey)) ?? []));
169
- }
119
+ const rr = new RequestResponse(req, res, {sessionManager: this.sessionManager, option: this.option});
120
+ /*
121
+ default setting first
122
+ */
123
+ rr.resSetHeader(HttpHeaders.Server, 'simple-boot-http-server');
124
+ const cookie = rr.reqCookieGet(this.option.sessionOption.key);
125
+ if (!cookie) {
126
+ const session = await this.sessionManager.session();
170
127
 
171
- // options로 요청오면은 allow로 넣고 그냥 200처리해야됨.
172
- if (rr.reqMethod()?.toUpperCase() === HttpMethod.OPTIONS.toUpperCase()) {
173
- rr.resSetHeader(HttpHeaders.Allow, methods.map(it => it.config.method).join(', '));
174
- rr.resStatusCode(HttpStatus.Ok);
175
- }
128
+ const cookieParts: string[] = [];
129
+ cookieParts.push(`${this.option.sessionOption.key}=${session.uuid}`);
130
+ cookieParts.push(`Path=${this.option.sessionOption.path}`);
131
+ if (this.option.sessionOption.httpOnly) cookieParts.push('HttpOnly');
132
+ if (this.option.sessionOption.secure) cookieParts.push('Secure');
133
+ if (this.option.sessionOption.sameSite != null && this.option.sessionOption.sameSite) cookieParts.push(`SameSite=${this.option.sessionOption.sameSite}`);
134
+ const maxAge = (this.option.sessionOption as any).maxAge ?? (this.sessionManager.sessionOption)?.maxAge;
135
+ if (maxAge != null) cookieParts.push(`Max-Age=${maxAge}`);
136
+ rr.resSetHeader(HttpHeaders.SetCookie, cookieParts.join('; '));
137
+ }
176
138
 
177
- // method 찾기
178
- methods = methods.filter(it => it && it.propertyKey && it.config && rr.reqMethod()?.toUpperCase() === it.config.method.toUpperCase());
179
- methods.sort((a, b) => {
180
- return ((b.config?.req?.contentType?.length ?? 0) + (b.config?.req?.accept?.length ?? 0)) - ((a.config?.req?.contentType?.length ?? 0) + (a.config?.req?.accept?.length ?? 0));
181
- });
182
- methods = methods
183
- .filter(it => it.config?.req?.contentType ? (!!it.config?.req?.contentType?.find(sit => rr.reqHasContentTypeHeader(sit))) : true)
184
- .filter(it => it.config?.req?.accept ? (!!it.config?.req?.accept?.find(sit => rr.reqHasAcceptHeader(sit))) : true);
139
+ const otherStorage = new Map<ConstructorType<any>, any>();
140
+ otherStorage.set(RequestResponse, rr);
141
+ otherStorage.set(IncomingMessage, req);
142
+ otherStorage.set(ServerResponse, res);
143
+ try {
144
+ transactionManager?.try();
145
+ if (this.option.requestEndPoints) {
146
+ for (const it of this.option.requestEndPoints) {
147
+ try {
148
+ const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim<EndPoint>({target: it}) : it) as EndPoint;
149
+ execute?.endPoint(rr, this);
150
+ } catch (e) {
151
+ }
152
+ }
153
+ }
185
154
 
186
- if (methods[0]) {
187
- const it = methods[0];
188
- const paramTypes = ReflectUtils.getParameterTypes(moduleInstance, it.propertyKey)
189
- const injects = getInject(moduleInstance, it.propertyKey);
190
- const validIndexs = getValidIndex(moduleInstance, it.propertyKey);
191
- if (injects) {
192
- const isJson = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_JSON_BODY);
193
- const isFormUrl = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_FORM_URL_BODY);
194
- const isTransactionManager = injects.find(it => it.config?.situationType === InjectSituationType.TransactionManager);
195
- const siturationContainers = new SituationTypeContainers();
196
- if (isJson) {
197
- let data = await rr.reqBodyJsonData()
198
- if (isJson.type) {
199
- data = Object.assign(new isJson.type(), data);
200
- }
201
- if (validIndexs.includes(isJson.index)) {
202
- const inValid = execValidationInValid(data);
203
- if ((inValid?.length ?? 0) > 0) {
204
- throw new ValidException(inValid);
205
- }
206
- }
207
- siturationContainers.push(new SituationTypeContainer({
208
- situationType: UrlMappingSituationType.REQ_JSON_BODY,
209
- data
210
- }));
211
- }
212
- if (isFormUrl) {
213
- let data = await rr.reqBodyFormUrlData()
214
- if (isFormUrl.type) {
215
- data = Object.assign(new isFormUrl.type(), data);
216
- }
217
- if (validIndexs.includes(isFormUrl.index)) {
218
- const inValid = execValidationInValid(data);
219
- if ((inValid?.length ?? 0) > 0) {
220
- throw new ValidException(inValid);
221
- }
222
- }
223
- siturationContainers.push(new SituationTypeContainer({situationType: UrlMappingSituationType.REQ_FORM_URL_BODY, data}));
224
- }
155
+ const filter = {
156
+ carrier: new Map<string, any>(),
157
+ filters: [] as { filter: Filter, sw: boolean }[]
158
+ };
159
+ for (let i = 0; this.option.filters && i < this.option.filters.length; i++) {
160
+ const it = this.option.filters[i];
161
+ const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target: it}) : it) as Filter;
162
+ let sw = true;
163
+ if (execute?.proceedBefore) {
164
+ sw = await execute.proceedBefore({rr, app: this, carrier: filter.carrier});
165
+ filter.filters.push({filter: execute, sw});
166
+ }
167
+ if (!sw) {
168
+ break;
169
+ }
170
+ }
225
171
 
226
- if (isTransactionManager && isTransactionManager.type && transactionManager && transactionManager.hasTransaction(isTransactionManager.type)) {
227
- let data = await transactionManager.getTransaction(isTransactionManager.type);
228
- if (data) {
229
- data = await data.try(isTransactionManager.config.argument);
230
- siturationContainers.push(new SituationTypeContainer({situationType: InjectSituationType.TransactionManager, data, index: isTransactionManager.index}));
231
- }
232
- }
233
- if (siturationContainers.length) {
234
- otherStorage.set(SituationTypeContainers, siturationContainers);
235
- }
236
- }
172
+ // body.. something..
173
+ if (!rr.resIsDone()) {
174
+ const routerModule = await super.routing(rr.reqIntent);
175
+ otherStorage.set(RouterModule, routerModule);
176
+ const moduleInstance = routerModule?.getModuleInstance?.();
177
+ let methods: SaveMappingConfig[] = [];
178
+ if (routerModule && moduleInstance) {
179
+ // router 클래스 내부에서 선언된 Route일때
180
+ if (routerModule.propertyKeys) {
181
+ const map = routerModule.propertyKeys?.map((it: string | symbol) => {
182
+ return {propertyKey: it, config: getUrlMapping(moduleInstance, it)} as SaveMappingConfig
183
+ });
184
+ methods.push(...(map ?? []));
185
+ } else {
186
+ methods.push(...(getUrlMappings(moduleInstance).filter(it => !getRoute(moduleInstance, it.propertyKey)) ?? []));
187
+ }
237
188
 
238
- for (const paramType of paramTypes) {
239
- if (paramType === ReqFormUrlBody) {
240
- otherStorage.set(ReqFormUrlBody, await rr.reqBodyReqFormUrlBody())
241
- } else if (paramType === ReqJsonBody) {
242
- otherStorage.set(ReqJsonBody, await rr.reqBodyReqJsonBody())
243
- } else if (paramType === URLSearchParams) {
244
- otherStorage.set(URLSearchParams, rr.reqUrlSearchParams)
245
- } else if (paramType === ReqMultipartFormBody) {
246
- otherStorage.set(ReqMultipartFormBody, rr.reqBodyMultipartFormData())
247
- } else if (paramType === ReqHeader) {
248
- otherStorage.set(ReqHeader, rr.reqHeaderObj)
249
- }
250
- }
189
+ // options로 요청오면은 allow로 넣고 그냥 200처리해야됨.
190
+ if (rr.reqMethod()?.toUpperCase() === HttpMethod.OPTIONS.toUpperCase()) {
191
+ rr.resSetHeader(HttpHeaders.Allow, methods.map(it => it.config.method).join(', '));
192
+ rr.resStatusCode(HttpStatus.Ok);
193
+ }
251
194
 
252
- // execute !!!
253
- let data = await this.simstanceManager.executeBindParameterSimPromise({
254
- target: moduleInstance,
255
- targetKey: it.propertyKey
256
- }, otherStorage);
257
- /*
258
- 여기에서 정해진 타입 리턴에 따른 조치
259
- ...
260
- */
261
- if (it.config?.resolver) {
262
- const execute = typeof it.config.resolver === 'function' ? this.simstanceManager.getOrNewSim({target:it.config.resolver}) : it.config.resolver;
263
- data = await execute?.resolve?.(data, rr);
264
- }
265
- const status = it.config?.res?.status ?? HttpStatus.Ok;
266
- const headers = it.config?.res?.header ?? {};
267
- if (it.config?.res?.contentType) {
268
- headers[HttpHeaders.ContentType] = it.config?.res?.contentType;
269
- }
270
- if ((it.config?.res?.contentType?.toLowerCase().indexOf(Mimes.ApplicationJson.toLowerCase()) ?? -1) > -1) {
271
- data = JSON.stringify(data);
272
- } else if (data && typeof data === 'object') {
273
- data = JSON.stringify(data);
274
- }
275
- rr.resSetHeaders(headers)
276
- rr.resSetStatusCode(status);
277
- rr.resWrite(data);
278
- }
279
- }
195
+ // method 찾기
196
+ methods = methods.filter(it => it && it.propertyKey && it.config && rr.reqMethod()?.toUpperCase() === it.config.method.toUpperCase());
197
+ methods.sort((a, b) => {
198
+ return ((b.config?.req?.contentType?.length ?? 0) + (b.config?.req?.accept?.length ?? 0)) - ((a.config?.req?.contentType?.length ?? 0) + (a.config?.req?.accept?.length ?? 0));
199
+ });
200
+ methods = methods
201
+ .filter(it => it.config?.req?.contentType ? (!!it.config?.req?.contentType?.find(sit => rr.reqHasContentTypeHeader(sit))) : true)
202
+ .filter(it => it.config?.req?.accept ? (!!it.config?.req?.accept?.find(sit => rr.reqHasAcceptHeader(sit))) : true);
280
203
 
281
- if (this.option.noSuchRouteEndPointMappingThrow && methods.length <= 0 && rr.reqMethod()?.toUpperCase() !== HttpMethod.OPTIONS) {
282
- throw this.option.noSuchRouteEndPointMappingThrow(rr);
204
+ if (methods[0]) {
205
+ const it = methods[0];
206
+ const paramTypes = ReflectUtils.getParameterTypes(moduleInstance, it.propertyKey)
207
+ const injects = getInject(moduleInstance, it.propertyKey);
208
+ const validIndexs = getValidIndex(moduleInstance, it.propertyKey);
209
+ if (injects) {
210
+ const isPathData = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_PATH_DATA);
211
+ const isJson = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_JSON_BODY);
212
+ const isSearchParamsObj = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_URL_SEARCH_PARAMS_OBJ);
213
+ const isFormUrl = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_FORM_URL_BODY);
214
+ // 우선 다시 제거한다.. 트랜젝션 어떻게 할지 다시 생각
215
+ // const isTransactionManager = injects.find(it => it.config?.situationType === InjectSituationType.TransactionManager);
216
+ const siturationContainers = new SituationTypeContainers();
217
+ if (isPathData) {
218
+ let data = await routerModule.pathData
219
+ if (isPathData.type) {
220
+ data = Object.assign(new isPathData.type(), data);
221
+ }
222
+ if (validIndexs.includes(isPathData.index)) {
223
+ const inValid = execValidationInValid(data);
224
+ if ((inValid?.length ?? 0) > 0) {
225
+ throw new ValidException(inValid);
283
226
  }
227
+ }
228
+ siturationContainers.push(new SituationTypeContainer({
229
+ situationType: UrlMappingSituationType.REQ_PATH_DATA,
230
+ data
231
+ }));
284
232
  }
285
-
286
- // after
287
- for (const it of filter.filters.reverse()) {
288
- if (it.filter?.proceedAfter && !await it.filter.proceedAfter({rr, app:this, before: it.sw, carrier: filter.carrier})) {
289
- break;
233
+ if (isJson) {
234
+ let data = await rr.reqBodyJsonData();
235
+ if (data !== null && isJson.type) {
236
+ data = Object.assign(new isJson.type(), data);
237
+ }
238
+ if (validIndexs.includes(isJson.index)) {
239
+ const inValid = execValidationInValid(data);
240
+ if ((inValid?.length ?? 0) > 0) {
241
+ throw new ValidException(inValid);
290
242
  }
243
+ }
244
+ siturationContainers.push(new SituationTypeContainer({
245
+ situationType: UrlMappingSituationType.REQ_JSON_BODY,
246
+ data
247
+ }));
291
248
  }
292
- } catch (e) {
293
- transactionManager?.catch(e);
294
- rr.resStatusCode(e instanceof HttpError ? e.status : HttpStatus.InternalServerError)
295
- const execute = typeof this.option.globalAdvice === 'function' ? this.simstanceManager.getOrNewSim(this.option.globalAdvice) : this.option.globalAdvice;
296
- if (!execute) {
297
- rr.resEnd();
298
- // rr.resEnd().catch(e => {
299
- // });
300
- return;
249
+ if (isSearchParamsObj) {
250
+ let data = rr.reqUrlSearchParamsObj
251
+ if (validIndexs.includes(isSearchParamsObj.index)) {
252
+ const inValid = execValidationInValid(data);
253
+ if ((inValid?.length ?? 0) > 0) {
254
+ throw new ValidException(inValid);
255
+ }
256
+ }
257
+ siturationContainers.push(new SituationTypeContainer({
258
+ situationType: UrlMappingSituationType.REQ_URL_SEARCH_PARAMS_OBJ,
259
+ data
260
+ }));
301
261
  }
302
- if (e && typeof e === 'object') {
303
- otherStorage.set(e.constructor as ConstructorType<any>, e);
304
- otherStorage.set(SituationTypeContainer, new SituationTypeContainer({
305
- situationType: ExceptionHandlerSituationType.ERROR_OBJECT,
306
- data: e
307
- }));
262
+ if (isFormUrl) {
263
+ let data = await rr.reqBodyFormUrlData()
264
+ if (isFormUrl.type) {
265
+ data = Object.assign(new isFormUrl.type(), data);
266
+ }
267
+ if (validIndexs.includes(isFormUrl.index)) {
268
+ const inValid = execValidationInValid(data);
269
+ if ((inValid?.length ?? 0) > 0) {
270
+ throw new ValidException(inValid);
271
+ }
272
+ }
273
+ siturationContainers.push(new SituationTypeContainer({situationType: UrlMappingSituationType.REQ_FORM_URL_BODY, data}));
308
274
  }
309
- const target = targetExceptionHandler(execute, e);
310
- if (target) {
311
- await this.simstanceManager.executeBindParameterSimPromise({
312
- target: execute,
313
- targetKey: target.propertyKey
314
- }, otherStorage);
275
+ // 트랜젝션 우선 제거 나중에 어떻게 구현할지 생각..
276
+ // if (isTransactionManager && isTransactionManager.type && transactionManager && transactionManager.hasTransaction(isTransactionManager.type)) {
277
+ // let data = await transactionManager.getTransaction(isTransactionManager.type);
278
+ // if (data) {
279
+ // data = await data.try(isTransactionManager.config.argument);
280
+ // siturationContainers.push(new SituationTypeContainer({situationType: InjectSituationType.TransactionManager, data, index: isTransactionManager.index}));
281
+ // }
282
+ // }
283
+ if (siturationContainers.length) {
284
+ otherStorage.set(SituationTypeContainers, siturationContainers);
315
285
  }
316
- } finally {
317
- transactionManager?.finally();
318
- }
286
+ }
287
+
288
+ for (const paramType of paramTypes) {
289
+ if (paramType === ReqFormUrlBody) {
290
+ otherStorage.set(ReqFormUrlBody, await rr.reqBodyReqFormUrlBody())
291
+ } else if (paramType === ReqPathData) {
292
+ otherStorage.set(ReqPathData, routerModule.pathData)
293
+ } else if (paramType === ReqJsonBody) {
294
+ otherStorage.set(ReqJsonBody, await rr.reqBodyReqJsonBody())
295
+ } else if (paramType === ReqSearchParamsObj) {
296
+ otherStorage.set(ReqSearchParamsObj, rr.reqUrlSearchParamsObj)
297
+ } else if (paramType === URLSearchParams) {
298
+ otherStorage.set(URLSearchParams, rr.reqUrlSearchParams)
299
+ } else if (paramType === ReqMultipartFormBody) {
300
+ otherStorage.set(ReqMultipartFormBody, rr.reqBodyMultipartFormData())
301
+ } else if (paramType === ReqHeader) {
302
+ otherStorage.set(ReqHeader, rr.reqHeaderObj)
303
+ }
304
+ }
319
305
 
320
- if (!rr.resIsDone()) {
321
- rr.resEnd();
306
+ // execute !!!
307
+ let data = await this.simstanceManager.executeBindParameterSimPromise({
308
+ target: moduleInstance,
309
+ targetKey: it.propertyKey
310
+ }, otherStorage);
311
+ /*
312
+ 여기에서 정해진 타입 리턴에 따른 조치
313
+ ...
314
+ */
315
+ if (it.config?.resolver) {
316
+ const execute = typeof it.config.resolver === 'function' ? this.simstanceManager.getOrNewSim({target: it.config.resolver}) : it.config.resolver;
317
+ data = await execute?.resolve?.(data, rr);
318
+ }
319
+ const status = it.config?.res?.status ?? HttpStatus.Ok;
320
+ const headers = it.config?.res?.header ?? {};
321
+ if (it.config?.res?.contentType) {
322
+ headers[HttpHeaders.ContentType] = it.config?.res?.contentType;
323
+ }
324
+ if ((it.config?.res?.contentType?.toLowerCase().indexOf(Mimes.ApplicationJson.toLowerCase()) ?? -1) > -1) {
325
+ data = JSON.stringify(data);
326
+ } else if (data && typeof data === 'object') {
327
+ data = JSON.stringify(data);
328
+ }
329
+ rr.resSetHeaders(headers)
330
+ rr.resSetStatusCode(status);
331
+ rr.resWrite(data);
322
332
  }
323
- });
333
+ }
334
+
335
+ if (this.option.noSuchRouteEndPointMappingThrow && methods.length <= 0 && rr.reqMethod()?.toUpperCase() !== HttpMethod.OPTIONS) {
336
+ throw this.option.noSuchRouteEndPointMappingThrow(rr);
337
+ }
338
+ }
339
+
340
+ // after
341
+ for (const it of filter.filters.reverse()) {
342
+ if (it.filter?.proceedAfter && !await it.filter.proceedAfter({rr, app: this, before: it.sw, carrier: filter.carrier})) {
343
+ break;
344
+ }
345
+ }
346
+ } catch (e) {
347
+ console.error('request error:', e);
348
+ transactionManager?.catch(e);
349
+ rr.resStatusCode(e instanceof HttpError ? e.status : HttpStatus.InternalServerError)
350
+ const execute = typeof this.option.globalAdvice === 'function' ? this.simstanceManager.getOrNewSim(this.option.globalAdvice) : this.option.globalAdvice;
351
+ if (!execute) {
352
+ rr.resEnd();
353
+ // rr.resEnd().catch(e => {
354
+ // });
355
+ return;
356
+ }
357
+ if (e && typeof e === 'object') {
358
+ otherStorage.set(e.constructor as ConstructorType<any>, e);
359
+ otherStorage.set(SituationTypeContainer, new SituationTypeContainer({
360
+ situationType: ExceptionHandlerSituationType.ERROR_OBJECT,
361
+ data: e
362
+ }));
363
+ }
364
+ const target = targetExceptionHandler(execute, e);
365
+ if (target) {
366
+ await this.simstanceManager.executeBindParameterSimPromise({
367
+ target: execute,
368
+ targetKey: target.propertyKey
369
+ }, otherStorage);
370
+ }
371
+ } finally {
372
+ transactionManager?.finally();
373
+ }
374
+
375
+ if (!rr.resIsDone()) {
376
+ rr.resEnd();
377
+ }
378
+ });
324
379
 
325
- this.server.listen(this.option.listen.port, this.option.listen.hostname, this.option.listen.backlog, () => {
326
- this.option.listen.listeningListener?.(this, this.server);
380
+ if (this.option.webSocketEndPoints) {
381
+ const webSocketServer = new WebSocketServer({server: this.server});
382
+ const execute = this.option.webSocketEndPoints.map(it => typeof it === 'function' ? this.simstanceManager.getOrNewSim({target: it}) : it);
383
+ webSocketServer.on('connection', async (ws, request) => {
384
+ this.webSocketClients.set(ws, {request});
385
+ const wsSet = {socket: ws, request};
386
+ execute.forEach(it => it.connect?.(wsSet));
387
+ ws.on('error', err => execute.forEach(it => it.error?.(wsSet, err)));
388
+ ws.on('message', (data, isBinary) => execute.forEach(it => it.message(wsSet, {data, isBinary})));
389
+ ws.on('ping', () => execute.forEach(it => it.ping?.(wsSet)));
390
+ ws.on('close', () => {
391
+ this.webSocketClients.delete(ws);
392
+ execute.forEach(it => it.close?.(wsSet));
327
393
  });
394
+ });
328
395
  }
396
+ this.server.listen(this.option.listen.port, this.option.listen.hostname, this.option.listen.backlog, () => {
397
+ this.option.listen.listeningListener?.(this, this.server);
398
+ });
399
+ }
329
400
  }