@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,3 +1,5 @@
1
+ import { Mimes } from './Mimes';
2
+
1
3
  export const HttpHeaders = {
2
4
  ContentLength : 'Content-Length',
3
5
  ContentType : 'Content-Type',
@@ -38,6 +40,15 @@ export const HttpHeaders = {
38
40
  IfNoneMatch : 'If-None-Match',
39
41
  IfRange : 'If-Range',
40
42
  Allow : 'Allow',
41
- Server : 'Server'
43
+ Server : 'Server',
44
+ XSimpleBootSsrIntentScheme: 'x-simple-boot-ssr-intent-scheme',
45
+ XSimpleBootHttpTopicProtocol: 'x-simple-boot-http-topic-protocol'
42
46
  }
43
- export type HttpHeadersType = keyof typeof HttpHeaders;
47
+ export type HttpHeadersType = keyof typeof HttpHeaders;
48
+
49
+ export const makeIntentHeaderBySymbolFor = (symbol: Symbol): HeadersInit => {
50
+ return {
51
+ [HttpHeaders.Accept]: Mimes.ApplicationJsonPostSimpleBootSsrIntentScheme,
52
+ [HttpHeaders.XSimpleBootSsrIntentScheme]: `Symbol.for(${symbol.description})`
53
+ }
54
+ };
@@ -2,31 +2,49 @@ export enum HttpStatus {
2
2
  Ok = 200,
3
3
 
4
4
  /**
5
+ * Multiple Choices ⇢ 요청에 대해서 둘 이상의 가능한 응답이 있음을 나타낸다.
6
+ * 클라이언트가 동시에 여러 리소스를 가리키는 URL을 요청한 경우, 그 리소스의 목록과 함께 반환된다.
7
+ * 어떤 서버가 하나의 HTML 문서를 영어와 프랑스어 모두로 제공하는 경우 등에 사용할 수 있다.
8
+ * 그러나 응답 중 하나를 선택하는 표준화된 방법이 없기 때문에, 이 응답 코드는 실무에선 거의 사용되지 않는다.
9
+ */
10
+ MultipleChoices = 300,
11
+
12
+ /**
13
+ * 영구
5
14
  * HTTP 301 Moved Permanently 리디렉션 상태 응답 코드는 요청한 리소스가 Location 헤더에 주어진 URL로 완전히 옮겨졌다는 것을 나타냅니다. 브라우저는 이 페이지로 리디렉트하고, 검색 엔진은 해당 리소스로 연결되는 링크를 갱신합니다.
15
+ * Moved Permanently ⇢ 영구적으로 이동 (영구 리다이렉션)
16
+ * 요청된 리소스가 Location 헤더가 지정한 URL로 이동되었음을 나타낸다.
17
+ * 해당 URL로 리다이렉션 되면, 요청 메서드가 GET으로 변하고 본문이 제거될수 있다.
18
+ * 따라서 301 코드는 GET 또는 HEAD 방법에 대한 응답으로만 사용하고, 대신 POST, PUT 같은 경우는 같은 영구 리디렉션인 308 Permanent Redirect 을 사용하는 것이 좋다.
6
19
  */
7
20
  MovedPermanently = 301,
8
- /**
21
+
22
+ /** 임시
9
23
  * https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Status/302
10
24
  * HTTP(HyperText Transfer Protocol) 302 Found 리디렉션 상태 응답 코드는 요청한 리소스가 Location 헤더에 지정된 URL로 일시적으로 이동되었음을 나타냅니다. 브라우저는 이 페이지로 리디렉션되지만 검색 엔진은 리소스에 대한 링크를 업데이트하지 않습니다('SEO-speak'에서는 'link-juice'가 새 URL로 전송되지 않는다고 합니다).
11
25
  * 명세서에서 리디렉션이 수행될 때 메서드(및 본문)가 변경되지 않도록 요구하더라도 모든 사용자 에이전트가 이를 준수하는 것은 아닙니다. 여러분은 여전히 이러한 유형의 버그가 있는 소프트웨어를 찾을 수 있습니다. 따라서 따라서 302 코드는 GET 또는 HEAD 메서드에 대한 응답으로만 설정하고 이 경우 메서드 변경이 명시적으로 금지되므로 307 Temporary Redirect 를 대신 사용하는 것이 좋습니다.
12
26
  * 사용하던 메서드를 GET으로 변경하려는 경우, 303 See Other을 대신 사용하십시오. PUT 메서드에 대한 응답을 업로드된 리소스가 아니라 'You successfully updown XYZ'와 같은 확인 메시지로 주고 싶을때 유용합니다.
13
27
  */
14
28
  Found = 302,
29
+
15
30
  /**
16
31
  * HTTP(HyperText Transfer Protocol) 303 See Other 리디렉션 상태 응답 코드는 리디렉션이 요청한 리소스 자체에 연결되지 않고 다른 페이지(예: 확인 페이지, 실제 개체 표시(HTTP range-14 참조) 또는 업로드 진행률 페이지)에 연결됨을 나타냅니다. 이 응답 코드는 PUT 또는 POST의 결과로 다시 전송되는 경우가 많습니다. 이 리디렉션 페이지를 표시하는 데 사용되는 방법은 항상 GET입니다.
17
32
  */
18
33
  SeeOther = 303,
34
+
19
35
  /**
20
36
  * 클라이언트 리디렉션 응답 코드 304 Not Modified 는 요청된 리소스를 재전송할 필요가 없음을 나타낸다. 캐시된 자원으로의 암묵적인 리디렉션이다. 이 는 GET 나 HEAD 요청처럼 요청 방법이 안전 한 경우 또는 요청이 조건부로 If-None-Match 또는 If-Modified-Since 헤더를 사용할 때 응답 된다.
21
37
  * 이에 상응하는 200 OK 응답에는 Cache-Control, Content-Location, Date, ETag, Expires, 그리고 Vary 가 포함되어 있었을 것이다.
22
38
  */
23
39
  NotModified = 304,
40
+
24
41
  /**
25
42
  * HTTP 307 Temporary Redirect 리다이렉트 상태 응답 코드는 요청한 리소스가 Location 헤더에 주어진 URL 로 임시로 옮겨졌다는 것을 나타냅니다.
26
43
  * 원래 요청한 메소드와 Body 를 재사용하여 요청을 리다이렉트 합니다. 여기서 메소드를 GET으로 바꾸기 위해서 303 See Other를 사용하시면 됩니다. 이것은 PUT요청에 업로드된 리소스가 아닌 "You successfully uploaded XYZ"와 같은 확인메시지 응답을 제공 하는데에 유용합니다.
27
44
  * 307과 302가 유일하게 다른점은 307은 Method 와 Body 를 변경하지 않고 리다이렉트 요청을 하도록 보장합니다. 302응답으로 인하여 일부 오래된 클라이언트들은 메소드를 GET으로 틀리게 변경하였습니다. GET이 아닌 다른 메소드에 302동작은 웹에서 예상되지 않지만 307 동작은 예상할수 있습니다. GET 요청에 대해서는 동일하게 동작 합니다.
28
45
  */
29
46
  TemporaryRedirect = 307,
47
+
30
48
  /**
31
49
  * 하이퍼텍스트 전송 프로토콜 (HTTP) 308 Permanent Redirect 리디렉션 상태 응답 코드는 요청된 리소스가 Location 헤더에 지정된 URL로 확실히 이동되었음을 나타냅니다. 브라우저가 이 페이지로 리디렉션되고 검색엔진은 리소스에 대한 링크를 업데이트합니다('SEO-speak'에서는 'link-juice'가 새 URL로 전송됩니다).
32
50
  * 요청 메서드와 본문은 변경되지 않지만, 301은 때때로 GET 메서드로 잘못 변경될 수 있습니다.
@@ -1,27 +1,29 @@
1
1
  export enum Mimes {
2
- ApplicationJson = 'application/json',
3
- ApplicationOctetStream = 'application/octet-stream',
4
- ApplicationXml = 'application/xml',
5
- ApplicationJsonPatch = 'application/json-patch+json',
6
- ApplicationXWwwFormUrlencoded = 'application/x-www-form-urlencoded',
7
- TextPlain = 'text/plain',
8
- TextHtml = 'text/html',
9
- All = '*/*',
10
- TextCss = 'text/css',
11
- TextJavascript = 'text/javascript',
12
- TextXml = 'text/xml',
13
- TextXslt = 'text/xslt',
14
- TextXmlDtd = 'text/xml-dtd',
15
- TextPlainUtf8 = 'text/plain; charset=utf-8',
16
- ImagePng = 'image/png',
17
- ImageGif = 'image/gif',
18
- ImageJpeg = 'image/jpeg',
19
- ImageSvg = 'image/svg+xml',
20
- ImageBmp = 'image/bmp',
21
- ImageTiff = 'image/tiff',
22
- ImagePdf = 'application/pdf',
23
- ImageXBmp = 'image/x-bmp',
24
- ImageXpixmap = 'image/x-xpixmap',
25
- ImageXxbm = 'image/x-xbm',
26
- MultipartFormData = 'multipart/form-data',
2
+ ApplicationJson = 'application/json',
3
+ ApplicationOctetStream = 'application/octet-stream',
4
+ ApplicationXml = 'application/xml',
5
+ ApplicationJsonPatch = 'application/json-patch+json',
6
+ ApplicationXWwwFormUrlencoded = 'application/x-www-form-urlencoded',
7
+ TextPlain = 'text/plain',
8
+ TextHtml = 'text/html',
9
+ All = '*/*',
10
+ TextCss = 'text/css',
11
+ TextJavascript = 'text/javascript',
12
+ TextXml = 'text/xml',
13
+ TextXslt = 'text/xslt',
14
+ TextXmlDtd = 'text/xml-dtd',
15
+ TextPlainUtf8 = 'text/plain; charset=utf-8',
16
+ ImagePng = 'image/png',
17
+ ImageGif = 'image/gif',
18
+ ImageJpeg = 'image/jpeg',
19
+ ImageSvg = 'image/svg+xml',
20
+ ImageBmp = 'image/bmp',
21
+ ImageTiff = 'image/tiff',
22
+ ImagePdf = 'application/pdf',
23
+ ImageXBmp = 'image/x-bmp',
24
+ ImageXpixmap = 'image/x-xpixmap',
25
+ ImageXxbm = 'image/x-xbm',
26
+ MultipartFormData = 'multipart/form-data',
27
+ ApplicationJsonPostSimpleBootSsrIntentScheme = 'application/json-post+simple-boot-ssr-intent-scheme',
28
+ Intent = 'intent'
27
29
  }
@@ -1,12 +1,15 @@
1
- import { ConstructorType } from '@dooboostore/core/types';
2
- import { ReflectMethod } from '@dooboostore/simple-boot/types/Types';
3
- import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';
1
+ import { ConstructorType } from '@dooboostore/core';
2
+ import { ReflectMethod } from '@dooboostore/simple-boot';
3
+ import { ReflectUtils } from '@dooboostore/core';
4
4
  import { Resolver } from '../resolvers/Resolver';
5
5
  import { Mimes } from '../codes/Mimes';
6
6
  import { HttpMethod } from '../codes/HttpMethod';
7
7
 
8
8
  export enum UrlMappingSituationType {
9
9
  REQ_JSON_BODY = 'SIMPLE_BOOT_HTTP_SERVER://URLMAPPING/REQ_JSON_BODY',
10
+ REQ_PATH_DATA = 'SIMPLE_BOOT_HTTP_SERVER://URLMAPPING/REQ_PATH_DATA',
11
+ // REQ_URL_SEARCH_PARAMS = 'SIMPLE_BOOT_HTTP_SERVER://URLMAPPING/REQ_URL_SEARCH_PARAMS',
12
+ REQ_URL_SEARCH_PARAMS_OBJ = 'SIMPLE_BOOT_HTTP_SERVER://URLMAPPING/REQ_URL_SEARCH_PARAMS_OBJ',
10
13
  REQ_FORM_URL_BODY = 'SIMPLE_BOOT_HTTP_SERVER://URLMAPPING/REQ_FORM_URL_BODY'
11
14
  }
12
15
  export type MappingConfig = {
@@ -0,0 +1,12 @@
1
+ import { RawData, WebSocket } from 'ws';
2
+ import { IncomingMessage } from 'http';
3
+
4
+ export type WebSocketSet ={ socket: WebSocket, request: IncomingMessage };
5
+ export interface WebSocketEndPoint {
6
+
7
+ connect?(wsSet: WebSocketSet): void;
8
+ ping?(wsSet: WebSocketSet): void;
9
+ close?(wsSet: WebSocketSet): void;
10
+ message(wsSet: WebSocketSet, data: {data: RawData, isBinary: boolean}): void;
11
+ error?(wsSet: WebSocketSet, error: Error): void;
12
+ }
@@ -4,85 +4,63 @@ import { RequestResponse } from '../models/RequestResponse';
4
4
  import { SimpleBootHttpServer } from '../SimpleBootHttpServer';
5
5
  import * as fs from 'fs';
6
6
  import * as path from 'path';
7
- import { FileUtils } from '@dooboostore/core-node/file/FileUtils';
8
- import { ConvertUtils } from '@dooboostore/core-node/convert/ConvertUtils';
9
- import { RandomUtils } from '@dooboostore/core/random/RandomUtils';
7
+ import { FileUtils } from '@dooboostore/core-node';
8
+ import { ConvertUtils } from '@dooboostore/core-node';
9
+ import { RandomUtils } from '@dooboostore/core';
10
10
 
11
- export type CacheFilterSessionType = { key: string, lifeTime: number, isUpdate: boolean, responseHeaders?: string[] };
11
+ export type CacheFilterSessionType = { key: string; lifeTime: number; isUpdate: boolean; responseHeaders?: string[] };
12
12
 
13
- type CacheConfigCacheItemType = { path: string, createTime: number, lifeTime: number, responseHeader: { [key: string]: string | number | string[] } };
13
+ type CacheConfigCacheItemType = { path: string; createTime: number; lifeTime: number; responseHeader: { [key: string]: string | number | string[] } };
14
14
 
15
- type KeyAndConfig = { key: string, lifeTime?: number, responseHeaders?: string[] } ;
15
+ type KeyAndConfig = { key: string; lifeTime?: number; responseHeaders?: string[] };
16
16
 
17
17
  export class CacheFilter implements Filter {
18
+ public static readonly SYMBOL = Symbol.for('CacheFilter');
18
19
  public static readonly CARRIER_KEY_NAME = '_CARRIER_CACHE_FILTER_KEY_NAME';
19
20
  private storage = new Map<string, string | Buffer>();
20
21
  private cacheConfig: {
21
22
  createDate: string;
22
23
  updateDate: string;
23
- caches: { [key: string]: CacheConfigCacheItemType }
24
- }
25
-
26
- constructor(private config: {
27
- config: {
28
- cacheDir?: string;
29
- lifeTime: number;
30
- startUpClean?: boolean;
31
- },
32
- filter?: (rr: RequestResponse, app: SimpleBootHttpServer) => boolean;
33
- key: (rr: RequestResponse, app: SimpleBootHttpServer) => KeyAndConfig;
34
- }) {
35
-
24
+ caches: { [key: string]: CacheConfigCacheItemType };
25
+ };
26
+
27
+ constructor(
28
+ private config: {
29
+ config: {
30
+ cacheDir?: string;
31
+ lifeTime: number;
32
+ startUpClean?: boolean;
33
+ };
34
+ filter?: (rr: RequestResponse, app: SimpleBootHttpServer) => boolean;
35
+ key: (rr: RequestResponse, app: SimpleBootHttpServer) => KeyAndConfig;
36
+ }
37
+ ) {
36
38
  if (config.config.cacheDir && config.config.startUpClean) {
37
- FileUtils.deleteSync(config.config.cacheDir, {options: {recursive: true}});
39
+ FileUtils.deleteSync(config.config.cacheDir, { options: { recursive: true } });
38
40
  }
39
41
  }
40
42
 
41
- async onInit(app: SimpleBootHttpServer) {
42
- }
43
+ async onInit(app: SimpleBootHttpServer) {}
43
44
 
44
- async proceedBefore({rr, app, carrier}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {
45
+ async proceedBefore({ rr, app, carrier }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
45
46
  // this.key = undefined;
46
47
  // this.lifeTime = undefined;
47
48
  // this.isUpdate = false;
48
- const filter = this.config.filter?.(rr,app);
49
+ const filter = this.config.filter?.(rr, app);
49
50
  if (!filter) {
50
51
  return true;
51
52
  }
52
- if (this.config.config.cacheDir) {
53
- FileUtils.mkdirSync(this.config.config.cacheDir, {recursive: true});
54
- }
55
- if (!this.cacheConfig && this.config.config.cacheDir) {
56
- try {
57
- this.cacheConfig = JSON.parse(ConvertUtils.toString(FileUtils.readSync([this.config.config.cacheDir, 'cacheConfig.json'], { option: {encoding: 'utf-8'}})));
58
- } catch (e) {
59
- }
60
- }
61
- const date = new Date().toISOString();
62
- this.cacheConfig ??= {
63
- createDate: date,
64
- updateDate: date,
65
- // accessDate: date,
66
- caches: {}
67
- };
68
- this.cacheConfig.createDate ??= date;
69
- this.cacheConfig.updateDate ??= date;
70
- // this.cacheConfig.accessDate ??= date;
71
- this.cacheConfig.caches ??= {};
72
-
73
-
53
+ this.initCacheConfig();
74
54
  const rkey = this.config.key(rr, app);
75
55
  // console.log('--path filter', rr.reqMethod(), rr.reqUrlPathName, filter, rkey)
76
- const sessionData: CacheFilterSessionType = {key: rkey.key, lifeTime: rkey.lifeTime ?? this.config.config.lifeTime, isUpdate: false, responseHeaders: rkey.responseHeaders};
77
-
56
+ const sessionData: CacheFilterSessionType = { key: rkey.key, lifeTime: rkey.lifeTime ?? this.config.config.lifeTime, isUpdate: false, responseHeaders: rkey.responseHeaders };
78
57
 
79
58
  const cache = this.cacheConfig.caches[sessionData.key];
80
59
  if (cache) {
81
60
  const existes = this.config.config.cacheDir ? FileUtils.existsSync(cache.path) : this.storage.has(cache.path);
82
61
  const diffTime = Date.now() - cache.createTime;
83
62
  if (!existes || diffTime > cache.lifeTime) {
84
- delete this.cacheConfig[sessionData.key];
85
- this.deleteChunk(cache.path);
63
+ this.clear(sessionData.key);
86
64
  sessionData.isUpdate = true;
87
65
  } else {
88
66
  rr.resSetHeaders({
@@ -92,10 +70,10 @@ export class CacheFilter implements Filter {
92
70
  // console.log('chunk--->', cache.path);
93
71
  try {
94
72
  const chunk = this.getChunk(cache.path);
95
- // console.log('chunk--->', chunk);
96
- await rr.resEnd(chunk);
73
+ // console.log('chunk--->', chunk);
74
+ await rr.resEnd(chunk);
97
75
  } catch (e) {
98
- console.log('--------e', e)
76
+ console.log('--------e', e);
99
77
  }
100
78
  }
101
79
  } else {
@@ -105,6 +83,73 @@ export class CacheFilter implements Filter {
105
83
  return sessionData.isUpdate;
106
84
  }
107
85
 
86
+ public async refresh(path: string, app: SimpleBootHttpServer) {
87
+ // 1. 기존 캐시 파일 삭제
88
+ this.clear(path);
89
+
90
+ // 2. HTTP Fetch를 통한 외부 호출 (GET)
91
+ // 아키텍트님의 지시에 따라 네트워크 레이어를 통해 정석대로 호출합니다.
92
+ const url = `${app.option.protocol}://${app.option.hostname}:${app.option.port}${path}`;
93
+ try {
94
+ await fetch(url, {
95
+ method: 'GET',
96
+ headers: {
97
+ 'x-cache-force-refresh': 'true',
98
+ 'User-Agent': 'SimpleBootHttpServer-Internal-Refresh'
99
+ }
100
+ });
101
+ } catch (e) {
102
+ console.error('CacheFilter.refresh fetch error:', e);
103
+ }
104
+ }
105
+
106
+ public clear(key: string) {
107
+ this.initCacheConfig();
108
+ const cache = this.cacheConfig.caches[key];
109
+ if (cache) {
110
+ this.deleteChunk(cache.path);
111
+ delete this.cacheConfig.caches[key];
112
+ this.saveCacheConfig();
113
+ }
114
+ }
115
+
116
+ public clearAll() {
117
+ this.initCacheConfig();
118
+ Object.keys(this.cacheConfig.caches).forEach(key => {
119
+ this.deleteChunk(this.cacheConfig.caches[key].path);
120
+ });
121
+ this.cacheConfig.caches = {};
122
+ this.saveCacheConfig();
123
+ }
124
+
125
+ private initCacheConfig() {
126
+ if (this.config.config.cacheDir) {
127
+ FileUtils.mkdirSync(this.config.config.cacheDir, { recursive: true });
128
+ }
129
+ if (!this.cacheConfig && this.config.config.cacheDir) {
130
+ try {
131
+ this.cacheConfig = JSON.parse(ConvertUtils.toString(FileUtils.readSync([this.config.config.cacheDir, 'cacheConfig.json'], { option: { encoding: 'utf-8' } })));
132
+ } catch (e) {}
133
+ }
134
+ const date = new Date().toISOString();
135
+ this.cacheConfig ??= {
136
+ createDate: date,
137
+ updateDate: date,
138
+ // accessDate: date,
139
+ caches: {}
140
+ };
141
+ this.cacheConfig.createDate ??= date;
142
+ this.cacheConfig.updateDate ??= date;
143
+ // this.cacheConfig.accessDate ??= date;
144
+ this.cacheConfig.caches ??= {};
145
+ }
146
+
147
+ private saveCacheConfig() {
148
+ if (this.config.config.cacheDir && this.cacheConfig) {
149
+ FileUtils.write(JSON.stringify(this.cacheConfig), { path: [this.config.config.cacheDir, 'cacheConfig.json'] });
150
+ }
151
+ }
152
+
108
153
  private deleteChunk(path: string) {
109
154
  if (this.config.config.cacheDir && FileUtils.existsSync(path)) {
110
155
  FileUtils.deleteFileSync(path);
@@ -117,29 +162,31 @@ export class CacheFilter implements Filter {
117
162
  return this.config.config.cacheDir ? FileUtils.readSync(path) : this.storage.get(path);
118
163
  }
119
164
 
120
- async proceedAfter({rr, app, carrier}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {
165
+ async proceedAfter({ rr, app, carrier }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
121
166
  // const data = await rr.resBodyStringData()
122
- const sessionData = carrier.get(CacheFilter.CARRIER_KEY_NAME) as CacheFilterSessionType ;
167
+ const sessionData = carrier.get(CacheFilter.CARRIER_KEY_NAME) as CacheFilterSessionType;
123
168
  if (sessionData && sessionData.isUpdate) {
124
169
  try {
125
170
  if (this.config.config.cacheDir) {
126
- FileUtils.mkdirSync([this.config.config.cacheDir, 'caches'], {recursive: true});
171
+ FileUtils.mkdirSync([this.config.config.cacheDir, 'caches'], { recursive: true });
127
172
  }
128
173
  const resBody = rr.resBodyData();
129
174
  if (!resBody) {
130
175
  return true;
131
176
  }
132
- let p: string | undefined = undefined;
177
+ let p: string | undefined = undefined;
133
178
  const destFileUUID = RandomUtils.uuid4();
134
179
  p = this.writeChunk(destFileUUID, resBody);
135
180
  const updateDateNow = Date.now();
136
181
  const updateDate = new Date(updateDateNow).toISOString();
137
182
  this.cacheConfig.createDate ??= updateDate;
138
183
  this.cacheConfig.updateDate = updateDate;
139
- const responseHeaders: {[key: string]: string | number | string[]} = {}
140
- sessionData.responseHeaders?.map(it=>it.toLowerCase()).forEach(it => {
141
- responseHeaders[it] = rr.resHeader(it);
142
- })
184
+ const responseHeaders: { [key: string]: string | number | string[] } = {};
185
+ sessionData.responseHeaders
186
+ ?.map(it => it.toLowerCase())
187
+ .forEach(it => {
188
+ responseHeaders[it] = rr.resHeader(it);
189
+ });
143
190
  this.cacheConfig.caches[sessionData.key] = {
144
191
  path: p,
145
192
  createTime: updateDateNow,
@@ -147,20 +194,18 @@ export class CacheFilter implements Filter {
147
194
  responseHeader: responseHeaders
148
195
  };
149
196
 
150
- if (this.config.config.cacheDir) {
151
- FileUtils.write(JSON.stringify(this.cacheConfig), {path: [this.config.config.cacheDir, 'cacheConfig.json']});
152
- }
197
+ this.saveCacheConfig();
153
198
  } catch (e) {
154
- console.log('---', e)
199
+ console.log('---', e);
155
200
  }
156
201
  }
157
202
 
158
203
  return true;
159
204
  }
160
205
 
161
- private writeChunk(destFileUUID: string, resBody: string | Buffer ) {
206
+ private writeChunk(destFileUUID: string, resBody: string | Buffer) {
162
207
  if (this.config.config.cacheDir) {
163
- return FileUtils.write(resBody, {path: [this.config.config.cacheDir, 'caches', destFileUUID]});
208
+ return FileUtils.write(resBody, { path: [this.config.config.cacheDir, 'caches', destFileUUID] });
164
209
  } else {
165
210
  this.storage.set(destFileUUID, resBody);
166
211
  return destFileUUID;
@@ -0,0 +1,69 @@
1
+ import { Filter } from './Filter';
2
+ import { HttpHeaders } from '../codes/HttpHeaders';
3
+ import { Intent } from '@dooboostore/simple-boot';
4
+ import { IntentManager } from '@dooboostore/simple-boot';
5
+ import { Sim } from '@dooboostore/simple-boot';
6
+ import { HttpStatus } from '../codes/HttpStatus';
7
+ import { RequestResponse } from '../models/RequestResponse';
8
+ import { SimpleBootHttpServer } from '../SimpleBootHttpServer';
9
+ import { Mimes } from '../codes/Mimes';
10
+ import { NotFoundError } from '../errors/NotFoundError';
11
+
12
+ @Sim
13
+ export class IntentSchemeFilter implements Filter {
14
+ constructor(private intentManager: IntentManager) {}
15
+
16
+ async onInit(app: SimpleBootHttpServer) {}
17
+
18
+ async proceedBefore({ rr, app }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
19
+ // const rr = rrr;
20
+ const url = rr.reqUrl;
21
+ const contentLength = Number(rr.reqHeader(HttpHeaders.ContentLength.toLowerCase() ?? '0'));
22
+ const acceptType = rr.reqHeader(HttpHeaders.Accept);
23
+ const contentType = rr.reqHeader(HttpHeaders.ContentType);
24
+ const intentScheme = rr.reqHeader(HttpHeaders.XSimpleBootSsrIntentScheme);
25
+ if (acceptType === Mimes.ApplicationJsonPostSimpleBootSsrIntentScheme && intentScheme) {
26
+ let intent = new Intent(`${intentScheme}:/${url}`);
27
+ // console.log('---------1--intent request', intentScheme, url, contentLength, contentType );
28
+ // const responseHeader = {} as any;
29
+ // responseHeader[HttpHeaders.ContentType] = Mimes.ApplicationJson;
30
+ if (contentLength > 0) {
31
+ if (contentType.includes(Mimes.ApplicationJson)) {
32
+ intent.data = [await rr.reqBodyJsonData(), rr];
33
+ } else if (contentType.includes(Mimes.MultipartFormData)) {
34
+ intent.data = [await rr.reqBodyMultipartFormDataObject(), rr];
35
+ }
36
+ // console.log('---------2--intent request',intent);
37
+ const { return: rdatas, target } = await this.intentManager.publishMeta(intent);
38
+ if (target.length <= 0) {
39
+ throw new NotFoundError({ message: 'Not found intent target' });
40
+ }
41
+ const rdata = rdatas[0];
42
+ const wdata = rdata instanceof Promise ? await rdata : rdata;
43
+ rr.resStatusCode(HttpStatus.Ok);
44
+ rr.resSetHeader(HttpHeaders.ContentType, [Mimes.ApplicationJson]);
45
+ await rr.resEnd(wdata ? JSON.stringify(wdata) : undefined);
46
+ } else {
47
+ intent.data = rr.reqUrlSearchParamTuples.length > 0 ? [rr.reqUrlSearchParamsObj, rr] : [rr];
48
+ const { return: rdatas, target } = await this.intentManager.publishMeta(intent);
49
+ if (target.length <= 0) {
50
+ throw new NotFoundError({ message: 'Not found intent target' });
51
+ }
52
+ const rdata = rdatas[0];
53
+ const wdata = rdata instanceof Promise ? await rdata : rdata;
54
+ // const wdata =undefined;
55
+ rr.resStatusCode(HttpStatus.Ok);
56
+ rr.resSetHeader(HttpHeaders.ContentType, [Mimes.ApplicationJson]);
57
+ await rr.resEnd(wdata ? JSON.stringify(wdata) : undefined);
58
+ }
59
+ // console.log('---------3--intent request', rr.req.readable, rr.req.readableLength);
60
+ return false;
61
+ } else {
62
+ return true;
63
+ }
64
+ }
65
+
66
+ async proceedAfter({ rr, app }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
67
+ return true;
68
+ }
69
+ }
@@ -47,7 +47,9 @@ export class ResourceFilter implements Filter {
47
47
  // console.log('resource filter!!**-------', url);
48
48
  let sw = true;
49
49
  const regExps = this.resources?.filter(it => {
50
+ // console.log('---it', it, it instanceof RegExp, typeof it)
50
51
  if (it instanceof RegExp) {
52
+ // console.log('--------', it.test(url))
51
53
  return it.test(url);
52
54
  }
53
55
 
@@ -62,8 +64,11 @@ export class ResourceFilter implements Filter {
62
64
  if (typeof it === 'object' && 'request' in it) {
63
65
  if (typeof it.request === 'function') {
64
66
  return it.request(rr, app);
67
+ } else if (it .request instanceof RegExp) {
68
+ return it.request.test(url);
69
+ } else {
70
+ return RegExp(it.request).test(url);
65
71
  }
66
- return RegExp(it.request).test(url);
67
72
  }
68
73
  })??[]
69
74
  // console.log('regExps', regExps, url);
@@ -91,6 +96,7 @@ export class ResourceFilter implements Filter {
91
96
  if (this.resourceDistPath) {
92
97
  // It's a string path
93
98
  const resourcePath = path.join(this.resourceDistPath, distValue);
99
+ // console.log('-----------',this.resourceDistPath, resourcePath);
94
100
  if (fs.existsSync(resourcePath)) {
95
101
  rr.resStatusCode(HttpStatus.Ok);
96
102
  rr.resSetHeader(HttpHeaders.ContentType, mime.lookup(resourcePath).toString());