@morojs/moro 1.0.0

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 (345) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/dist/core/config/index.d.ts +19 -0
  4. package/dist/core/config/index.js +59 -0
  5. package/dist/core/config/index.js.map +1 -0
  6. package/dist/core/config/loader.d.ts +6 -0
  7. package/dist/core/config/loader.js +288 -0
  8. package/dist/core/config/loader.js.map +1 -0
  9. package/dist/core/config/schema.d.ts +335 -0
  10. package/dist/core/config/schema.js +286 -0
  11. package/dist/core/config/schema.js.map +1 -0
  12. package/dist/core/config/utils.d.ts +50 -0
  13. package/dist/core/config/utils.js +185 -0
  14. package/dist/core/config/utils.js.map +1 -0
  15. package/dist/core/database/adapters/drizzle.d.ts +29 -0
  16. package/dist/core/database/adapters/drizzle.js +366 -0
  17. package/dist/core/database/adapters/drizzle.js.map +1 -0
  18. package/dist/core/database/adapters/index.d.ts +8 -0
  19. package/dist/core/database/adapters/index.js +48 -0
  20. package/dist/core/database/adapters/index.js.map +1 -0
  21. package/dist/core/database/adapters/mongodb.d.ts +35 -0
  22. package/dist/core/database/adapters/mongodb.js +215 -0
  23. package/dist/core/database/adapters/mongodb.js.map +1 -0
  24. package/dist/core/database/adapters/mysql.d.ts +23 -0
  25. package/dist/core/database/adapters/mysql.js +149 -0
  26. package/dist/core/database/adapters/mysql.js.map +1 -0
  27. package/dist/core/database/adapters/postgresql.d.ts +24 -0
  28. package/dist/core/database/adapters/postgresql.js +160 -0
  29. package/dist/core/database/adapters/postgresql.js.map +1 -0
  30. package/dist/core/database/adapters/redis.d.ts +50 -0
  31. package/dist/core/database/adapters/redis.js +266 -0
  32. package/dist/core/database/adapters/redis.js.map +1 -0
  33. package/dist/core/database/adapters/sqlite.d.ts +23 -0
  34. package/dist/core/database/adapters/sqlite.js +194 -0
  35. package/dist/core/database/adapters/sqlite.js.map +1 -0
  36. package/dist/core/database/index.d.ts +2 -0
  37. package/dist/core/database/index.js +20 -0
  38. package/dist/core/database/index.js.map +1 -0
  39. package/dist/core/docs/index.d.ts +63 -0
  40. package/dist/core/docs/index.js +170 -0
  41. package/dist/core/docs/index.js.map +1 -0
  42. package/dist/core/docs/openapi-generator.d.ts +124 -0
  43. package/dist/core/docs/openapi-generator.js +413 -0
  44. package/dist/core/docs/openapi-generator.js.map +1 -0
  45. package/dist/core/docs/simple-docs.d.ts +21 -0
  46. package/dist/core/docs/simple-docs.js +268 -0
  47. package/dist/core/docs/simple-docs.js.map +1 -0
  48. package/dist/core/docs/swagger-ui.d.ts +28 -0
  49. package/dist/core/docs/swagger-ui.js +317 -0
  50. package/dist/core/docs/swagger-ui.js.map +1 -0
  51. package/dist/core/docs/zod-to-openapi.d.ts +29 -0
  52. package/dist/core/docs/zod-to-openapi.js +414 -0
  53. package/dist/core/docs/zod-to-openapi.js.map +1 -0
  54. package/dist/core/events/event-bus.d.ts +27 -0
  55. package/dist/core/events/event-bus.js +193 -0
  56. package/dist/core/events/event-bus.js.map +1 -0
  57. package/dist/core/events/index.d.ts +2 -0
  58. package/dist/core/events/index.js +7 -0
  59. package/dist/core/events/index.js.map +1 -0
  60. package/dist/core/framework.d.ts +57 -0
  61. package/dist/core/framework.js +432 -0
  62. package/dist/core/framework.js.map +1 -0
  63. package/dist/core/http/http-server.d.ts +114 -0
  64. package/dist/core/http/http-server.js +1154 -0
  65. package/dist/core/http/http-server.js.map +1 -0
  66. package/dist/core/http/index.d.ts +3 -0
  67. package/dist/core/http/index.js +10 -0
  68. package/dist/core/http/index.js.map +1 -0
  69. package/dist/core/http/router.d.ts +14 -0
  70. package/dist/core/http/router.js +113 -0
  71. package/dist/core/http/router.js.map +1 -0
  72. package/dist/core/logger/filters.d.ts +9 -0
  73. package/dist/core/logger/filters.js +134 -0
  74. package/dist/core/logger/filters.js.map +1 -0
  75. package/dist/core/logger/index.d.ts +3 -0
  76. package/dist/core/logger/index.js +26 -0
  77. package/dist/core/logger/index.js.map +1 -0
  78. package/dist/core/logger/logger.d.ts +49 -0
  79. package/dist/core/logger/logger.js +332 -0
  80. package/dist/core/logger/logger.js.map +1 -0
  81. package/dist/core/logger/outputs.d.ts +42 -0
  82. package/dist/core/logger/outputs.js +110 -0
  83. package/dist/core/logger/outputs.js.map +1 -0
  84. package/dist/core/middleware/built-in/adapters/cache/file.d.ts +15 -0
  85. package/dist/core/middleware/built-in/adapters/cache/file.js +128 -0
  86. package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -0
  87. package/dist/core/middleware/built-in/adapters/cache/index.d.ts +5 -0
  88. package/dist/core/middleware/built-in/adapters/cache/index.js +28 -0
  89. package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -0
  90. package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +11 -0
  91. package/dist/core/middleware/built-in/adapters/cache/memory.js +65 -0
  92. package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -0
  93. package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +17 -0
  94. package/dist/core/middleware/built-in/adapters/cache/redis.js +91 -0
  95. package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -0
  96. package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +21 -0
  97. package/dist/core/middleware/built-in/adapters/cdn/azure.js +40 -0
  98. package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -0
  99. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +14 -0
  100. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +77 -0
  101. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -0
  102. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +15 -0
  103. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +73 -0
  104. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -0
  105. package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +5 -0
  106. package/dist/core/middleware/built-in/adapters/cdn/index.js +28 -0
  107. package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -0
  108. package/dist/core/middleware/built-in/adapters/index.d.ts +4 -0
  109. package/dist/core/middleware/built-in/adapters/index.js +26 -0
  110. package/dist/core/middleware/built-in/adapters/index.js.map +1 -0
  111. package/dist/core/middleware/built-in/auth.d.ts +2 -0
  112. package/dist/core/middleware/built-in/auth.js +38 -0
  113. package/dist/core/middleware/built-in/auth.js.map +1 -0
  114. package/dist/core/middleware/built-in/cache.d.ts +3 -0
  115. package/dist/core/middleware/built-in/cache.js +188 -0
  116. package/dist/core/middleware/built-in/cache.js.map +1 -0
  117. package/dist/core/middleware/built-in/cdn.d.ts +3 -0
  118. package/dist/core/middleware/built-in/cdn.js +115 -0
  119. package/dist/core/middleware/built-in/cdn.js.map +1 -0
  120. package/dist/core/middleware/built-in/cookie.d.ts +14 -0
  121. package/dist/core/middleware/built-in/cookie.js +68 -0
  122. package/dist/core/middleware/built-in/cookie.js.map +1 -0
  123. package/dist/core/middleware/built-in/cors.d.ts +2 -0
  124. package/dist/core/middleware/built-in/cors.js +29 -0
  125. package/dist/core/middleware/built-in/cors.js.map +1 -0
  126. package/dist/core/middleware/built-in/csp.d.ts +22 -0
  127. package/dist/core/middleware/built-in/csp.js +74 -0
  128. package/dist/core/middleware/built-in/csp.js.map +1 -0
  129. package/dist/core/middleware/built-in/csrf.d.ts +9 -0
  130. package/dist/core/middleware/built-in/csrf.js +66 -0
  131. package/dist/core/middleware/built-in/csrf.js.map +1 -0
  132. package/dist/core/middleware/built-in/error-tracker.d.ts +1 -0
  133. package/dist/core/middleware/built-in/error-tracker.js +19 -0
  134. package/dist/core/middleware/built-in/error-tracker.js.map +1 -0
  135. package/dist/core/middleware/built-in/index.d.ts +70 -0
  136. package/dist/core/middleware/built-in/index.js +70 -0
  137. package/dist/core/middleware/built-in/index.js.map +1 -0
  138. package/dist/core/middleware/built-in/performance-monitor.d.ts +1 -0
  139. package/dist/core/middleware/built-in/performance-monitor.js +22 -0
  140. package/dist/core/middleware/built-in/performance-monitor.js.map +1 -0
  141. package/dist/core/middleware/built-in/rate-limit.d.ts +6 -0
  142. package/dist/core/middleware/built-in/rate-limit.js +47 -0
  143. package/dist/core/middleware/built-in/rate-limit.js.map +1 -0
  144. package/dist/core/middleware/built-in/request-logger.d.ts +1 -0
  145. package/dist/core/middleware/built-in/request-logger.js +15 -0
  146. package/dist/core/middleware/built-in/request-logger.js.map +1 -0
  147. package/dist/core/middleware/built-in/session.d.ts +41 -0
  148. package/dist/core/middleware/built-in/session.js +209 -0
  149. package/dist/core/middleware/built-in/session.js.map +1 -0
  150. package/dist/core/middleware/built-in/sse.d.ts +6 -0
  151. package/dist/core/middleware/built-in/sse.js +73 -0
  152. package/dist/core/middleware/built-in/sse.js.map +1 -0
  153. package/dist/core/middleware/built-in/validation.d.ts +2 -0
  154. package/dist/core/middleware/built-in/validation.js +31 -0
  155. package/dist/core/middleware/built-in/validation.js.map +1 -0
  156. package/dist/core/middleware/index.d.ts +21 -0
  157. package/dist/core/middleware/index.js +152 -0
  158. package/dist/core/middleware/index.js.map +1 -0
  159. package/dist/core/modules/auto-discovery.d.ts +27 -0
  160. package/dist/core/modules/auto-discovery.js +255 -0
  161. package/dist/core/modules/auto-discovery.js.map +1 -0
  162. package/dist/core/modules/index.d.ts +2 -0
  163. package/dist/core/modules/index.js +11 -0
  164. package/dist/core/modules/index.js.map +1 -0
  165. package/dist/core/modules/modules.d.ts +10 -0
  166. package/dist/core/modules/modules.js +137 -0
  167. package/dist/core/modules/modules.js.map +1 -0
  168. package/dist/core/networking/index.d.ts +2 -0
  169. package/dist/core/networking/index.js +9 -0
  170. package/dist/core/networking/index.js.map +1 -0
  171. package/dist/core/networking/service-discovery.d.ts +38 -0
  172. package/dist/core/networking/service-discovery.js +233 -0
  173. package/dist/core/networking/service-discovery.js.map +1 -0
  174. package/dist/core/networking/websocket-manager.d.ts +27 -0
  175. package/dist/core/networking/websocket-manager.js +211 -0
  176. package/dist/core/networking/websocket-manager.js.map +1 -0
  177. package/dist/core/routing/app-integration.d.ts +42 -0
  178. package/dist/core/routing/app-integration.js +152 -0
  179. package/dist/core/routing/app-integration.js.map +1 -0
  180. package/dist/core/routing/index.d.ts +106 -0
  181. package/dist/core/routing/index.js +343 -0
  182. package/dist/core/routing/index.js.map +1 -0
  183. package/dist/core/runtime/aws-lambda-adapter.d.ts +43 -0
  184. package/dist/core/runtime/aws-lambda-adapter.js +108 -0
  185. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -0
  186. package/dist/core/runtime/base-adapter.d.ts +16 -0
  187. package/dist/core/runtime/base-adapter.js +105 -0
  188. package/dist/core/runtime/base-adapter.js.map +1 -0
  189. package/dist/core/runtime/cloudflare-workers-adapter.d.ts +18 -0
  190. package/dist/core/runtime/cloudflare-workers-adapter.js +131 -0
  191. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -0
  192. package/dist/core/runtime/index.d.ts +14 -0
  193. package/dist/core/runtime/index.js +56 -0
  194. package/dist/core/runtime/index.js.map +1 -0
  195. package/dist/core/runtime/node-adapter.d.ts +15 -0
  196. package/dist/core/runtime/node-adapter.js +204 -0
  197. package/dist/core/runtime/node-adapter.js.map +1 -0
  198. package/dist/core/runtime/vercel-edge-adapter.d.ts +10 -0
  199. package/dist/core/runtime/vercel-edge-adapter.js +106 -0
  200. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -0
  201. package/dist/core/utilities/circuit-breaker.d.ts +14 -0
  202. package/dist/core/utilities/circuit-breaker.js +42 -0
  203. package/dist/core/utilities/circuit-breaker.js.map +1 -0
  204. package/dist/core/utilities/container.d.ts +116 -0
  205. package/dist/core/utilities/container.js +529 -0
  206. package/dist/core/utilities/container.js.map +1 -0
  207. package/dist/core/utilities/hooks.d.ts +24 -0
  208. package/dist/core/utilities/hooks.js +131 -0
  209. package/dist/core/utilities/hooks.js.map +1 -0
  210. package/dist/core/utilities/index.d.ts +4 -0
  211. package/dist/core/utilities/index.js +22 -0
  212. package/dist/core/utilities/index.js.map +1 -0
  213. package/dist/core/validation/index.d.ts +30 -0
  214. package/dist/core/validation/index.js +144 -0
  215. package/dist/core/validation/index.js.map +1 -0
  216. package/dist/index.d.ts +30 -0
  217. package/dist/index.js +72 -0
  218. package/dist/index.js.map +1 -0
  219. package/dist/moro.d.ts +82 -0
  220. package/dist/moro.js +679 -0
  221. package/dist/moro.js.map +1 -0
  222. package/dist/types/cache.d.ts +34 -0
  223. package/dist/types/cache.js +3 -0
  224. package/dist/types/cache.js.map +1 -0
  225. package/dist/types/cdn.d.ts +19 -0
  226. package/dist/types/cdn.js +3 -0
  227. package/dist/types/cdn.js.map +1 -0
  228. package/dist/types/core.d.ts +13 -0
  229. package/dist/types/core.js +3 -0
  230. package/dist/types/core.js.map +1 -0
  231. package/dist/types/database.d.ts +29 -0
  232. package/dist/types/database.js +3 -0
  233. package/dist/types/database.js.map +1 -0
  234. package/dist/types/discovery.d.ts +6 -0
  235. package/dist/types/discovery.js +3 -0
  236. package/dist/types/discovery.js.map +1 -0
  237. package/dist/types/events.d.ts +116 -0
  238. package/dist/types/events.js +3 -0
  239. package/dist/types/events.js.map +1 -0
  240. package/dist/types/hooks.d.ts +38 -0
  241. package/dist/types/hooks.js +3 -0
  242. package/dist/types/hooks.js.map +1 -0
  243. package/dist/types/http.d.ts +51 -0
  244. package/dist/types/http.js +3 -0
  245. package/dist/types/http.js.map +1 -0
  246. package/dist/types/logger.d.ts +77 -0
  247. package/dist/types/logger.js +3 -0
  248. package/dist/types/logger.js.map +1 -0
  249. package/dist/types/module.d.ts +91 -0
  250. package/dist/types/module.js +3 -0
  251. package/dist/types/module.js.map +1 -0
  252. package/dist/types/runtime.d.ts +48 -0
  253. package/dist/types/runtime.js +3 -0
  254. package/dist/types/runtime.js.map +1 -0
  255. package/dist/types/session.d.ts +66 -0
  256. package/dist/types/session.js +3 -0
  257. package/dist/types/session.js.map +1 -0
  258. package/package.json +176 -0
  259. package/src/core/config/index.ts +47 -0
  260. package/src/core/config/loader.ts +366 -0
  261. package/src/core/config/schema.ts +346 -0
  262. package/src/core/config/utils.ts +220 -0
  263. package/src/core/database/README.md +228 -0
  264. package/src/core/database/adapters/drizzle.ts +425 -0
  265. package/src/core/database/adapters/index.ts +45 -0
  266. package/src/core/database/adapters/mongodb.ts +292 -0
  267. package/src/core/database/adapters/mysql.ts +217 -0
  268. package/src/core/database/adapters/postgresql.ts +211 -0
  269. package/src/core/database/adapters/redis.ts +331 -0
  270. package/src/core/database/adapters/sqlite.ts +255 -0
  271. package/src/core/database/index.ts +3 -0
  272. package/src/core/docs/index.ts +245 -0
  273. package/src/core/docs/openapi-generator.ts +588 -0
  274. package/src/core/docs/simple-docs.ts +305 -0
  275. package/src/core/docs/swagger-ui.ts +370 -0
  276. package/src/core/docs/zod-to-openapi.ts +532 -0
  277. package/src/core/events/event-bus.ts +249 -0
  278. package/src/core/events/index.ts +12 -0
  279. package/src/core/framework.ts +621 -0
  280. package/src/core/http/http-server.ts +1421 -0
  281. package/src/core/http/index.ts +11 -0
  282. package/src/core/http/router.ts +153 -0
  283. package/src/core/logger/filters.ts +148 -0
  284. package/src/core/logger/index.ts +20 -0
  285. package/src/core/logger/logger.ts +434 -0
  286. package/src/core/logger/outputs.ts +136 -0
  287. package/src/core/middleware/built-in/adapters/cache/file.ts +106 -0
  288. package/src/core/middleware/built-in/adapters/cache/index.ts +26 -0
  289. package/src/core/middleware/built-in/adapters/cache/memory.ts +73 -0
  290. package/src/core/middleware/built-in/adapters/cache/redis.ts +103 -0
  291. package/src/core/middleware/built-in/adapters/cdn/azure.ts +68 -0
  292. package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +100 -0
  293. package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +92 -0
  294. package/src/core/middleware/built-in/adapters/cdn/index.ts +23 -0
  295. package/src/core/middleware/built-in/adapters/index.ts +7 -0
  296. package/src/core/middleware/built-in/auth.ts +39 -0
  297. package/src/core/middleware/built-in/cache.ts +228 -0
  298. package/src/core/middleware/built-in/cdn.ts +151 -0
  299. package/src/core/middleware/built-in/cookie.ts +90 -0
  300. package/src/core/middleware/built-in/cors.ts +38 -0
  301. package/src/core/middleware/built-in/csp.ts +107 -0
  302. package/src/core/middleware/built-in/csrf.ts +87 -0
  303. package/src/core/middleware/built-in/error-tracker.ts +16 -0
  304. package/src/core/middleware/built-in/index.ts +57 -0
  305. package/src/core/middleware/built-in/performance-monitor.ts +25 -0
  306. package/src/core/middleware/built-in/rate-limit.ts +60 -0
  307. package/src/core/middleware/built-in/request-logger.ts +14 -0
  308. package/src/core/middleware/built-in/session.ts +311 -0
  309. package/src/core/middleware/built-in/sse.ts +91 -0
  310. package/src/core/middleware/built-in/validation.ts +33 -0
  311. package/src/core/middleware/index.ts +188 -0
  312. package/src/core/modules/auto-discovery.ts +265 -0
  313. package/src/core/modules/index.ts +6 -0
  314. package/src/core/modules/modules.ts +125 -0
  315. package/src/core/networking/index.ts +7 -0
  316. package/src/core/networking/service-discovery.ts +309 -0
  317. package/src/core/networking/websocket-manager.ts +259 -0
  318. package/src/core/routing/app-integration.ts +229 -0
  319. package/src/core/routing/index.ts +519 -0
  320. package/src/core/runtime/aws-lambda-adapter.ts +157 -0
  321. package/src/core/runtime/base-adapter.ts +140 -0
  322. package/src/core/runtime/cloudflare-workers-adapter.ts +166 -0
  323. package/src/core/runtime/index.ts +74 -0
  324. package/src/core/runtime/node-adapter.ts +210 -0
  325. package/src/core/runtime/vercel-edge-adapter.ts +125 -0
  326. package/src/core/utilities/circuit-breaker.ts +46 -0
  327. package/src/core/utilities/container.ts +760 -0
  328. package/src/core/utilities/hooks.ts +148 -0
  329. package/src/core/utilities/index.ts +16 -0
  330. package/src/core/validation/index.ts +216 -0
  331. package/src/index.ts +120 -0
  332. package/src/moro.ts +842 -0
  333. package/src/types/cache.ts +38 -0
  334. package/src/types/cdn.ts +22 -0
  335. package/src/types/core.ts +17 -0
  336. package/src/types/database.ts +40 -0
  337. package/src/types/discovery.ts +7 -0
  338. package/src/types/events.ts +90 -0
  339. package/src/types/hooks.ts +47 -0
  340. package/src/types/http.ts +70 -0
  341. package/src/types/logger.ts +109 -0
  342. package/src/types/module.ts +87 -0
  343. package/src/types/runtime.ts +91 -0
  344. package/src/types/session.ts +89 -0
  345. package/tsconfig.json +21 -0
