@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
package/src/moro.ts ADDED
@@ -0,0 +1,842 @@
1
+ // Moro Framework - Modern TypeScript API Framework
2
+ // Built for developers who demand performance, elegance, and zero compromises
3
+ // Event-driven • Modular • Enterprise-ready • Developer-first
4
+ import { Moro as MoroCore } from "./core/framework";
5
+ import { HttpRequest, HttpResponse, middleware } from "./core/http";
6
+ import { ModuleConfig, InternalRouteDefinition } from "./types/module";
7
+ import { MoroOptions } from "./types/core";
8
+ import { MoroEventBus } from "./core/events";
9
+ import {
10
+ createFrameworkLogger,
11
+ logger as globalLogger,
12
+ applyLoggingConfiguration,
13
+ } from "./core/logger";
14
+ import { IntelligentRoutingManager } from "./core/routing/app-integration";
15
+ import { RouteBuilder, RouteSchema, CompiledRoute } from "./core/routing";
16
+ import { AppDocumentationManager, DocsConfig } from "./core/docs";
17
+ import { readdirSync, statSync } from "fs";
18
+ import { join } from "path";
19
+ import { EventEmitter } from "events";
20
+ // Configuration System Integration
21
+ import {
22
+ initializeConfig,
23
+ getGlobalConfig,
24
+ type AppConfig,
25
+ } from "./core/config";
26
+ // Runtime System Integration
27
+ import {
28
+ RuntimeAdapter,
29
+ RuntimeType,
30
+ createRuntimeAdapter,
31
+ NodeRuntimeAdapter,
32
+ } from "./core/runtime";
33
+
34
+ export class Moro extends EventEmitter {
35
+ private coreFramework: MoroCore;
36
+ private routes: InternalRouteDefinition[] = [];
37
+ private moduleCounter = 0;
38
+ private loadedModules = new Set<string>();
39
+ private routeHandlers: Record<string, Function> = {};
40
+ // Enterprise event system integration
41
+ private eventBus: MoroEventBus;
42
+ // Application logger
43
+ private logger = createFrameworkLogger("App");
44
+ // Intelligent routing system
45
+ private intelligentRouting = new IntelligentRoutingManager();
46
+ // Documentation system
47
+ private documentation = new AppDocumentationManager();
48
+ // Configuration system
49
+ private config: AppConfig;
50
+ // Runtime system
51
+ private runtimeAdapter: RuntimeAdapter;
52
+ private runtimeType: RuntimeType;
53
+
54
+ constructor(options: MoroOptions = {}) {
55
+ super(); // Call EventEmitter constructor
56
+
57
+ // Configure logger from environment variables BEFORE config system initialization
58
+ // This ensures the config loading process respects the log level
59
+ const envLogLevel = process.env.LOG_LEVEL || process.env.MORO_LOG_LEVEL;
60
+ if (envLogLevel) {
61
+ applyLoggingConfiguration({ level: envLogLevel }, undefined);
62
+ }
63
+
64
+ // Initialize configuration system
65
+ this.config = initializeConfig();
66
+
67
+ // Apply additional logging configuration from createApp options (takes precedence)
68
+ if (options.logger !== undefined) {
69
+ applyLoggingConfiguration(undefined, options.logger);
70
+ }
71
+
72
+ this.logger.info(
73
+ `Configuration system initialized: ${this.config.server.environment}:${this.config.server.port}`,
74
+ );
75
+
76
+ // Initialize runtime system
77
+ this.runtimeType = options.runtime?.type || "node";
78
+ this.runtimeAdapter =
79
+ options.runtime?.adapter || createRuntimeAdapter(this.runtimeType);
80
+
81
+ this.logger.info(
82
+ `Runtime system initialized: ${this.runtimeType}`,
83
+ "Runtime",
84
+ );
85
+
86
+ this.coreFramework = new MoroCore();
87
+
88
+ // Access enterprise event bus from core framework
89
+ this.eventBus = (this.coreFramework as any).eventBus;
90
+
91
+ // Setup default middleware if enabled - use config defaults with options override
92
+ this.setupDefaultMiddleware({
93
+ ...this.getDefaultOptionsFromConfig(),
94
+ ...options,
95
+ });
96
+
97
+ // Auto-discover modules if enabled
98
+ if (options.autoDiscover !== false) {
99
+ this.autoDiscoverModules(options.modulesPath || "./modules");
100
+ }
101
+
102
+ // Emit initialization event through enterprise event bus
103
+ this.eventBus.emit("framework:initialized", {
104
+ options,
105
+ config: this.config,
106
+ runtime: this.runtimeType,
107
+ });
108
+ }
109
+
110
+ /**
111
+ * Get configuration object
112
+ */
113
+ getConfig(): AppConfig {
114
+ return this.config;
115
+ }
116
+
117
+ /**
118
+ * Get runtime adapter
119
+ */
120
+ getRuntime(): RuntimeAdapter {
121
+ return this.runtimeAdapter;
122
+ }
123
+
124
+ /**
125
+ * Get runtime type
126
+ */
127
+ getRuntimeType(): RuntimeType {
128
+ return this.runtimeType;
129
+ }
130
+
131
+ /**
132
+ * Extract default options from configuration
133
+ */
134
+ private getDefaultOptionsFromConfig(): Partial<MoroOptions> {
135
+ return {
136
+ cors: this.config.security.cors.enabled,
137
+ compression: this.config.performance.compression.enabled,
138
+ helmet: this.config.security.helmet.enabled,
139
+ };
140
+ }
141
+
142
+ // Intelligent route methods - chainable with automatic middleware ordering
143
+ // Overloads for better TypeScript inference
144
+ get(path: string): RouteBuilder;
145
+ get(
146
+ path: string,
147
+ handler: (req: HttpRequest, res: HttpResponse) => any,
148
+ options?: any,
149
+ ): this;
150
+ get(
151
+ path: string,
152
+ handler?: (req: HttpRequest, res: HttpResponse) => any,
153
+ options?: any,
154
+ ): RouteBuilder | this {
155
+ if (handler) {
156
+ // Direct route registration
157
+ return this.addRoute("GET", path, handler, options);
158
+ }
159
+ // Chainable route builder
160
+ return this.intelligentRouting.get(path);
161
+ }
162
+
163
+ post(path: string): RouteBuilder;
164
+ post(
165
+ path: string,
166
+ handler: (req: HttpRequest, res: HttpResponse) => any,
167
+ options?: any,
168
+ ): this;
169
+ post(
170
+ path: string,
171
+ handler?: (req: HttpRequest, res: HttpResponse) => any,
172
+ options?: any,
173
+ ): RouteBuilder | this {
174
+ if (handler) {
175
+ // Direct route registration
176
+ return this.addRoute("POST", path, handler, options);
177
+ }
178
+ // Chainable route builder
179
+ return this.intelligentRouting.post(path);
180
+ }
181
+
182
+ put(path: string): RouteBuilder;
183
+ put(
184
+ path: string,
185
+ handler: (req: HttpRequest, res: HttpResponse) => any,
186
+ options?: any,
187
+ ): this;
188
+ put(
189
+ path: string,
190
+ handler?: (req: HttpRequest, res: HttpResponse) => any,
191
+ options?: any,
192
+ ): RouteBuilder | this {
193
+ if (handler) {
194
+ // Direct route registration
195
+ return this.addRoute("PUT", path, handler, options);
196
+ }
197
+ // Chainable route builder
198
+ return this.intelligentRouting.put(path);
199
+ }
200
+
201
+ delete(path: string): RouteBuilder;
202
+ delete(
203
+ path: string,
204
+ handler: (req: HttpRequest, res: HttpResponse) => any,
205
+ options?: any,
206
+ ): this;
207
+ delete(
208
+ path: string,
209
+ handler?: (req: HttpRequest, res: HttpResponse) => any,
210
+ options?: any,
211
+ ): RouteBuilder | this {
212
+ if (handler) {
213
+ // Direct route registration
214
+ return this.addRoute("DELETE", path, handler, options);
215
+ }
216
+ // Chainable route builder
217
+ return this.intelligentRouting.delete(path);
218
+ }
219
+
220
+ patch(path: string): RouteBuilder;
221
+ patch(
222
+ path: string,
223
+ handler: (req: HttpRequest, res: HttpResponse) => any,
224
+ options?: any,
225
+ ): this;
226
+ patch(
227
+ path: string,
228
+ handler?: (req: HttpRequest, res: HttpResponse) => any,
229
+ options?: any,
230
+ ): RouteBuilder | this {
231
+ if (handler) {
232
+ // Direct route registration
233
+ return this.addRoute("PATCH", path, handler, options);
234
+ }
235
+ // Chainable route builder
236
+ return this.intelligentRouting.patch(path);
237
+ }
238
+
239
+ // Schema-first route method
240
+ route(schema: RouteSchema): CompiledRoute {
241
+ return this.intelligentRouting.route(schema);
242
+ }
243
+
244
+ // Enable automatic API documentation
245
+ enableDocs(config: DocsConfig): void {
246
+ this.documentation.enableDocs(config, this.intelligentRouting);
247
+
248
+ this.logger.info(
249
+ `API Documentation enabled at ${config.basePath || "/docs"}`,
250
+ "Documentation",
251
+ );
252
+ this.eventBus.emit("docs:enabled", { config });
253
+ }
254
+
255
+ // Get OpenAPI specification
256
+ getOpenAPISpec() {
257
+ return this.documentation.getOpenAPISpec();
258
+ }
259
+
260
+ // Get documentation as JSON
261
+ getDocsJSON(): string {
262
+ return this.documentation.getDocsJSON();
263
+ }
264
+
265
+ // Get documentation as YAML
266
+ getDocsYAML(): string {
267
+ return this.documentation.getDocsYAML();
268
+ }
269
+
270
+ // Refresh documentation (useful after adding routes dynamically)
271
+ refreshDocs(): void {
272
+ this.documentation.refreshDocs();
273
+ }
274
+
275
+ // Universal middleware system - seamlessly handles standard and advanced middleware
276
+ async use(middlewareOrFunction: any, config?: any) {
277
+ // Standard middleware integration (req, res, next pattern)
278
+ if (
279
+ typeof middlewareOrFunction === "function" &&
280
+ middlewareOrFunction.length >= 3
281
+ ) {
282
+ this.coreFramework.addMiddleware(middlewareOrFunction);
283
+ this.eventBus.emit("middleware:registered", {
284
+ type: "standard",
285
+ middleware: middlewareOrFunction,
286
+ });
287
+ return this;
288
+ }
289
+
290
+ // Function-style middleware execution
291
+ if (
292
+ typeof middlewareOrFunction === "function" &&
293
+ middlewareOrFunction.length <= 1
294
+ ) {
295
+ await middlewareOrFunction(this);
296
+ this.eventBus.emit("middleware:executed", {
297
+ type: "function",
298
+ middleware: middlewareOrFunction,
299
+ });
300
+ return this;
301
+ }
302
+
303
+ // Advanced middleware pipeline integration
304
+ this.eventBus.emit("middleware:advanced", {
305
+ middleware: middlewareOrFunction,
306
+ config,
307
+ });
308
+ this.logger.debug(
309
+ "Advanced middleware integration - enhanced capabilities loading...",
310
+ "Middleware",
311
+ );
312
+ return this;
313
+ }
314
+
315
+ // Plugin compatibility layer - unified middleware interface
316
+ async plugin(middleware: any, options?: any): Promise<this> {
317
+ return this.use(middleware, options);
318
+ }
319
+
320
+ // Module loading with events
321
+ async loadModule(moduleOrPath: ModuleConfig | string) {
322
+ this.eventBus.emit("module:loading", {
323
+ moduleId:
324
+ typeof moduleOrPath === "string" ? moduleOrPath : moduleOrPath.name,
325
+ });
326
+
327
+ if (typeof moduleOrPath === "string") {
328
+ const module = await this.importModule(moduleOrPath);
329
+ await this.coreFramework.loadModule(module);
330
+ this.loadedModules.add(moduleOrPath);
331
+ this.eventBus.emit("module:loaded", {
332
+ moduleId: module.name,
333
+ version: module.version || "1.0.0",
334
+ });
335
+ } else {
336
+ await this.coreFramework.loadModule(moduleOrPath);
337
+ this.loadedModules.add(moduleOrPath.name);
338
+ this.eventBus.emit("module:loaded", {
339
+ moduleId: moduleOrPath.name,
340
+ version: moduleOrPath.version || "1.0.0",
341
+ });
342
+ }
343
+ return this;
344
+ }
345
+
346
+ // Database helper with events
347
+ database(adapter: any) {
348
+ this.eventBus.emit("database:connected", {
349
+ adapter: adapter.constructor.name,
350
+ config: "hidden",
351
+ });
352
+ this.coreFramework.registerDatabase(adapter);
353
+ return this;
354
+ }
355
+
356
+ // WebSocket helper with events
357
+ websocket(namespace: string, handlers: Record<string, Function>) {
358
+ this.emit("websocket:registering", { namespace, handlers });
359
+
360
+ const io = this.coreFramework.getIOServer();
361
+ const ns = io.of(namespace);
362
+
363
+ Object.entries(handlers).forEach(([event, handler]) => {
364
+ ns.on("connection", (socket) => {
365
+ this.emit("websocket:connection", { namespace, event, socket });
366
+
367
+ socket.on(event, (data, callback) => {
368
+ this.emit("websocket:event", { namespace, event, data });
369
+
370
+ Promise.resolve(handler(socket, data))
371
+ .then((result) => {
372
+ this.emit("websocket:response", { namespace, event, result });
373
+ if (callback) callback(result);
374
+ else if (result) socket.emit(`${event}:response`, result);
375
+ })
376
+ .catch((error) => {
377
+ this.emit("websocket:error", { namespace, event, error });
378
+ const errorResponse = { success: false, error: error.message };
379
+ if (callback) callback(errorResponse);
380
+ else socket.emit("error", errorResponse);
381
+ });
382
+ });
383
+ });
384
+ });
385
+
386
+ this.emit("websocket:registered", { namespace, handlers });
387
+ return this;
388
+ }
389
+
390
+ // Start server with events (Node.js only)
391
+ listen(port: number, callback?: () => void): void;
392
+ listen(port: number, host: string, callback?: () => void): void;
393
+ listen(port: number, host?: string | (() => void), callback?: () => void) {
394
+ // Only available for Node.js runtime
395
+ if (this.runtimeType !== "node") {
396
+ throw new Error(
397
+ `listen() is only available for Node.js runtime. Current runtime: ${this.runtimeType}. Use getHandler() for other runtimes.`,
398
+ );
399
+ }
400
+
401
+ // Handle overloaded parameters (port, callback) or (port, host, callback)
402
+ if (typeof host === "function") {
403
+ callback = host;
404
+ host = undefined;
405
+ }
406
+ this.eventBus.emit("server:starting", { port, runtime: this.runtimeType });
407
+
408
+ // Add documentation middleware first (if enabled)
409
+ try {
410
+ const docsMiddleware = this.documentation.getDocsMiddleware();
411
+ this.coreFramework.addMiddleware(docsMiddleware);
412
+ this.logger.debug("Documentation middleware added", "Documentation");
413
+ } catch (error) {
414
+ // Documentation not enabled, that's fine
415
+ this.logger.debug("Documentation not enabled", "Documentation");
416
+ }
417
+
418
+ // Add intelligent routing middleware to handle chainable routes
419
+ this.coreFramework.addMiddleware(
420
+ async (req: HttpRequest, res: HttpResponse, next: () => void) => {
421
+ // Try intelligent routing first
422
+ const handled = await this.intelligentRouting.handleIntelligentRoute(
423
+ req,
424
+ res,
425
+ );
426
+ if (!handled) {
427
+ next(); // Fall back to direct routes
428
+ }
429
+ },
430
+ );
431
+
432
+ // Register direct routes with the HTTP server
433
+ if (this.routes.length > 0) {
434
+ this.registerDirectRoutes();
435
+ }
436
+
437
+ const actualCallback = () => {
438
+ const displayHost = host || "localhost";
439
+ this.logger.info("Moro Server Started", "Server");
440
+ this.logger.info(`Runtime: ${this.runtimeType}`, "Server");
441
+ this.logger.info(`HTTP API: http://${displayHost}:${port}`, "Server");
442
+ this.logger.info(`WebSocket: ws://${displayHost}:${port}`, "Server");
443
+ this.logger.info(
444
+ "Native Node.js HTTP • Zero Dependencies • Maximum Performance",
445
+ "Server",
446
+ );
447
+ this.logger.info("Learn more at https://morojs.com", "Server");
448
+
449
+ // Log intelligent routes info
450
+ const intelligentRoutes = this.intelligentRouting.getIntelligentRoutes();
451
+ if (intelligentRoutes.length > 0) {
452
+ this.logger.info(
453
+ `Intelligent Routes: ${intelligentRoutes.length} registered`,
454
+ "Server",
455
+ );
456
+ }
457
+
458
+ this.eventBus.emit("server:started", { port, runtime: this.runtimeType });
459
+ if (callback) callback();
460
+ };
461
+
462
+ if (host && typeof host === "string") {
463
+ this.coreFramework.listen(port, host, actualCallback);
464
+ } else {
465
+ this.coreFramework.listen(port, actualCallback);
466
+ }
467
+ }
468
+
469
+ // Get handler for non-Node.js runtimes
470
+ getHandler() {
471
+ // Create a unified request handler that works with the runtime adapter
472
+ const handler = async (req: HttpRequest, res: HttpResponse) => {
473
+ // Add documentation middleware first (if enabled)
474
+ try {
475
+ const docsMiddleware = this.documentation.getDocsMiddleware();
476
+ await docsMiddleware(req, res, () => {});
477
+ if (res.headersSent) return;
478
+ } catch (error) {
479
+ // Documentation not enabled, that's fine
480
+ }
481
+
482
+ // Try intelligent routing first
483
+ const handled = await this.intelligentRouting.handleIntelligentRoute(
484
+ req,
485
+ res,
486
+ );
487
+ if (handled) return;
488
+
489
+ // Handle direct routes
490
+ if (this.routes.length > 0) {
491
+ await this.handleDirectRoutes(req, res);
492
+ }
493
+ };
494
+
495
+ // Use the runtime adapter to create the appropriate handler
496
+ return this.runtimeAdapter.createServer(handler);
497
+ }
498
+
499
+ // Handle direct routes for runtime adapters
500
+ private async handleDirectRoutes(req: HttpRequest, res: HttpResponse) {
501
+ // Find matching route
502
+ const route = this.findMatchingRoute(req.method!, req.path);
503
+ if (!route) {
504
+ (res as any).status(404).json({ success: false, error: "Not found" });
505
+ return;
506
+ }
507
+
508
+ try {
509
+ // Extract path parameters
510
+ const matches = req.path.match(route.pattern);
511
+ if (matches) {
512
+ req.params = {};
513
+ route.paramNames.forEach((name, index) => {
514
+ req.params[name] = matches[index + 1];
515
+ });
516
+ }
517
+
518
+ // Get handler function
519
+ const handler = this.routeHandlers[route.handler];
520
+ if (!handler) {
521
+ (res as any)
522
+ .status(500)
523
+ .json({ success: false, error: "Handler not found" });
524
+ return;
525
+ }
526
+
527
+ // Execute validation if present
528
+ if (route.validation) {
529
+ try {
530
+ const validated = route.validation.parse(req.body);
531
+ req.body = validated;
532
+ } catch (error: any) {
533
+ if (error.issues) {
534
+ (res as any).status(400).json({
535
+ success: false,
536
+ error: "Validation failed",
537
+ details: error.issues.map((issue: any) => ({
538
+ field: issue.path.length > 0 ? issue.path.join(".") : "body",
539
+ message: issue.message,
540
+ code: issue.code,
541
+ })),
542
+ });
543
+ return;
544
+ }
545
+ throw error;
546
+ }
547
+ }
548
+
549
+ // Execute rate limiting if present
550
+ if (route.rateLimit) {
551
+ const clientId = req.ip || "unknown";
552
+ const key = `${route.method}:${route.path}:${clientId}`;
553
+
554
+ if (!this.checkRateLimit(key, route.rateLimit)) {
555
+ (res as any).status(429).json({
556
+ success: false,
557
+ error: "Rate limit exceeded",
558
+ retryAfter: Math.ceil(route.rateLimit.window / 1000),
559
+ });
560
+ return;
561
+ }
562
+ }
563
+
564
+ // Execute the handler
565
+ const result = await handler(req, res);
566
+ if (result && !(res as any).headersSent) {
567
+ (res as any).json(result);
568
+ }
569
+ } catch (error) {
570
+ if (!(res as any).headersSent) {
571
+ (res as any).status(500).json({
572
+ success: false,
573
+ error:
574
+ error instanceof Error ? error.message : "Internal server error",
575
+ });
576
+ }
577
+ }
578
+ }
579
+
580
+ // Find matching route
581
+ private findMatchingRoute(method: string, path: string) {
582
+ for (const route of this.routes) {
583
+ if (route.method === method) {
584
+ const pattern = this.pathToRegex(route.path);
585
+ if (pattern.pattern.test(path)) {
586
+ return {
587
+ ...route,
588
+ pattern: pattern.pattern,
589
+ paramNames: pattern.paramNames,
590
+ };
591
+ }
592
+ }
593
+ }
594
+ return null;
595
+ }
596
+
597
+ // Convert path to regex (simplified version)
598
+ private pathToRegex(path: string): { pattern: RegExp; paramNames: string[] } {
599
+ const paramNames: string[] = [];
600
+ const regexPath = path
601
+ .replace(/\//g, "\\/")
602
+ .replace(/:([^/]+)/g, (match, paramName) => {
603
+ paramNames.push(paramName);
604
+ return "([^/]+)";
605
+ });
606
+
607
+ return {
608
+ pattern: new RegExp(`^${regexPath}$`),
609
+ paramNames,
610
+ };
611
+ }
612
+
613
+ // Access enterprise event system for advanced integrations
614
+ get events() {
615
+ return this.eventBus;
616
+ }
617
+
618
+ // Access to core framework for advanced usage
619
+ get core() {
620
+ return this.coreFramework;
621
+ }
622
+
623
+ // Private methods
624
+ private addRoute(
625
+ method: string,
626
+ path: string,
627
+ handler: Function,
628
+ options: any = {},
629
+ ) {
630
+ const handlerName = `handler_${this.routes.length}`;
631
+
632
+ this.routes.push({
633
+ method: method as any,
634
+ path,
635
+ handler: handlerName,
636
+ validation: options.validation,
637
+ rateLimit: options.rateLimit,
638
+ cache: options.cache,
639
+ middleware: options.middleware,
640
+ });
641
+
642
+ // Store handler for later module creation
643
+ this.routeHandlers[handlerName] = handler;
644
+
645
+ return this;
646
+ }
647
+
648
+ private registerDirectRoutes() {
649
+ // Register routes directly with the HTTP server for optimal performance
650
+ // This provides the intuitive developer experience users expect
651
+ for (const route of this.routes) {
652
+ const handler = this.routeHandlers[route.handler];
653
+
654
+ // Get direct access to the HTTP server through the core framework
655
+ const httpServer = (this.coreFramework as any).httpServer;
656
+
657
+ // Create a wrapper handler that handles validation, rate limiting, and return values
658
+ const wrappedHandler = async (req: any, res: any) => {
659
+ try {
660
+ // Enhance request with events property for direct routes
661
+ req.events = this.eventBus;
662
+
663
+ // Validation middleware (Zod-only)
664
+ if (route.validation) {
665
+ try {
666
+ const validated = route.validation.parse(req.body);
667
+ req.body = validated;
668
+ } catch (error: any) {
669
+ if (error.issues) {
670
+ res.status(400).json({
671
+ success: false,
672
+ error: "Validation failed",
673
+ details: error.issues.map((issue: any) => ({
674
+ field:
675
+ issue.path.length > 0 ? issue.path.join(".") : "body",
676
+ message: issue.message,
677
+ code: issue.code,
678
+ })),
679
+ });
680
+ return;
681
+ }
682
+ throw error;
683
+ }
684
+ }
685
+
686
+ // Rate limiting middleware
687
+ if (route.rateLimit) {
688
+ const clientId =
689
+ req.ip || req.connection.remoteAddress || "unknown";
690
+ const key = `${route.method}:${route.path}:${clientId}`;
691
+
692
+ if (!this.checkRateLimit(key, route.rateLimit)) {
693
+ res.status(429).json({
694
+ success: false,
695
+ error: "Rate limit exceeded",
696
+ retryAfter: Math.ceil(route.rateLimit.window / 1000),
697
+ });
698
+ return;
699
+ }
700
+ }
701
+
702
+ // Execute the actual handler
703
+ const result = await handler(req, res);
704
+ if (result && !res.headersSent) {
705
+ res.json(result);
706
+ }
707
+ } catch (error) {
708
+ if (!res.headersSent) {
709
+ res.status(500).json({
710
+ success: false,
711
+ error:
712
+ error instanceof Error
713
+ ? error.message
714
+ : "Internal server error",
715
+ });
716
+ }
717
+ }
718
+ };
719
+
720
+ // Register with the appropriate HTTP method
721
+ const method = route.method.toLowerCase();
722
+ if (httpServer && httpServer[method]) {
723
+ httpServer[method](route.path, wrappedHandler);
724
+ }
725
+ }
726
+ }
727
+
728
+ // Simple rate limiting for direct routes
729
+ private rateLimitStore = new Map<
730
+ string,
731
+ { count: number; resetTime: number }
732
+ >();
733
+
734
+ private checkRateLimit(
735
+ key: string,
736
+ config: { requests: number; window: number },
737
+ ): boolean {
738
+ const now = Date.now();
739
+ const bucket = this.rateLimitStore.get(key);
740
+
741
+ if (!bucket || now > bucket.resetTime) {
742
+ // Create new bucket or reset expired bucket
743
+ this.rateLimitStore.set(key, {
744
+ count: 1,
745
+ resetTime: now + config.window,
746
+ });
747
+ return true;
748
+ }
749
+
750
+ if (bucket.count >= config.requests) {
751
+ return false; // Rate limit exceeded
752
+ }
753
+
754
+ bucket.count++;
755
+ return true;
756
+ }
757
+
758
+ private setupDefaultMiddleware(options: MoroOptions) {
759
+ // CORS
760
+ if (options.cors !== false) {
761
+ const corsOptions = typeof options.cors === "object" ? options.cors : {};
762
+ this.use(middleware.cors(corsOptions));
763
+ }
764
+
765
+ // Helmet
766
+ if (options.helmet !== false) {
767
+ this.use(middleware.helmet());
768
+ }
769
+
770
+ // Compression
771
+ if (options.compression !== false) {
772
+ const compressionOptions =
773
+ typeof options.compression === "object" ? options.compression : {};
774
+ this.use(middleware.compression(compressionOptions));
775
+ }
776
+
777
+ // Body size limiting
778
+ this.use(middleware.bodySize({ limit: "10mb" }));
779
+ }
780
+
781
+ private autoDiscoverModules(modulesPath: string) {
782
+ try {
783
+ if (!statSync(modulesPath).isDirectory()) return;
784
+
785
+ const items = readdirSync(modulesPath);
786
+ items.forEach((item) => {
787
+ const fullPath = join(modulesPath, item);
788
+ if (statSync(fullPath).isDirectory()) {
789
+ const indexPath = join(fullPath, "index.ts");
790
+ try {
791
+ statSync(indexPath);
792
+ // Module directory found, will be loaded later
793
+ this.logger.debug(`Discovered module: ${item}`, "ModuleDiscovery");
794
+ } catch {
795
+ // No index.ts, skip
796
+ }
797
+ }
798
+ });
799
+ } catch {
800
+ // Modules directory doesn't exist, that's fine
801
+ }
802
+ }
803
+
804
+ private async importModule(modulePath: string): Promise<ModuleConfig> {
805
+ const module = await import(modulePath);
806
+ return module.default || module;
807
+ }
808
+ }
809
+
810
+ // Export convenience function
811
+ export function createApp(options?: MoroOptions): Moro {
812
+ return new Moro(options);
813
+ }
814
+
815
+ // Runtime-specific convenience functions
816
+ export function createAppNode(options?: Omit<MoroOptions, "runtime">): Moro {
817
+ return new Moro({
818
+ ...options,
819
+ runtime: { type: "node" },
820
+ });
821
+ }
822
+
823
+ export function createAppEdge(options?: Omit<MoroOptions, "runtime">): Moro {
824
+ return new Moro({
825
+ ...options,
826
+ runtime: { type: "vercel-edge" },
827
+ });
828
+ }
829
+
830
+ export function createAppLambda(options?: Omit<MoroOptions, "runtime">): Moro {
831
+ return new Moro({
832
+ ...options,
833
+ runtime: { type: "aws-lambda" },
834
+ });
835
+ }
836
+
837
+ export function createAppWorker(options?: Omit<MoroOptions, "runtime">): Moro {
838
+ return new Moro({
839
+ ...options,
840
+ runtime: { type: "cloudflare-workers" },
841
+ });
842
+ }