@morojs/moro 1.6.1 → 1.6.2

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 (404) hide show
  1. package/README.md +74 -256
  2. package/dist/core/auth/morojs-adapter.js +20 -20
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-manager.d.ts +44 -0
  5. package/dist/core/config/config-manager.js +104 -0
  6. package/dist/core/config/config-manager.js.map +1 -0
  7. package/dist/core/config/config-sources.d.ts +21 -0
  8. package/dist/core/config/config-sources.js +503 -0
  9. package/dist/core/config/config-sources.js.map +1 -0
  10. package/dist/core/config/config-validator.d.ts +21 -0
  11. package/dist/core/config/config-validator.js +791 -0
  12. package/dist/core/config/config-validator.js.map +1 -0
  13. package/dist/core/config/file-loader.d.ts +1 -6
  14. package/dist/core/config/file-loader.js +21 -249
  15. package/dist/core/config/file-loader.js.map +1 -1
  16. package/dist/core/config/index.d.ts +41 -12
  17. package/dist/core/config/index.js +65 -54
  18. package/dist/core/config/index.js.map +1 -1
  19. package/dist/core/config/schema.d.ts +2 -2
  20. package/dist/core/config/schema.js +55 -44
  21. package/dist/core/config/schema.js.map +1 -1
  22. package/dist/core/config/utils.d.ts +10 -3
  23. package/dist/core/config/utils.js +31 -58
  24. package/dist/core/config/utils.js.map +1 -1
  25. package/dist/core/database/adapters/drizzle.d.ts +1 -1
  26. package/dist/core/database/adapters/drizzle.js +18 -11
  27. package/dist/core/database/adapters/drizzle.js.map +1 -1
  28. package/dist/core/database/adapters/index.d.ts +7 -7
  29. package/dist/core/database/adapters/index.js +19 -29
  30. package/dist/core/database/adapters/index.js.map +1 -1
  31. package/dist/core/database/adapters/mongodb.d.ts +13 -1
  32. package/dist/core/database/adapters/mongodb.js +46 -10
  33. package/dist/core/database/adapters/mongodb.js.map +1 -1
  34. package/dist/core/database/adapters/mysql.d.ts +14 -1
  35. package/dist/core/database/adapters/mysql.js +19 -9
  36. package/dist/core/database/adapters/mysql.js.map +1 -1
  37. package/dist/core/database/adapters/postgresql.d.ts +12 -2
  38. package/dist/core/database/adapters/postgresql.js +19 -9
  39. package/dist/core/database/adapters/postgresql.js.map +1 -1
  40. package/dist/core/database/adapters/redis.d.ts +12 -1
  41. package/dist/core/database/adapters/redis.js +48 -13
  42. package/dist/core/database/adapters/redis.js.map +1 -1
  43. package/dist/core/database/adapters/sqlite.d.ts +3 -1
  44. package/dist/core/database/adapters/sqlite.js +19 -8
  45. package/dist/core/database/adapters/sqlite.js.map +1 -1
  46. package/dist/core/database/index.d.ts +2 -2
  47. package/dist/core/database/index.js +2 -18
  48. package/dist/core/database/index.js.map +1 -1
  49. package/dist/core/docs/index.d.ts +9 -9
  50. package/dist/core/docs/index.js +14 -35
  51. package/dist/core/docs/index.js.map +1 -1
  52. package/dist/core/docs/openapi-generator.d.ts +2 -2
  53. package/dist/core/docs/openapi-generator.js +11 -16
  54. package/dist/core/docs/openapi-generator.js.map +1 -1
  55. package/dist/core/docs/schema-to-openapi.d.ts +2 -2
  56. package/dist/core/docs/schema-to-openapi.js +5 -11
  57. package/dist/core/docs/schema-to-openapi.js.map +1 -1
  58. package/dist/core/docs/simple-docs.d.ts +1 -1
  59. package/dist/core/docs/simple-docs.js +4 -9
  60. package/dist/core/docs/simple-docs.js.map +1 -1
  61. package/dist/core/docs/swagger-ui.d.ts +2 -2
  62. package/dist/core/docs/swagger-ui.js +26 -29
  63. package/dist/core/docs/swagger-ui.js.map +1 -1
  64. package/dist/core/docs/zod-to-openapi.js +31 -28
  65. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  66. package/dist/core/events/event-bus.d.ts +1 -1
  67. package/dist/core/events/event-bus.js +7 -11
  68. package/dist/core/events/event-bus.js.map +1 -1
  69. package/dist/core/events/index.d.ts +2 -2
  70. package/dist/core/events/index.js +1 -5
  71. package/dist/core/events/index.js.map +1 -1
  72. package/dist/core/framework.d.ts +20 -13
  73. package/dist/core/framework.js +285 -102
  74. package/dist/core/framework.js.map +1 -1
  75. package/dist/core/http/http-server.d.ts +59 -7
  76. package/dist/core/http/http-server.js +190 -176
  77. package/dist/core/http/http-server.js.map +1 -1
  78. package/dist/core/http/index.d.ts +4 -3
  79. package/dist/core/http/index.js +3 -8
  80. package/dist/core/http/index.js.map +1 -1
  81. package/dist/core/http/uws-http-server.d.ts +46 -0
  82. package/dist/core/http/uws-http-server.js +523 -0
  83. package/dist/core/http/uws-http-server.js.map +1 -0
  84. package/dist/core/logger/filters.d.ts +1 -1
  85. package/dist/core/logger/filters.js +20 -23
  86. package/dist/core/logger/filters.js.map +1 -1
  87. package/dist/core/logger/index.d.ts +3 -3
  88. package/dist/core/logger/index.js +2 -24
  89. package/dist/core/logger/index.js.map +1 -1
  90. package/dist/core/logger/logger.d.ts +30 -14
  91. package/dist/core/logger/logger.js +398 -223
  92. package/dist/core/logger/logger.js.map +1 -1
  93. package/dist/core/logger/outputs.d.ts +1 -1
  94. package/dist/core/logger/outputs.js +8 -17
  95. package/dist/core/logger/outputs.js.map +1 -1
  96. package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
  97. package/dist/core/middleware/built-in/adapters/cache/file.js +10 -47
  98. package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
  99. package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
  100. package/dist/core/middleware/built-in/adapters/cache/index.js +10 -17
  101. package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
  102. package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
  103. package/dist/core/middleware/built-in/adapters/cache/memory.js +3 -7
  104. package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
  105. package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +3 -1
  106. package/dist/core/middleware/built-in/adapters/cache/redis.js +11 -9
  107. package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
  108. package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
  109. package/dist/core/middleware/built-in/adapters/cdn/azure.js +3 -7
  110. package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
  111. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
  112. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +3 -7
  113. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
  114. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +3 -1
  115. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +12 -10
  116. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
  117. package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
  118. package/dist/core/middleware/built-in/adapters/cdn/index.js +10 -17
  119. package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -1
  120. package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
  121. package/dist/core/middleware/built-in/adapters/index.js +4 -23
  122. package/dist/core/middleware/built-in/adapters/index.js.map +1 -1
  123. package/dist/core/middleware/built-in/auth-helpers.js +11 -22
  124. package/dist/core/middleware/built-in/auth-helpers.js.map +1 -1
  125. package/dist/core/middleware/built-in/auth-providers.d.ts +1 -1
  126. package/dist/core/middleware/built-in/auth-providers.js +4 -9
  127. package/dist/core/middleware/built-in/auth-providers.js.map +1 -1
  128. package/dist/core/middleware/built-in/auth.d.ts +2 -2
  129. package/dist/core/middleware/built-in/auth.js +93 -26
  130. package/dist/core/middleware/built-in/auth.js.map +1 -1
  131. package/dist/core/middleware/built-in/cache.d.ts +2 -2
  132. package/dist/core/middleware/built-in/cache.js +11 -12
  133. package/dist/core/middleware/built-in/cache.js.map +1 -1
  134. package/dist/core/middleware/built-in/cdn.d.ts +2 -2
  135. package/dist/core/middleware/built-in/cdn.js +5 -9
  136. package/dist/core/middleware/built-in/cdn.js.map +1 -1
  137. package/dist/core/middleware/built-in/cookie.d.ts +1 -1
  138. package/dist/core/middleware/built-in/cookie.js +3 -7
  139. package/dist/core/middleware/built-in/cookie.js.map +1 -1
  140. package/dist/core/middleware/built-in/cors.d.ts +1 -1
  141. package/dist/core/middleware/built-in/cors.js +3 -7
  142. package/dist/core/middleware/built-in/cors.js.map +1 -1
  143. package/dist/core/middleware/built-in/csp.d.ts +1 -1
  144. package/dist/core/middleware/built-in/csp.js +5 -8
  145. package/dist/core/middleware/built-in/csp.js.map +1 -1
  146. package/dist/core/middleware/built-in/csrf.d.ts +1 -1
  147. package/dist/core/middleware/built-in/csrf.js +5 -8
  148. package/dist/core/middleware/built-in/csrf.js.map +1 -1
  149. package/dist/core/middleware/built-in/error-tracker.js +3 -7
  150. package/dist/core/middleware/built-in/error-tracker.js.map +1 -1
  151. package/dist/core/middleware/built-in/index.d.ts +28 -27
  152. package/dist/core/middleware/built-in/index.js +48 -78
  153. package/dist/core/middleware/built-in/index.js.map +1 -1
  154. package/dist/core/middleware/built-in/jwt-helpers.d.ts +118 -0
  155. package/dist/core/middleware/built-in/jwt-helpers.js +218 -0
  156. package/dist/core/middleware/built-in/jwt-helpers.js.map +1 -0
  157. package/dist/core/middleware/built-in/performance-monitor.js +3 -7
  158. package/dist/core/middleware/built-in/performance-monitor.js.map +1 -1
  159. package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
  160. package/dist/core/middleware/built-in/rate-limit.js +3 -7
  161. package/dist/core/middleware/built-in/rate-limit.js.map +1 -1
  162. package/dist/core/middleware/built-in/request-logger.js +5 -8
  163. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  164. package/dist/core/middleware/built-in/session.d.ts +2 -2
  165. package/dist/core/middleware/built-in/session.js +11 -15
  166. package/dist/core/middleware/built-in/session.js.map +1 -1
  167. package/dist/core/middleware/built-in/sse.d.ts +1 -1
  168. package/dist/core/middleware/built-in/sse.js +12 -14
  169. package/dist/core/middleware/built-in/sse.js.map +1 -1
  170. package/dist/core/middleware/built-in/validation.d.ts +1 -1
  171. package/dist/core/middleware/built-in/validation.js +3 -7
  172. package/dist/core/middleware/built-in/validation.js.map +1 -1
  173. package/dist/core/middleware/index.d.ts +4 -4
  174. package/dist/core/middleware/index.js +8 -28
  175. package/dist/core/middleware/index.js.map +1 -1
  176. package/dist/core/modules/auto-discovery.d.ts +19 -2
  177. package/dist/core/modules/auto-discovery.js +391 -74
  178. package/dist/core/modules/auto-discovery.js.map +1 -1
  179. package/dist/core/modules/index.d.ts +2 -2
  180. package/dist/core/modules/index.js +2 -9
  181. package/dist/core/modules/index.js.map +1 -1
  182. package/dist/core/modules/modules.d.ts +3 -3
  183. package/dist/core/modules/modules.js +23 -54
  184. package/dist/core/modules/modules.js.map +1 -1
  185. package/dist/core/networking/adapters/index.d.ts +4 -3
  186. package/dist/core/networking/adapters/index.js +3 -7
  187. package/dist/core/networking/adapters/index.js.map +1 -1
  188. package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -1
  189. package/dist/core/networking/adapters/socketio-adapter.js +5 -40
  190. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  191. package/dist/core/networking/adapters/uws-adapter.d.ts +44 -0
  192. package/dist/core/networking/adapters/uws-adapter.js +513 -0
  193. package/dist/core/networking/adapters/uws-adapter.js.map +1 -0
  194. package/dist/core/networking/adapters/ws-adapter.d.ts +2 -2
  195. package/dist/core/networking/adapters/ws-adapter.js +8 -43
  196. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  197. package/dist/core/networking/index.d.ts +3 -2
  198. package/dist/core/networking/index.js +2 -7
  199. package/dist/core/networking/index.js.map +1 -1
  200. package/dist/core/networking/service-discovery.js +8 -12
  201. package/dist/core/networking/service-discovery.js.map +1 -1
  202. package/dist/core/networking/websocket-adapter.js +1 -2
  203. package/dist/core/networking/websocket-adapter.js.map +1 -1
  204. package/dist/core/networking/websocket-manager.d.ts +3 -3
  205. package/dist/core/networking/websocket-manager.js +9 -11
  206. package/dist/core/networking/websocket-manager.js.map +1 -1
  207. package/dist/core/pooling/object-pool-manager.d.ts +140 -0
  208. package/dist/core/pooling/object-pool-manager.js +502 -0
  209. package/dist/core/pooling/object-pool-manager.js.map +1 -0
  210. package/dist/core/routing/app-integration.d.ts +14 -12
  211. package/dist/core/routing/app-integration.js +49 -85
  212. package/dist/core/routing/app-integration.js.map +1 -1
  213. package/dist/core/routing/index.d.ts +17 -11
  214. package/dist/core/routing/index.js +48 -237
  215. package/dist/core/routing/index.js.map +1 -1
  216. package/dist/core/routing/path-matcher.d.ts +67 -0
  217. package/dist/core/routing/path-matcher.js +182 -0
  218. package/dist/core/routing/path-matcher.js.map +1 -0
  219. package/dist/core/routing/router.d.ts +38 -0
  220. package/dist/core/routing/router.js +68 -0
  221. package/dist/core/routing/router.js.map +1 -0
  222. package/dist/core/routing/unified-router.d.ts +148 -0
  223. package/dist/core/routing/unified-router.js +684 -0
  224. package/dist/core/routing/unified-router.js.map +1 -0
  225. package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
  226. package/dist/core/runtime/aws-lambda-adapter.js +2 -6
  227. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
  228. package/dist/core/runtime/base-adapter.d.ts +2 -2
  229. package/dist/core/runtime/base-adapter.js +3 -7
  230. package/dist/core/runtime/base-adapter.js.map +1 -1
  231. package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
  232. package/dist/core/runtime/cloudflare-workers-adapter.js +2 -6
  233. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  234. package/dist/core/runtime/index.d.ts +12 -12
  235. package/dist/core/runtime/index.js +22 -35
  236. package/dist/core/runtime/index.js.map +1 -1
  237. package/dist/core/runtime/node-adapter.d.ts +4 -4
  238. package/dist/core/runtime/node-adapter.js +18 -49
  239. package/dist/core/runtime/node-adapter.js.map +1 -1
  240. package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
  241. package/dist/core/runtime/vercel-edge-adapter.js +2 -6
  242. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  243. package/dist/core/utilities/circuit-breaker.js +1 -5
  244. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  245. package/dist/core/utilities/container.js +12 -22
  246. package/dist/core/utilities/container.js.map +1 -1
  247. package/dist/core/utilities/hooks.d.ts +2 -2
  248. package/dist/core/utilities/hooks.js +7 -12
  249. package/dist/core/utilities/hooks.js.map +1 -1
  250. package/dist/core/utilities/index.d.ts +5 -4
  251. package/dist/core/utilities/index.js +5 -19
  252. package/dist/core/utilities/index.js.map +1 -1
  253. package/dist/core/utilities/package-utils.d.ts +38 -0
  254. package/dist/core/utilities/package-utils.js +57 -0
  255. package/dist/core/utilities/package-utils.js.map +1 -0
  256. package/dist/core/validation/adapters.d.ts +1 -1
  257. package/dist/core/validation/adapters.js +15 -26
  258. package/dist/core/validation/adapters.js.map +1 -1
  259. package/dist/core/validation/index.d.ts +6 -4
  260. package/dist/core/validation/index.js +57 -28
  261. package/dist/core/validation/index.js.map +1 -1
  262. package/dist/core/validation/schema-interface.js +3 -9
  263. package/dist/core/validation/schema-interface.js.map +1 -1
  264. package/dist/index.d.ts +51 -52
  265. package/dist/index.js +23 -132
  266. package/dist/index.js.map +1 -1
  267. package/dist/moro.d.ts +70 -16
  268. package/dist/moro.js +658 -271
  269. package/dist/moro.js.map +1 -1
  270. package/dist/types/auth.js +3 -9
  271. package/dist/types/auth.js.map +1 -1
  272. package/dist/types/cache.js +1 -2
  273. package/dist/types/cdn.js +1 -2
  274. package/dist/types/config.d.ts +73 -2
  275. package/dist/types/config.js +1 -2
  276. package/dist/types/config.js.map +1 -1
  277. package/dist/types/core.d.ts +36 -42
  278. package/dist/types/core.js +1 -2
  279. package/dist/types/database.js +1 -2
  280. package/dist/types/discovery.js +1 -2
  281. package/dist/types/events.js +1 -2
  282. package/dist/types/hooks.d.ts +1 -1
  283. package/dist/types/hooks.js +1 -2
  284. package/dist/types/http.d.ts +16 -1
  285. package/dist/types/http.js +1 -2
  286. package/dist/types/logger.d.ts +7 -0
  287. package/dist/types/logger.js +1 -2
  288. package/dist/types/module.d.ts +11 -0
  289. package/dist/types/module.js +1 -2
  290. package/dist/types/runtime.d.ts +1 -1
  291. package/dist/types/runtime.js +1 -2
  292. package/dist/types/session.js +1 -2
  293. package/jest.config.mjs +41 -0
  294. package/package.json +19 -52
  295. package/src/core/auth/morojs-adapter.ts +18 -13
  296. package/src/core/config/config-manager.ts +133 -0
  297. package/src/core/config/config-sources.ts +600 -0
  298. package/src/core/config/config-validator.ts +1116 -0
  299. package/src/core/config/file-loader.ts +16 -273
  300. package/src/core/config/index.ts +83 -34
  301. package/src/core/config/schema.ts +47 -33
  302. package/src/core/config/utils.ts +24 -31
  303. package/src/core/database/README.md +26 -16
  304. package/src/core/database/adapters/drizzle.ts +18 -6
  305. package/src/core/database/adapters/index.ts +13 -13
  306. package/src/core/database/adapters/mongodb.ts +53 -5
  307. package/src/core/database/adapters/mysql.ts +32 -4
  308. package/src/core/database/adapters/postgresql.ts +30 -5
  309. package/src/core/database/adapters/redis.ts +61 -8
  310. package/src/core/database/adapters/sqlite.ts +19 -3
  311. package/src/core/database/index.ts +2 -2
  312. package/src/core/docs/index.ts +8 -8
  313. package/src/core/docs/openapi-generator.ts +4 -4
  314. package/src/core/docs/schema-to-openapi.ts +3 -6
  315. package/src/core/docs/simple-docs.ts +2 -2
  316. package/src/core/docs/swagger-ui.ts +19 -16
  317. package/src/core/docs/zod-to-openapi.ts +34 -34
  318. package/src/core/events/event-bus.ts +3 -3
  319. package/src/core/events/index.ts +2 -2
  320. package/src/core/framework.ts +320 -71
  321. package/src/core/http/http-server.ts +203 -143
  322. package/src/core/http/index.ts +4 -3
  323. package/src/core/http/uws-http-server.ts +591 -0
  324. package/src/core/logger/filters.ts +13 -5
  325. package/src/core/logger/index.ts +4 -3
  326. package/src/core/logger/logger.ts +435 -216
  327. package/src/core/logger/outputs.ts +1 -3
  328. package/src/core/middleware/built-in/adapters/cache/file.ts +3 -3
  329. package/src/core/middleware/built-in/adapters/cache/index.ts +7 -7
  330. package/src/core/middleware/built-in/adapters/cache/memory.ts +2 -2
  331. package/src/core/middleware/built-in/adapters/cache/redis.ts +18 -4
  332. package/src/core/middleware/built-in/adapters/cdn/azure.ts +2 -2
  333. package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +2 -2
  334. package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +16 -5
  335. package/src/core/middleware/built-in/adapters/cdn/index.ts +7 -7
  336. package/src/core/middleware/built-in/adapters/index.ts +4 -4
  337. package/src/core/middleware/built-in/auth-helpers.ts +1 -1
  338. package/src/core/middleware/built-in/auth-providers.ts +1 -1
  339. package/src/core/middleware/built-in/auth.ts +102 -21
  340. package/src/core/middleware/built-in/cache.ts +8 -6
  341. package/src/core/middleware/built-in/cdn.ts +4 -4
  342. package/src/core/middleware/built-in/cookie.ts +2 -2
  343. package/src/core/middleware/built-in/cors.ts +2 -2
  344. package/src/core/middleware/built-in/csp.ts +3 -3
  345. package/src/core/middleware/built-in/csrf.ts +3 -3
  346. package/src/core/middleware/built-in/error-tracker.ts +1 -1
  347. package/src/core/middleware/built-in/index.ts +38 -30
  348. package/src/core/middleware/built-in/jwt-helpers.ts +243 -0
  349. package/src/core/middleware/built-in/performance-monitor.ts +1 -1
  350. package/src/core/middleware/built-in/rate-limit.ts +2 -2
  351. package/src/core/middleware/built-in/request-logger.ts +3 -1
  352. package/src/core/middleware/built-in/session.ts +7 -8
  353. package/src/core/middleware/built-in/sse.ts +11 -9
  354. package/src/core/middleware/built-in/validation.ts +2 -2
  355. package/src/core/middleware/index.ts +6 -6
  356. package/src/core/modules/auto-discovery.ts +478 -15
  357. package/src/core/modules/index.ts +2 -2
  358. package/src/core/modules/modules.ts +23 -12
  359. package/src/core/networking/adapters/index.ts +4 -3
  360. package/src/core/networking/adapters/socketio-adapter.ts +5 -3
  361. package/src/core/networking/adapters/uws-adapter.ts +619 -0
  362. package/src/core/networking/adapters/ws-adapter.ts +8 -9
  363. package/src/core/networking/index.ts +3 -2
  364. package/src/core/networking/service-discovery.ts +6 -7
  365. package/src/core/networking/websocket-manager.ts +7 -7
  366. package/src/core/pooling/object-pool-manager.ts +630 -0
  367. package/src/core/routing/app-integration.ts +60 -112
  368. package/src/core/routing/index.ts +66 -293
  369. package/src/core/routing/path-matcher.ts +222 -0
  370. package/src/core/routing/router.ts +97 -0
  371. package/src/core/routing/unified-router.ts +870 -0
  372. package/src/core/runtime/aws-lambda-adapter.ts +3 -3
  373. package/src/core/runtime/base-adapter.ts +2 -2
  374. package/src/core/runtime/cloudflare-workers-adapter.ts +3 -3
  375. package/src/core/runtime/index.ts +13 -13
  376. package/src/core/runtime/node-adapter.ts +16 -10
  377. package/src/core/runtime/vercel-edge-adapter.ts +3 -3
  378. package/src/core/utilities/hooks.ts +3 -3
  379. package/src/core/utilities/index.ts +5 -4
  380. package/src/core/utilities/package-utils.ts +59 -0
  381. package/src/core/validation/adapters.ts +1 -1
  382. package/src/core/validation/index.ts +68 -16
  383. package/src/index.ts +73 -66
  384. package/src/moro.ts +784 -253
  385. package/src/types/config.ts +74 -2
  386. package/src/types/core.ts +49 -47
  387. package/src/types/hooks.ts +1 -1
  388. package/src/types/http.ts +23 -1
  389. package/src/types/logger.ts +9 -0
  390. package/src/types/module.ts +12 -0
  391. package/src/types/runtime.ts +1 -1
  392. package/tsconfig.json +4 -2
  393. package/dist/core/config/loader.d.ts +0 -7
  394. package/dist/core/config/loader.js +0 -269
  395. package/dist/core/config/loader.js.map +0 -1
  396. package/dist/core/config/validation.d.ts +0 -17
  397. package/dist/core/config/validation.js +0 -131
  398. package/dist/core/config/validation.js.map +0 -1
  399. package/dist/core/http/router.d.ts +0 -14
  400. package/dist/core/http/router.js +0 -109
  401. package/dist/core/http/router.js.map +0 -1
  402. package/src/core/config/loader.ts +0 -633
  403. package/src/core/config/validation.ts +0 -140
  404. package/src/core/http/router.ts +0 -141