@@ -0,0 +1,621 @@
1
+ // src/core/framework.ts
2
+ import { createServer, Server } from "http";
3
+ import {
4
+ createSecureServer as createHttp2SecureServer,
5
+ createServer as createHttp2Server,
6
+ } from "http2";
7
+ import { Server as SocketIOServer } from "socket.io";
8
+ import { EventEmitter } from "events";
9
+ import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from "./http";
10
+ import { Router } from "./http";
11
+ import { Container } from "./utilities";
12
+ import { ModuleLoader } from "./modules";
13
+ import { WebSocketManager } from "./networking";
14
+ import { CircuitBreaker } from "./utilities";
15
+ import { MoroEventBus } from "./events";
16
+ import { createFrameworkLogger, logger as globalLogger } from "./logger";
17
+ import { ModuleConfig, InternalRouteDefinition } from "../types/module";
18
+ import { LogLevel, LoggerOptions } from "../types/logger";
19
+
20
+ export interface MoroOptions {
21
+ http2?: boolean;
22
+ https?: {
23
+ key: string | Buffer;
24
+ cert: string | Buffer;
25
+ ca?: string | Buffer;
26
+ };
27
+ compression?: {
28
+ enabled?: boolean;
29
+ threshold?: number;
30
+ };
31
+ websocket?: {
32
+ compression?: boolean;
33
+ customIdGenerator?: () => string;
34
+ };
35
+ logger?: LoggerOptions | boolean;
36
+ }
37
+
38
+ export class Moro extends EventEmitter {
39
+ private httpServer: MoroHttpServer;
40
+ private server: Server | any; // HTTP/2 server type
41
+ private io: SocketIOServer;
42
+ private container: Container;
43
+ private moduleLoader: ModuleLoader;
44
+ private websocketManager: WebSocketManager;
45
+ private circuitBreakers = new Map<string, CircuitBreaker>();
46
+ private rateLimiters = new Map<
47
+ string,
48
+ Map<string, { count: number; resetTime: number }>
49
+ >();
50
+ private ioInstance: SocketIOServer;
51
+ // Enterprise-grade event system
52
+ private eventBus: MoroEventBus;
53
+ // Framework logger
54
+ private logger: any;
55
+ private options: MoroOptions;
56
+
57
+ constructor(options: MoroOptions = {}) {
58
+ super();
59
+ this.options = options;
60
+
61
+ // Configure global logger based on options
62
+ if (options.logger !== undefined) {
63
+ if (options.logger === false) {
64
+ // Disable logging by setting level to fatal (highest level)
65
+ globalLogger.setLevel("fatal");
66
+ } else if (typeof options.logger === "object") {
67
+ // Configure logger with provided options
68
+ if (options.logger.level) {
69
+ globalLogger.setLevel(options.logger.level);
70
+ }
71
+ // Additional logger options can be configured here in the future
72
+ // For now, we focus on the level setting which is the most common need
73
+ }
74
+ }
75
+
76
+ // Initialize framework logger after global configuration
77
+ this.logger = createFrameworkLogger("Core");
78
+
79
+ this.httpServer = new MoroHttpServer();
80
+
81
+ // Create HTTP/2 or HTTP/1.1 server based on options
82
+ if (options.http2) {
83
+ if (options.https) {
84
+ this.server = createHttp2SecureServer(options.https);
85
+ } else {
86
+ this.server = createHttp2Server();
87
+ }
88
+
89
+ // Handle HTTP/2 streams manually
90
+ this.server.on("stream", (stream: any, headers: any) => {
91
+ // Convert HTTP/2 stream to HTTP/1.1-like request/response
92
+ const req = stream as any;
93
+ const res = stream as any;
94
+ req.url = headers[":path"];
95
+ req.method = headers[":method"];
96
+ req.headers = headers;
97
+ this.httpServer["handleRequest"](req, res);
98
+ });
99
+
100
+ this.logger.info("HTTP/2 server created", "ServerInit");
101
+ } else {
102
+ this.server = this.httpServer.getServer();
103
+ }
104
+
105
+ this.io = new SocketIOServer(this.server, {
106
+ cors: { origin: "*" },
107
+ path: "/socket.io/",
108
+ });
109
+
110
+ this.ioInstance = this.io;
111
+ this.container = new Container();
112
+ this.moduleLoader = new ModuleLoader(this.container);
113
+ this.websocketManager = new WebSocketManager(this.io, this.container);
114
+
115
+ // Configure WebSocket advanced features
116
+ if (options.websocket?.customIdGenerator) {
117
+ this.websocketManager.setCustomIdGenerator(
118
+ options.websocket.customIdGenerator,
119
+ );
120
+ }
121
+
122
+ if (options.websocket?.compression) {
123
+ this.websocketManager.enableCompression();
124
+ }
125
+
126
+ // Initialize enterprise event bus
127
+ this.eventBus = new MoroEventBus({
128
+ maxListeners: 200,
129
+ enableMetrics: true,
130
+ isolation: "module",
131
+ });
132
+
133
+ // Register event bus in DI container as factory
134
+ this.container.register("eventBus", () => this.eventBus);
135
+
136
+ this.setupCore();
137
+ }
138
+
139
+ // Middleware support
140
+ use(middleware: any): this {
141
+ this.httpServer.use(middleware);
142
+ return this;
143
+ }
144
+
145
+ private setupCore() {
146
+ // Security middleware
147
+ this.httpServer.use(middleware.helmet());
148
+ this.httpServer.use(middleware.cors());
149
+
150
+ // Performance middleware
151
+ this.httpServer.use(middleware.compression());
152
+ this.httpServer.use(middleware.bodySize({ limit: "10mb" }));
153
+
154
+ // Request tracking middleware
155
+ this.httpServer.use(this.requestTrackingMiddleware());
156
+
157
+ // Error boundary middleware
158
+ this.httpServer.use(this.errorBoundaryMiddleware());
159
+ }
160
+
161
+ private requestTrackingMiddleware() {
162
+ return (req: HttpRequest, res: HttpResponse, next: () => void) => {
163
+ const startTime = Date.now();
164
+
165
+ res.on("finish", () => {
166
+ const duration = Date.now() - startTime;
167
+ this.logger.info(
168
+ `${req.method} ${req.path} - ${res.statusCode} - ${duration}ms [${req.requestId}]`,
169
+ );
170
+ });
171
+
172
+ next();
173
+ };
174
+ }
175
+
176
+ private errorBoundaryMiddleware() {
177
+ return async (req: HttpRequest, res: HttpResponse, next: () => void) => {
178
+ try {
179
+ next();
180
+ } catch (error: any) {
181
+ this.logger.error("Error:", error.message, error.stack);
182
+
183
+ if (!res.headersSent) {
184
+ res.status(500).json({
185
+ success: false,
186
+ error: "Internal server error",
187
+ requestId: req.requestId,
188
+ });
189
+ }
190
+ }
191
+ };
192
+ }
193
+
194
+ // Public API for adding middleware
195
+ addMiddleware(middleware: any) {
196
+ this.httpServer.use(middleware);
197
+ this.emit("middleware:added", { middleware });
198
+ return this;
199
+ }
200
+
201
+ // Public API for database registration
202
+ registerDatabase(adapter: any) {
203
+ this.container.register("database", () => adapter, true);
204
+ this.emit("database:registered", { adapter });
205
+ return this;
206
+ }
207
+
208
+ // Public API for accessing HTTP server
209
+ getHttpServer() {
210
+ return this.httpServer;
211
+ }
212
+
213
+ // Public API for accessing Socket.IO server
214
+ getIOServer() {
215
+ return this.io;
216
+ }
217
+
218
+ async loadModule(moduleConfig: ModuleConfig): Promise<void> {
219
+ this.logger.info(
220
+ `Loading module: ${moduleConfig.name}@${moduleConfig.version}`,
221
+ "ModuleLoader",
222
+ );
223
+
224
+ // Create module event bus once during module loading
225
+ const moduleEventBus = this.eventBus.createModuleBus(moduleConfig.name);
226
+
227
+ // Register services in DI container
228
+ this.registerServices(moduleConfig);
229
+
230
+ // Create module router with resilience patterns
231
+ const router = await this.createModuleRouter(moduleConfig, moduleEventBus);
232
+
233
+ // Setup WebSocket handlers
234
+ if (moduleConfig.websockets) {
235
+ await this.setupWebSocketHandlers(moduleConfig);
236
+ }
237
+
238
+ // Mount with versioning
239
+ this.logger.debug(
240
+ `Module version before basePath: "${moduleConfig.version}"`,
241
+ "ModuleLoader",
242
+ );
243
+ const basePath = `/api/v${moduleConfig.version}/${moduleConfig.name}`;
244
+ this.logger.debug(`Generated basePath: "${basePath}"`, "ModuleLoader");
245
+ this.mountRouter(basePath, router);
246
+
247
+ this.logger.info(`Module loaded: ${moduleConfig.name}`, "ModuleLoader");
248
+ this.emit("moduleLoaded", moduleConfig.name);
249
+ }
250
+
251
+ private registerServices(config: ModuleConfig): void {
252
+ if (!config.services) return;
253
+
254
+ for (const service of config.services) {
255
+ const factory = () => {
256
+ const dependencies = (service.dependencies || []).map((dep) =>
257
+ this.container.resolve(dep),
258
+ );
259
+ return new service.implementation(...dependencies);
260
+ };
261
+
262
+ this.container.register(
263
+ service.name,
264
+ factory,
265
+ service.singleton || false,
266
+ );
267
+ }
268
+
269
+ // Register functional route handlers if they exist
270
+ if (config.routeHandlers) {
271
+ for (const [name, handler] of Object.entries(config.routeHandlers)) {
272
+ this.container.register(name, () => handler, false);
273
+ }
274
+ }
275
+
276
+ // Register functional socket handlers if they exist
277
+ if (config.socketHandlers) {
278
+ for (const [name, handler] of Object.entries(config.socketHandlers)) {
279
+ this.container.register(name, () => handler, false);
280
+ }
281
+ }
282
+ }
283
+
284
+ private async createModuleRouter(
285
+ config: ModuleConfig,
286
+ moduleEventBus: any,
287
+ ): Promise<Router> {
288
+ const router = new Router();
289
+
290
+ this.logger.debug(`Creating router for module: ${config.name}`, "Router");
291
+ this.logger.debug(
292
+ `Module has ${config.routes?.length || 0} routes`,
293
+ "Router",
294
+ );
295
+
296
+ if (!config.routes) return router;
297
+
298
+ for (const route of config.routes) {
299
+ this.logger.debug(
300
+ `Adding route: ${route.method} ${route.path} -> ${route.handler}`,
301
+ "Router",
302
+ );
303
+ const handler = await this.createResilientHandler(
304
+ route,
305
+ config,
306
+ moduleEventBus,
307
+ );
308
+ const method = route.method.toLowerCase() as keyof Router;
309
+
310
+ // Add route to router
311
+ (router[method] as Function)(route.path, handler);
312
+ }
313
+
314
+ this.logger.debug(
315
+ `Router created with ${router.getRoutes().length} total routes`,
316
+ "Router",
317
+ );
318
+ return router;
319
+ }
320
+
321
+ private async createResilientHandler(
322
+ route: InternalRouteDefinition,
323
+ config: ModuleConfig,
324
+ moduleEventBus: any,
325
+ ) {
326
+ const handlerKey = `${config.name}.${route.handler}`;
327
+
328
+ return async (req: HttpRequest, res: HttpResponse) => {
329
+ const requestId =
330
+ req.headers["x-request-id"] || Math.random().toString(36);
331
+
332
+ try {
333
+ // Try to get functional handler first, then fall back to service-based
334
+ let handler;
335
+ let useEnhancedReq = false;
336
+
337
+ if (config.routeHandlers && config.routeHandlers[route.handler]) {
338
+ // New functional handler
339
+ handler = config.routeHandlers[route.handler];
340
+ useEnhancedReq = true;
341
+ this.logger.debug(
342
+ `Using functional handler: ${route.handler}`,
343
+ "Handler",
344
+ {
345
+ availableHandlers: Object.keys(config.routeHandlers || {}),
346
+ },
347
+ );
348
+ } else if (this.container.has(config.name)) {
349
+ // Old service-based handler
350
+ const service = this.container.resolve(config.name) as any;
351
+ handler = service[route.handler];
352
+ this.logger.debug(
353
+ `Using service handler: ${config.name}.${route.handler}`,
354
+ "Handler",
355
+ );
356
+ } else {
357
+ this.logger.error(
358
+ `No handler found for route ${route.method} ${route.path}`,
359
+ "Handler",
360
+ {
361
+ routeHandlers: Object.keys(config.routeHandlers || {}),
362
+ containerHasModule: this.container.has(config.name),
363
+ },
364
+ );
365
+ throw new Error(
366
+ `Handler ${route.handler} not found for module ${config.name}`,
367
+ );
368
+ }
369
+
370
+ if (!handler || typeof handler !== "function") {
371
+ throw new Error(`Handler ${route.handler} is not a function`);
372
+ }
373
+
374
+ // Validate request if validation schema is provided
375
+ if (route.validation) {
376
+ try {
377
+ // Validate body
378
+ if (route.validation.body && req.body !== undefined) {
379
+ req.body = route.validation.body.parse(req.body);
380
+ }
381
+
382
+ // Validate query
383
+ if (route.validation.query && req.query !== undefined) {
384
+ req.query = route.validation.query.parse(req.query);
385
+ }
386
+
387
+ // Validate params
388
+ if (route.validation.params && req.params !== undefined) {
389
+ req.params = route.validation.params.parse(req.params);
390
+ }
391
+
392
+ // Validate headers
393
+ if (route.validation.headers && req.headers !== undefined) {
394
+ req.headers = route.validation.headers.parse(req.headers);
395
+ }
396
+
397
+ this.logger.debug(
398
+ "Module route validation passed",
399
+ "ModuleValidation",
400
+ {
401
+ route: `${route.method} ${route.path}`,
402
+ module: config.name,
403
+ },
404
+ );
405
+ } catch (validationError: any) {
406
+ if (validationError.issues) {
407
+ this.logger.debug(
408
+ "Module route validation failed",
409
+ "ModuleValidation",
410
+ {
411
+ route: `${route.method} ${route.path}`,
412
+ module: config.name,
413
+ errors: validationError.issues.length,
414
+ },
415
+ );
416
+
417
+ res.status(400).json({
418
+ success: false,
419
+ error: "Validation failed",
420
+ details: validationError.issues.map((issue: any) => ({
421
+ field:
422
+ issue.path.length > 0 ? issue.path.join(".") : "request",
423
+ message: issue.message,
424
+ code: issue.code,
425
+ })),
426
+ requestId,
427
+ });
428
+ return;
429
+ }
430
+ throw validationError;
431
+ }
432
+ }
433
+
434
+ // Prepare request object based on handler type
435
+ let requestToUse: any = req;
436
+ if (useEnhancedReq) {
437
+ // Use the pre-created module event bus
438
+ requestToUse = {
439
+ ...req,
440
+ database: this.container.has("database")
441
+ ? this.container.resolve("database")
442
+ : undefined,
443
+ events: moduleEventBus, // Use pre-created event bus
444
+ app: {
445
+ get: (key: string) =>
446
+ key === "io" ? this.ioInstance : undefined,
447
+ },
448
+ };
449
+ this.logger.debug(
450
+ `Database available: ${!!requestToUse.database}`,
451
+ "Handler",
452
+ {
453
+ moduleId: config.name,
454
+ },
455
+ );
456
+ }
457
+
458
+ // Execute with circuit breaker
459
+ const circuitBreaker = this.getCircuitBreaker(handlerKey);
460
+ const result = await circuitBreaker.execute(() =>
461
+ handler(requestToUse, res),
462
+ );
463
+
464
+ // For functional handlers, ensure the response is sent
465
+ if (
466
+ useEnhancedReq &&
467
+ result !== undefined &&
468
+ result !== null &&
469
+ !res.headersSent
470
+ ) {
471
+ this.logger.debug(`Sending functional handler result`, "Handler", {
472
+ result,
473
+ });
474
+ res.json(result);
475
+ }
476
+
477
+ return result;
478
+ } catch (error: any) {
479
+ this.logger.error(
480
+ `Route handler error [${requestId}]: ${error.message}`,
481
+ "Handler",
482
+ {
483
+ requestId,
484
+ handlerKey,
485
+ stack: error.stack,
486
+ },
487
+ );
488
+ if (!res.headersSent) {
489
+ res.status(500).json({
490
+ success: false,
491
+ error: "Internal server error",
492
+ requestId,
493
+ });
494
+ }
495
+ throw error;
496
+ }
497
+ };
498
+ }
499
+
500
+ private mountRouter(basePath: string, router: Router): void {
501
+ this.logger.debug(`Mounting router for basePath: ${basePath}`, "Router");
502
+
503
+ // Enterprise-grade middleware integration with performance optimization
504
+ this.httpServer.use(
505
+ async (req: HttpRequest, res: HttpResponse, next: () => void) => {
506
+ if (req.path.startsWith(basePath)) {
507
+ this.logger.debug(
508
+ `Module middleware handling: ${req.method} ${req.path}`,
509
+ "Middleware",
510
+ {
511
+ basePath,
512
+ },
513
+ );
514
+
515
+ try {
516
+ const handled = await router.handle(req, res, basePath);
517
+ this.logger.debug(`Route handled: ${handled}`, "Router");
518
+
519
+ if (!handled) {
520
+ next(); // Let other middleware handle it
521
+ }
522
+ // If handled, the router already sent the response, so don't call next()
523
+ } catch (error) {
524
+ this.logger.error("Router error", "Router", {
525
+ error: error instanceof Error ? error.message : String(error),
526
+ });
527
+ if (!res.headersSent) {
528
+ res
529
+ .status(500)
530
+ .json({ success: false, error: "Internal server error" });
531
+ }
532
+ }
533
+ } else {
534
+ next();
535
+ }
536
+ },
537
+ );
538
+
539
+ this.logger.info(`Router mounted for ${basePath}`, "Router");
540
+ }
541
+
542
+ private async setupWebSocketHandlers(config: ModuleConfig): Promise<void> {
543
+ const namespace = this.io.of(`/${config.name}`);
544
+
545
+ for (const wsConfig of config.websockets || []) {
546
+ await this.websocketManager.registerHandler(namespace, wsConfig, config);
547
+ }
548
+ }
549
+
550
+ private checkRateLimit(
551
+ identifier: string,
552
+ rateLimit: { requests: number; window: number },
553
+ ): boolean {
554
+ if (!this.rateLimiters.has(identifier)) {
555
+ this.rateLimiters.set(identifier, new Map());
556
+ }
557
+
558
+ const handlerLimiter = this.rateLimiters.get(identifier)!;
559
+ const now = Date.now();
560
+ const limit = handlerLimiter.get(identifier);
561
+
562
+ if (!limit || now > limit.resetTime) {
563
+ handlerLimiter.set(identifier, {
564
+ count: 1,
565
+ resetTime: now + rateLimit.window,
566
+ });
567
+ return true;
568
+ }
569
+
570
+ if (limit.count >= rateLimit.requests) {
571
+ return false;
572
+ }
573
+
574
+ limit.count++;
575
+ return true;
576
+ }
577
+
578
+ private getCircuitBreaker(key: string): CircuitBreaker {
579
+ if (!this.circuitBreakers.has(key)) {
580
+ this.circuitBreakers.set(
581
+ key,
582
+ new CircuitBreaker({
583
+ failureThreshold: 5,
584
+ resetTimeout: 30000,
585
+ monitoringPeriod: 10000,
586
+ }),
587
+ );
588
+ }
589
+ return this.circuitBreakers.get(key)!;
590
+ }
591
+
592
+ listen(port: number, callback?: () => void): void;
593
+ listen(port: number, host: string, callback?: () => void): void;
594
+ listen(
595
+ port: number,
596
+ host?: string | (() => void),
597
+ callback?: () => void,
598
+ ): void {
599
+ if (typeof host === "function") {
600
+ this.httpServer.listen(port, host);
601
+ } else if (host) {
602
+ this.httpServer.listen(port, host, callback);
603
+ } else {
604
+ this.httpServer.listen(port, callback);
605
+ }
606
+ }
607
+
608
+ // Compatibility method for existing controllers
609
+ set(key: string, value: any): void {
610
+ if (key === "io") {
611
+ this.ioInstance = value;
612
+ }
613
+ }
614
+
615
+ get(key: string): any {
616
+ if (key === "io") {
617
+ return this.ioInstance;
618
+ }
619
+ return undefined;
620
+ }
621
+ }