@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,272 @@
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
+ const index_js_1 = require("../studio/index.js");
11
+ /**
12
+ * Create a new micro API instance
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const app = micro();
17
+ * app.get("/", () => "Hello World");
18
+ * app.listen(3000);
19
+ * ```
20
+ *
21
+ * @param config - Optional configuration
22
+ * @returns MicroApp instance
23
+ * @public API
24
+ */
25
+ function micro(config) {
26
+ // Disable the log buffering from AppExpress since micro() doesn't use the banner system
27
+ // This restores normal console output for micro API users
28
+ application_express_js_1.AppExpress.disableBuffering();
29
+ const app = (0, express_1.default)();
30
+ const logger = new core_1.Logger();
31
+ const globalPrefix = config?.globalPrefix?.replace(/\/$/, "") || "";
32
+ let httpServer;
33
+ let errorHandler = null;
34
+ let studioConfig = config?.studio ?? {};
35
+ // Lazy proxy for the Studio Agent middleware. Installed at position 0 so
36
+ // it always runs before route handlers — even though initializeStudio()
37
+ // is only called in listen(). Once the agent starts, it sets the real
38
+ // handler; until then the proxy is a no-op pass-through.
39
+ let studioMiddlewareDelegate = null;
40
+ app.use((req, res, next) => {
41
+ if (studioMiddlewareDelegate) {
42
+ return studioMiddlewareDelegate(req, res, next);
43
+ }
44
+ next();
45
+ });
46
+ // Auto-enable JSON parsing by default
47
+ if (config?.autoParseJson !== false) {
48
+ app.use(express_1.default.json());
49
+ app.use(express_1.default.urlencoded({ extended: true }));
50
+ }
51
+ /**
52
+ * Wrap handler to auto-send return values
53
+ */
54
+ const wrapHandler = (handler) => {
55
+ return async (req, res, next) => {
56
+ try {
57
+ const result = await handler(req, res, next);
58
+ // If response already sent, don't send again
59
+ if (res.headersSent) {
60
+ return;
61
+ }
62
+ // Auto-send return values
63
+ if (result !== undefined) {
64
+ if (typeof result === "string") {
65
+ res.send(result);
66
+ }
67
+ else {
68
+ res.json(result);
69
+ }
70
+ }
71
+ }
72
+ catch (error) {
73
+ next(error);
74
+ }
75
+ };
76
+ };
77
+ /**
78
+ * Register a route with Express-style middleware ordering
79
+ */
80
+ const route = (method, path, ...handlers) => {
81
+ const fullPath = `${globalPrefix}${path.startsWith("/") ? path : `/${path}`}`;
82
+ const handler = handlers.pop();
83
+ const middleware = handlers;
84
+ app[method](fullPath, ...middleware, wrapHandler(handler));
85
+ logger.info(`Route ${method.toUpperCase()} '${fullPath}' registered`, "micro");
86
+ // Register in the suggestions engine so 404s can produce "Did you mean ...?"
87
+ try {
88
+ (0, core_1.getRouteRegistry)().register(method.toUpperCase(), fullPath, fullPath);
89
+ }
90
+ catch {
91
+ // Suggestions registry is optional; never fail registration because of it.
92
+ }
93
+ return microApp;
94
+ };
95
+ /**
96
+ * Install a catch-all 404 fallback that mirrors the behavior of the full
97
+ * inversify-express-server: log "Did you mean ...?" via the framework Logger
98
+ * and respond with a structured RFC-7807-style JSON body.
99
+ *
100
+ * Skipped entirely when the suggestion engine is disabled (the env-aware
101
+ * default disables it in NODE_ENV=production).
102
+ */
103
+ const installNotFoundHandler = () => {
104
+ app.use((req, res, next) => {
105
+ if (res.headersSent) {
106
+ return next();
107
+ }
108
+ const requestedPath = req.originalUrl || req.url;
109
+ const requestedMethod = req.method;
110
+ const body = {
111
+ type: "https://expressots.dev/errors/not-found",
112
+ title: "Route Not Found",
113
+ status: 404,
114
+ detail: `Route '${requestedMethod} ${requestedPath}' does not exist`,
115
+ instance: requestedPath,
116
+ timestamp: new Date().toISOString(),
117
+ };
118
+ const suggestionsConfig = (0, core_1.getDefaultSuggestionsConfig)();
119
+ if (suggestionsConfig.enabled) {
120
+ const hints = (0, core_1.getErrorHints)(new Error(`Route '${requestedMethod} ${requestedPath}' not found`), {
121
+ path: requestedPath,
122
+ method: requestedMethod,
123
+ statusCode: 404,
124
+ }, suggestionsConfig);
125
+ if (hints.length > 0) {
126
+ try {
127
+ const formatted = (0, core_1.formatSuggestions)(hints);
128
+ if (formatted) {
129
+ logger.warn(`Route not found: ${requestedMethod} ${requestedPath}${formatted}`, "router-404");
130
+ }
131
+ }
132
+ catch {
133
+ // best-effort logging
134
+ }
135
+ const routeSuggestion = hints.find((hint) => hint.type === "route");
136
+ const actionHint = hints.find((hint) => hint.type === "hint");
137
+ if (routeSuggestion?.routes && routeSuggestion.routes.length > 0) {
138
+ body.suggestions = routeSuggestion.routes.map((suggestion) => ({
139
+ method: suggestion.route.method,
140
+ path: suggestion.route.fullPath || suggestion.route.path,
141
+ similarity: Math.round(suggestion.similarity * 100),
142
+ reason: suggestion.reason,
143
+ }));
144
+ }
145
+ else if (actionHint?.actions && actionHint.actions.length > 0) {
146
+ body.actions = actionHint.actions;
147
+ }
148
+ }
149
+ }
150
+ res.status(404).type("application/json").send(JSON.stringify(body));
151
+ });
152
+ };
153
+ /**
154
+ * Handle server shutdown. In development, exit immediately for fast
155
+ * hot-reload. In production, drain connections before exiting.
156
+ */
157
+ const handleExit = () => {
158
+ const environment = config?.environment || process.env.NODE_ENV || "development";
159
+ void (0, index_js_1.stopStudio)();
160
+ if (environment === "development") {
161
+ process.exit(0);
162
+ }
163
+ if (httpServer) {
164
+ httpServer.close(() => process.exit(0));
165
+ setTimeout(() => process.exit(0), 5000).unref();
166
+ }
167
+ else {
168
+ process.exit(0);
169
+ }
170
+ };
171
+ const microApp = {
172
+ get: (path, ...handlers) => route("get", path, ...handlers),
173
+ post: (path, ...handlers) => route("post", path, ...handlers),
174
+ put: (path, ...handlers) => route("put", path, ...handlers),
175
+ patch: (path, ...handlers) => route("patch", path, ...handlers),
176
+ delete: (path, ...handlers) => route("delete", path, ...handlers),
177
+ use(...args) {
178
+ if (typeof args[0] === "string") {
179
+ app.use(args[0], ...args.slice(1));
180
+ }
181
+ else {
182
+ app.use(...args);
183
+ }
184
+ return microApp;
185
+ },
186
+ setErrorHandler(handler) {
187
+ errorHandler = handler;
188
+ return microApp;
189
+ },
190
+ async listen(port, appInfo) {
191
+ const normalizedPort = typeof port === "string" ? parseInt(port, 10) : port;
192
+ const listenStartedAt = Date.now();
193
+ // Initialize Studio Agent. The agent's middleware is registered via
194
+ // app.use() inside initializeStudio, but that lands AFTER the user's
195
+ // routes in the Express stack. Our lazy proxy (installed at position 0
196
+ // during micro() creation) ensures CORS headers are injected before
197
+ // any route handler sends a response.
198
+ const studioStarted = await (0, index_js_1.initializeStudio)(app, {
199
+ ...studioConfig,
200
+ serviceName: studioConfig.serviceName ?? "expressots-micro",
201
+ appPort: normalizedPort,
202
+ globalPrefix: globalPrefix || undefined,
203
+ });
204
+ if (studioStarted) {
205
+ const agent = (0, index_js_1.getStudioAgent)();
206
+ if (agent) {
207
+ studioMiddlewareDelegate = agent.createMiddleware();
208
+ }
209
+ }
210
+ // Install the 404 fallback before the user error handler so unmatched
211
+ // routes get suggestions instead of falling through to the default
212
+ // Express HTML or - worse - to a regular middleware that arity-confused
213
+ // its way into running on every request.
214
+ installNotFoundHandler();
215
+ // Apply error handler last. Wrap it in a 4-arity function so that
216
+ // Express recognizes it as an error-handling middleware regardless of
217
+ // whether the user wrote `(err, req, res)` or `(err, req, res, next)`.
218
+ // Without this wrapper, Express would treat a 3-arg user handler as a
219
+ // regular middleware and run it on every request, which both swallows
220
+ // 404s and crashes when the user calls `res.status(...)` (positional
221
+ // `res` would actually be Express's `next`).
222
+ if (errorHandler) {
223
+ const userHandler = errorHandler;
224
+ const wrappedErrorHandler = (err, req, res, next) => userHandler(err, req, res, next);
225
+ app.use(wrappedErrorHandler);
226
+ }
227
+ return new Promise((resolve, reject) => {
228
+ httpServer = app.listen(normalizedPort, async () => {
229
+ const address = httpServer.address();
230
+ const actualPort = typeof address === "object" && address?.port ? address.port : normalizedPort;
231
+ if (config?.showBanner !== false) {
232
+ const name = appInfo?.appName || "ExpressoTS Micro";
233
+ const version = appInfo?.appVersion || "1.0.0";
234
+ const environment = config?.environment || process.env.NODE_ENV || "development";
235
+ logger.info(`${name} version ${version} is running on port ${actualPort} - Environment: ${environment}`, "micro");
236
+ }
237
+ // Push runtime info to Studio Agent now that we know the actual port
238
+ (0, index_js_1.reportStudioRuntimeInfo)({
239
+ appPort: actualPort,
240
+ globalPrefix: globalPrefix || undefined,
241
+ startupMs: Date.now() - listenStartedAt,
242
+ });
243
+ // Re-scan routes so Studio sees the fully-populated Express router
244
+ void (0, index_js_1.rescanStudioRoutes)();
245
+ // Handle graceful shutdown
246
+ ["SIGTERM", "SIGHUP", "SIGBREAK", "SIGQUIT", "SIGINT"].forEach((signal) => {
247
+ process.on(signal, handleExit);
248
+ });
249
+ resolve();
250
+ });
251
+ httpServer.on("error", (error) => {
252
+ logger.error(`Server error: ${error.message}`, "micro");
253
+ reject(error);
254
+ });
255
+ });
256
+ },
257
+ getHttpServer() {
258
+ return httpServer ?? null;
259
+ },
260
+ getApp() {
261
+ return app;
262
+ },
263
+ setStudio(cfg) {
264
+ studioConfig = cfg;
265
+ return microApp;
266
+ },
267
+ isStudioEnabled() {
268
+ return (0, index_js_1.isStudioEnabled)();
269
+ },
270
+ };
271
+ return microApp;
272
+ }
@@ -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 });
@@ -0,0 +1,255 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.RabbitMQConsumer = void 0;
27
+ /**
28
+ * Load amqplib dynamically to avoid requiring it as a dependency
29
+ */
30
+ async function loadAmqpLib() {
31
+ try {
32
+ // `amqplib` is an OPTIONAL peer dep - it is intentionally not installed
33
+ // in this package's devDependencies. We route the specifier through a
34
+ // variable so TypeScript does not try to statically resolve it during
35
+ // build (TS treats variable-typed specifiers in `await import(...)` as
36
+ // `any` and skips the resolution check). Resolution happens at runtime
37
+ // in user apps that have actually installed amqplib.
38
+ const specifier = "amqplib";
39
+ const amqp = (await Promise.resolve(`${specifier}`).then(s => __importStar(require(s))));
40
+ return amqp;
41
+ }
42
+ catch {
43
+ throw new Error("amqplib is not installed. Install it with: npm install amqplib @types/amqplib");
44
+ }
45
+ }
46
+ /**
47
+ * RabbitMQ Consumer - Message queue consumer for RabbitMQ.
48
+ *
49
+ * Features:
50
+ * - Message consumption with handlers
51
+ * - Message publishing
52
+ * - Exchange support
53
+ * - Automatic reconnection
54
+ * - Prefetch control
55
+ * - Dead letter queue support
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const orderQueue = new RabbitMQConsumer({
60
+ * url: process.env.RABBITMQ_URL,
61
+ * queue: "orders",
62
+ * prefetch: 10,
63
+ * });
64
+ *
65
+ * // Start consuming
66
+ * await orderQueue.consume(async (message) => {
67
+ * const order = message.body;
68
+ * console.log("Processing order:", order.id);
69
+ * await processOrder(order);
70
+ * });
71
+ *
72
+ * // Publish from HTTP endpoint
73
+ * app.Route.post("/orders", async (req, res) => {
74
+ * await orderQueue.publish(req.body);
75
+ * res.status(202).json({ message: "Order queued" });
76
+ * });
77
+ *
78
+ * // Graceful shutdown
79
+ * process.on("SIGTERM", async () => {
80
+ * await orderQueue.close();
81
+ * });
82
+ * ```
83
+ *
84
+ * Note: This implementation requires the 'amqplib' package.
85
+ * Install with: npm install amqplib @types/amqplib
86
+ */
87
+ class RabbitMQConsumer {
88
+ constructor(config) {
89
+ // Using 'any' for AMQP types since amqplib is an optional peer dependency
90
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
+ this.connection = null;
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ this.channel = null;
94
+ this.stats = {
95
+ messagesReceived: 0,
96
+ messagesProcessed: 0,
97
+ messagesFailed: 0,
98
+ messagesPublished: 0,
99
+ isConnected: false,
100
+ };
101
+ this.config = {
102
+ queue: config.queue,
103
+ url: config.url,
104
+ exchange: config.exchange ?? "",
105
+ exchangeType: config.exchangeType ?? "direct",
106
+ routingKey: config.routingKey ?? config.queue,
107
+ prefetch: config.prefetch ?? 1,
108
+ durable: config.durable ?? true,
109
+ concurrency: config.concurrency ?? 1,
110
+ autoAck: config.autoAck ?? true,
111
+ debug: config.debug ?? false,
112
+ };
113
+ }
114
+ /**
115
+ * Connect to RabbitMQ
116
+ */
117
+ async connect() {
118
+ if (this.connection)
119
+ return;
120
+ try {
121
+ const amqp = await loadAmqpLib();
122
+ this.connection = await amqp.connect(this.config.url);
123
+ this.channel = await this.connection.createChannel();
124
+ // Set prefetch
125
+ await this.channel.prefetch(this.config.prefetch);
126
+ // Declare queue
127
+ await this.channel.assertQueue(this.config.queue, {
128
+ durable: this.config.durable,
129
+ });
130
+ // Declare exchange if configured
131
+ if (this.config.exchange) {
132
+ await this.channel.assertExchange(this.config.exchange, this.config.exchangeType, {
133
+ durable: true,
134
+ });
135
+ // Bind queue to exchange
136
+ await this.channel.bindQueue(this.config.queue, this.config.exchange, this.config.routingKey);
137
+ }
138
+ this.stats.isConnected = true;
139
+ if (this.config.debug) {
140
+ console.log(`[RabbitMQ] Connected to ${this.config.url}, queue: ${this.config.queue}`);
141
+ }
142
+ // Handle connection close
143
+ this.connection.on("close", () => {
144
+ this.stats.isConnected = false;
145
+ console.log("[RabbitMQ] Connection closed");
146
+ });
147
+ this.connection.on("error", (err) => {
148
+ console.error("[RabbitMQ] Connection error:", err);
149
+ });
150
+ }
151
+ catch (error) {
152
+ console.error("[RabbitMQ] Failed to connect:", error);
153
+ throw error;
154
+ }
155
+ }
156
+ /**
157
+ * Start consuming messages
158
+ */
159
+ async consume(handler) {
160
+ await this.connect();
161
+ if (!this.channel) {
162
+ throw new Error("Channel not initialized");
163
+ }
164
+ await this.channel.consume(this.config.queue,
165
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
166
+ async (msg) => {
167
+ if (!msg)
168
+ return;
169
+ this.stats.messagesReceived++;
170
+ this.stats.lastMessageAt = new Date();
171
+ try {
172
+ // Parse message
173
+ const body = JSON.parse(msg.content.toString());
174
+ const queueMessage = {
175
+ id: msg.properties.messageId || Date.now().toString(36),
176
+ body,
177
+ headers: msg.properties.headers,
178
+ timestamp: new Date(msg.properties.timestamp || Date.now()),
179
+ receiveCount: msg.properties.headers?.["x-delivery-count"] || 1,
180
+ raw: msg,
181
+ };
182
+ if (this.config.debug) {
183
+ console.log(`[RabbitMQ] Received message:`, queueMessage.id);
184
+ }
185
+ // Process message
186
+ await handler(queueMessage);
187
+ this.stats.messagesProcessed++;
188
+ // Acknowledge
189
+ if (!this.config.autoAck && this.channel) {
190
+ this.channel.ack(msg);
191
+ }
192
+ }
193
+ catch (error) {
194
+ this.stats.messagesFailed++;
195
+ console.error("[RabbitMQ] Message processing failed:", error);
196
+ // Reject and requeue if not auto-ack
197
+ if (!this.config.autoAck && this.channel) {
198
+ this.channel.nack(msg, false, true);
199
+ }
200
+ }
201
+ }, { noAck: this.config.autoAck });
202
+ if (this.config.debug) {
203
+ console.log(`[RabbitMQ] Consuming from ${this.config.queue}`);
204
+ }
205
+ }
206
+ /**
207
+ * Publish a message to the queue
208
+ */
209
+ async publish(message) {
210
+ await this.connect();
211
+ if (!this.channel) {
212
+ throw new Error("Channel not initialized");
213
+ }
214
+ const content = Buffer.from(JSON.stringify(message));
215
+ const properties = {
216
+ messageId: Date.now().toString(36),
217
+ timestamp: Date.now(),
218
+ contentType: "application/json",
219
+ };
220
+ if (this.config.exchange) {
221
+ this.channel.publish(this.config.exchange, this.config.routingKey, content, properties);
222
+ }
223
+ else {
224
+ this.channel.sendToQueue(this.config.queue, content, properties);
225
+ }
226
+ this.stats.messagesPublished++;
227
+ if (this.config.debug) {
228
+ console.log(`[RabbitMQ] Published message to ${this.config.queue}`);
229
+ }
230
+ }
231
+ /**
232
+ * Close the connection
233
+ */
234
+ async close() {
235
+ if (this.channel) {
236
+ await this.channel.close();
237
+ this.channel = null;
238
+ }
239
+ if (this.connection) {
240
+ await this.connection.close();
241
+ this.connection = null;
242
+ }
243
+ this.stats.isConnected = false;
244
+ if (this.config.debug) {
245
+ console.log("[RabbitMQ] Connection closed");
246
+ }
247
+ }
248
+ /**
249
+ * Get consumer statistics
250
+ */
251
+ getStats() {
252
+ return { ...this.stats };
253
+ }
254
+ }
255
+ exports.RabbitMQConsumer = RabbitMQConsumer;