@@ -1,41 +1,39 @@
1
1
  // Zod to OpenAPI Schema Converter
2
2
  // Transforms Zod schemas into OpenAPI 3.0 schema definitions
3
3
 
4
- import { createFrameworkLogger } from '../logger';
4
+ import { createFrameworkLogger } from '../logger/index.js';
5
+ import { createUserRequire, isPackageAvailable } from '../utilities/package-utils.js';
6
+
7
+ const logger = createFrameworkLogger('ZodToOpenAPI');
5
8
 
6
9
  // Dynamic Zod imports (optional dependency)
7
- let ZodSchema: any,
8
- ZodType: any,
9
- ZodObject: any,
10
- ZodArray: any,
11
- ZodString: any,
12
- ZodNumber: any,
13
- ZodBoolean: any,
14
- ZodEnum: any,
15
- ZodOptional: any,
16
- ZodDefault: any,
17
- ZodUnion: any,
18
- ZodLiteral: any;
19
-
20
- try {
21
- const zod = require('zod');
22
- ZodSchema = zod.ZodSchema;
23
- ZodType = zod.ZodType;
24
- ZodObject = zod.ZodObject;
25
- ZodArray = zod.ZodArray;
26
- ZodString = zod.ZodString;
27
- ZodNumber = zod.ZodNumber;
28
- ZodBoolean = zod.ZodBoolean;
29
- ZodEnum = zod.ZodEnum;
30
- ZodOptional = zod.ZodOptional;
31
- ZodDefault = zod.ZodDefault;
32
- ZodUnion = zod.ZodUnion;
33
- ZodLiteral = zod.ZodLiteral;
34
- } catch {
35
- // Zod not available - that's fine!
36
- }
10
+ let zodModule: any = null;
11
+ let zodLoadAttempted = false;
37
12
 
