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

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 (239) hide show
  1. package/README.md +39 -96
  2. package/lib/CHANGELOG.md +31 -5
  3. package/lib/README.md +39 -96
  4. package/lib/cjs/adapter-express/application-express.base.js +3 -1
  5. package/lib/cjs/adapter-express/application-express.js +1049 -85
  6. package/lib/cjs/adapter-express/express-utils/conditional-middleware.js +102 -0
  7. package/lib/cjs/adapter-express/express-utils/constants.js +17 -0
  8. package/lib/cjs/adapter-express/express-utils/content-negotiation-decorators.js +129 -0
  9. package/lib/cjs/adapter-express/express-utils/decorators.js +186 -49
  10. package/lib/cjs/adapter-express/express-utils/exception-filter-decorators.js +11 -0
  11. package/lib/cjs/adapter-express/express-utils/guard-context-factory.js +84 -0
  12. package/lib/cjs/adapter-express/express-utils/guard-middleware.js +115 -0
  13. package/lib/cjs/adapter-express/express-utils/guard-utils.js +18 -0
  14. package/lib/cjs/adapter-express/express-utils/http-context-store.js +15 -0
  15. package/lib/cjs/adapter-express/express-utils/http-status-middleware.js +37 -2
  16. package/lib/cjs/adapter-express/express-utils/index.js +67 -1
  17. package/lib/cjs/adapter-express/express-utils/interceptor-middleware.js +132 -0
  18. package/lib/cjs/adapter-express/express-utils/inversify-express-server.js +810 -63
  19. package/lib/cjs/adapter-express/express-utils/lazy-module-middleware.js +241 -0
  20. package/lib/cjs/adapter-express/express-utils/middleware-composition.js +95 -0
  21. package/lib/cjs/adapter-express/express-utils/permission-preloader.middleware.js +48 -0
  22. package/lib/cjs/adapter-express/express-utils/route-constraints.js +95 -0
  23. package/lib/cjs/adapter-express/express-utils/scope-extractor.interface.js +2 -0
  24. package/lib/cjs/adapter-express/express-utils/scope-extractor.js +66 -0
  25. package/lib/cjs/adapter-express/express-utils/setup-authorization.js +71 -0
  26. package/lib/cjs/adapter-express/express-utils/setup-event-system.js +113 -0
  27. package/lib/cjs/adapter-express/express-utils/setup-interceptors.js +103 -0
  28. package/lib/cjs/adapter-express/express-utils/setup-lazy-loading.js +228 -0
  29. package/lib/cjs/adapter-express/express-utils/utils.js +30 -12
  30. package/lib/cjs/adapter-express/express-utils/validation-decorators.js +205 -0
  31. package/lib/cjs/adapter-express/express-utils/validation-service.js +252 -0
  32. package/lib/cjs/adapter-express/index.js +7 -5
  33. package/lib/cjs/adapter-express/micro-api/application-express-micro-route.js +31 -1
  34. package/lib/cjs/adapter-express/micro-api/application-express-micro.js +11 -37
  35. package/lib/cjs/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
  36. package/lib/cjs/adapter-express/micro-api/gateway/index.js +11 -0
  37. package/lib/cjs/adapter-express/micro-api/gateway/service-proxy.js +214 -0
  38. package/lib/cjs/adapter-express/micro-api/index.js +27 -3
  39. package/lib/cjs/adapter-express/micro-api/micro.js +217 -0
  40. package/lib/cjs/adapter-express/micro-api/queue/index.js +8 -0
  41. package/lib/cjs/adapter-express/micro-api/queue/queue.interface.js +2 -0
  42. package/lib/cjs/adapter-express/micro-api/queue/rabbitmq-consumer.js +255 -0
  43. package/lib/cjs/adapter-express/micro-api/serverless/aws-lambda.adapter.js +183 -0
  44. package/lib/cjs/adapter-express/micro-api/serverless/cloudflare.adapter.js +158 -0
  45. package/lib/cjs/adapter-express/micro-api/serverless/index.js +12 -0
  46. package/lib/cjs/adapter-express/micro-api/serverless/vercel.adapter.js +102 -0
  47. package/lib/cjs/adapter-express/micro-api/service-mesh/index.js +10 -0
  48. package/lib/cjs/adapter-express/micro-api/service-mesh/service-client.js +194 -0
  49. package/lib/cjs/adapter-express/micro-api/service-mesh/service-discovery.js +261 -0
  50. package/lib/cjs/adapter-express/middleware/index.js +21 -0
  51. package/lib/cjs/adapter-express/middleware/request-logging.middleware.js +244 -0
  52. package/lib/cjs/adapter-express/render/engine.js +15 -15
  53. package/lib/cjs/adapter-express/render/index.js +5 -0
  54. package/lib/cjs/adapter-express/studio/index.js +9 -0
  55. package/lib/cjs/adapter-express/studio/studio-integration.js +214 -0
  56. package/lib/cjs/index.js +1 -1
  57. package/lib/cjs/types/adapter-express/application-express.base.d.ts +20 -7
  58. package/lib/cjs/types/adapter-express/application-express.d.ts +273 -32
  59. package/lib/cjs/types/adapter-express/express-utils/base-middleware.d.ts +2 -2
  60. package/lib/cjs/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
  61. package/lib/cjs/types/adapter-express/express-utils/constants.d.ts +13 -0
  62. package/lib/cjs/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
  63. package/lib/cjs/types/adapter-express/express-utils/decorators.d.ts +54 -6
  64. package/lib/cjs/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
  65. package/lib/cjs/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
  66. package/lib/cjs/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
  67. package/lib/cjs/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
  68. package/lib/cjs/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
  69. package/lib/cjs/types/adapter-express/express-utils/httpResponseMessage.d.ts +1 -1
  70. package/lib/cjs/types/adapter-express/express-utils/index.d.ts +30 -2
  71. package/lib/cjs/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
  72. package/lib/cjs/types/adapter-express/express-utils/interfaces.d.ts +42 -5
  73. package/lib/cjs/types/adapter-express/express-utils/inversify-express-server.d.ts +114 -2
  74. package/lib/cjs/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
  75. package/lib/cjs/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
  76. package/lib/cjs/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
  77. package/lib/cjs/types/adapter-express/express-utils/route-constraints.d.ts +89 -0
  78. package/lib/cjs/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
  79. package/lib/cjs/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
  80. package/lib/cjs/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
  81. package/lib/cjs/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
  82. package/lib/cjs/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
  83. package/lib/cjs/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
  84. package/lib/cjs/types/adapter-express/express-utils/utils.d.ts +17 -2
  85. package/lib/cjs/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
  86. package/lib/cjs/types/adapter-express/express-utils/validation-service.d.ts +88 -0
  87. package/lib/cjs/types/adapter-express/index.d.ts +6 -4
  88. package/lib/cjs/types/adapter-express/micro-api/application-express-micro-route.d.ts +25 -14
  89. package/lib/cjs/types/adapter-express/micro-api/application-express-micro.d.ts +3 -10
  90. package/lib/cjs/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
  91. package/lib/cjs/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
  92. package/lib/cjs/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
  93. package/lib/cjs/types/adapter-express/micro-api/index.d.ts +7 -1
  94. package/lib/cjs/types/adapter-express/micro-api/micro.d.ts +66 -0
  95. package/lib/cjs/types/adapter-express/micro-api/queue/index.d.ts +5 -0
  96. package/lib/cjs/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
  97. package/lib/cjs/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
  98. package/lib/cjs/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
  99. package/lib/cjs/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
  100. package/lib/cjs/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
  101. package/lib/cjs/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
  102. package/lib/cjs/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
  103. package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
  104. package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
  105. package/lib/cjs/types/adapter-express/middleware/index.d.ts +5 -0
  106. package/lib/cjs/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
  107. package/lib/cjs/types/adapter-express/render/index.d.ts +1 -0
  108. package/lib/cjs/types/adapter-express/studio/index.d.ts +1 -0
  109. package/lib/cjs/types/adapter-express/studio/studio-integration.d.ts +92 -0
  110. package/lib/cjs/types/index.d.ts +1 -1
  111. package/lib/esm/adapter-express/application-express.base.js +24 -0
  112. package/lib/esm/adapter-express/application-express.js +1300 -0
  113. package/lib/esm/adapter-express/application-express.types.js +1 -0
  114. package/lib/esm/adapter-express/express-utils/base-middleware.js +19 -0
  115. package/lib/esm/adapter-express/express-utils/conditional-middleware.js +96 -0
  116. package/lib/esm/adapter-express/express-utils/constants.js +63 -0
  117. package/lib/esm/adapter-express/express-utils/content/httpContent.js +6 -0
  118. package/lib/esm/adapter-express/express-utils/content-negotiation-decorators.js +120 -0
  119. package/lib/esm/adapter-express/express-utils/decorators.js +575 -0
  120. package/lib/esm/adapter-express/express-utils/exception-filter-decorators.js +6 -0
  121. package/lib/esm/adapter-express/express-utils/guard-context-factory.js +83 -0
  122. package/lib/esm/adapter-express/express-utils/guard-middleware.js +115 -0
  123. package/lib/esm/adapter-express/express-utils/guard-utils.js +14 -0
  124. package/lib/esm/adapter-express/express-utils/http-context-store.js +10 -0
  125. package/lib/esm/adapter-express/express-utils/http-status-middleware.js +116 -0
  126. package/lib/esm/adapter-express/express-utils/httpResponseMessage.js +29 -0
  127. package/lib/esm/adapter-express/express-utils/index.js +24 -0
  128. package/lib/esm/adapter-express/express-utils/interceptor-middleware.js +130 -0
  129. package/lib/esm/adapter-express/express-utils/interfaces.js +1 -0
  130. package/lib/esm/adapter-express/express-utils/inversify-express-server.js +1031 -0
  131. package/lib/esm/adapter-express/express-utils/lazy-module-middleware.js +236 -0
  132. package/lib/esm/adapter-express/express-utils/middleware-composition.js +89 -0
  133. package/lib/esm/adapter-express/express-utils/permission-preloader.middleware.js +45 -0
  134. package/lib/esm/adapter-express/express-utils/resolver-multer.js +30 -0
  135. package/lib/esm/adapter-express/express-utils/route-constraints.js +91 -0
  136. package/lib/esm/adapter-express/express-utils/scope-extractor.interface.js +1 -0
  137. package/lib/esm/adapter-express/express-utils/scope-extractor.js +63 -0
  138. package/lib/esm/adapter-express/express-utils/setup-authorization.js +68 -0
  139. package/lib/esm/adapter-express/express-utils/setup-event-system.js +110 -0
  140. package/lib/esm/adapter-express/express-utils/setup-interceptors.js +100 -0
  141. package/lib/esm/adapter-express/express-utils/setup-lazy-loading.js +225 -0
  142. package/lib/esm/adapter-express/express-utils/utils.js +68 -0
  143. package/lib/esm/adapter-express/express-utils/validation-decorators.js +199 -0
  144. package/lib/esm/adapter-express/express-utils/validation-service.js +251 -0
  145. package/lib/esm/adapter-express/index.js +7 -0
  146. package/lib/esm/adapter-express/micro-api/application-express-micro-container.js +48 -0
  147. package/lib/esm/adapter-express/micro-api/application-express-micro-route.js +128 -0
  148. package/lib/esm/adapter-express/micro-api/application-express-micro.js +161 -0
  149. package/lib/esm/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
  150. package/lib/esm/adapter-express/micro-api/gateway/index.js +5 -0
  151. package/lib/esm/adapter-express/micro-api/gateway/service-proxy.js +210 -0
  152. package/lib/esm/adapter-express/micro-api/index.js +10 -0
  153. package/lib/esm/adapter-express/micro-api/micro.js +211 -0
  154. package/lib/esm/adapter-express/micro-api/queue/index.js +4 -0
  155. package/lib/esm/adapter-express/micro-api/queue/queue.interface.js +1 -0
  156. package/lib/esm/adapter-express/micro-api/queue/rabbitmq-consumer.js +229 -0
  157. package/lib/esm/adapter-express/micro-api/serverless/aws-lambda.adapter.js +180 -0
  158. package/lib/esm/adapter-express/micro-api/serverless/cloudflare.adapter.js +155 -0
  159. package/lib/esm/adapter-express/micro-api/serverless/index.js +6 -0
  160. package/lib/esm/adapter-express/micro-api/serverless/vercel.adapter.js +99 -0
  161. package/lib/esm/adapter-express/micro-api/service-mesh/index.js +5 -0
  162. package/lib/esm/adapter-express/micro-api/service-mesh/service-client.js +191 -0
  163. package/lib/esm/adapter-express/micro-api/service-mesh/service-discovery.js +259 -0
  164. package/lib/esm/adapter-express/middleware/index.js +5 -0
  165. package/lib/esm/adapter-express/middleware/request-logging.middleware.js +239 -0
  166. package/lib/esm/adapter-express/render/constants.js +37 -0
  167. package/lib/esm/adapter-express/render/engine.js +51 -0
  168. package/lib/esm/adapter-express/render/index.js +1 -0
  169. package/lib/esm/adapter-express/render/resolve-render.js +30 -0
  170. package/lib/esm/adapter-express/studio/index.js +1 -0
  171. package/lib/esm/adapter-express/studio/studio-integration.js +184 -0
  172. package/lib/esm/index.mjs +1 -0
  173. package/lib/esm/package.json +3 -0
  174. package/lib/esm/types/adapter-express/application-express.base.d.ts +77 -0
  175. package/lib/esm/types/adapter-express/application-express.d.ts +411 -0
  176. package/lib/esm/types/adapter-express/application-express.types.d.ts +23 -0
  177. package/lib/esm/types/adapter-express/express-utils/base-middleware.d.ts +8 -0
  178. package/lib/esm/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
  179. package/lib/esm/types/adapter-express/express-utils/constants.d.ts +57 -0
  180. package/lib/esm/types/adapter-express/express-utils/content/httpContent.d.ts +6 -0
  181. package/lib/esm/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
  182. package/lib/esm/types/adapter-express/express-utils/decorators.d.ts +257 -0
  183. package/lib/esm/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
  184. package/lib/esm/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
  185. package/lib/esm/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
  186. package/lib/esm/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
  187. package/lib/esm/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
  188. package/lib/esm/types/adapter-express/express-utils/http-status-middleware.d.ts +26 -0
  189. package/lib/esm/types/adapter-express/express-utils/httpResponseMessage.d.ts +14 -0
  190. package/lib/esm/types/adapter-express/express-utils/index.d.ts +30 -0
  191. package/lib/esm/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
  192. package/lib/esm/types/adapter-express/express-utils/interfaces.d.ts +115 -0
  193. package/lib/esm/types/adapter-express/express-utils/inversify-express-server.d.ts +172 -0
  194. package/lib/esm/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
  195. package/lib/esm/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
  196. package/lib/esm/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
  197. package/lib/esm/types/adapter-express/express-utils/resolver-multer.d.ts +7 -0
  198. package/lib/esm/types/adapter-express/express-utils/route-constraints.d.ts +89 -0
  199. package/lib/esm/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
  200. package/lib/esm/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
  201. package/lib/esm/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
  202. package/lib/esm/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
  203. package/lib/esm/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
  204. package/lib/esm/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
  205. package/lib/esm/types/adapter-express/express-utils/utils.d.ts +24 -0
  206. package/lib/esm/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
  207. package/lib/esm/types/adapter-express/express-utils/validation-service.d.ts +88 -0
  208. package/lib/esm/types/adapter-express/index.d.ts +7 -0
  209. package/lib/esm/types/adapter-express/micro-api/application-express-micro-container.d.ts +47 -0
  210. package/lib/esm/types/adapter-express/micro-api/application-express-micro-route.d.ts +104 -0
  211. package/lib/esm/types/adapter-express/micro-api/application-express-micro.d.ts +72 -0
  212. package/lib/esm/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
  213. package/lib/esm/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
  214. package/lib/esm/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
  215. package/lib/esm/types/adapter-express/micro-api/index.d.ts +7 -0
  216. package/lib/esm/types/adapter-express/micro-api/micro.d.ts +66 -0
  217. package/lib/esm/types/adapter-express/micro-api/queue/index.d.ts +5 -0
  218. package/lib/esm/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
  219. package/lib/esm/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
  220. package/lib/esm/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
  221. package/lib/esm/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
  222. package/lib/esm/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
  223. package/lib/esm/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
  224. package/lib/esm/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
  225. package/lib/esm/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
  226. package/lib/esm/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
  227. package/lib/esm/types/adapter-express/middleware/index.d.ts +5 -0
  228. package/lib/esm/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
  229. package/lib/esm/types/adapter-express/render/constants.d.ts +26 -0
  230. package/lib/esm/types/adapter-express/render/engine.d.ts +20 -0
  231. package/lib/esm/types/adapter-express/render/index.d.ts +5 -0
  232. package/lib/esm/types/adapter-express/render/resolve-render.d.ts +7 -0
  233. package/lib/esm/types/adapter-express/studio/index.d.ts +1 -0
  234. package/lib/esm/types/adapter-express/studio/studio-integration.d.ts +92 -0
  235. package/lib/esm/types/index.d.ts +1 -0
  236. package/lib/package.json +156 -146
  237. package/package.json +156 -146
  238. package/lib/cjs/di/di.interfaces.js +0 -10
  239. package/lib/cjs/types/di/di.interfaces.d.ts +0 -289
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CircuitBreaker = void 0;
4
+ /**
5
+ * CircuitBreaker - Protect against cascading failures in distributed systems.
6
+ *
7
+ * States:
8
+ * - CLOSED: Normal operation, requests pass through
9
+ * - OPEN: Requests fail immediately without calling the service
10
+ * - HALF_OPEN: Limited requests pass through to test if service recovered
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const circuitBreaker = new CircuitBreaker({
15
+ * failureThreshold: 5,
16
+ * timeout: 60000,
17
+ * });
18
+ *
19
+ * app.Route.get("/external-api", async (req, res) => {
20
+ * try {
21
+ * const result = await circuitBreaker.execute(async () => {
22
+ * return await fetch("https://external-api.com/data");
23
+ * });
24
+ * res.json(await result.json());
25
+ * } catch (error) {
26
+ * if (error.message === "Circuit breaker is OPEN") {
27
+ * res.status(503).json({ error: "Service temporarily unavailable" });
28
+ * } else {
29
+ * res.status(500).json({ error: error.message });
30
+ * }
31
+ * }
32
+ * });
33
+ * ```
34
+ */
35
+ class CircuitBreaker {
36
+ constructor(config) {
37
+ this.state = "CLOSED";
38
+ this.failures = 0;
39
+ this.successes = 0;
40
+ this.totalSuccesses = 0;
41
+ this.totalCalls = 0;
42
+ this.recentFailures = [];
43
+ this.config = {
44
+ failureThreshold: config?.failureThreshold ?? 5,
45
+ successThreshold: config?.successThreshold ?? 2,
46
+ timeout: config?.timeout ?? 60000,
47
+ monitoringPeriod: config?.monitoringPeriod ?? 10000,
48
+ };
49
+ }
50
+ /**
51
+ * Execute a function with circuit breaker protection
52
+ * @param fn - Function to execute
53
+ * @throws Error if circuit is open
54
+ */
55
+ async execute(fn) {
56
+ this.totalCalls++;
57
+ // Check if circuit is open
58
+ if (this.state === "OPEN") {
59
+ // Check if timeout has passed
60
+ if (this.shouldAttemptReset()) {
61
+ this.state = "HALF_OPEN";
62
+ this.successes = 0;
63
+ }
64
+ else {
65
+ throw new Error("Circuit breaker is OPEN");
66
+ }
67
+ }
68
+ try {
69
+ const result = await fn();
70
+ this.onSuccess();
71
+ return result;
72
+ }
73
+ catch (error) {
74
+ this.onFailure();
75
+ throw error;
76
+ }
77
+ }
78
+ /**
79
+ * Get current circuit state
80
+ */
81
+ getState() {
82
+ return this.state;
83
+ }
84
+ /**
85
+ * Get circuit breaker statistics
86
+ */
87
+ getStats() {
88
+ return {
89
+ state: this.state,
90
+ failures: this.failures,
91
+ successes: this.totalSuccesses,
92
+ totalCalls: this.totalCalls,
93
+ lastFailure: this.lastFailure,
94
+ lastSuccess: this.lastSuccess,
95
+ openedAt: this.openedAt,
96
+ };
97
+ }
98
+ /**
99
+ * Manually reset the circuit breaker
100
+ */
101
+ reset() {
102
+ this.state = "CLOSED";
103
+ this.failures = 0;
104
+ this.successes = 0;
105
+ this.totalSuccesses = 0;
106
+ this.recentFailures = [];
107
+ this.openedAt = undefined;
108
+ }
109
+ /**
110
+ * Manually open the circuit
111
+ */
112
+ open() {
113
+ this.state = "OPEN";
114
+ this.openedAt = new Date();
115
+ }
116
+ /**
117
+ * Handle successful call
118
+ */
119
+ onSuccess() {
120
+ this.totalSuccesses++;
121
+ this.lastSuccess = new Date();
122
+ if (this.state === "HALF_OPEN") {
123
+ this.successes++;
124
+ if (this.successes >= this.config.successThreshold) {
125
+ this.state = "CLOSED";
126
+ this.failures = 0;
127
+ this.recentFailures = [];
128
+ this.openedAt = undefined;
129
+ }
130
+ }
131
+ else if (this.state === "CLOSED") {
132
+ // Clear old failures outside monitoring period
133
+ this.cleanupRecentFailures();
134
+ }
135
+ }
136
+ /**
137
+ * Handle failed call
138
+ */
139
+ onFailure() {
140
+ this.failures++;
141
+ this.lastFailure = new Date();
142
+ this.recentFailures.push(this.lastFailure);
143
+ if (this.state === "HALF_OPEN") {
144
+ // Any failure in half-open state reopens the circuit
145
+ this.state = "OPEN";
146
+ this.openedAt = new Date();
147
+ this.successes = 0;
148
+ }
149
+ else if (this.state === "CLOSED") {
150
+ this.cleanupRecentFailures();
151
+ // Check if we've hit the failure threshold
152
+ if (this.recentFailures.length >= this.config.failureThreshold) {
153
+ this.state = "OPEN";
154
+ this.openedAt = new Date();
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Check if timeout has passed and we should try to reset
160
+ */
161
+ shouldAttemptReset() {
162
+ if (!this.openedAt)
163
+ return true;
164
+ return Date.now() - this.openedAt.getTime() >= this.config.timeout;
165
+ }
166
+ /**
167
+ * Remove failures outside the monitoring period
168
+ */
169
+ cleanupRecentFailures() {
170
+ const cutoff = Date.now() - this.config.monitoringPeriod;
171
+ this.recentFailures = this.recentFailures.filter((date) => date.getTime() > cutoff);
172
+ }
173
+ }
174
+ exports.CircuitBreaker = CircuitBreaker;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * API Gateway Utilities for ExpressoTS Micro Template
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createProxy = exports.ServiceProxy = exports.CircuitBreaker = void 0;
7
+ var circuit_breaker_js_1 = require("./circuit-breaker.js");
8
+ Object.defineProperty(exports, "CircuitBreaker", { enumerable: true, get: function () { return circuit_breaker_js_1.CircuitBreaker; } });
9
+ var service_proxy_js_1 = require("./service-proxy.js");
10
+ Object.defineProperty(exports, "ServiceProxy", { enumerable: true, get: function () { return service_proxy_js_1.ServiceProxy; } });
11
+ Object.defineProperty(exports, "createProxy", { enumerable: true, get: function () { return service_proxy_js_1.createProxy; } });
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServiceProxy = void 0;
4
+ exports.createProxy = createProxy;
5
+ const circuit_breaker_js_1 = require("./circuit-breaker.js");
6
+ /**
7
+ * ServiceProxy - Proxy requests to other microservices.
8
+ *
9
+ * Features:
10
+ * - Automatic request forwarding
11
+ * - Path rewriting
12
+ * - Custom headers
13
+ * - Request timeout
14
+ * - Retry support
15
+ * - Optional circuit breaker integration
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Proxy to user service
20
+ * const userProxy = createProxy({
21
+ * target: "http://user-service:3001",
22
+ * pathRewrite: (path) => path.replace("/api/users", ""),
23
+ * timeout: 5000,
24
+ * retries: 3,
25
+ * circuitBreaker: true,
26
+ * });
27
+ *
28
+ * app.Route.get("/api/users/*", userProxy.handler());
29
+ * app.Route.post("/api/users/*", userProxy.handler());
30
+ * ```
31
+ */
32
+ class ServiceProxy {
33
+ constructor(config) {
34
+ this.config = {
35
+ target: config.target,
36
+ timeout: config.timeout ?? 30000,
37
+ retries: config.retries ?? 0,
38
+ headers: config.headers ?? {},
39
+ pathRewrite: config.pathRewrite ?? ((path) => path),
40
+ debug: config.debug ?? false,
41
+ };
42
+ // Initialize circuit breaker if enabled
43
+ if (config.circuitBreaker) {
44
+ const cbConfig = typeof config.circuitBreaker === "object" ? config.circuitBreaker : undefined;
45
+ this.config.circuitBreaker = new circuit_breaker_js_1.CircuitBreaker(cbConfig);
46
+ }
47
+ }
48
+ /**
49
+ * Create an Express handler for proxying requests
50
+ */
51
+ handler() {
52
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
53
+ return async (req, res, _next) => {
54
+ try {
55
+ const result = await this.proxyRequest(req);
56
+ // Copy status and headers
57
+ res.status(result.status);
58
+ result.headers.forEach((value, key) => {
59
+ // Skip certain headers
60
+ if (!["content-encoding", "transfer-encoding"].includes(key.toLowerCase())) {
61
+ res.setHeader(key, value);
62
+ }
63
+ });
64
+ // Send body
65
+ const body = await result.text();
66
+ res.send(body);
67
+ }
68
+ catch (error) {
69
+ const errorMessage = error instanceof Error ? error.message : String(error);
70
+ if (this.config.debug) {
71
+ console.error(`[Proxy] Error:`, errorMessage);
72
+ }
73
+ if (errorMessage === "Circuit breaker is OPEN") {
74
+ res.status(503).json({
75
+ error: "Service temporarily unavailable",
76
+ service: this.config.target,
77
+ });
78
+ }
79
+ else if (error instanceof Error && error.name === "AbortError") {
80
+ res.status(504).json({
81
+ error: "Gateway timeout",
82
+ service: this.config.target,
83
+ });
84
+ }
85
+ else {
86
+ res.status(502).json({
87
+ error: "Bad gateway",
88
+ message: errorMessage,
89
+ service: this.config.target,
90
+ });
91
+ }
92
+ }
93
+ };
94
+ }
95
+ /**
96
+ * Proxy a request to the target service
97
+ */
98
+ async proxyRequest(req) {
99
+ const execute = async () => {
100
+ return await this.executeWithRetry(req);
101
+ };
102
+ if (this.config.circuitBreaker) {
103
+ return await this.config.circuitBreaker.execute(execute);
104
+ }
105
+ return await execute();
106
+ }
107
+ /**
108
+ * Execute request with retry logic
109
+ */
110
+ async executeWithRetry(req, attempt = 0) {
111
+ try {
112
+ return await this.executeRequest(req);
113
+ }
114
+ catch (error) {
115
+ if (attempt < this.config.retries) {
116
+ // Exponential backoff
117
+ await this.delay(Math.pow(2, attempt) * 100);
118
+ return await this.executeWithRetry(req, attempt + 1);
119
+ }
120
+ throw error;
121
+ }
122
+ }
123
+ /**
124
+ * Execute a single request
125
+ */
126
+ async executeRequest(req) {
127
+ // Rewrite path if configured
128
+ const path = this.config.pathRewrite(req.path);
129
+ const url = new URL(path, this.config.target);
130
+ // Copy query parameters
131
+ Object.entries(req.query).forEach(([key, value]) => {
132
+ if (typeof value === "string") {
133
+ url.searchParams.append(key, value);
134
+ }
135
+ });
136
+ // Build headers
137
+ const headers = {
138
+ ...this.extractHeaders(req),
139
+ ...this.config.headers,
140
+ };
141
+ // Build request options
142
+ const controller = new AbortController();
143
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
144
+ const requestInit = {
145
+ method: req.method,
146
+ headers,
147
+ signal: controller.signal,
148
+ };
149
+ // Add body for non-GET requests
150
+ if (req.method !== "GET" && req.method !== "HEAD" && req.body) {
151
+ requestInit.body = JSON.stringify(req.body);
152
+ headers["content-type"] = "application/json";
153
+ }
154
+ if (this.config.debug) {
155
+ console.log(`[Proxy] ${req.method} ${url.toString()}`);
156
+ }
157
+ try {
158
+ const response = await fetch(url.toString(), requestInit);
159
+ clearTimeout(timeoutId);
160
+ // Cast to ProxyResponse to avoid conflict with Express Response type
161
+ return response;
162
+ }
163
+ catch (error) {
164
+ clearTimeout(timeoutId);
165
+ throw error;
166
+ }
167
+ }
168
+ /**
169
+ * Extract relevant headers from incoming request
170
+ */
171
+ extractHeaders(req) {
172
+ const headers = {};
173
+ const forwardHeaders = [
174
+ "authorization",
175
+ "content-type",
176
+ "accept",
177
+ "user-agent",
178
+ "x-request-id",
179
+ "x-trace-id",
180
+ "x-span-id",
181
+ "x-correlation-id",
182
+ ];
183
+ forwardHeaders.forEach((header) => {
184
+ const value = req.headers[header];
185
+ if (typeof value === "string") {
186
+ headers[header] = value;
187
+ }
188
+ });
189
+ // Add X-Forwarded headers
190
+ headers["x-forwarded-for"] = req.ip || req.socket.remoteAddress || "unknown";
191
+ headers["x-forwarded-host"] = req.headers.host || "";
192
+ headers["x-forwarded-proto"] = req.protocol;
193
+ return headers;
194
+ }
195
+ /**
196
+ * Delay helper
197
+ */
198
+ delay(ms) {
199
+ return new Promise((resolve) => setTimeout(resolve, ms));
200
+ }
201
+ /**
202
+ * Get circuit breaker stats (if enabled)
203
+ */
204
+ getCircuitBreakerStats() {
205
+ return this.config.circuitBreaker?.getStats();
206
+ }
207
+ }
208
+ exports.ServiceProxy = ServiceProxy;
209
+ /**
210
+ * Create a new service proxy
211
+ */
212
+ function createProxy(config) {
213
+ return new ServiceProxy(config);
214
+ }
@@ -1,5 +1,29 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createMicroAPI = void 0;
4
- var application_express_micro_1 = require("./application-express-micro");
5
- Object.defineProperty(exports, "createMicroAPI", { enumerable: true, get: function () { return application_express_micro_1.createMicroAPI; } });
17
+ exports.createMicroAPI = exports.micro = void 0;
18
+ // Primary API - pure simplicity
19
+ var micro_js_1 = require("./micro.js");
20
+ Object.defineProperty(exports, "micro", { enumerable: true, get: function () { return micro_js_1.micro; } });
21
+ // Advanced features - import separately when needed
22
+ __exportStar(require("./gateway/index.js"), exports); // CircuitBreaker, ServiceProxy
23
+ __exportStar(require("./service-mesh/index.js"), exports); // ServiceDiscovery, ServiceClient
24
+ __exportStar(require("./serverless/index.js"), exports); // Lambda, Cloudflare, Vercel adapters
25
+ __exportStar(require("./queue/index.js"), exports); // RabbitMQ consumer
26
+ // Legacy API - deprecated, will be removed in v6
27
+ /** @deprecated Use micro() instead */
28
+ var application_express_micro_js_1 = require("./application-express-micro.js");
29
+ Object.defineProperty(exports, "createMicroAPI", { enumerable: true, get: function () { return application_express_micro_js_1.createMicroAPI; } });
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.micro = micro;
7
+ const core_1 = require("@expressots/core");
8
+ const express_1 = __importDefault(require("express"));
9
+ const application_express_js_1 = require("../application-express.js");
10
+ /**
11
+ * Create a new micro API instance
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const app = micro();
16
+ * app.get("/", () => "Hello World");
17
+ * app.listen(3000);
18
+ * ```
19
+ *
20
+ * @param config - Optional configuration
21
+ * @returns MicroApp instance
22
+ * @public API
23
+ */
24
+ function micro(config) {
25
+ // Disable the log buffering from AppExpress since micro() doesn't use the banner system
26
+ // This restores normal console output for micro API users
27
+ application_express_js_1.AppExpress.disableBuffering();
28
+ const app = (0, express_1.default)();
29
+ const logger = new core_1.Logger();
30
+ const console = new core_1.Console();
31
+ const globalPrefix = config?.globalPrefix?.replace(/\/$/, "") || "";
32
+ let httpServer;
33
+ let errorHandler = null;
34
+ // Auto-enable JSON parsing by default
35
+ if (config?.autoParseJson !== false) {
36
+ app.use(express_1.default.json());
37
+ app.use(express_1.default.urlencoded({ extended: true }));
38
+ }
39
+ /**
40
+ * Wrap handler to auto-send return values
41
+ */
42
+ const wrapHandler = (handler) => {
43
+ return async (req, res, next) => {
44
+ try {
45
+ const result = await handler(req, res, next);
46
+ // If response already sent, don't send again
47
+ if (res.headersSent) {
48
+ return;
49
+ }
50
+ // Auto-send return values
51
+ if (result !== undefined) {
52
+ if (typeof result === "string") {
53
+ res.send(result);
54
+ }
55
+ else {
56
+ res.json(result);
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ next(error);
62
+ }
63
+ };
64
+ };
65
+ /**
66
+ * Register a route with Express-style middleware ordering
67
+ */
68
+ const route = (method, path, ...handlers) => {
69
+ const fullPath = `${globalPrefix}${path.startsWith("/") ? path : `/${path}`}`;
70
+ const handler = handlers.pop();
71
+ const middleware = handlers;
72
+ app[method](fullPath, ...middleware, wrapHandler(handler));
73
+ logger.info(`Route ${method.toUpperCase()} '${fullPath}' registered`, "micro");
74
+ // Register in the suggestions engine so 404s can produce "Did you mean ...?"
75
+ try {
76
+ (0, core_1.getRouteRegistry)().register(method.toUpperCase(), fullPath, fullPath);
77
+ }
78
+ catch {
79
+ // Suggestions registry is optional; never fail registration because of it.
80
+ }
81
+ return microApp;
82
+ };
83
+ /**
84
+ * Install a catch-all 404 fallback that mirrors the behavior of the full
85
+ * inversify-express-server: log "Did you mean ...?" via the framework Logger
86
+ * and respond with a structured RFC-7807-style JSON body.
87
+ *
88
+ * Skipped entirely when the suggestion engine is disabled (the env-aware
89
+ * default disables it in NODE_ENV=production).
90
+ */
91
+ const installNotFoundHandler = () => {
92
+ app.use((req, res, next) => {
93
+ if (res.headersSent) {
94
+ return next();
95
+ }
96
+ const suggestionsConfig = (0, core_1.getDefaultSuggestionsConfig)();
97
+ if (!suggestionsConfig.enabled) {
98
+ return next();
99
+ }
100
+ const requestedPath = req.originalUrl || req.url;
101
+ const requestedMethod = req.method;
102
+ const hints = (0, core_1.getErrorHints)(new Error(`Route '${requestedMethod} ${requestedPath}' not found`), {
103
+ path: requestedPath,
104
+ method: requestedMethod,
105
+ statusCode: 404,
106
+ }, suggestionsConfig);
107
+ if (hints.length > 0) {
108
+ try {
109
+ const formatted = (0, core_1.formatSuggestions)(hints);
110
+ if (formatted) {
111
+ logger.warn(`Route not found: ${requestedMethod} ${requestedPath}${formatted}`, "router-404");
112
+ }
113
+ }
114
+ catch {
115
+ // best-effort logging
116
+ }
117
+ }
118
+ const routeSuggestion = hints.find((hint) => hint.type === "route");
119
+ const actionHint = hints.find((hint) => hint.type === "hint");
120
+ const body = {
121
+ type: "https://expressots.dev/errors/not-found",
122
+ title: "Route Not Found",
123
+ status: 404,
124
+ detail: `Route '${requestedMethod} ${requestedPath}' does not exist`,
125
+ instance: requestedPath,
126
+ timestamp: new Date().toISOString(),
127
+ };
128
+ if (routeSuggestion?.routes && routeSuggestion.routes.length > 0) {
129
+ body.suggestions = routeSuggestion.routes.map((suggestion) => ({
130
+ method: suggestion.route.method,
131
+ path: suggestion.route.fullPath || suggestion.route.path,
132
+ similarity: Math.round(suggestion.similarity * 100),
133
+ reason: suggestion.reason,
134
+ }));
135
+ }
136
+ else if (actionHint?.actions && actionHint.actions.length > 0) {
137
+ body.actions = actionHint.actions;
138
+ }
139
+ res.status(404).type("application/json").send(JSON.stringify(body));
140
+ });
141
+ };
142
+ /**
143
+ * Handle server shutdown gracefully
144
+ */
145
+ const handleExit = () => {
146
+ logger.info("Server shutting down", "micro");
147
+ process.exit(0);
148
+ };
149
+ const microApp = {
150
+ get: (path, ...handlers) => route("get", path, ...handlers),
151
+ post: (path, ...handlers) => route("post", path, ...handlers),
152
+ put: (path, ...handlers) => route("put", path, ...handlers),
153
+ patch: (path, ...handlers) => route("patch", path, ...handlers),
154
+ delete: (path, ...handlers) => route("delete", path, ...handlers),
155
+ use(...args) {
156
+ if (typeof args[0] === "string") {
157
+ app.use(args[0], ...args.slice(1));
158
+ }
159
+ else {
160
+ app.use(...args);
161
+ }
162
+ return microApp;
163
+ },
164
+ setErrorHandler(handler) {
165
+ errorHandler = handler;
166
+ return microApp;
167
+ },
168
+ async listen(port, appInfo) {
169
+ const normalizedPort = typeof port === "string" ? parseInt(port, 10) : port;
170
+ // Install the 404 fallback before the user error handler so unmatched
171
+ // routes get suggestions instead of falling through to the default
172
+ // Express HTML or - worse - to a regular middleware that arity-confused
173
+ // its way into running on every request.
174
+ installNotFoundHandler();
175
+ // Apply error handler last. Wrap it in a 4-arity function so that
176
+ // Express recognizes it as an error-handling middleware regardless of
177
+ // whether the user wrote `(err, req, res)` or `(err, req, res, next)`.
178
+ // Without this wrapper, Express would treat a 3-arg user handler as a
179
+ // regular middleware and run it on every request, which both swallows
180
+ // 404s and crashes when the user calls `res.status(...)` (positional
181
+ // `res` would actually be Express's `next`).
182
+ if (errorHandler) {
183
+ const userHandler = errorHandler;
184
+ const wrappedErrorHandler = (err, req, res, next) => userHandler(err, req, res, next);
185
+ app.use(wrappedErrorHandler);
186
+ }
187
+ return new Promise((resolve, reject) => {
188
+ httpServer = app.listen(normalizedPort, async () => {
189
+ const address = httpServer.address();
190
+ const actualPort = typeof address === "object" && address?.port ? address.port : normalizedPort;
191
+ if (config?.showBanner !== false) {
192
+ await console.messageServer(actualPort, "development", {
193
+ appName: appInfo?.appName || "ExpressoTS Micro",
194
+ appVersion: appInfo?.appVersion || "1.0.0",
195
+ });
196
+ }
197
+ // Handle graceful shutdown
198
+ ["SIGTERM", "SIGHUP", "SIGBREAK", "SIGQUIT", "SIGINT"].forEach((signal) => {
199
+ process.on(signal, handleExit);
200
+ });
201
+ resolve();
202
+ });
203
+ httpServer.on("error", (error) => {
204
+ logger.error(`Server error: ${error.message}`, "micro");
205
+ reject(error);
206
+ });
207
+ });
208
+ },
209
+ getHttpServer() {
210
+ return httpServer;
211
+ },
212
+ getApp() {
213
+ return app;
214
+ },
215
+ };
216
+ return microApp;
217
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Queue Integration for ExpressoTS Micro Template
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RabbitMQConsumer = void 0;
7
+ var rabbitmq_consumer_js_1 = require("./rabbitmq-consumer.js");
8
+ Object.defineProperty(exports, "RabbitMQConsumer", { enumerable: true, get: function () { return rabbitmq_consumer_js_1.RabbitMQConsumer; } });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });