@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,236 @@
1
+ /**
2
+ * Studio Integration - Auto-detects and integrates ExpressoTS Studio Agent
3
+ *
4
+ * This module provides automatic integration with @expressots/studio-agent
5
+ * when it's installed in the project. It enables request recording, tracing,
6
+ * and real-time monitoring without requiring manual setup.
7
+ */
8
+ import { Logger } from "@expressots/core";
9
+ // Lazy logger accessor so `new Logger()` only fires the first time we
10
+ // actually emit a Studio message. Routing through Logger means the
11
+ // framework's log-level configuration (e.g. `LOG_LEVEL=WARN`) silences
12
+ // the "listening" line as expected, instead of `console.log` always
13
+ // printing it. Lazy construction also keeps consumers that mock
14
+ // `@expressots/core` (test environments) from blowing up at module
15
+ // load when their Logger mock omits `.withContext`.
16
+ let _studioLogger = null;
17
+ function logger() {
18
+ if (!_studioLogger) {
19
+ _studioLogger = new Logger().withContext("studio");
20
+ }
21
+ return _studioLogger;
22
+ }
23
+ let studioAgent = null;
24
+ let studioEnabled = false;
25
+ /**
26
+ * Check if `@expressots/studio-agent` is installed and importable from the
27
+ * current process. Uses a dynamic `import()` rather than `require.resolve`
28
+ * because the latter is unavailable in pure-ESM consumers — adapter-express
29
+ * is published as a dual CJS/ESM build and this helper is exercised by both
30
+ * targets.
31
+ *
32
+ * The result is cached on first hit (success) so we avoid paying for the
33
+ * import twice. On failure we always retry, since the user may install the
34
+ * package mid-session in `expressots dev` workflows.
35
+ */
36
+ let _studioAgentModule = null;
37
+ async function isStudioAgentInstalled() {
38
+ const debug = process.env.EXPRESSOTS_STUDIO_DEBUG === "true";
39
+ if (_studioAgentModule !== null)
40
+ return true;
41
+ try {
42
+ // Dynamic import works for both CJS (returns module.exports) and ESM
43
+ // (returns the ESM namespace). If the package isn't installed, Node
44
+ // throws ERR_MODULE_NOT_FOUND / MODULE_NOT_FOUND, which we treat as
45
+ // "agent not present" — adapter-express continues without Studio.
46
+ _studioAgentModule = await import("@expressots/studio-agent");
47
+ if (debug)
48
+ console.log("[Studio] Loaded studio-agent successfully");
49
+ return true;
50
+ }
51
+ catch (error) {
52
+ if (debug)
53
+ console.log("[Studio] Cannot load studio-agent:", error instanceof Error ? error.message : error);
54
+ return false;
55
+ }
56
+ }
57
+ /**
58
+ * Initialize the Studio Agent if available
59
+ */
60
+ export async function initializeStudio(app, config = {}, appContainer) {
61
+ const debug = process.env.EXPRESSOTS_STUDIO_DEBUG === "true";
62
+ // Check if explicitly disabled
63
+ if (config.enabled === false || process.env.EXPRESSOTS_STUDIO === "false") {
64
+ if (debug)
65
+ console.log("[Studio] Disabled via config or env");
66
+ return false;
67
+ }
68
+ // Only enable in development by default
69
+ const isDev = process.env.NODE_ENV === "development" || !process.env.NODE_ENV;
70
+ if (!isDev && config.enabled !== true) {
71
+ if (debug)
72
+ console.log("[Studio] Not in development mode, skipping");
73
+ return false;
74
+ }
75
+ // Check if studio-agent is installed
76
+ const installed = await isStudioAgentInstalled();
77
+ if (debug)
78
+ console.log("[Studio] studio-agent installed:", installed);
79
+ if (!installed) {
80
+ return false;
81
+ }
82
+ // Defensive: if a previous agent instance from this same process is still
83
+ // around (e.g. App.init() called twice without a stop in between) shut it
84
+ // down first so we don't leak the WebSocket port.
85
+ if (studioAgent) {
86
+ try {
87
+ await studioAgent.stop();
88
+ }
89
+ catch {
90
+ // best-effort cleanup
91
+ }
92
+ studioAgent = null;
93
+ studioEnabled = false;
94
+ }
95
+ try {
96
+ if (debug)
97
+ console.log("[Studio] Attempting dynamic import...");
98
+ // Dynamic import for ESM module
99
+ const studioAgentModule = await import("@expressots/studio-agent");
100
+ if (debug)
101
+ console.log("[Studio] Import successful, keys:", Object.keys(studioAgentModule));
102
+ // studio-agent ships only named exports; cast through `any` so the
103
+ // ESM build does not reject the legacy `default.StudioAgent`
104
+ // fallback (kept for older preview tarballs).
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ const studioAgentModuleAny = studioAgentModule;
107
+ const StudioAgent = studioAgentModuleAny.StudioAgent || studioAgentModuleAny.default?.StudioAgent;
108
+ if (!StudioAgent) {
109
+ logger().warn("Studio Agent module found but StudioAgent class not exported");
110
+ if (debug)
111
+ logger().debug(`Module contents: ${Object.keys(studioAgentModule).join(", ")}`);
112
+ return false;
113
+ }
114
+ if (debug)
115
+ console.log("[Studio] StudioAgent class found, initializing...");
116
+ const agentOptions = {
117
+ port: config.port ?? parseInt(process.env.EXPRESSOTS_STUDIO_PORT ?? "3334", 10),
118
+ dbPath: config.dbPath ?? process.env.EXPRESSOTS_STUDIO_DB ?? ".studio/studio.db",
119
+ serviceName: config.serviceName ?? "expressots-app",
120
+ enableRecording: true,
121
+ enableProfiling: true,
122
+ expressApp: app, // Pass Express app for runtime route scanning
123
+ appContainer, // Pass AppContainer so the agent can build a DI snapshot
124
+ appPort: config.appPort,
125
+ globalPrefix: config.globalPrefix,
126
+ };
127
+ studioAgent = new StudioAgent(agentOptions);
128
+ // Add the middleware BEFORE other routes to capture all requests
129
+ const middleware = studioAgent.createMiddleware();
130
+ app.use(middleware);
131
+ // Start the agent (this also scans routes)
132
+ await studioAgent.start();
133
+ studioEnabled = true;
134
+ logger().info(`Studio Agent listening on ws://localhost:${agentOptions.port}`);
135
+ return true;
136
+ }
137
+ catch (error) {
138
+ // Best-effort cleanup so a half-initialised agent doesn't hold the
139
+ // WebSocket port across a retry.
140
+ if (studioAgent) {
141
+ try {
142
+ await studioAgent.stop();
143
+ }
144
+ catch {
145
+ // ignore
146
+ }
147
+ studioAgent = null;
148
+ }
149
+ studioEnabled = false;
150
+ const errorMessage = error instanceof Error ? error.message : String(error);
151
+ const errorCode = error && typeof error === "object" && "code" in error
152
+ ? error.code
153
+ : undefined;
154
+ // Expected when @expressots/studio-agent isn't installed — silent.
155
+ if (errorMessage.includes("Cannot find module") ||
156
+ errorMessage.includes("ERR_MODULE_NOT_FOUND")) {
157
+ return false;
158
+ }
159
+ // Friendlier message for the most common failure mode: hot-reload
160
+ // race left the port in TIME_WAIT.
161
+ if (errorCode === "EADDRINUSE") {
162
+ logger().warn(`Studio Agent could not bind its WebSocket port ` +
163
+ `(${errorMessage}). The host app will continue without Studio. ` +
164
+ `If this happened during hot-reload, the next restart should recover.`);
165
+ return false;
166
+ }
167
+ logger().warn(`Failed to initialize Studio Agent: ${errorMessage}`);
168
+ return false;
169
+ }
170
+ }
171
+ /**
172
+ * Push runtime details to the agent that the host only knows after the
173
+ * HTTP server has started — most importantly the actual listening port
174
+ * and total boot time. No-ops when:
175
+ * - the agent isn't running, or
176
+ * - the installed agent is from an older preview without
177
+ * `updateRuntimeInfo()` (we feature-detect to stay forward-compatible).
178
+ */
179
+ export function reportStudioRuntimeInfo(patch) {
180
+ if (!studioAgent)
181
+ return;
182
+ if (typeof studioAgent.updateRuntimeInfo !== "function")
183
+ return;
184
+ try {
185
+ studioAgent.updateRuntimeInfo(patch);
186
+ }
187
+ catch {
188
+ // Best-effort — never break the host on a status-page update.
189
+ }
190
+ }
191
+ /**
192
+ * Re-trigger the Studio Agent's route discovery. Used by the host
193
+ * after `app.listen()` so that the agent's runtime route scanner sees
194
+ * the fully-populated Express `_router` stack (controllers are bound
195
+ * by `InversifyExpressServer.build()` AFTER `initializeStudio()` runs,
196
+ * so the agent's first scan only catches static-source routes).
197
+ *
198
+ * No-ops when:
199
+ * - Studio isn't enabled, or
200
+ * - the installed agent is too old to expose `scanRoutes()`.
201
+ */
202
+ export async function rescanStudioRoutes() {
203
+ if (!studioAgent)
204
+ return;
205
+ if (typeof studioAgent.scanRoutes !== "function")
206
+ return;
207
+ try {
208
+ await studioAgent.scanRoutes();
209
+ }
210
+ catch (error) {
211
+ // Best-effort — never break the host on a Studio rescan.
212
+ logger().warn(`Studio route rescan failed: ${error instanceof Error ? error.message : String(error)}`);
213
+ }
214
+ }
215
+ /**
216
+ * Stop the Studio Agent
217
+ */
218
+ export async function stopStudio() {
219
+ if (studioAgent) {
220
+ await studioAgent.stop();
221
+ studioAgent = null;
222
+ studioEnabled = false;
223
+ }
224
+ }
225
+ /**
226
+ * Check if Studio is enabled
227
+ */
228
+ export function isStudioEnabled() {
229
+ return studioEnabled;
230
+ }
231
+ /**
232
+ * Get the Studio Agent instance
233
+ */
234
+ export function getStudioAgent() {
235
+ return studioAgent;
236
+ }
@@ -0,0 +1 @@
1
+ export * from "./adapter-express/index.js";
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Abstract class ApplicationBase.
3
+ *
4
+ * ApplicationBase serves as the foundational structure for building
5
+ * server applications. It declares the lifecycle hooks that allow
6
+ * subclasses to configure services, handle post-server initialization,
7
+ * and perform cleanup when the server is shutting down. Extending
8
+ * classes are required to provide implementations for these methods
9
+ * to define specific behaviors for their particular use cases.
10
+ *
11
+ * @example
12
+ * class Application extends ApplicationBase {
13
+ * protected configureServices() { //... }
14
+ * protected postServerInitialization() { //... }
15
+ * protected serverShutdown(signal) {
16
+ * console.log(`Shutting down due to ${signal}`);
17
+ * }
18
+ * }
19
+ *
20
+ * @export
21
+ * @abstract
22
+ */
23
+ export declare abstract class ApplicationBase {
24
+ /**
25
+ * Implement this method to set up global configurations for the server.
26
+ * This method is called synchronously in the constructor before any other
27
+ * server initialization methods. Use this method to configure global settings
28
+ * that apply to the entire server application.
29
+ *
30
+ * Note: This method is synchronous and called during object construction.
31
+ * For asynchronous initialization, use `configureServices()` instead.
32
+ *
33
+ * @abstract
34
+ * @returns {void}
35
+ * @public API
36
+ */
37
+ protected abstract globalConfiguration(): void;
38
+ /**
39
+ * Implement this method to set up required services or configurations before
40
+ * the server starts. This is essential for initializing dependencies or settings
41
+ * necessary for server operation. Supports asynchronous setup with a Promise.
42
+ *
43
+ * @abstract
44
+ * @returns {void | Promise<void>}
45
+ * @public API
46
+ */
47
+ protected abstract configureServices(): void | Promise<void>;
48
+ /**
49
+ * Implement this method to execute actions or configurations after the server
50
+ * has started. Use this for operations that need to run once the server is
51
+ * operational. Supports asynchronous execution with a Promise.
52
+ *
53
+ * @abstract
54
+ * @returns {void | Promise<void>}
55
+ * @public API
56
+ */
57
+ protected abstract postServerInitialization(): void | Promise<void>;
58
+ /**
59
+ * Implement this method to handle cleanup and final actions when the server
60
+ * is shutting down. Ideal for closing resources, stopping tasks, or other
61
+ * cleanup procedures to ensure a graceful server shutdown. Supports asynchronous
62
+ * cleanup with a Promise.
63
+ *
64
+ * The signal parameter indicates what triggered the shutdown:
65
+ * - SIGTERM: Graceful termination (e.g., Kubernetes pod shutdown)
66
+ * - SIGINT: User interrupt (e.g., Ctrl+C)
67
+ * - SIGHUP: Terminal hangup
68
+ * - SIGQUIT: Quit with core dump
69
+ * - SIGBREAK: Windows break signal
70
+ *
71
+ * @abstract
72
+ * @param signal - The signal that triggered the shutdown (optional for backward compatibility)
73
+ * @returns {void | Promise<void>}
74
+ * @public API
75
+ */
76
+ protected abstract serverShutdown(signal?: NodeJS.Signals): void | Promise<void>;
77
+ }