@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,11 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createFrameworkLogger = exports.logger = exports.MoroLogger = void 0;
4
- exports.configureGlobalLogger = configureGlobalLogger;
5
- exports.applyLoggingConfiguration = applyLoggingConfiguration;
6
1
  // Moro Logger - Beautiful, Fast, Feature-Rich
7
- const perf_hooks_1 = require("perf_hooks");
8
- class MoroLogger {
2
+ import { performance } from 'perf_hooks';
3
+ export class MoroLogger {
9
4
  level = 'info';
10
5
  options;
11
6
  outputs = new Map();
@@ -32,12 +27,23 @@ class MoroLogger {
32
27
  cachedTimestamp = '';
33
28
  lastTimestamp = 0;
34
29
  timestampCacheInterval = 100; // 100ms for better precision
35
- // Buffered output for micro-batching
30
+ // Object pooling for LogEntry objects (Pino's technique)
31
+ static ENTRY_POOL = [];
32
+ static MAX_POOL_SIZE = 100;
33
+ static poolIndex = 0;
34
+ // String builder for efficient concatenation
35
+ static stringBuilder = [];
36
+ static stringBuilderIndex = 0;
37
+ // Buffered output for performance
36
38
  outputBuffer = [];
37
39
  bufferSize = 0;
38
- maxBufferSize = 1024; // 1KB buffer
40
+ maxBufferSize = 1000;
39
41
  flushTimeout = null;
40
42
  flushInterval = 1; // 1ms micro-batching
43
+ // Buffer overflow protection
44
+ bufferOverflowThreshold;
45
+ emergencyFlushInProgress = false;
46
+ isDestroyed = false;
41
47
  // High-performance output methods
42
48
  static LEVELS = {
43
49
  debug: 0,
@@ -46,76 +52,6 @@ class MoroLogger {
46
52
  error: 3,
47
53
  fatal: 4,
48
54
  };
49
- // Static pre-allocated strings for maximum performance
50
- static LEVEL_STRINGS = {
51
- debug: 'DEBUG',
52
- info: 'INFO',
53
- warn: 'WARN',
54
- error: 'ERROR',
55
- fatal: 'FATAL',
56
- };
57
- // Pre-allocated ANSI color codes
58
- static ANSI_COLORS = {
59
- reset: '\x1b[0m',
60
- bold: '\x1b[1m',
61
- dim: '\x1b[2m',
62
- red: '\x1b[31m',
63
- green: '\x1b[32m',
64
- yellow: '\x1b[33m',
65
- blue: '\x1b[34m',
66
- magenta: '\x1b[35m',
67
- cyan: '\x1b[36m',
68
- white: '\x1b[37m',
69
- gray: '\x1b[90m',
70
- };
71
- // Object pool for LogEntry reuse
72
- static ENTRY_POOL = [];
73
- static MAX_POOL_SIZE = 100;
74
- static poolIndex = 0;
75
- // Object pool management
76
- static getPooledEntry() {
77
- if (MoroLogger.poolIndex > 0) {
78
- return MoroLogger.ENTRY_POOL[--MoroLogger.poolIndex];
79
- }
80
- return {
81
- timestamp: new Date(),
82
- level: 'info',
83
- message: '',
84
- context: undefined,
85
- metadata: undefined,
86
- };
87
- }
88
- static returnPooledEntry(entry) {
89
- if (MoroLogger.poolIndex < MoroLogger.MAX_POOL_SIZE) {
90
- // Reset the entry
91
- entry.timestamp = new Date();
92
- entry.level = 'info';
93
- entry.message = '';
94
- entry.context = undefined;
95
- entry.metadata = undefined;
96
- MoroLogger.ENTRY_POOL[MoroLogger.poolIndex++] = entry;
97
- }
98
- }
99
- // String builder for efficient concatenation
100
- static stringBuilder = [];
101
- static stringBuilderIndex = 0;
102
- static resetStringBuilder() {
103
- MoroLogger.stringBuilderIndex = 0;
104
- }
105
- static appendToBuilder(str) {
106
- if (MoroLogger.stringBuilderIndex < MoroLogger.stringBuilder.length) {
107
- MoroLogger.stringBuilder[MoroLogger.stringBuilderIndex++] = str;
108
- }
109
- else {
110
- MoroLogger.stringBuilder.push(str);
111
- MoroLogger.stringBuilderIndex++;
112
- }
113
- }
114
- static buildString() {
115
- const result = MoroLogger.stringBuilder.slice(0, MoroLogger.stringBuilderIndex).join('');
116
- MoroLogger.resetStringBuilder();
117
- return result;
118
- }
119
55
  static COLORS = {
120
56
  debug: '\x1b[36m', // Cyan
121
57
  info: '\x1b[32m', // Green
@@ -126,11 +62,20 @@ class MoroLogger {
126
62
  context: '\x1b[34m', // Blue
127
63
  metadata: '\x1b[37m', // White
128
64
  performance: '\x1b[36m', // Cyan
65
+ reset: '\x1b[0m', // Reset
129
66
  };
130
67
  static RESET = '\x1b[0m';
131
68
  static BOLD = '\x1b[1m';
69
+ // Static pre-allocated strings for performance
70
+ static LEVEL_STRINGS = {
71
+ debug: 'DEBUG',
72
+ info: 'INFO ',
73
+ warn: 'WARN ',
74
+ error: 'ERROR',
75
+ fatal: 'FATAL',
76
+ };
132
77
  constructor(options = {}) {
133
- this.options = {
78
+ this.options = this.validateOptions({
134
79
  level: 'info',
135
80
  enableColors: true,
136
81
  enableTimestamp: true,
@@ -141,9 +86,14 @@ class MoroLogger {
141
86
  outputs: [],
142
87
  filters: [],
143
88
  maxEntries: 1000,
89
+ maxBufferSize: 1000,
144
90
  ...options,
145
- };
91
+ });
146
92
  this.level = this.options.level || 'info';
93
+ // Initialize buffer size from options
94
+ this.maxBufferSize = this.options.maxBufferSize || 1000;
95
+ // Initialize buffer overflow protection
96
+ this.bufferOverflowThreshold = this.maxBufferSize * 2;
147
97
  // Add default console output
148
98
  this.addOutput({
149
99
  name: 'console',
@@ -154,6 +104,52 @@ class MoroLogger {
154
104
  this.options.outputs?.forEach(output => this.addOutput(output));
155
105
  this.options.filters?.forEach(filter => this.addFilter(filter));
156
106
  }
107
+ // Object pooling methods
108
+ static getPooledEntry() {
109
+ if (MoroLogger.ENTRY_POOL.length > 0) {
110
+ const entry = MoroLogger.ENTRY_POOL.pop();
111
+ // Properly reset ALL properties to prevent memory leaks
112
+ entry.timestamp = new Date();
113
+ entry.level = 'info';
114
+ entry.message = '';
115
+ entry.context = undefined;
116
+ entry.metadata = undefined;
117
+ entry.performance = undefined;
118
+ entry.moduleId = undefined;
119
+ return entry;
120
+ }
121
+ return MoroLogger.createFreshEntry();
122
+ }
123
+ // ADD this new method:
124
+ static createFreshEntry() {
125
+ return {
126
+ timestamp: new Date(),
127
+ level: 'info',
128
+ message: '',
129
+ context: undefined,
130
+ metadata: undefined,
131
+ performance: undefined,
132
+ moduleId: undefined,
133
+ };
134
+ }
135
+ static returnPooledEntry(entry) {
136
+ if (MoroLogger.ENTRY_POOL.length < MoroLogger.MAX_POOL_SIZE) {
137
+ MoroLogger.ENTRY_POOL.push(entry);
138
+ }
139
+ }
140
+ // String builder methods
141
+ static resetStringBuilder() {
142
+ MoroLogger.stringBuilder.length = 0;
143
+ MoroLogger.stringBuilderIndex = 0;
144
+ }
145
+ static appendToBuilder(str) {
146
+ MoroLogger.stringBuilder[MoroLogger.stringBuilderIndex++] = str;
147
+ }
148
+ static buildString() {
149
+ const result = MoroLogger.stringBuilder.join('');
150
+ MoroLogger.resetStringBuilder();
151
+ return result;
152
+ }
157
153
  debug(message, context, metadata) {
158
154
  this.log('debug', message, context, metadata);
159
155
  }
@@ -174,12 +170,12 @@ class MoroLogger {
174
170
  this.log('fatal', msg, context, { ...metadata, stack });
175
171
  }
176
172
  time(label) {
177
- this.timers.set(label, perf_hooks_1.performance.now());
173
+ this.timers.set(label, performance.now());
178
174
  }
179
175
  timeEnd(label, context, metadata) {
180
176
  const startTime = this.timers.get(label);
181
177
  if (startTime !== undefined) {
182
- const duration = perf_hooks_1.performance.now() - startTime;
178
+ const duration = performance.now() - startTime;
183
179
  this.timers.delete(label);
184
180
  this.log('info', `Timer: ${label}`, context, {
185
181
  ...metadata,
@@ -188,7 +184,9 @@ class MoroLogger {
188
184
  }
189
185
  }
190
186
  child(context, metadata) {
191
- const childLogger = new MoroLogger(this.options);
187
+ // Create child logger with current parent level (not original options level)
188
+ const childOptions = { ...this.options, level: this.level };
189
+ const childLogger = new MoroLogger(childOptions);
192
190
  childLogger.contextPrefix = this.contextPrefix ? `${this.contextPrefix}:${context}` : context;
193
191
  childLogger.contextMetadata = { ...this.contextMetadata, ...metadata };
194
192
  childLogger.outputs = this.outputs;
@@ -200,6 +198,9 @@ class MoroLogger {
200
198
  setLevel(level) {
201
199
  this.level = level;
202
200
  }
201
+ getLevel() {
202
+ return this.level;
203
+ }
203
204
  addOutput(output) {
204
205
  this.outputs.set(output.name, output);
205
206
  }
@@ -242,6 +243,16 @@ class MoroLogger {
242
243
  }
243
244
  return this.cachedTimestamp;
244
245
  }
246
+ // Cached timestamp generation (updates once per second)
247
+ getFastCachedTimestamp() {
248
+ const now = Date.now();
249
+ if (now - this.lastTimestamp > 1000) {
250
+ // Update every second
251
+ this.lastTimestamp = now;
252
+ this.cachedTimestamp = new Date(now).toISOString().slice(0, 19).replace('T', ' ');
253
+ }
254
+ return this.cachedTimestamp;
255
+ }
245
256
  getMetrics() {
246
257
  const now = Date.now();
247
258
  const uptime = (now - this.startTime) / 1000; // seconds
@@ -266,47 +277,38 @@ class MoroLogger {
266
277
  memoryUsage: 0,
267
278
  };
268
279
  }
269
- // Optimized logging method with aggressive level checking
280
+ // Optimized logging method
270
281
  log(level, message, context, metadata) {
271
- // AGGRESSIVE LEVEL CHECK - numeric comparison for maximum speed
272
- const levelNum = MoroLogger.LEVELS[level];
273
- const effectiveLevelNum = this.parent
274
- ? MoroLogger.LEVELS[this.parent.level]
275
- : MoroLogger.LEVELS[this.level];
276
- if (levelNum < effectiveLevelNum) {
277
- return; // Exit immediately if level is too low
278
- }
279
- // ULTRA-FAST PATH: Just message, no context, no metadata
282
+ // Prevent logging after destroy() is called (important for test cleanup)
283
+ if (this.isDestroyed) {
284
+ return;
285
+ }
286
+ // Quick level check - use parent level if available (for child loggers)
287
+ const effectiveLevel = this.parent ? this.parent.level : this.level;
288
+ if (MoroLogger.LEVELS[level] < MoroLogger.LEVELS[effectiveLevel]) {
289
+ return;
290
+ }
291
+ // Absolute minimal path for simple logs - pure speed
280
292
  if (!metadata && !context && !this.contextPrefix && !this.contextMetadata) {
281
- const levelStr = MoroLogger.LEVEL_STRINGS[level];
282
- this.output(`${levelStr} ${message}\n`, level);
293
+ this.writeSimpleLog(level, message);
283
294
  return;
284
295
  }
285
- // FAST PATH: Message + context, no metadata
296
+ // Minimal path for logs with context but no metadata
286
297
  if (!metadata && !this.contextMetadata) {
287
- const levelStr = MoroLogger.LEVEL_STRINGS[level];
288
- if (context) {
289
- this.output(`${levelStr} [${context}] ${message}\n`, level);
290
- }
291
- else {
292
- this.output(`${levelStr} ${message}\n`, level);
293
- }
298
+ this.writeSimpleLog(level, message, context);
294
299
  return;
295
300
  }
296
- // MEDIUM PATH: Message + context + simple metadata
297
- if (metadata && Object.keys(metadata).length <= 3 && !this.contextMetadata) {
298
- const levelStr = MoroLogger.LEVEL_STRINGS[level];
299
- const contextStr = context ? `[${context}] ` : '';
300
- const metaStr = this.stringify(metadata);
301
- this.output(`${levelStr} ${contextStr}${message} ${metaStr}\n`, level);
301
+ // Path for complex logs
302
+ if (metadata && Object.keys(metadata).length > 0) {
303
+ this.complexLog(level, message, context, metadata);
302
304
  return;
303
305
  }
304
- // FULL PATH: All features enabled
306
+ // Full logging path for complex logs
305
307
  this.fullLog(level, message, context, metadata);
306
308
  }
307
- // Full logging with all features using object pooling
309
+ // Full logging with all features
308
310
  fullLog(level, message, context, metadata) {
309
- // Get pooled entry to avoid allocation
311
+ // Use object pooling for LogEntry (Pino's technique)
310
312
  const entry = MoroLogger.getPooledEntry();
311
313
  const now = Date.now();
312
314
  entry.timestamp = new Date(now);
@@ -323,6 +325,7 @@ class MoroLogger {
323
325
  if (this.filters.size > 0) {
324
326
  for (const filter of this.filters.values()) {
325
327
  if (!filter.filter(entry)) {
328
+ MoroLogger.returnPooledEntry(entry);
326
329
  return;
327
330
  }
328
331
  }
@@ -333,8 +336,76 @@ class MoroLogger {
333
336
  this.addToHistory(entry);
334
337
  // Write to outputs with batched processing
335
338
  this.writeToOutputs(entry, level);
336
- // Return entry to pool after a short delay to allow async operations
337
- setTimeout(() => MoroLogger.returnPooledEntry(entry), 0);
339
+ // Return entry to pool
340
+ MoroLogger.returnPooledEntry(entry);
341
+ }
342
+ // Absolute minimal logging - pure speed, no overhead
343
+ complexLog(level, message, context, metadata) {
344
+ // Use object pooling for LogEntry (Pino's technique)
345
+ const entry = MoroLogger.getPooledEntry();
346
+ const now = Date.now();
347
+ entry.timestamp = new Date(now);
348
+ entry.level = level;
349
+ entry.message = message;
350
+ entry.context = this.contextPrefix
351
+ ? context
352
+ ? `${this.contextPrefix}:${context}`
353
+ : this.contextPrefix
354
+ : context;
355
+ entry.metadata = this.createMetadata(metadata);
356
+ entry.performance = this.options.enablePerformance ? this.getPerformanceData(now) : undefined;
357
+ // Write to outputs with batched processing
358
+ this.writeToOutputs(entry, level);
359
+ // Return entry to pool
360
+ MoroLogger.returnPooledEntry(entry);
361
+ }
362
+ // Simple log writer with colors for minimal overhead cases
363
+ writeSimpleLog(level, message, context) {
364
+ const colors = this.options.enableColors !== false;
365
+ const levelReset = colors ? MoroLogger.RESET : '';
366
+ MoroLogger.resetStringBuilder();
367
+ // Timestamp with caching optimization
368
+ if (this.options.enableTimestamp !== false) {
369
+ const timestamp = this.getFastCachedTimestamp();
370
+ if (colors) {
371
+ MoroLogger.appendToBuilder(MoroLogger.COLORS.timestamp);
372
+ MoroLogger.appendToBuilder(timestamp);
373
+ MoroLogger.appendToBuilder(levelReset);
374
+ }
375
+ else {
376
+ MoroLogger.appendToBuilder(timestamp);
377
+ }
378
+ MoroLogger.appendToBuilder(' ');
379
+ }
380
+ // Level with pre-allocated strings
381
+ const levelStr = MoroLogger.LEVEL_STRINGS[level];
382
+ if (colors) {
383
+ MoroLogger.appendToBuilder(MoroLogger.COLORS[level]);
384
+ MoroLogger.appendToBuilder(MoroLogger.BOLD);
385
+ MoroLogger.appendToBuilder(levelStr);
386
+ MoroLogger.appendToBuilder(levelReset);
387
+ }
388
+ else {
389
+ MoroLogger.appendToBuilder(levelStr);
390
+ }
391
+ // Context
392
+ if (context && this.options.enableContext !== false) {
393
+ MoroLogger.appendToBuilder(' ');
394
+ if (colors) {
395
+ MoroLogger.appendToBuilder(MoroLogger.COLORS.context);
396
+ MoroLogger.appendToBuilder(`[${context}]`);
397
+ MoroLogger.appendToBuilder(levelReset);
398
+ }
399
+ else {
400
+ MoroLogger.appendToBuilder(`[${context}]`);
401
+ }
402
+ }
403
+ // Message
404
+ MoroLogger.appendToBuilder(' ');
405
+ MoroLogger.appendToBuilder(message);
406
+ // Output main log line with high-performance method
407
+ const finalMessage = MoroLogger.buildString();
408
+ this.output(`${finalMessage}\n`, level);
338
409
  }
339
410
  updateMetrics(entry) {
340
411
  this.metrics.totalLogs++;
@@ -382,23 +453,35 @@ class MoroLogger {
382
453
  writeToOutputs(entry, level) {
383
454
  if (this.outputs.size === 0)
384
455
  return;
456
+ let successCount = 0;
457
+ const errors = [];
385
458
  for (const output of this.outputs.values()) {
386
459
  if (!output.level || MoroLogger.LEVELS[level] >= MoroLogger.LEVELS[output.level]) {
387
460
  try {
388
461
  output.write(entry);
462
+ successCount++;
389
463
  }
390
464
  catch (error) {
391
- // Fallback to console.error for logger errors
392
- // eslint-disable-next-line no-console
393
- console.error('Logger output error:', error);
465
+ errors.push({ outputName: output.name, error });
466
+ this.handleOutputError(output.name, error);
394
467
  }
395
468
  }
396
469
  }
470
+ // If all outputs fail, use emergency console
471
+ if (successCount === 0 && this.outputs.size > 0) {
472
+ this.emergencyConsoleWrite(entry);
473
+ }
474
+ // Log output errors (but avoid infinite loops)
475
+ if (errors.length > 0 && level !== 'error') {
476
+ this.error(`Logger output errors: ${errors.length} failed`, 'MoroLogger', {
477
+ errors: errors.map(e => e.outputName),
478
+ });
479
+ }
397
480
  }
398
481
  writeToConsole(entry) {
399
482
  const format = this.options.format || 'pretty';
400
483
  if (format === 'json') {
401
- this.output(JSON.stringify(entry) + '\n', entry.level);
484
+ this.output(`${this.safeStringify(entry)}\n`, entry.level);
402
485
  return;
403
486
  }
404
487
  if (format === 'compact') {
@@ -412,6 +495,7 @@ class MoroLogger {
412
495
  }
413
496
  writePrettyLog(entry) {
414
497
  const colors = this.options.enableColors !== false;
498
+ const levelReset = colors ? MoroLogger.RESET : '';
415
499
  MoroLogger.resetStringBuilder();
416
500
  // Timestamp with caching optimization
417
501
  if (this.options.enableTimestamp !== false) {
@@ -419,35 +503,29 @@ class MoroLogger {
419
503
  if (colors) {
420
504
  MoroLogger.appendToBuilder(MoroLogger.COLORS.timestamp);
421
505
  MoroLogger.appendToBuilder(timestamp);
422
- MoroLogger.appendToBuilder(MoroLogger.RESET);
506
+ MoroLogger.appendToBuilder(levelReset);
423
507
  }
424
508
  else {
425
509
  MoroLogger.appendToBuilder(timestamp);
426
510
  }
427
- }
428
- // Level with color using pre-allocated strings
429
- const levelColor = colors ? MoroLogger.COLORS[entry.level] : '';
430
- const levelReset = colors ? MoroLogger.RESET : '';
431
- const levelText = MoroLogger.LEVEL_STRINGS[entry.level];
432
- // Add space after timestamp if present
433
- if (this.options.enableTimestamp !== false) {
434
511
  MoroLogger.appendToBuilder(' ');
435
512
  }
513
+ // Level with pre-allocated strings
514
+ const levelStr = MoroLogger.LEVEL_STRINGS[entry.level];
436
515
  if (colors) {
437
- MoroLogger.appendToBuilder(levelColor);
516
+ MoroLogger.appendToBuilder(MoroLogger.COLORS[entry.level]);
438
517
  MoroLogger.appendToBuilder(MoroLogger.BOLD);
439
- MoroLogger.appendToBuilder(levelText);
518
+ MoroLogger.appendToBuilder(levelStr);
440
519
  MoroLogger.appendToBuilder(levelReset);
441
520
  }
442
521
  else {
443
- MoroLogger.appendToBuilder(levelText);
522
+ MoroLogger.appendToBuilder(levelStr);
444
523
  }
445
524
  // Context
446
525
  if (entry.context && this.options.enableContext !== false) {
447
- const contextColor = colors ? MoroLogger.COLORS.context : '';
448
- MoroLogger.appendToBuilder(' '); // Space before context
526
+ MoroLogger.appendToBuilder(' ');
449
527
  if (colors) {
450
- MoroLogger.appendToBuilder(contextColor);
528
+ MoroLogger.appendToBuilder(MoroLogger.COLORS.context);
451
529
  MoroLogger.appendToBuilder(`[${entry.context}]`);
452
530
  MoroLogger.appendToBuilder(levelReset);
453
531
  }
@@ -456,7 +534,7 @@ class MoroLogger {
456
534
  }
457
535
  }
458
536
  // Message
459
- MoroLogger.appendToBuilder(' '); // Space before message
537
+ MoroLogger.appendToBuilder(' ');
460
538
  MoroLogger.appendToBuilder(entry.message);
461
539
  // Performance info
462
540
  if (entry.performance && this.options.enablePerformance !== false) {
@@ -469,7 +547,7 @@ class MoroLogger {
469
547
  perfParts.push(`${Math.round(entry.performance.memory)}MB`);
470
548
  }
471
549
  if (perfParts.length > 0) {
472
- MoroLogger.appendToBuilder(' '); // Space before performance info
550
+ MoroLogger.appendToBuilder(' ');
473
551
  if (colors) {
474
552
  MoroLogger.appendToBuilder(perfColor);
475
553
  MoroLogger.appendToBuilder(`(${perfParts.join(', ')})`);
@@ -487,19 +565,20 @@ class MoroLogger {
487
565
  const metaColor = colors ? MoroLogger.COLORS.metadata : '';
488
566
  const cleanMetadata = this.cleanMetadata(entry.metadata);
489
567
  if (Object.keys(cleanMetadata).length > 0) {
568
+ MoroLogger.appendToBuilder(' ');
490
569
  if (colors) {
491
570
  MoroLogger.appendToBuilder(metaColor);
492
- MoroLogger.appendToBuilder(this.stringify(cleanMetadata));
571
+ MoroLogger.appendToBuilder(this.safeStringify(cleanMetadata));
493
572
  MoroLogger.appendToBuilder(levelReset);
494
573
  }
495
574
  else {
496
- MoroLogger.appendToBuilder(this.stringify(cleanMetadata));
575
+ MoroLogger.appendToBuilder(this.safeStringify(cleanMetadata));
497
576
  }
498
577
  }
499
578
  }
500
579
  // Output main log line with high-performance method
501
580
  const finalMessage = MoroLogger.buildString();
502
- this.output(finalMessage + '\n', entry.level);
581
+ this.output(`${finalMessage}\n`, entry.level);
503
582
  // Stack trace for errors
504
583
  if (entry.metadata?.stack && (entry.level === 'error' || entry.level === 'fatal')) {
505
584
  const stackColor = colors ? MoroLogger.COLORS.error : '';
@@ -516,77 +595,181 @@ class MoroLogger {
516
595
  }
517
596
  return clean;
518
597
  }
519
- // Fast JSON stringify with error handling
520
- stringify(obj) {
521
- try {
522
- return JSON.stringify(obj);
523
- }
524
- catch {
525
- return '[Circular Reference]';
526
- }
527
- }
528
- // High-performance output with micro-batching
598
+ // High-performance output with buffering
529
599
  output(message, level = 'info') {
530
- // Add to buffer
600
+ // Prevent memory exhaustion
601
+ if (this.outputBuffer.length >= this.bufferOverflowThreshold &&
602
+ !this.emergencyFlushInProgress) {
603
+ this.emergencyFlushInProgress = true;
604
+ this.forceFlushBuffer();
605
+ this.emergencyFlushInProgress = false;
606
+ }
531
607
  this.outputBuffer.push(message);
532
- this.bufferSize += message.length;
533
- // Flush immediately if buffer is full or for errors
534
- if (this.bufferSize >= this.maxBufferSize || level === 'error' || level === 'fatal') {
608
+ this.bufferSize++;
609
+ // Immediate flush for critical levels or full buffer
610
+ if (level === 'fatal' || level === 'error' || this.bufferSize >= this.maxBufferSize) {
535
611
  this.flushBuffer();
536
612
  }
537
613
  else {
538
- // Schedule flush with micro-batching
539
614
  this.scheduleFlush();
540
615
  }
541
616
  }
542
617
  scheduleFlush() {
543
- if (this.flushTimeout)
544
- return; // Already scheduled
618
+ if (this.flushTimeout || this.isDestroyed) {
619
+ return; // Already scheduled or destroyed
620
+ }
545
621
  this.flushTimeout = setTimeout(() => {
546
622
  this.flushBuffer();
547
- this.flushTimeout = null;
548
623
  }, this.flushInterval);
624
+ // Unref the timeout so it doesn't prevent process exit (important for tests)
625
+ this.flushTimeout.unref();
549
626
  }
550
627
  flushBuffer() {
551
- if (this.outputBuffer.length === 0)
628
+ if (this.outputBuffer.length === 0) {
552
629
  return;
553
- try {
554
- // Group by stream type for efficiency
555
- const stdoutMessages = [];
556
- const stderrMessages = [];
557
- for (const message of this.outputBuffer) {
558
- // Determine stream based on message content (simple heuristic)
559
- if (message.includes('ERROR') || message.includes('FATAL')) {
560
- stderrMessages.push(message);
561
- }
562
- else {
563
- stdoutMessages.push(message);
564
- }
630
+ }
631
+ // Group messages by stream type
632
+ const stdoutMessages = [];
633
+ const stderrMessages = [];
634
+ for (const message of this.outputBuffer) {
635
+ // Determine stream based on message content or level
636
+ if (message.includes('ERROR') || message.includes('FATAL')) {
637
+ stderrMessages.push(message);
638
+ }
639
+ else {
640
+ stdoutMessages.push(message);
565
641
  }
566
- // Write to streams
567
- if (stdoutMessages.length > 0) {
642
+ }
643
+ // Write to appropriate streams with error handling
644
+ try {
645
+ if (stdoutMessages.length > 0 && process.stdout.writable) {
568
646
  process.stdout.write(stdoutMessages.join(''));
569
647
  }
570
- if (stderrMessages.length > 0) {
648
+ if (stderrMessages.length > 0 && process.stderr.writable) {
571
649
  process.stderr.write(stderrMessages.join(''));
572
650
  }
573
651
  }
574
652
  catch {
575
- // Fallback to console methods if stream write fails
576
- for (const message of this.outputBuffer) {
577
- if (message.includes('ERROR') || message.includes('FATAL')) {
578
- // eslint-disable-next-line no-console
579
- console.error(message.trim());
580
- }
581
- else {
582
- // eslint-disable-next-line no-console
583
- console.log(message.trim());
584
- }
653
+ // Fallback to console if streams fail
654
+ try {
655
+ // eslint-disable-next-line no-console
656
+ console.log(this.outputBuffer.join(''));
657
+ }
658
+ catch {
659
+ // If even console.log fails, just ignore
585
660
  }
586
661
  }
587
- // Reset buffer
662
+ // Clear buffer
588
663
  this.outputBuffer.length = 0;
589
664
  this.bufferSize = 0;
665
+ // Clear timeout
666
+ if (this.flushTimeout) {
667
+ clearTimeout(this.flushTimeout);
668
+ this.flushTimeout = null;
669
+ }
670
+ }
671
+ // Emergency flush for buffer overflow protection
672
+ forceFlushBuffer() {
673
+ if (this.outputBuffer.length === 0)
674
+ return;
675
+ try {
676
+ const message = this.outputBuffer.join('');
677
+ process.stdout.write(message);
678
+ }
679
+ catch (error) {
680
+ // Emergency fallback - write individual messages
681
+ for (const msg of this.outputBuffer) {
682
+ try {
683
+ process.stdout.write(msg);
684
+ }
685
+ catch {
686
+ // If even this fails, give up on this batch
687
+ break;
688
+ }
689
+ }
690
+ }
691
+ finally {
692
+ this.outputBuffer.length = 0;
693
+ this.bufferSize = 0;
694
+ }
695
+ }
696
+ // Safe stringify with circular reference detection
697
+ safeStringify(obj, maxDepth = 3) {
698
+ const seen = new WeakSet();
699
+ const stringify = (value, depth) => {
700
+ if (depth > maxDepth)
701
+ return '[Max Depth Reached]';
702
+ if (value === null || typeof value !== 'object')
703
+ return value;
704
+ if (seen.has(value))
705
+ return '[Circular Reference]';
706
+ seen.add(value);
707
+ if (Array.isArray(value)) {
708
+ return value.map(item => stringify(item, depth + 1));
709
+ }
710
+ const result = {};
711
+ for (const [key, val] of Object.entries(value)) {
712
+ if (typeof val !== 'function') {
713
+ // Skip functions
714
+ result[key] = stringify(val, depth + 1);
715
+ }
716
+ }
717
+ return result;
718
+ };
719
+ try {
720
+ return JSON.stringify(stringify(obj, 0));
721
+ }
722
+ catch (error) {
723
+ return '[Stringify Error]';
724
+ }
725
+ }
726
+ // Configuration validation
727
+ validateOptions(options) {
728
+ const validated = { ...options };
729
+ // Validate log level
730
+ const validLevels = ['debug', 'info', 'warn', 'error', 'fatal'];
731
+ if (validated.level && !validLevels.includes(validated.level)) {
732
+ console.warn(`[MoroLogger] Invalid log level: ${validated.level}, defaulting to 'info'`);
733
+ validated.level = 'info';
734
+ }
735
+ // Validate max entries
736
+ if (validated.maxEntries !== undefined) {
737
+ if (validated.maxEntries < 1 || validated.maxEntries > 100000) {
738
+ console.warn(`[MoroLogger] Invalid maxEntries: ${validated.maxEntries}, defaulting to 1000`);
739
+ validated.maxEntries = 1000;
740
+ }
741
+ }
742
+ // Validate buffer size
743
+ if (validated.maxBufferSize !== undefined) {
744
+ if (validated.maxBufferSize < 10 || validated.maxBufferSize > 10000) {
745
+ console.warn(`[MoroLogger] Invalid maxBufferSize: ${validated.maxBufferSize}, defaulting to 1000`);
746
+ validated.maxBufferSize = 1000;
747
+ }
748
+ }
749
+ return validated;
750
+ }
751
+ // Error handling methods
752
+ handleOutputError(outputName, error) {
753
+ // Could implement output retry logic, circuit breaker, etc.
754
+ // For now, just track the error
755
+ if (!this.metrics.outputErrors) {
756
+ this.metrics.outputErrors = {};
757
+ }
758
+ this.metrics.outputErrors[outputName] = (this.metrics.outputErrors[outputName] || 0) + 1;
759
+ }
760
+ emergencyConsoleWrite(entry) {
761
+ const message = `${entry.timestamp.toISOString()} ${entry.level.toUpperCase()} ${entry.message}`;
762
+ try {
763
+ if (entry.level === 'error' || entry.level === 'fatal') {
764
+ process.stderr.write(`[EMERGENCY] ${message}\n`);
765
+ }
766
+ else {
767
+ process.stdout.write(`[EMERGENCY] ${message}\n`);
768
+ }
769
+ }
770
+ catch {
771
+ // If even emergency write fails, there's nothing more we can do
772
+ }
590
773
  }
591
774
  // Force flush streams (useful for shutdown)
592
775
  flush() {
@@ -598,76 +781,69 @@ class MoroLogger {
598
781
  // Flush any remaining buffer
599
782
  this.flushBuffer();
600
783
  try {
601
- // Force flush streams
784
+ // Force flush streams without ending them
602
785
  if (process.stdout.writable) {
603
- process.stdout.end();
786
+ process.stdout.write(''); // Force flush without ending
604
787
  }
605
788
  if (process.stderr.writable) {
606
- process.stderr.end();
789
+ process.stderr.write(''); // Force flush without ending
607
790
  }
608
791
  }
609
792
  catch {
610
793
  // Ignore flush errors
611
794
  }
612
795
  }
613
- // Cleanup method to clear all timeouts and handles
614
- cleanup() {
615
- // Clear any pending flush timeout
796
+ // Destroy logger and clean up all resources (for testing)
797
+ destroy() {
798
+ // Mark as destroyed to prevent new timeouts
799
+ this.isDestroyed = true;
800
+ // Clear any remaining timeouts
616
801
  if (this.flushTimeout) {
617
802
  clearTimeout(this.flushTimeout);
618
803
  this.flushTimeout = null;
619
804
  }
620
- // Flush any remaining output
805
+ // Flush any remaining buffer
621
806
  this.flushBuffer();
807
+ // Clear outputs and filters
808
+ this.outputs.clear();
809
+ this.filters.clear();
810
+ // Clear history
811
+ this.history.length = 0;
812
+ this.historyIndex = 0;
813
+ this.historySize = 0;
622
814
  }
623
815
  }
624
- exports.MoroLogger = MoroLogger;
625
816
  // Global logger instance
626
817
  const initialLogLevel = process.env.LOG_LEVEL ||
627
818
  process.env.MORO_LOG_LEVEL ||
628
819
  (process.env.NODE_ENV === 'production' ? 'warn' : 'debug');
629
- exports.logger = new MoroLogger({
820
+ export const logger = new MoroLogger({
630
821
  level: initialLogLevel,
631
822
  enableColors: !process.env.NO_COLOR,
632
823
  format: process.env.LOG_FORMAT || 'pretty',
633
824
  });
634
- // Add cleanup handlers for Jest and other test runners
635
- if (typeof process !== 'undefined') {
636
- // Cleanup on process exit
637
- process.on('beforeExit', () => {
638
- exports.logger.cleanup();
639
- });
640
- process.on('SIGINT', () => {
641
- exports.logger.cleanup();
642
- process.exit(0);
643
- });
644
- process.on('SIGTERM', () => {
645
- exports.logger.cleanup();
646
- process.exit(0);
647
- });
648
- // For Jest and other test runners - cleanup on uncaught exceptions
649
- process.on('uncaughtException', () => {
650
- exports.logger.cleanup();
651
- });
652
- process.on('unhandledRejection', () => {
653
- exports.logger.cleanup();
654
- });
655
- }
656
825
  /**
657
826
  * Configure the global logger with new settings
658
827
  * This allows runtime configuration of the logger
659
828
  */
660
- function configureGlobalLogger(options) {
829
+ export function configureGlobalLogger(options) {
661
830
  if (options.level) {
662
- exports.logger.setLevel(options.level);
831
+ logger.setLevel(options.level);
663
832
  }
664
833
  // Additional configuration options can be added here as needed
665
834
  // For now, focusing on level which is the most critical
666
835
  }
836
+ /**
837
+ * Destroy the global logger and clean up resources (for testing)
838
+ * @internal
839
+ */
840
+ export function destroyGlobalLogger() {
841
+ logger.destroy();
842
+ }
667
843
  /**
668
844
  * Apply logging configuration from the config system and/or createApp options
669
845
  */
670
- function applyLoggingConfiguration(configLogging, appOptions) {
846
+ export function applyLoggingConfiguration(configLogging, appOptions) {
671
847
  // First apply config system settings (from environment variables)
672
848
  if (configLogging?.level) {
673
849
  configureGlobalLogger({ level: configLogging.level });
@@ -684,20 +860,19 @@ function applyLoggingConfiguration(configLogging, appOptions) {
684
860
  }
685
861
  }
686
862
  // Framework-specific logger
687
- const createFrameworkLogger = (context) => {
688
- return exports.logger.child('Moro', { framework: 'moro', context });
863
+ export const createFrameworkLogger = (context) => {
864
+ return logger.child('Moro', { framework: 'moro', context });
689
865
  };
690
- exports.createFrameworkLogger = createFrameworkLogger;
691
866
  // Graceful shutdown handler to flush any pending logs
692
867
  process.on('SIGINT', () => {
693
- exports.logger.flush();
868
+ logger.flush();
694
869
  process.exit(0);
695
870
  });
696
871
  process.on('SIGTERM', () => {
697
- exports.logger.flush();
872
+ logger.flush();
698
873
  process.exit(0);
699
874
  });
700
875
  process.on('beforeExit', () => {
701
- exports.logger.flush();
876
+ logger.flush();
702
877
  });
703
878
  //# sourceMappingURL=logger.js.map