38
- const logger = createFrameworkLogger('ZodToOpenAPI');
13
+ // Lazy synchronous initialization for Zod
14
+ function loadZodSync() {
15
+ if (zodLoadAttempted) {
16
+ return zodModule;
17
+ }
18
+
19
+ zodLoadAttempted = true;
20
+
21
+ try {
22
+ if (!isPackageAvailable('zod')) {
23
+ zodModule = null;
24
+ return zodModule;
25
+ }
26
+
27
+ // Use synchronous require for immediate availability
28
+ const userRequire = createUserRequire();
29
+ zodModule = userRequire('zod');
30
+ } catch {
31
+ // Zod not available - that's fine!
32
+ zodModule = null;
33
+ }
34
+
35
+ return zodModule;
36
+ }
39
37
 
40
38
  // OpenAPI schema types
41
39
  export interface OpenAPISchema {
@@ -72,7 +70,8 @@ export interface ConversionOptions {
72
70
  // Main conversion function
73
71
  export function zodToOpenAPI(schema: any, options: ConversionOptions = {}): OpenAPISchema {
74
72
  // Check if Zod is available
75
- if (!ZodSchema) {
73
+ const zod = loadZodSync();
74
+ if (!zod) {
76
75
  throw new Error('Zod is not installed. Please install zod to use zodToOpenAPI function.');
77
76
  }
78
77
 
@@ -420,7 +419,8 @@ function hasDefault(type: any): boolean {
420
419
  // Generate example data from Zod schema
421
420
  export function generateExampleFromSchema(schema: any): any {
422
421
  // Check if Zod is available
423
- if (!ZodSchema) {
422
+ const zod = loadZodSync();
423
+ if (!zod) {
424
424
  throw new Error(
425
425
  'Zod is not installed. Please install zod to use generateExampleFromSchema function.'
426
426
  );
@@ -8,8 +8,8 @@ import {
8
8
  GlobalEventBus,
9
9
  EventMetrics,
10
10
  EventHandler,
11
- } from '../../types/events';
12
- import { createFrameworkLogger } from '../logger';
11
+ } from '../../types/events.js';
12
+ import { createFrameworkLogger } from '../logger/index.js';
13
13
 
14
14
  export class MoroEventBus implements GlobalEventBus {
15
15
  private emitter = new EventEmitter();
@@ -33,7 +33,7 @@ export class MoroEventBus implements GlobalEventBus {
33
33
 
34
34
  // Global event emission with full context and metrics
35
35
  async emit<T = any>(event: string, data: T, context?: Partial<EventContext>): Promise<boolean> {
36
- // Fast path: skip processing if no listeners
36
+ // Skip processing if no listeners
37
37
  if (this.emitter.listenerCount(event) === 0) {
38
38
  return false;
39
39
  }
@@ -1,5 +1,5 @@
1
1
  // Event System - Centralized Exports
2
- export { MoroEventBus } from './event-bus';
2
+ export { MoroEventBus } from './event-bus.js';
3
3
  export type {
4
4
  EventContext,
5
5
  EventPayload,
@@ -9,4 +9,4 @@ export type {
9
9
  EventMetrics,
10
10
  SystemEvents,
11
11
  EventHandler,
12
- } from '../../types/events';
12
+ } from '../../types/events.js';
@@ -5,29 +5,29 @@ import {
5
5
  createServer as createHttp2Server,
6
6
  } from 'http2';
7
7
  import { EventEmitter } from 'events';
8
- import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from './http';
9
- import { Router } from './http';
10
- import { Container } from './utilities';
11
- import { ModuleLoader } from './modules';
12
- import { WebSocketManager } from './networking';
13
- import { CircuitBreaker } from './utilities';
14
- import { MoroEventBus } from './events';
15
- import { createFrameworkLogger, logger as globalLogger } from './logger';
16
- import { ModuleConfig, InternalRouteDefinition } from '../types/module';
17
- import { LogLevel, LoggerOptions } from '../types/logger';
18
- import { WebSocketAdapter, WebSocketAdapterOptions } from './networking/websocket-adapter';
19
-
20
- export interface MoroOptions {
8
+ import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from './http/index.js';
9
+ import { UWebSocketsHttpServer } from './http/uws-http-server.js';
10
+ import { Router } from './routing/router.js';
11
+ import { Container } from './utilities/container.js';
12
+ import { ModuleLoader } from './modules/index.js';
13
+ import { WebSocketManager } from './networking/websocket-manager.js';
14
+ import { CircuitBreaker } from './utilities/circuit-breaker.js';
15
+ import { isPackageAvailable } from './utilities/package-utils.js';
16
+ import { MoroEventBus } from './events/index.js';
17
+ import { createFrameworkLogger, logger as globalLogger } from './logger/index.js';
18
+ import { ModuleConfig, InternalRouteDefinition } from '../types/module.js';
19
+ import { LogLevel, LoggerOptions } from '../types/logger.js';
20
+ import { MoroOptions as CoreMoroOptions } from '../types/core.js';
21
+ import { WebSocketAdapter, WebSocketAdapterOptions } from './networking/websocket-adapter.js';
22
+
23
+ // Extended MoroOptions that includes both core options and framework-specific options
24
+ export interface MoroOptions extends CoreMoroOptions {
21
25
  http2?: boolean;
22
26
  https?: {
23
27
  key: string | Buffer;
24
28
  cert: string | Buffer;
25
29
  ca?: string | Buffer;
26
30
  };
27
- compression?: {
28
- enabled?: boolean;
29
- threshold?: number;
30
- };
31
31
  websocket?:
32
32
  | {
33
33
  enabled?: boolean;
@@ -37,12 +37,12 @@ export interface MoroOptions {
37
37
  options?: WebSocketAdapterOptions;
38
38
  }
39
39
  | false;
40
- logger?: LoggerOptions | boolean;
40
+ config?: any; // Full configuration object
41
41
  }
42
42
 
43
43
  export class Moro extends EventEmitter {
44
- private httpServer: MoroHttpServer;
45
- private server: Server | any; // HTTP/2 server type
44
+ private httpServer: MoroHttpServer | UWebSocketsHttpServer;
45
+ private server: Server | any; // HTTP/2 server type or uWebSockets app
46
46
  private websocketAdapter?: WebSocketAdapter;
47
47
  private container: Container;
48
48
  private moduleLoader: ModuleLoader;
@@ -54,10 +54,15 @@ export class Moro extends EventEmitter {
54
54
  // Framework logger
55
55
  private logger: any;
56
56
  private options: MoroOptions;
57
+ private config: any;
58
+ private usingUWebSockets = false;
59
+ // WebSocket initialization promise to handle async adapter detection
60
+ private websocketSetupPromise: Promise<void> | null = null;
57
61
 
58
62
  constructor(options: MoroOptions = {}) {
59
63
  super();
60
64
  this.options = options;
65
+ this.config = options.config || {};
61
66
 
62
67
  // Configure global logger based on options
63
68
  if (options.logger !== undefined) {
@@ -77,10 +82,33 @@ export class Moro extends EventEmitter {
77
82
  // Initialize framework logger after global configuration
78
83
  this.logger = createFrameworkLogger('Core');
79
84
 
80
- this.httpServer = new MoroHttpServer();
85
+ // Check if uWebSockets should be used for HTTP and WebSocket
86
+ const useUWebSockets = this.config.server?.useUWebSockets || false;
87
+
88
+ if (useUWebSockets) {
89
+ try {
90
+ // Try to use uWebSockets for high performance HTTP and WebSocket
91
+ const sslOptions = this.config.server?.ssl || options.https;
92
+ this.httpServer = new UWebSocketsHttpServer({ ssl: sslOptions });
93
+ this.server = (this.httpServer as UWebSocketsHttpServer).getApp();
94
+ this.usingUWebSockets = true;
95
+ this.logger.info('uWebSockets HTTP+WebSocket server created', 'ServerInit');
96
+ } catch (error) {
97
+ // Fallback to standard HTTP/1.1 if uWebSockets fails to load
98
+ this.logger.warn(
99
+ 'uWebSockets failed to initialize, falling back to Node.js http.Server. ' +
100
+ 'Error: ' +
101
+ (error instanceof Error ? error.message : String(error)),
102
+ 'ServerInit'
103
+ );
104
+ this.usingUWebSockets = false;
105
+ this.httpServer = new MoroHttpServer();
106
+ this.server = (this.httpServer as MoroHttpServer).getServer();
107
+ }
108
+ } else if (options.http2) {
109
+ // Use HTTP/2
110
+ this.httpServer = new MoroHttpServer();
81
111
 
82
- // Create HTTP/2 or HTTP/1.1 server based on options
83
- if (options.http2) {
84
112
  if (options.https) {
85
113
  this.server = createHttp2SecureServer(options.https);
86
114
  } else {
@@ -95,20 +123,26 @@ export class Moro extends EventEmitter {
95
123
  req.url = headers[':path'];
96
124
  req.method = headers[':method'];
97
125
  req.headers = headers;
98
- this.httpServer['handleRequest'](req, res);
126
+ (this.httpServer as MoroHttpServer)['handleRequest'](req, res);
99
127
  });
100
128
 
101
129
  this.logger.info('HTTP/2 server created', 'ServerInit');
102
130
  } else {
103
- this.server = this.httpServer.getServer();
131
+ // Use standard HTTP/1.1
132
+ this.httpServer = new MoroHttpServer();
133
+ this.server = (this.httpServer as MoroHttpServer).getServer();
104
134
  }
105
135
 
106
136
  this.container = new Container();
107
137
  this.moduleLoader = new ModuleLoader(this.container);
108
138
 
109
- // Setup WebSocket adapter if enabled
110
- if (options.websocket !== false) {
111
- this.setupWebSockets(options.websocket || {});
139
+ // Setup WebSocket adapter if enabled in config OR options
140
+ if (
141
+ this.config.websocket.enabled ||
142
+ (options.websocket && typeof options.websocket === 'object')
143
+ ) {
144
+ // Store the promise so we can await it before using websockets
145
+ this.websocketSetupPromise = this.setupWebSockets(options.websocket || {});
112
146
  }
113
147
 
114
148
  // Initialize enterprise event bus
@@ -131,19 +165,54 @@ export class Moro extends EventEmitter {
131
165
  }
132
166
 
133
167
  private setupCore() {
134
- // Security middleware
135
- this.httpServer.use(middleware.helmet());
136
- this.httpServer.use(middleware.cors());
168
+ // PERFORMANCE FIX: Only apply middleware if enabled in config OR options
169
+
170
+ // Security middleware - check config enabled property OR options.security.*.enabled === true
171
+ if (this.config.security.helmet.enabled || this.options.security?.helmet?.enabled === true) {
172
+ this.httpServer.use(middleware.helmet());
173
+ }
174
+
175
+ if (this.config.security.cors.enabled || this.options.security?.cors?.enabled === true) {
176
+ const corsOptions =
177
+ typeof this.options.cors === 'object'
178
+ ? this.options.cors
179
+ : this.config.security.cors
180
+ ? this.config.security.cors
181
+ : {};
182
+ this.httpServer.use(middleware.cors(corsOptions));
183
+ }
137
184
 
138
- // Performance middleware
139
- this.httpServer.use(middleware.compression());
140
- this.httpServer.use(middleware.bodySize({ limit: '10mb' }));
185
+ // Performance middleware - check config enabled property OR options.performance.*.enabled === true
186
+ if (
187
+ this.config.performance.compression.enabled ||
188
+ this.options.performance?.compression?.enabled === true
189
+ ) {
190
+ const compressionOptions =
191
+ typeof this.options.compression === 'object'
192
+ ? this.options.compression
193
+ : this.config.performance.compression
194
+ ? this.config.performance.compression
195
+ : {};
196
+ this.httpServer.use(middleware.compression(compressionOptions));
197
+ }
198
+
199
+ // Body size middleware - always enabled with configurable limit
200
+ this.httpServer.use(middleware.bodySize({ limit: this.config.server.bodySizeLimit }));
141
201
 
142
- // Request tracking middleware
143
- this.httpServer.use(this.requestTrackingMiddleware());
202
+ // Configure request tracking (ID generation) in HTTP server
203
+ if (this.httpServer.setRequestTracking) {
204
+ this.httpServer.setRequestTracking(this.config.server.requestTracking.enabled);
205
+ }
144
206
 
145
- // Error boundary middleware
146
- this.httpServer.use(this.errorBoundaryMiddleware());
207
+ // Request logging middleware - separate from request tracking (ID generation)
208
+ if (this.config.server.requestLogging.enabled) {
209
+ this.httpServer.use(this.requestLoggingMiddleware());
210
+ }
211
+
212
+ // Error boundary middleware - configurable but recommended to keep enabled
213
+ if (this.config.server.errorBoundary.enabled) {
214
+ this.httpServer.use(this.errorBoundaryMiddleware());
215
+ }
147
216
  }
148
217
 
149
218
  /**
@@ -151,29 +220,47 @@ export class Moro extends EventEmitter {
151
220
  */
152
221
  private async setupWebSockets(wsConfig: any): Promise<void> {
153
222
  try {
154
- // Use provided adapter or try to auto-detect
155
- if (wsConfig.adapter) {
156
- this.websocketAdapter = wsConfig.adapter;
223
+ // If using uWebSockets HTTP server, automatically use uWebSockets for WebSocket too
224
+ if (this.usingUWebSockets) {
225
+ const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
226
+ this.websocketAdapter = new UWebSocketsAdapter();
227
+
228
+ // For uWebSockets, we need to integrate with the existing app
229
+ const uwsHttpServer = this.httpServer as UWebSocketsHttpServer;
230
+ await this.websocketAdapter.initialize(uwsHttpServer.getApp(), wsConfig.options);
231
+
232
+ this.logger.info(
233
+ 'uWebSockets adapter initialized (integrated with HTTP server)',
234
+ 'WebSocketSetup'
235
+ );
157
236
  } else {
158
- this.websocketAdapter = (await this.detectWebSocketAdapter()) || undefined;
237
+ // Use provided adapter or try to auto-detect
238
+ if (wsConfig.adapter) {
239
+ this.websocketAdapter = wsConfig.adapter;
240
+ } else {
241
+ this.websocketAdapter = (await this.detectWebSocketAdapter()) || undefined;
242
+ }
243
+
244
+ if (this.websocketAdapter) {
245
+ await this.websocketAdapter.initialize(this.server, wsConfig.options);
246
+
247
+ this.logger.info(
248
+ `WebSocket adapter initialized: ${this.websocketAdapter.getAdapterName()}`,
249
+ 'WebSocketSetup'
250
+ );
251
+ }
159
252
  }
160
253
 
254
+ // Configure adapter features (if adapter was created)
161
255
  if (this.websocketAdapter) {
162
- await this.websocketAdapter.initialize(this.server, wsConfig.options);
163
256
  this.websocketManager = new WebSocketManager(this.websocketAdapter, this.container);
164
257
 
165
- // Configure adapter features
166
258
  if (wsConfig.compression) {
167
259
  this.websocketAdapter.setCompression(true);
168
260
  }
169
261
  if (wsConfig.customIdGenerator) {
170
262
  this.websocketAdapter.setCustomIdGenerator(wsConfig.customIdGenerator);
171
263
  }
172
-
173
- this.logger.info(
174
- `WebSocket adapter initialized: ${this.websocketAdapter.getAdapterName()}`,
175
- 'WebSocketSetup'
176
- );
177
264
  }
178
265
  } catch (error) {
179
266
  this.logger.warn(
@@ -186,40 +273,86 @@ export class Moro extends EventEmitter {
186
273
 
187
274
  /**
188
275
  * Auto-detect available WebSocket adapter
276
+ * Tests if the library is actually installed by checking require.resolve
189
277
  */
190
278
  private async detectWebSocketAdapter(): Promise<WebSocketAdapter | null> {
191
- // Try socket.io first
192
- try {
193
- const { SocketIOAdapter } = await import('./networking/adapters');
194
- return new SocketIOAdapter();
195
- } catch {
196
- // socket.io not available
279
+ // Check if adapter is specified in config
280
+ if (this.config.websocket?.adapter) {
281
+ const adapterType = this.config.websocket.adapter;
282
+
283
+ if (adapterType === 'uws' && isPackageAvailable('uWebSockets.js')) {
284
+ try {
285
+ const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
286
+ return new UWebSocketsAdapter();
287
+ } catch {
288
+ this.logger.warn('uWebSockets.js specified but failed to load', 'AdapterDetection');
289
+ }
290
+ } else if (adapterType === 'socket.io' && isPackageAvailable('socket.io')) {
291
+ try {
292
+ const { SocketIOAdapter } = await import('./networking/adapters/index.js');
293
+ return new SocketIOAdapter();
294
+ } catch {
295
+ this.logger.warn('socket.io specified but failed to load', 'AdapterDetection');
296
+ }
297
+ } else if (adapterType === 'ws' && isPackageAvailable('ws')) {
298
+ try {
299
+ const { WSAdapter } = await import('./networking/adapters/index.js');
300
+ return new WSAdapter();
301
+ } catch {
302
+ this.logger.warn('ws specified but failed to load', 'AdapterDetection');
303
+ }
304
+ }
197
305
  }
198
306
 
199
- // Try native ws library
200
- try {
201
- const { WSAdapter } = await import('./networking/adapters');
202
- return new WSAdapter();
203
- } catch {
204
- // ws not available
307
+ // Auto-detect: Try uWebSockets.js first (highest performance)
308
+ if (isPackageAvailable('uWebSockets.js')) {
309
+ try {
310
+ const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
311
+ this.logger.debug('uWebSockets.js detected and loaded', 'AdapterDetection');
312
+ return new UWebSocketsAdapter();
313
+ } catch {
314
+ // Failed to load adapter
315
+ }
316
+ }
317
+
318
+ // Try socket.io second
319
+ if (isPackageAvailable('socket.io')) {
320
+ try {
321
+ const { SocketIOAdapter } = await import('./networking/adapters/index.js');
322
+ this.logger.debug('socket.io detected and loaded', 'AdapterDetection');
323
+ return new SocketIOAdapter();
324
+ } catch {
325
+ // Failed to load adapter
326
+ }
327
+ }
328
+
329
+ // Try native ws library last
330
+ if (isPackageAvailable('ws')) {
331
+ try {
332
+ const { WSAdapter } = await import('./networking/adapters/index.js');
333
+ this.logger.debug('ws detected and loaded', 'AdapterDetection');
334
+ return new WSAdapter();
335
+ } catch {
336
+ // Failed to load adapter
337
+ }
205
338
  }
206
339
 
207
340
  this.logger.warn(
208
- 'No WebSocket adapter found. Install socket.io or ws for WebSocket support',
341
+ 'No WebSocket adapter found. Install uWebSockets.js, socket.io, or ws for WebSocket support',
209
342
  'AdapterDetection'
210
343
  );
211
344
  return null;
212
345
  }
213
346
 
214
- private requestTrackingMiddleware() {
347
+ private requestLoggingMiddleware() {
215
348
  return (req: HttpRequest, res: HttpResponse, next: () => void) => {
216
349
  const startTime = Date.now();
217
350
 
218
351
  res.on('finish', () => {
219
352
  const duration = Date.now() - startTime;
220
- this.logger.info(
221
- `${req.method} ${req.path} - ${res.statusCode} - ${duration}ms [${req.requestId}]`
222
- );
353
+ // Include request ID in log if request tracking is enabled
354
+ const idPart = req.requestId ? ` [${req.requestId}]` : '';
355
+ this.logger.info(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms${idPart}`);
223
356
  });
224
357
 
225
358
  next();
@@ -284,6 +417,15 @@ export class Moro extends EventEmitter {
284
417
  return this.websocketAdapter;
285
418
  }
286
419
 
420
+ /**
421
+ * Ensure WebSocket setup is complete (for async adapter detection)
422
+ */
423
+ async ensureWebSocketReady(): Promise<void> {
424
+ if (this.websocketSetupPromise) {
425
+ await this.websocketSetupPromise;
426
+ }
427
+ }
428
+
287
429
  /**
288
430
  * Get the WebSocket manager
289
431
  */
@@ -411,6 +553,76 @@ export class Moro extends EventEmitter {
411
553
  throw new Error(`Handler ${route.handler} is not a function`);
412
554
  }
413
555
 
556
+ // Check authentication if auth configuration is provided
557
+ if ((route as any).auth) {
558
+ const auth = (req as any).auth;
559
+ const authConfig = (route as any).auth;
560
+
561
+ if (!auth) {
562
+ res.status(401);
563
+ res.json({
564
+ success: false,
565
+ error: 'Authentication required',
566
+ message: 'You must be logged in to access this resource',
567
+ });
568
+ return;
569
+ }
570
+
571
+ // Check authentication requirement (default is required unless optional: true)
572
+ if (!authConfig.optional && !auth.isAuthenticated) {
573
+ res.status(401);
574
+ res.json({
575
+ success: false,
576
+ error: 'Authentication required',
577
+ message: 'You must be logged in to access this resource',
578
+ });
579
+ return;
580
+ }
581
+
582
+ // Skip further checks if not authenticated but optional
583
+ if (!auth.isAuthenticated && authConfig.optional) {
584
+ // Continue to handler
585
+ } else if (auth.isAuthenticated) {
586
+ const user = auth.user;
587
+
588
+ // Check roles if specified
589
+ if (authConfig.roles && authConfig.roles.length > 0) {
590
+ const userRoles = user?.roles || [];
591
+ const hasRole = authConfig.roles.some((role: string) => userRoles.includes(role));
592
+
593
+ if (!hasRole) {
594
+ res.status(403);
595
+ res.json({
596
+ success: false,
597
+ error: 'Insufficient permissions',
598
+ message: `Required roles: ${authConfig.roles.join(', ')}`,
599
+ userRoles,
600
+ });
601
+ return;
602
+ }
603
+ }
604
+
605
+ // Check permissions if specified
606
+ if (authConfig.permissions && authConfig.permissions.length > 0) {
607
+ const userPermissions = user?.permissions || [];
608
+ const hasPermission = authConfig.permissions.every((permission: string) =>
609
+ userPermissions.includes(permission)
610
+ );
611
+
612
+ if (!hasPermission) {
613
+ res.status(403);
614
+ res.json({
615
+ success: false,
616
+ error: 'Insufficient permissions',
617
+ message: `Required permissions: ${authConfig.permissions.join(', ')}`,
618
+ userPermissions,
619
+ });
620
+ return;
621
+ }
622
+ }
623
+ }
624
+ }
625
+
414
626
  // Validate request if validation schema is provided
415
627
  if (route.validation) {
416
628
  try {
@@ -516,22 +728,61 @@ export class Moro extends EventEmitter {
516
728
  this.logger.debug(`Mounting router for basePath: ${basePath}`, 'Router');
517
729
 
518
730
  // Enterprise-grade middleware integration with performance optimization
731
+ // IMPORTANT: Module middleware runs AFTER user middleware (like auth) to ensure proper order
519
732
  this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
520
733
  if (req.path.startsWith(basePath)) {
521
734
  this.logger.debug(`Module middleware handling: ${req.method} ${req.path}`, 'Middleware', {
522
735
  basePath,
523
736
  });
524
737
 
738
+ // Mark this request as being handled by a module
739
+ (req as any).__moduleBasePath = basePath;
740
+ (req as any).__moduleRouter = router;
741
+
742
+ // Continue to next middleware (including auth) first
743
+ next();
744
+ } else {
745
+ next();
746
+ }
747
+ });
748
+
749
+ this.logger.info(`Router mounted for ${basePath}`, 'Router');
750
+ }
751
+
752
+ private finalModuleHandlerSetup = false;
753
+
754
+ // Setup final module handler that runs after all user middleware
755
+ setupFinalModuleHandler(): void {
756
+ // Prevent duplicate setup
757
+ if (this.finalModuleHandlerSetup) {
758
+ this.logger.debug('Final module handler already set up, skipping', 'ModuleSystem');
759
+ return;
760
+ }
761
+ this.finalModuleHandlerSetup = true;
762
+
763
+ this.logger.info(
764
+ 'Setting up final module handler to run after user middleware',
765
+ 'ModuleSystem'
766
+ );
767
+
768
+ this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
769
+ // Check if this request was marked for module handling
770
+ const moduleBasePath = (req as any).__moduleBasePath;
771
+ const moduleRouter = (req as any).__moduleRouter;
772
+
773
+ if (moduleBasePath && moduleRouter && !res.headersSent) {
774
+ this.logger.debug(`Final module handler processing: ${req.method} ${req.path}`, 'Router');
775
+
525
776
  try {
526
- const handled = await router.handle(req, res, basePath);
527
- this.logger.debug(`Route handled: ${handled}`, 'Router');
777
+ const handled = await moduleRouter.handle(req, res, moduleBasePath);
778
+ this.logger.debug(`Route handled by module: ${handled}`, 'Router');
528
779
 
529
780
  if (!handled) {
530
781
  next(); // Let other middleware handle it
531
782
  }
532
783
  // If handled, the router already sent the response, so don't call next()
533
784
  } catch (error) {
534
- this.logger.error('Router error', 'Router', {
785
+ this.logger.error('Module router error', 'Router', {
535
786
  error: error instanceof Error ? error.message : String(error),
536
787
  });
537
788
  if (!res.headersSent) {
@@ -542,8 +793,6 @@ export class Moro extends EventEmitter {
542
793
  next();
543
794
  }
544
795
  });
545
-
546
- this.logger.info(`Router mounted for ${basePath}`, 'Router');
547
796
  }
548
797
 
549
798
  private async setupWebSocketHandlers(config: ModuleConfig): Promise<void> {