@expressots/adapter-express 3.0.0 → 4.0.0-preview.3

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 (244) hide show
  1. package/LICENSE.md +21 -21
  2. package/README.md +61 -118
  3. package/lib/CHANGELOG.md +36 -5
  4. package/lib/README.md +61 -118
  5. package/lib/cjs/adapter-express/application-express.base.js +3 -1
  6. package/lib/cjs/adapter-express/application-express.js +1405 -85
  7. package/lib/cjs/adapter-express/express-utils/conditional-middleware.js +102 -0
  8. package/lib/cjs/adapter-express/express-utils/constants.js +17 -0
  9. package/lib/cjs/adapter-express/express-utils/content-negotiation-decorators.js +129 -0
  10. package/lib/cjs/adapter-express/express-utils/decorators.js +225 -59
  11. package/lib/cjs/adapter-express/express-utils/exception-filter-decorators.js +11 -0
  12. package/lib/cjs/adapter-express/express-utils/guard-context-factory.js +84 -0
  13. package/lib/cjs/adapter-express/express-utils/guard-middleware.js +115 -0
  14. package/lib/cjs/adapter-express/express-utils/guard-utils.js +18 -0
  15. package/lib/cjs/adapter-express/express-utils/http-context-store.js +15 -0
  16. package/lib/cjs/adapter-express/express-utils/http-status-middleware.js +37 -2
  17. package/lib/cjs/adapter-express/express-utils/index.js +67 -1
  18. package/lib/cjs/adapter-express/express-utils/interceptor-middleware.js +132 -0
  19. package/lib/cjs/adapter-express/express-utils/inversify-express-server.js +827 -64
  20. package/lib/cjs/adapter-express/express-utils/lazy-module-middleware.js +241 -0
  21. package/lib/cjs/adapter-express/express-utils/middleware-composition.js +95 -0
  22. package/lib/cjs/adapter-express/express-utils/path-pattern-compat.js +129 -0
  23. package/lib/cjs/adapter-express/express-utils/permission-preloader.middleware.js +48 -0
  24. package/lib/cjs/adapter-express/express-utils/route-constraints.js +104 -0
  25. package/lib/cjs/adapter-express/express-utils/scope-extractor.interface.js +2 -0
  26. package/lib/cjs/adapter-express/express-utils/scope-extractor.js +66 -0
  27. package/lib/cjs/adapter-express/express-utils/setup-authorization.js +71 -0
  28. package/lib/cjs/adapter-express/express-utils/setup-event-system.js +113 -0
  29. package/lib/cjs/adapter-express/express-utils/setup-interceptors.js +103 -0
  30. package/lib/cjs/adapter-express/express-utils/setup-lazy-loading.js +228 -0
  31. package/lib/cjs/adapter-express/express-utils/utils.js +30 -12
  32. package/lib/cjs/adapter-express/express-utils/validation-decorators.js +205 -0
  33. package/lib/cjs/adapter-express/express-utils/validation-service.js +252 -0
  34. package/lib/cjs/adapter-express/index.js +7 -5
  35. package/lib/cjs/adapter-express/micro-api/application-express-micro-route.js +31 -1
  36. package/lib/cjs/adapter-express/micro-api/application-express-micro.js +8 -38
  37. package/lib/cjs/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
  38. package/lib/cjs/adapter-express/micro-api/gateway/index.js +11 -0
  39. package/lib/cjs/adapter-express/micro-api/gateway/service-proxy.js +214 -0
  40. package/lib/cjs/adapter-express/micro-api/index.js +27 -3
  41. package/lib/cjs/adapter-express/micro-api/micro.js +272 -0
  42. package/lib/cjs/adapter-express/micro-api/queue/index.js +8 -0
  43. package/lib/cjs/adapter-express/micro-api/queue/queue.interface.js +2 -0
  44. package/lib/cjs/adapter-express/micro-api/queue/rabbitmq-consumer.js +255 -0
  45. package/lib/cjs/adapter-express/micro-api/serverless/aws-lambda.adapter.js +183 -0
  46. package/lib/cjs/adapter-express/micro-api/serverless/cloudflare.adapter.js +158 -0
  47. package/lib/cjs/adapter-express/micro-api/serverless/index.js +12 -0
  48. package/lib/cjs/adapter-express/micro-api/serverless/vercel.adapter.js +102 -0
  49. package/lib/cjs/adapter-express/micro-api/service-mesh/index.js +10 -0
  50. package/lib/cjs/adapter-express/micro-api/service-mesh/service-client.js +194 -0
  51. package/lib/cjs/adapter-express/micro-api/service-mesh/service-discovery.js +261 -0
  52. package/lib/cjs/adapter-express/middleware/index.js +21 -0
  53. package/lib/cjs/adapter-express/middleware/request-logging.middleware.js +244 -0
  54. package/lib/cjs/adapter-express/render/engine.js +15 -15
  55. package/lib/cjs/adapter-express/render/index.js +5 -0
  56. package/lib/cjs/adapter-express/studio/index.js +10 -0
  57. package/lib/cjs/adapter-express/studio/studio-integration.js +267 -0
  58. package/lib/cjs/index.js +1 -1
  59. package/lib/cjs/types/adapter-express/application-express.base.d.ts +20 -7
  60. package/lib/cjs/types/adapter-express/application-express.d.ts +316 -33
  61. package/lib/cjs/types/adapter-express/express-utils/base-middleware.d.ts +2 -2
  62. package/lib/cjs/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
  63. package/lib/cjs/types/adapter-express/express-utils/constants.d.ts +13 -0
  64. package/lib/cjs/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
  65. package/lib/cjs/types/adapter-express/express-utils/decorators.d.ts +54 -6
  66. package/lib/cjs/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
  67. package/lib/cjs/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
  68. package/lib/cjs/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
  69. package/lib/cjs/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
  70. package/lib/cjs/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
  71. package/lib/cjs/types/adapter-express/express-utils/httpResponseMessage.d.ts +1 -1
  72. package/lib/cjs/types/adapter-express/express-utils/index.d.ts +30 -2
  73. package/lib/cjs/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
  74. package/lib/cjs/types/adapter-express/express-utils/interfaces.d.ts +42 -5
  75. package/lib/cjs/types/adapter-express/express-utils/inversify-express-server.d.ts +114 -2
  76. package/lib/cjs/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
  77. package/lib/cjs/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
  78. package/lib/cjs/types/adapter-express/express-utils/path-pattern-compat.d.ts +66 -0
  79. package/lib/cjs/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
  80. package/lib/cjs/types/adapter-express/express-utils/route-constraints.d.ts +98 -0
  81. package/lib/cjs/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
  82. package/lib/cjs/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
  83. package/lib/cjs/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
  84. package/lib/cjs/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
  85. package/lib/cjs/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
  86. package/lib/cjs/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
  87. package/lib/cjs/types/adapter-express/express-utils/utils.d.ts +17 -2
  88. package/lib/cjs/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
  89. package/lib/cjs/types/adapter-express/express-utils/validation-service.d.ts +88 -0
  90. package/lib/cjs/types/adapter-express/index.d.ts +6 -4
  91. package/lib/cjs/types/adapter-express/micro-api/application-express-micro-route.d.ts +25 -14
  92. package/lib/cjs/types/adapter-express/micro-api/application-express-micro.d.ts +3 -10
  93. package/lib/cjs/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
  94. package/lib/cjs/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
  95. package/lib/cjs/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
  96. package/lib/cjs/types/adapter-express/micro-api/index.d.ts +7 -1
  97. package/lib/cjs/types/adapter-express/micro-api/micro.d.ts +83 -0
  98. package/lib/cjs/types/adapter-express/micro-api/queue/index.d.ts +5 -0
  99. package/lib/cjs/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
  100. package/lib/cjs/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
  101. package/lib/cjs/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
  102. package/lib/cjs/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
  103. package/lib/cjs/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
  104. package/lib/cjs/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
  105. package/lib/cjs/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
  106. package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
  107. package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
  108. package/lib/cjs/types/adapter-express/middleware/index.d.ts +5 -0
  109. package/lib/cjs/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
  110. package/lib/cjs/types/adapter-express/render/index.d.ts +1 -0
  111. package/lib/cjs/types/adapter-express/studio/index.d.ts +1 -0
  112. package/lib/cjs/types/adapter-express/studio/studio-integration.d.ts +170 -0
  113. package/lib/cjs/types/index.d.ts +1 -1
  114. package/lib/esm/adapter-express/application-express.base.js +24 -0
  115. package/lib/esm/adapter-express/application-express.js +1656 -0
  116. package/lib/esm/adapter-express/application-express.types.js +1 -0
  117. package/lib/esm/adapter-express/express-utils/base-middleware.js +19 -0
  118. package/lib/esm/adapter-express/express-utils/conditional-middleware.js +96 -0
  119. package/lib/esm/adapter-express/express-utils/constants.js +63 -0
  120. package/lib/esm/adapter-express/express-utils/content/httpContent.js +6 -0
  121. package/lib/esm/adapter-express/express-utils/content-negotiation-decorators.js +120 -0
  122. package/lib/esm/adapter-express/express-utils/decorators.js +604 -0
  123. package/lib/esm/adapter-express/express-utils/exception-filter-decorators.js +6 -0
  124. package/lib/esm/adapter-express/express-utils/guard-context-factory.js +83 -0
  125. package/lib/esm/adapter-express/express-utils/guard-middleware.js +115 -0
  126. package/lib/esm/adapter-express/express-utils/guard-utils.js +14 -0
  127. package/lib/esm/adapter-express/express-utils/http-context-store.js +10 -0
  128. package/lib/esm/adapter-express/express-utils/http-status-middleware.js +116 -0
  129. package/lib/esm/adapter-express/express-utils/httpResponseMessage.js +29 -0
  130. package/lib/esm/adapter-express/express-utils/index.js +24 -0
  131. package/lib/esm/adapter-express/express-utils/interceptor-middleware.js +130 -0
  132. package/lib/esm/adapter-express/express-utils/interfaces.js +1 -0
  133. package/lib/esm/adapter-express/express-utils/inversify-express-server.js +1047 -0
  134. package/lib/esm/adapter-express/express-utils/lazy-module-middleware.js +236 -0
  135. package/lib/esm/adapter-express/express-utils/middleware-composition.js +89 -0
  136. package/lib/esm/adapter-express/express-utils/path-pattern-compat.js +125 -0
  137. package/lib/esm/adapter-express/express-utils/permission-preloader.middleware.js +45 -0
  138. package/lib/esm/adapter-express/express-utils/resolver-multer.js +30 -0
  139. package/lib/esm/adapter-express/express-utils/route-constraints.js +100 -0
  140. package/lib/esm/adapter-express/express-utils/scope-extractor.interface.js +1 -0
  141. package/lib/esm/adapter-express/express-utils/scope-extractor.js +63 -0
  142. package/lib/esm/adapter-express/express-utils/setup-authorization.js +68 -0
  143. package/lib/esm/adapter-express/express-utils/setup-event-system.js +110 -0
  144. package/lib/esm/adapter-express/express-utils/setup-interceptors.js +100 -0
  145. package/lib/esm/adapter-express/express-utils/setup-lazy-loading.js +225 -0
  146. package/lib/esm/adapter-express/express-utils/utils.js +68 -0
  147. package/lib/esm/adapter-express/express-utils/validation-decorators.js +199 -0
  148. package/lib/esm/adapter-express/express-utils/validation-service.js +251 -0
  149. package/lib/esm/adapter-express/index.js +7 -0
  150. package/lib/esm/adapter-express/micro-api/application-express-micro-container.js +48 -0
  151. package/lib/esm/adapter-express/micro-api/application-express-micro-route.js +128 -0
  152. package/lib/esm/adapter-express/micro-api/application-express-micro.js +157 -0
  153. package/lib/esm/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
  154. package/lib/esm/adapter-express/micro-api/gateway/index.js +5 -0
  155. package/lib/esm/adapter-express/micro-api/gateway/service-proxy.js +210 -0
  156. package/lib/esm/adapter-express/micro-api/index.js +10 -0
  157. package/lib/esm/adapter-express/micro-api/micro.js +266 -0
  158. package/lib/esm/adapter-express/micro-api/queue/index.js +4 -0
  159. package/lib/esm/adapter-express/micro-api/queue/queue.interface.js +1 -0
  160. package/lib/esm/adapter-express/micro-api/queue/rabbitmq-consumer.js +229 -0
  161. package/lib/esm/adapter-express/micro-api/serverless/aws-lambda.adapter.js +180 -0
  162. package/lib/esm/adapter-express/micro-api/serverless/cloudflare.adapter.js +155 -0
  163. package/lib/esm/adapter-express/micro-api/serverless/index.js +6 -0
  164. package/lib/esm/adapter-express/micro-api/serverless/vercel.adapter.js +99 -0
  165. package/lib/esm/adapter-express/micro-api/service-mesh/index.js +5 -0
  166. package/lib/esm/adapter-express/micro-api/service-mesh/service-client.js +191 -0
  167. package/lib/esm/adapter-express/micro-api/service-mesh/service-discovery.js +259 -0
  168. package/lib/esm/adapter-express/middleware/index.js +5 -0
  169. package/lib/esm/adapter-express/middleware/request-logging.middleware.js +239 -0
  170. package/lib/esm/adapter-express/render/constants.js +37 -0
  171. package/lib/esm/adapter-express/render/engine.js +51 -0
  172. package/lib/esm/adapter-express/render/index.js +1 -0
  173. package/lib/esm/adapter-express/render/resolve-render.js +30 -0
  174. package/lib/esm/adapter-express/studio/index.js +1 -0
  175. package/lib/esm/adapter-express/studio/studio-integration.js +236 -0
  176. package/lib/esm/index.mjs +1 -0
  177. package/lib/esm/package.json +3 -0
  178. package/lib/esm/types/adapter-express/application-express.base.d.ts +77 -0
  179. package/lib/esm/types/adapter-express/application-express.d.ts +453 -0
  180. package/lib/esm/types/adapter-express/application-express.types.d.ts +23 -0
  181. package/lib/esm/types/adapter-express/express-utils/base-middleware.d.ts +8 -0
  182. package/lib/esm/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
  183. package/lib/esm/types/adapter-express/express-utils/constants.d.ts +57 -0
  184. package/lib/esm/types/adapter-express/express-utils/content/httpContent.d.ts +6 -0
  185. package/lib/esm/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
  186. package/lib/esm/types/adapter-express/express-utils/decorators.d.ts +257 -0
  187. package/lib/esm/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
  188. package/lib/esm/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
  189. package/lib/esm/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
  190. package/lib/esm/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
  191. package/lib/esm/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
  192. package/lib/esm/types/adapter-express/express-utils/http-status-middleware.d.ts +26 -0
  193. package/lib/esm/types/adapter-express/express-utils/httpResponseMessage.d.ts +14 -0
  194. package/lib/esm/types/adapter-express/express-utils/index.d.ts +30 -0
  195. package/lib/esm/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
  196. package/lib/esm/types/adapter-express/express-utils/interfaces.d.ts +115 -0
  197. package/lib/esm/types/adapter-express/express-utils/inversify-express-server.d.ts +172 -0
  198. package/lib/esm/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
  199. package/lib/esm/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
  200. package/lib/esm/types/adapter-express/express-utils/path-pattern-compat.d.ts +66 -0
  201. package/lib/esm/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
  202. package/lib/esm/types/adapter-express/express-utils/resolver-multer.d.ts +7 -0
  203. package/lib/esm/types/adapter-express/express-utils/route-constraints.d.ts +98 -0
  204. package/lib/esm/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
  205. package/lib/esm/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
  206. package/lib/esm/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
  207. package/lib/esm/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
  208. package/lib/esm/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
  209. package/lib/esm/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
  210. package/lib/esm/types/adapter-express/express-utils/utils.d.ts +24 -0
  211. package/lib/esm/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
  212. package/lib/esm/types/adapter-express/express-utils/validation-service.d.ts +88 -0
  213. package/lib/esm/types/adapter-express/index.d.ts +7 -0
  214. package/lib/esm/types/adapter-express/micro-api/application-express-micro-container.d.ts +47 -0
  215. package/lib/esm/types/adapter-express/micro-api/application-express-micro-route.d.ts +104 -0
  216. package/lib/esm/types/adapter-express/micro-api/application-express-micro.d.ts +72 -0
  217. package/lib/esm/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
  218. package/lib/esm/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
  219. package/lib/esm/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
  220. package/lib/esm/types/adapter-express/micro-api/index.d.ts +7 -0
  221. package/lib/esm/types/adapter-express/micro-api/micro.d.ts +83 -0
  222. package/lib/esm/types/adapter-express/micro-api/queue/index.d.ts +5 -0
  223. package/lib/esm/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
  224. package/lib/esm/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
  225. package/lib/esm/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
  226. package/lib/esm/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
  227. package/lib/esm/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
  228. package/lib/esm/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
  229. package/lib/esm/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
  230. package/lib/esm/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
  231. package/lib/esm/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
  232. package/lib/esm/types/adapter-express/middleware/index.d.ts +5 -0
  233. package/lib/esm/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
  234. package/lib/esm/types/adapter-express/render/constants.d.ts +26 -0
  235. package/lib/esm/types/adapter-express/render/engine.d.ts +20 -0
  236. package/lib/esm/types/adapter-express/render/index.d.ts +5 -0
  237. package/lib/esm/types/adapter-express/render/resolve-render.d.ts +7 -0
  238. package/lib/esm/types/adapter-express/studio/index.d.ts +1 -0
  239. package/lib/esm/types/adapter-express/studio/studio-integration.d.ts +170 -0
  240. package/lib/esm/types/index.d.ts +1 -0
  241. package/lib/package.json +170 -146
  242. package/package.json +170 -146
  243. package/lib/cjs/di/di.interfaces.js +0 -10
  244. package/lib/cjs/types/di/di.interfaces.d.ts +0 -289
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServiceDiscovery = void 0;
4
+ /**
5
+ * ServiceDiscovery - Service discovery for microservices.
6
+ *
7
+ * Features:
8
+ * - Static service registration
9
+ * - Consul integration
10
+ * - etcd integration
11
+ * - Automatic service refresh
12
+ * - Round-robin load balancing
13
+ * - Health-based filtering
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Static service discovery
18
+ * const discovery = new ServiceDiscovery({ type: "static" });
19
+ *
20
+ * discovery.registerService({
21
+ * id: "user-service-1",
22
+ * name: "user-service",
23
+ * host: "user-service",
24
+ * port: 3001,
25
+ * health: "healthy",
26
+ * lastCheck: new Date(),
27
+ * });
28
+ *
29
+ * // Get a healthy instance
30
+ * const instance = discovery.getService("user-service");
31
+ * const client = new ServiceClient({
32
+ * name: "user-service",
33
+ * baseUrl: `http://${instance.host}:${instance.port}`,
34
+ * });
35
+ *
36
+ * // Or with Consul
37
+ * const discovery = new ServiceDiscovery({
38
+ * type: "consul",
39
+ * endpoint: "http://consul:8500",
40
+ * });
41
+ * await discovery.initialize();
42
+ * ```
43
+ */
44
+ class ServiceDiscovery {
45
+ constructor(config) {
46
+ this.services = new Map();
47
+ this.roundRobinIndex = new Map();
48
+ this.config = {
49
+ type: config.type,
50
+ endpoint: config.endpoint ?? "",
51
+ refreshInterval: config.refreshInterval ?? 30000,
52
+ debug: config.debug ?? false,
53
+ };
54
+ }
55
+ /**
56
+ * Initialize the service discovery
57
+ * For consul/etcd, this starts the refresh loop
58
+ */
59
+ async initialize() {
60
+ if (this.config.type === "static") {
61
+ // Static configuration - no auto-discovery
62
+ return;
63
+ }
64
+ // Initial refresh
65
+ await this.refresh();
66
+ // Start refresh loop
67
+ if (this.config.refreshInterval > 0) {
68
+ this.refreshTimer = setInterval(() => this.refresh(), this.config.refreshInterval);
69
+ }
70
+ }
71
+ /**
72
+ * Register a service instance (for static mode)
73
+ * @param service - Service instance to register
74
+ */
75
+ registerService(service) {
76
+ const instances = this.services.get(service.name) || [];
77
+ // Check if instance already exists
78
+ const existingIndex = instances.findIndex((i) => i.id === service.id);
79
+ if (existingIndex >= 0) {
80
+ instances[existingIndex] = service;
81
+ }
82
+ else {
83
+ instances.push(service);
84
+ }
85
+ this.services.set(service.name, instances);
86
+ if (this.config.debug) {
87
+ console.log(`[ServiceDiscovery] Registered ${service.name} (${service.id})`);
88
+ }
89
+ }
90
+ /**
91
+ * Deregister a service instance
92
+ * @param serviceName - Service name
93
+ * @param instanceId - Instance ID to remove
94
+ */
95
+ deregisterService(serviceName, instanceId) {
96
+ const instances = this.services.get(serviceName);
97
+ if (!instances)
98
+ return;
99
+ const filtered = instances.filter((i) => i.id !== instanceId);
100
+ this.services.set(serviceName, filtered);
101
+ if (this.config.debug) {
102
+ console.log(`[ServiceDiscovery] Deregistered ${serviceName} (${instanceId})`);
103
+ }
104
+ }
105
+ /**
106
+ * Get a healthy instance of a service (round-robin)
107
+ * @param name - Service name
108
+ * @returns A healthy service instance or null
109
+ */
110
+ getService(name) {
111
+ const instances = this.services.get(name);
112
+ if (!instances || instances.length === 0) {
113
+ return null;
114
+ }
115
+ // Filter to healthy instances only
116
+ const healthy = instances.filter((i) => i.health === "healthy");
117
+ if (healthy.length === 0) {
118
+ return null;
119
+ }
120
+ // Round-robin selection
121
+ const currentIndex = this.roundRobinIndex.get(name) ?? 0;
122
+ const instance = healthy[currentIndex % healthy.length];
123
+ this.roundRobinIndex.set(name, currentIndex + 1);
124
+ return instance;
125
+ }
126
+ /**
127
+ * Get all instances of a service
128
+ * @param name - Service name
129
+ * @param healthyOnly - Only return healthy instances (default: true)
130
+ */
131
+ getServiceInstances(name, healthyOnly = true) {
132
+ const instances = this.services.get(name) || [];
133
+ if (healthyOnly) {
134
+ return instances.filter((i) => i.health === "healthy");
135
+ }
136
+ return instances;
137
+ }
138
+ /**
139
+ * Get all registered services
140
+ */
141
+ getAllServices() {
142
+ return new Map(this.services);
143
+ }
144
+ /**
145
+ * List all registered service names
146
+ */
147
+ listServices() {
148
+ return Array.from(this.services.keys());
149
+ }
150
+ /**
151
+ * Update health status of a service instance
152
+ * @param serviceName - Service name
153
+ * @param instanceId - Instance ID
154
+ * @param health - New health status
155
+ */
156
+ updateHealth(serviceName, instanceId, health) {
157
+ const instances = this.services.get(serviceName);
158
+ if (!instances)
159
+ return false;
160
+ const instance = instances.find((i) => i.id === instanceId);
161
+ if (!instance)
162
+ return false;
163
+ instance.health = health;
164
+ instance.lastCheck = new Date();
165
+ if (this.config.debug) {
166
+ console.log(`[ServiceDiscovery] Updated ${serviceName} (${instanceId}) health to ${health}`);
167
+ }
168
+ return true;
169
+ }
170
+ /**
171
+ * Get service statistics
172
+ */
173
+ getStats() {
174
+ const stats = {};
175
+ for (const [name, instances] of this.services) {
176
+ stats[name] = {
177
+ total: instances.length,
178
+ healthy: instances.filter((i) => i.health === "healthy").length,
179
+ unhealthy: instances.filter((i) => i.health === "unhealthy").length,
180
+ };
181
+ }
182
+ return stats;
183
+ }
184
+ /**
185
+ * Stop the service discovery
186
+ */
187
+ stop() {
188
+ if (this.refreshTimer) {
189
+ clearInterval(this.refreshTimer);
190
+ this.refreshTimer = undefined;
191
+ }
192
+ }
193
+ /**
194
+ * Refresh service list from discovery backend
195
+ */
196
+ async refresh() {
197
+ try {
198
+ if (this.config.type === "consul") {
199
+ await this.refreshFromConsul();
200
+ }
201
+ else if (this.config.type === "etcd") {
202
+ await this.refreshFromEtcd();
203
+ }
204
+ }
205
+ catch (error) {
206
+ console.error("[ServiceDiscovery] Refresh failed:", error);
207
+ }
208
+ }
209
+ /**
210
+ * Refresh from Consul
211
+ */
212
+ async refreshFromConsul() {
213
+ if (!this.config.endpoint) {
214
+ throw new Error("Consul endpoint not configured");
215
+ }
216
+ try {
217
+ // Get list of services
218
+ const servicesResponse = await fetch(`${this.config.endpoint}/v1/catalog/services`);
219
+ const services = await servicesResponse.json();
220
+ // Get instances for each service
221
+ for (const serviceName of Object.keys(services)) {
222
+ const instances = await this.getConsulInstances(serviceName);
223
+ this.services.set(serviceName, instances);
224
+ }
225
+ if (this.config.debug) {
226
+ console.log(`[ServiceDiscovery] Refreshed ${this.services.size} services from Consul`);
227
+ }
228
+ }
229
+ catch (error) {
230
+ console.error("[ServiceDiscovery] Consul refresh failed:", error);
231
+ throw error;
232
+ }
233
+ }
234
+ /**
235
+ * Get instances from Consul for a specific service
236
+ */
237
+ async getConsulInstances(serviceName) {
238
+ const response = await fetch(`${this.config.endpoint}/v1/health/service/${serviceName}?passing=true`);
239
+ const data = (await response.json());
240
+ return data.map((entry) => ({
241
+ id: entry.Service.ID,
242
+ name: entry.Service.Service,
243
+ host: entry.Service.Address || entry.Node.Address,
244
+ port: entry.Service.Port,
245
+ metadata: entry.Service.Meta,
246
+ health: "healthy",
247
+ lastCheck: new Date(),
248
+ }));
249
+ }
250
+ /**
251
+ * Refresh from etcd
252
+ */
253
+ async refreshFromEtcd() {
254
+ if (!this.config.endpoint) {
255
+ throw new Error("etcd endpoint not configured");
256
+ }
257
+ // etcd v3 API implementation
258
+ console.log("[ServiceDiscovery] etcd integration requires etcd3 client library");
259
+ }
260
+ }
261
+ exports.ServiceDiscovery = ServiceDiscovery;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * @file middleware/index.ts
4
+ * @description Exports for ExpressoTS middleware
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ __exportStar(require("./request-logging.middleware.js"), exports);
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ /**
3
+ * @file request-logging.middleware.ts
4
+ * @description HTTP request/response logging middleware with context enrichment
5
+ * @module @expressots/adapter-express
6
+ *
7
+ * Features:
8
+ * - Request ID generation/extraction
9
+ * - Request/response timing
10
+ * - Slow request detection
11
+ * - Configurable verbosity levels
12
+ * - Body logging with redaction support
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getDefaultRequestLoggingConfig = getDefaultRequestLoggingConfig;
16
+ exports.createRequestLoggingMiddleware = createRequestLoggingMiddleware;
17
+ exports.requestIdMiddleware = requestIdMiddleware;
18
+ const core_1 = require("@expressots/core");
19
+ /**
20
+ * Default request logging configuration.
21
+ */
22
+ function getDefaultRequestLoggingConfig() {
23
+ return {
24
+ verbosity: "normal",
25
+ logBody: false,
26
+ logHeaders: false,
27
+ logResponseBody: false,
28
+ slowRequestThreshold: 1000, // 1 second
29
+ skipPatterns: [/^\/health$/, /^\/ready$/, /^\/live$/, /^\/_health$/],
30
+ requestIdHeader: "x-request-id",
31
+ correlationIdHeader: "x-correlation-id",
32
+ logUserAgent: true,
33
+ logIp: true,
34
+ };
35
+ }
36
+ /**
37
+ * Create request logging middleware.
38
+ * @param logger - Logger instance to use
39
+ * @param config - Optional configuration
40
+ * @returns Express middleware function
41
+ * @public API
42
+ */
43
+ function createRequestLoggingMiddleware(logger, config) {
44
+ const finalConfig = {
45
+ ...getDefaultRequestLoggingConfig(),
46
+ ...config,
47
+ };
48
+ return (req, res, next) => {
49
+ // Skip logging for configured patterns
50
+ if (finalConfig.skipPatterns.some((pattern) => pattern.test(req.path))) {
51
+ next();
52
+ return;
53
+ }
54
+ // Create HTTP context with custom header names
55
+ const httpContext = core_1.ContextManager.createHttpContext(req, {
56
+ requestIdHeader: finalConfig.requestIdHeader,
57
+ correlationIdHeader: finalConfig.correlationIdHeader,
58
+ });
59
+ // Set request/correlation ID headers for downstream services
60
+ res.setHeader(finalConfig.requestIdHeader, httpContext.requestId);
61
+ if (httpContext.correlationId) {
62
+ res.setHeader(finalConfig.correlationIdHeader, httpContext.correlationId);
63
+ }
64
+ // Create log context
65
+ const logContext = {
66
+ requestId: httpContext.requestId,
67
+ userId: httpContext.userId,
68
+ tenantId: httpContext.tenantId,
69
+ metadata: {
70
+ method: httpContext.method,
71
+ path: httpContext.path,
72
+ },
73
+ };
74
+ // Initialize flow tracker (if flow tracking is enabled)
75
+ const flowConfig = logger.getConfig()?.flow;
76
+ const flowTracker = (0, core_1.getFlowTracker)(httpContext.requestId, httpContext.method, httpContext.path, flowConfig);
77
+ // Log request start based on verbosity
78
+ logRequestStart(logger, httpContext, finalConfig);
79
+ // Capture response timing
80
+ const startTime = Date.now();
81
+ const startMemory = process.memoryUsage().heapUsed;
82
+ // Store error on request for later retrieval
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ req.__expressotsFlowError = undefined;
85
+ // Override res.end to capture response
86
+ const originalEnd = res.end;
87
+ let endCalled = false;
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ res.end = function (...args) {
90
+ // Prevent multiple calls
91
+ if (endCalled) {
92
+ return originalEnd.apply(this, args);
93
+ }
94
+ endCalled = true;
95
+ const duration = Date.now() - startTime;
96
+ const memoryDelta = process.memoryUsage().heapUsed - startMemory;
97
+ // Get error from request if available (set by controllers, guards, or error handlers)
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ const error = req.__expressotsFlowError;
100
+ // Finalize flow and get flow data (pass error if available)
101
+ const flow = flowTracker.finalize(res.statusCode, error);
102
+ // Log response with flow data
103
+ logRequestEnd(logger, httpContext, res, duration, memoryDelta, finalConfig, flow);
104
+ // Cleanup flow tracker
105
+ (0, core_1.removeFlowTracker)(httpContext.requestId);
106
+ // Call original end
107
+ return originalEnd.apply(this, args);
108
+ };
109
+ // Wrap next to capture errors passed to next()
110
+ const wrappedNext = (err) => {
111
+ if (err) {
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ req.__expressotsFlowError = err instanceof Error ? err : new Error(String(err));
114
+ }
115
+ next(err);
116
+ };
117
+ // Also hook into res.status() to capture error status codes
118
+ // This helps capture errors that Express error handlers set
119
+ const originalStatus = res.status.bind(res);
120
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
121
+ res.status = function (code) {
122
+ // If status is >= 400 and no error is stored yet, try to get it from Express error handling
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ if (code >= 400 && !req.__expressotsFlowError) {
125
+ // Check if there's an error in the response locals (Express error handlers sometimes put it there)
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ const errorFromLocals = res.locals?.error;
128
+ if (errorFromLocals) {
129
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
+ req.__expressotsFlowError =
131
+ errorFromLocals instanceof Error ? errorFromLocals : new Error(String(errorFromLocals));
132
+ }
133
+ }
134
+ return originalStatus(code);
135
+ };
136
+ // Run the rest of the middleware chain with context
137
+ core_1.ContextManager.runWithContext(logContext, () => {
138
+ wrappedNext();
139
+ });
140
+ };
141
+ }
142
+ /**
143
+ * Log request start.
144
+ */
145
+ function logRequestStart(logger, context, config) {
146
+ const { verbosity, logHeaders, logUserAgent, logIp } = config;
147
+ if (verbosity === "minimal") {
148
+ // Minimal: Just log that request started
149
+ logger.debug(`→ ${context.method} ${context.path}`, { requestId: context.requestId });
150
+ return;
151
+ }
152
+ // Build log data based on verbosity
153
+ const logData = {
154
+ requestId: context.requestId,
155
+ };
156
+ if (logIp && context.ip) {
157
+ logData.ip = context.ip;
158
+ }
159
+ if (logUserAgent && context.userAgent) {
160
+ logData.userAgent =
161
+ context.userAgent.length > 50
162
+ ? context.userAgent.substring(0, 50) + "..."
163
+ : context.userAgent;
164
+ }
165
+ if (context.userId) {
166
+ logData.userId = context.userId;
167
+ }
168
+ if (context.tenantId) {
169
+ logData.tenantId = context.tenantId;
170
+ }
171
+ if (verbosity === "detailed" || verbosity === "debug") {
172
+ if (logHeaders && context.headers) {
173
+ logData.headers = context.headers;
174
+ }
175
+ }
176
+ logger.info(`→ ${context.method} ${context.path}`, "request", logData);
177
+ }
178
+ /**
179
+ * Log request end.
180
+ */
181
+ function logRequestEnd(logger, context, res, duration, memoryDelta, config, flow) {
182
+ const { verbosity, slowRequestThreshold } = config;
183
+ const statusCode = res.statusCode;
184
+ // Determine log level based on status and duration
185
+ const isSlowRequest = duration >= slowRequestThreshold;
186
+ const isError = statusCode >= 400;
187
+ // Build log data
188
+ const logData = {
189
+ requestId: context.requestId,
190
+ status: statusCode,
191
+ duration: `${duration}ms`,
192
+ };
193
+ if (verbosity === "detailed" || verbosity === "debug") {
194
+ logData.memoryDelta = `${(memoryDelta / 1024).toFixed(1)}KB`;
195
+ }
196
+ if (context.userId) {
197
+ logData.userId = context.userId;
198
+ }
199
+ // Format message
200
+ const statusEmoji = isError ? "✗" : "✓";
201
+ const message = `← ${context.method} ${context.path} ${statusCode} ${statusEmoji} ${duration}ms`;
202
+ // Log with appropriate level and include flow data if available
203
+ if (isError && statusCode >= 500) {
204
+ logger.error(message, "request", { ...logData, flow });
205
+ }
206
+ else if (isError) {
207
+ logger.warn(message, "request", { ...logData, flow });
208
+ }
209
+ else if (isSlowRequest) {
210
+ logger.warn(`[SLOW] ${message}`, "request", {
211
+ ...logData,
212
+ slowRequestThreshold: `${slowRequestThreshold}ms`,
213
+ flow,
214
+ });
215
+ }
216
+ else if (verbosity !== "minimal") {
217
+ logger.info(message, "request", { ...logData, flow });
218
+ }
219
+ else {
220
+ // debug only takes 2 args: message and data
221
+ logger.debug(`[request] ${message}`, { ...logData, flow });
222
+ }
223
+ }
224
+ /**
225
+ * Express middleware that assigns a request ID to each request.
226
+ * Simpler alternative to full request logging.
227
+ * @param headerName - Header name for request ID (default: x-request-id)
228
+ * @returns Express middleware
229
+ * @public API
230
+ */
231
+ function requestIdMiddleware(headerName = "x-request-id") {
232
+ return (req, res, next) => {
233
+ const existingId = req.headers[headerName.toLowerCase()];
234
+ const requestId = existingId || core_1.ContextManager.generateRequestId();
235
+ // Set on request for access by other middleware
236
+ req.requestId = requestId;
237
+ // Set on response header
238
+ res.setHeader(headerName, requestId);
239
+ // Run with context
240
+ core_1.ContextManager.runWithContext({ requestId }, () => {
241
+ next();
242
+ });
243
+ };
244
+ }
@@ -4,17 +4,17 @@ exports.setEngineEjs = setEngineEjs;
4
4
  exports.setEngineHandlebars = setEngineHandlebars;
5
5
  exports.setEnginePug = setEnginePug;
6
6
  const core_1 = require("@expressots/core");
7
- const resolve_render_1 = require("./resolve-render");
8
- const constants_1 = require("./constants");
7
+ const resolve_render_js_1 = require("./resolve-render.js");
8
+ const constants_js_1 = require("./constants.js");
9
9
  /**
10
10
  * Set Ejs as the view engine
11
11
  * @param {Application} app - The express application
12
12
  * @param {EjsOptions} [options=EJS_DEFAULTS] - The ejs options
13
13
  */
14
- async function setEngineEjs(app, options = constants_1.EJS_DEFAULTS) {
15
- (0, resolve_render_1.packageResolver)("ejs");
16
- app.set("view engine", options.viewEngine || constants_1.EJS_DEFAULTS.viewEngine);
17
- app.set("views", options.viewsDir || constants_1.EJS_DEFAULTS.viewsDir);
14
+ async function setEngineEjs(app, options = constants_js_1.EJS_DEFAULTS) {
15
+ (0, resolve_render_js_1.packageResolver)("ejs");
16
+ app.set("view engine", options.viewEngine || constants_js_1.EJS_DEFAULTS.viewEngine);
17
+ app.set("views", options.viewsDir || constants_js_1.EJS_DEFAULTS.viewsDir);
18
18
  if (Array.isArray(options.viewsDir)) {
19
19
  options.viewsDir.forEach((dir) => {
20
20
  app.set("views", dir);
@@ -32,13 +32,13 @@ async function setEngineEjs(app, options = constants_1.EJS_DEFAULTS) {
32
32
  * @param {express.Application} app - The express application
33
33
  * @param {HandlebarsOptions} [options=HANDLEBARS_DEFAULTS] - The handlebars options
34
34
  */
35
- async function setEngineHandlebars(app, options = constants_1.HANDLEBARS_DEFAULTS) {
35
+ async function setEngineHandlebars(app, options = constants_js_1.HANDLEBARS_DEFAULTS) {
36
36
  const logger = new core_1.Logger();
37
37
  try {
38
- const hbs = (0, resolve_render_1.packageResolver)("hbs");
39
- hbs.registerPartials(options.partialsDir || constants_1.DEFAULT_PARTIALS_DIR);
40
- app.set("view engine", options.viewEngine || constants_1.HANDLEBARS_DEFAULTS.viewEngine);
41
- app.set("views", options.viewsDir || constants_1.HANDLEBARS_DEFAULTS.viewsDir);
38
+ const hbs = (0, resolve_render_js_1.packageResolver)("hbs");
39
+ hbs.registerPartials(options.partialsDir || constants_js_1.DEFAULT_PARTIALS_DIR);
40
+ app.set("view engine", options.viewEngine || constants_js_1.HANDLEBARS_DEFAULTS.viewEngine);
41
+ app.set("views", options.viewsDir || constants_js_1.HANDLEBARS_DEFAULTS.viewsDir);
42
42
  }
43
43
  catch (error) {
44
44
  logger.error(error.message, "handlebars-config");
@@ -49,8 +49,8 @@ async function setEngineHandlebars(app, options = constants_1.HANDLEBARS_DEFAULT
49
49
  * @param {express.Application} app - The express application
50
50
  * @param {PugOptions} [options=PUG_DEFAULTS] - The pug options
51
51
  */
52
- async function setEnginePug(app, options = constants_1.PUG_DEFAULTS) {
53
- (0, resolve_render_1.packageResolver)("pug");
54
- app.set("view engine", options.viewEngine || constants_1.PUG_DEFAULTS.viewEngine);
55
- app.set("views", options.viewsDir || constants_1.PUG_DEFAULTS.viewsDir);
52
+ async function setEnginePug(app, options = constants_js_1.PUG_DEFAULTS) {
53
+ (0, resolve_render_js_1.packageResolver)("pug");
54
+ app.set("view engine", options.viewEngine || constants_js_1.PUG_DEFAULTS.viewEngine);
55
+ app.set("views", options.viewsDir || constants_js_1.PUG_DEFAULTS.viewsDir);
56
56
  }
@@ -1,2 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setEnginePug = exports.setEngineHandlebars = exports.setEngineEjs = void 0;
4
+ var engine_js_1 = require("./engine.js");
5
+ Object.defineProperty(exports, "setEngineEjs", { enumerable: true, get: function () { return engine_js_1.setEngineEjs; } });
6
+ Object.defineProperty(exports, "setEngineHandlebars", { enumerable: true, get: function () { return engine_js_1.setEngineHandlebars; } });
7
+ Object.defineProperty(exports, "setEnginePug", { enumerable: true, get: function () { return engine_js_1.setEnginePug; } });
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rescanStudioRoutes = exports.reportStudioRuntimeInfo = exports.getStudioAgent = exports.isStudioEnabled = exports.stopStudio = exports.initializeStudio = void 0;
4
+ var studio_integration_js_1 = require("./studio-integration.js");
5
+ Object.defineProperty(exports, "initializeStudio", { enumerable: true, get: function () { return studio_integration_js_1.initializeStudio; } });
6
+ Object.defineProperty(exports, "stopStudio", { enumerable: true, get: function () { return studio_integration_js_1.stopStudio; } });
7
+ Object.defineProperty(exports, "isStudioEnabled", { enumerable: true, get: function () { return studio_integration_js_1.isStudioEnabled; } });
8
+ Object.defineProperty(exports, "getStudioAgent", { enumerable: true, get: function () { return studio_integration_js_1.getStudioAgent; } });
9
+ Object.defineProperty(exports, "reportStudioRuntimeInfo", { enumerable: true, get: function () { return studio_integration_js_1.reportStudioRuntimeInfo; } });
10
+ Object.defineProperty(exports, "rescanStudioRoutes", { enumerable: true, get: function () { return studio_integration_js_1.rescanStudioRoutes; } });