@morojs/moro 1.7.30 → 1.8.1

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 (373) hide show
  1. package/README.md +89 -46
  2. package/dist/core/auth/morojs-adapter.js +95 -45
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-manager.js.map +1 -1
  5. package/dist/core/config/config-sources.js +119 -48
  6. package/dist/core/config/config-sources.js.map +1 -1
  7. package/dist/core/config/config-validator.js +189 -8
  8. package/dist/core/config/config-validator.js.map +1 -1
  9. package/dist/core/config/file-loader.js.map +1 -1
  10. package/dist/core/config/index.js.map +1 -1
  11. package/dist/core/config/schema.js +35 -4
  12. package/dist/core/config/schema.js.map +1 -1
  13. package/dist/core/config/utils.js.map +1 -1
  14. package/dist/core/database/adapters/drizzle.js +2 -2
  15. package/dist/core/database/adapters/drizzle.js.map +1 -1
  16. package/dist/core/database/adapters/index.js.map +1 -1
  17. package/dist/core/database/adapters/mongodb.d.ts +1 -0
  18. package/dist/core/database/adapters/mongodb.js +16 -0
  19. package/dist/core/database/adapters/mongodb.js.map +1 -1
  20. package/dist/core/database/adapters/mysql.d.ts +1 -0
  21. package/dist/core/database/adapters/mysql.js +13 -2
  22. package/dist/core/database/adapters/mysql.js.map +1 -1
  23. package/dist/core/database/adapters/postgresql.js +2 -2
  24. package/dist/core/database/adapters/postgresql.js.map +1 -1
  25. package/dist/core/database/adapters/redis.js.map +1 -1
  26. package/dist/core/database/adapters/sql-safety.js +5 -4
  27. package/dist/core/database/adapters/sql-safety.js.map +1 -1
  28. package/dist/core/database/adapters/sqlite.js.map +1 -1
  29. package/dist/core/database/index.js.map +1 -1
  30. package/dist/core/docs/index.js +11 -7
  31. package/dist/core/docs/index.js.map +1 -1
  32. package/dist/core/docs/openapi-generator.js +8 -6
  33. package/dist/core/docs/openapi-generator.js.map +1 -1
  34. package/dist/core/docs/schema-to-openapi.js +3 -3
  35. package/dist/core/docs/schema-to-openapi.js.map +1 -1
  36. package/dist/core/docs/simple-docs.js.map +1 -1
  37. package/dist/core/docs/swagger-ui.js.map +1 -1
  38. package/dist/core/docs/zod-to-openapi.js +2 -2
  39. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  40. package/dist/core/events/event-bus.js +14 -5
  41. package/dist/core/events/event-bus.js.map +1 -1
  42. package/dist/core/events/index.js.map +1 -1
  43. package/dist/core/framework.d.ts +41 -3
  44. package/dist/core/framework.js +342 -95
  45. package/dist/core/framework.js.map +1 -1
  46. package/dist/core/graphql/adapter.js.map +1 -1
  47. package/dist/core/graphql/adapters/graphql-js-adapter.js.map +1 -1
  48. package/dist/core/graphql/core.js.map +1 -1
  49. package/dist/core/graphql/index.js.map +1 -1
  50. package/dist/core/graphql/loader.js.map +1 -1
  51. package/dist/core/graphql/types.js.map +1 -1
  52. package/dist/core/grpc/adapters/grpc-js-adapter.js +4 -0
  53. package/dist/core/grpc/adapters/grpc-js-adapter.js.map +1 -1
  54. package/dist/core/grpc/adapters/index.js.map +1 -1
  55. package/dist/core/grpc/grpc-adapter.js.map +1 -1
  56. package/dist/core/grpc/grpc-manager.js.map +1 -1
  57. package/dist/core/grpc/index.js.map +1 -1
  58. package/dist/core/grpc/middleware/auth.js +1 -1
  59. package/dist/core/grpc/middleware/auth.js.map +1 -1
  60. package/dist/core/grpc/middleware/logging.js.map +1 -1
  61. package/dist/core/grpc/middleware/validation.js +1 -1
  62. package/dist/core/grpc/middleware/validation.js.map +1 -1
  63. package/dist/core/grpc/types.d.ts +7 -7
  64. package/dist/core/grpc/types.js.map +1 -1
  65. package/dist/core/http/http-server.d.ts +17 -23
  66. package/dist/core/http/http-server.js +109 -249
  67. package/dist/core/http/http-server.js.map +1 -1
  68. package/dist/core/http/http2-server.d.ts +6 -16
  69. package/dist/core/http/http2-server.js +40 -83
  70. package/dist/core/http/http2-server.js.map +1 -1
  71. package/dist/core/http/index.d.ts +1 -0
  72. package/dist/core/http/index.js +3 -0
  73. package/dist/core/http/index.js.map +1 -1
  74. package/dist/core/http/moro-engine-server.d.ts +263 -0
  75. package/dist/core/http/moro-engine-server.js +1962 -0
  76. package/dist/core/http/moro-engine-server.js.map +1 -0
  77. package/dist/core/http/utils/compression.d.ts +47 -0
  78. package/dist/core/http/utils/compression.js +132 -0
  79. package/dist/core/http/utils/compression.js.map +1 -0
  80. package/dist/core/http/utils/lazy-event-emitter.d.ts +11 -0
  81. package/dist/core/http/utils/lazy-event-emitter.js +69 -0
  82. package/dist/core/http/utils/lazy-event-emitter.js.map +1 -0
  83. package/dist/core/http/utils/multipart-parser.d.ts +32 -0
  84. package/dist/core/http/utils/multipart-parser.js +215 -0
  85. package/dist/core/http/utils/multipart-parser.js.map +1 -0
  86. package/dist/core/http/utils/query-parser.d.ts +1 -0
  87. package/dist/core/http/utils/query-parser.js +44 -0
  88. package/dist/core/http/utils/query-parser.js.map +1 -0
  89. package/dist/core/http/utils/size.d.ts +33 -0
  90. package/dist/core/http/utils/size.js +37 -0
  91. package/dist/core/http/utils/size.js.map +1 -0
  92. package/dist/core/http/utils/ssl-config.d.ts +69 -0
  93. package/dist/core/http/utils/ssl-config.js +116 -0
  94. package/dist/core/http/utils/ssl-config.js.map +1 -0
  95. package/dist/core/http/utils/uws-worker-clustering.js +45 -32
  96. package/dist/core/http/utils/uws-worker-clustering.js.map +1 -1
  97. package/dist/core/http/uws-http-server.d.ts +25 -3
  98. package/dist/core/http/uws-http-server.js +465 -86
  99. package/dist/core/http/uws-http-server.js.map +1 -1
  100. package/dist/core/jobs/cron-parser.js +7 -5
  101. package/dist/core/jobs/cron-parser.js.map +1 -1
  102. package/dist/core/jobs/index.js.map +1 -1
  103. package/dist/core/jobs/job-executor.d.ts +1 -1
  104. package/dist/core/jobs/job-executor.js.map +1 -1
  105. package/dist/core/jobs/job-scheduler.d.ts +3 -3
  106. package/dist/core/jobs/job-scheduler.js.map +1 -1
  107. package/dist/core/jobs/job-state-manager.d.ts +3 -3
  108. package/dist/core/jobs/job-state-manager.js +25 -4
  109. package/dist/core/jobs/job-state-manager.js.map +1 -1
  110. package/dist/core/jobs/leader-election.d.ts +15 -0
  111. package/dist/core/jobs/leader-election.js +158 -69
  112. package/dist/core/jobs/leader-election.js.map +1 -1
  113. package/dist/core/jobs/types.d.ts +4 -4
  114. package/dist/core/jobs/types.js.map +1 -1
  115. package/dist/core/jobs/utils.d.ts +1 -1
  116. package/dist/core/jobs/utils.js +7 -3
  117. package/dist/core/jobs/utils.js.map +1 -1
  118. package/dist/core/logger/filters.js +3 -2
  119. package/dist/core/logger/filters.js.map +1 -1
  120. package/dist/core/logger/index.js.map +1 -1
  121. package/dist/core/logger/logger.js +56 -25
  122. package/dist/core/logger/logger.js.map +1 -1
  123. package/dist/core/logger/outputs.js.map +1 -1
  124. package/dist/core/mail/adapters/console-adapter.js.map +1 -1
  125. package/dist/core/mail/adapters/index.js.map +1 -1
  126. package/dist/core/mail/adapters/nodemailer-adapter.js.map +1 -1
  127. package/dist/core/mail/adapters/resend-adapter.js.map +1 -1
  128. package/dist/core/mail/adapters/sendgrid-adapter.js.map +1 -1
  129. package/dist/core/mail/adapters/ses-adapter.js.map +1 -1
  130. package/dist/core/mail/index.js.map +1 -1
  131. package/dist/core/mail/mail-adapter.js.map +1 -1
  132. package/dist/core/mail/mail-manager.d.ts +10 -0
  133. package/dist/core/mail/mail-manager.js +21 -5
  134. package/dist/core/mail/mail-manager.js.map +1 -1
  135. package/dist/core/mail/template-engine.js.map +1 -1
  136. package/dist/core/mail/types.js.map +1 -1
  137. package/dist/core/middleware/built-in/auth/core.js +3 -3
  138. package/dist/core/middleware/built-in/auth/core.js.map +1 -1
  139. package/dist/core/middleware/built-in/auth/helpers.js +4 -4
  140. package/dist/core/middleware/built-in/auth/helpers.js.map +1 -1
  141. package/dist/core/middleware/built-in/auth/hook.js.map +1 -1
  142. package/dist/core/middleware/built-in/auth/index.js.map +1 -1
  143. package/dist/core/middleware/built-in/auth/jwt-helpers.d.ts +4 -4
  144. package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -1
  145. package/dist/core/middleware/built-in/auth/middleware.js.map +1 -1
  146. package/dist/core/middleware/built-in/auth/providers.js.map +1 -1
  147. package/dist/core/middleware/built-in/body-parsers/index.js.map +1 -1
  148. package/dist/core/middleware/built-in/body-size/core.js +2 -2
  149. package/dist/core/middleware/built-in/body-size/core.js.map +1 -1
  150. package/dist/core/middleware/built-in/body-size/hook.js.map +1 -1
  151. package/dist/core/middleware/built-in/body-size/index.js.map +1 -1
  152. package/dist/core/middleware/built-in/body-size/middleware.js.map +1 -1
  153. package/dist/core/middleware/built-in/cache/adapters/cache/file.js +3 -1
  154. package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -1
  155. package/dist/core/middleware/built-in/cache/adapters/cache/index.js.map +1 -1
  156. package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -1
  157. package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -1
  158. package/dist/core/middleware/built-in/cache/adapters/index.js.map +1 -1
  159. package/dist/core/middleware/built-in/cache/core.js.map +1 -1
  160. package/dist/core/middleware/built-in/cache/hook.js +3 -3
  161. package/dist/core/middleware/built-in/cache/hook.js.map +1 -1
  162. package/dist/core/middleware/built-in/cache/index.js.map +1 -1
  163. package/dist/core/middleware/built-in/cache/middleware.js.map +1 -1
  164. package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -1
  165. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -1
  166. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -1
  167. package/dist/core/middleware/built-in/cdn/adapters/cdn/index.js.map +1 -1
  168. package/dist/core/middleware/built-in/cdn/adapters/index.js.map +1 -1
  169. package/dist/core/middleware/built-in/cdn/core.js.map +1 -1
  170. package/dist/core/middleware/built-in/cdn/hook.js.map +1 -1
  171. package/dist/core/middleware/built-in/cdn/index.js.map +1 -1
  172. package/dist/core/middleware/built-in/cdn/middleware.js.map +1 -1
  173. package/dist/core/middleware/built-in/compression/core.d.ts +3 -0
  174. package/dist/core/middleware/built-in/compression/core.js +28 -34
  175. package/dist/core/middleware/built-in/compression/core.js.map +1 -1
  176. package/dist/core/middleware/built-in/compression/hook.js.map +1 -1
  177. package/dist/core/middleware/built-in/compression/index.js.map +1 -1
  178. package/dist/core/middleware/built-in/compression/middleware.js.map +1 -1
  179. package/dist/core/middleware/built-in/cookie/core.js.map +1 -1
  180. package/dist/core/middleware/built-in/cookie/hook.js.map +1 -1
  181. package/dist/core/middleware/built-in/cookie/index.js.map +1 -1
  182. package/dist/core/middleware/built-in/cookie/middleware.js.map +1 -1
  183. package/dist/core/middleware/built-in/cors/core.js.map +1 -1
  184. package/dist/core/middleware/built-in/cors/hook.js.map +1 -1
  185. package/dist/core/middleware/built-in/cors/index.js.map +1 -1
  186. package/dist/core/middleware/built-in/cors/middleware.js.map +1 -1
  187. package/dist/core/middleware/built-in/csp/core.js.map +1 -1
  188. package/dist/core/middleware/built-in/csp/hook.js.map +1 -1
  189. package/dist/core/middleware/built-in/csp/index.js.map +1 -1
  190. package/dist/core/middleware/built-in/csp/middleware.js.map +1 -1
  191. package/dist/core/middleware/built-in/csrf/core.js +1 -1
  192. package/dist/core/middleware/built-in/csrf/core.js.map +1 -1
  193. package/dist/core/middleware/built-in/csrf/hook.js.map +1 -1
  194. package/dist/core/middleware/built-in/csrf/index.js.map +1 -1
  195. package/dist/core/middleware/built-in/csrf/middleware.js.map +1 -1
  196. package/dist/core/middleware/built-in/error-tracker/index.js.map +1 -1
  197. package/dist/core/middleware/built-in/error-tracker/middleware.js.map +1 -1
  198. package/dist/core/middleware/built-in/graphql/core.js.map +1 -1
  199. package/dist/core/middleware/built-in/graphql/helpers.js.map +1 -1
  200. package/dist/core/middleware/built-in/graphql/hook.js.map +1 -1
  201. package/dist/core/middleware/built-in/graphql/index.js.map +1 -1
  202. package/dist/core/middleware/built-in/graphql/middleware.js.map +1 -1
  203. package/dist/core/middleware/built-in/graphql/subscriptions.js.map +1 -1
  204. package/dist/core/middleware/built-in/helmet/core.js.map +1 -1
  205. package/dist/core/middleware/built-in/helmet/hook.js.map +1 -1
  206. package/dist/core/middleware/built-in/helmet/index.js.map +1 -1
  207. package/dist/core/middleware/built-in/helmet/middleware.js.map +1 -1
  208. package/dist/core/middleware/built-in/http2/core.js.map +1 -1
  209. package/dist/core/middleware/built-in/http2/hook.js.map +1 -1
  210. package/dist/core/middleware/built-in/http2/index.js.map +1 -1
  211. package/dist/core/middleware/built-in/http2/middleware.js.map +1 -1
  212. package/dist/core/middleware/built-in/index.js.map +1 -1
  213. package/dist/core/middleware/built-in/performance-monitor/index.js.map +1 -1
  214. package/dist/core/middleware/built-in/performance-monitor/middleware.js.map +1 -1
  215. package/dist/core/middleware/built-in/range/core.js +4 -1
  216. package/dist/core/middleware/built-in/range/core.js.map +1 -1
  217. package/dist/core/middleware/built-in/range/hook.js.map +1 -1
  218. package/dist/core/middleware/built-in/range/index.js.map +1 -1
  219. package/dist/core/middleware/built-in/range/middleware.js.map +1 -1
  220. package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -1
  221. package/dist/core/middleware/built-in/rate-limit/hook.js.map +1 -1
  222. package/dist/core/middleware/built-in/rate-limit/index.js.map +1 -1
  223. package/dist/core/middleware/built-in/rate-limit/middleware.js.map +1 -1
  224. package/dist/core/middleware/built-in/request-logger/index.js.map +1 -1
  225. package/dist/core/middleware/built-in/request-logger/middleware.js.map +1 -1
  226. package/dist/core/middleware/built-in/session/core.js +4 -4
  227. package/dist/core/middleware/built-in/session/core.js.map +1 -1
  228. package/dist/core/middleware/built-in/session/hook.js.map +1 -1
  229. package/dist/core/middleware/built-in/session/index.js.map +1 -1
  230. package/dist/core/middleware/built-in/session/middleware.js.map +1 -1
  231. package/dist/core/middleware/built-in/sse/core.js.map +1 -1
  232. package/dist/core/middleware/built-in/sse/hook.js.map +1 -1
  233. package/dist/core/middleware/built-in/sse/index.js.map +1 -1
  234. package/dist/core/middleware/built-in/sse/middleware.js.map +1 -1
  235. package/dist/core/middleware/built-in/static/core.js.map +1 -1
  236. package/dist/core/middleware/built-in/static/hook.js.map +1 -1
  237. package/dist/core/middleware/built-in/static/index.js.map +1 -1
  238. package/dist/core/middleware/built-in/static/middleware.js.map +1 -1
  239. package/dist/core/middleware/built-in/template/core.js +1 -1
  240. package/dist/core/middleware/built-in/template/core.js.map +1 -1
  241. package/dist/core/middleware/built-in/template/hook.js.map +1 -1
  242. package/dist/core/middleware/built-in/template/index.js.map +1 -1
  243. package/dist/core/middleware/built-in/template/middleware.js.map +1 -1
  244. package/dist/core/middleware/built-in/upload/core.js.map +1 -1
  245. package/dist/core/middleware/built-in/upload/hook.js.map +1 -1
  246. package/dist/core/middleware/built-in/upload/index.js.map +1 -1
  247. package/dist/core/middleware/built-in/upload/middleware.js.map +1 -1
  248. package/dist/core/middleware/built-in/validation/core.js.map +1 -1
  249. package/dist/core/middleware/built-in/validation/hook.js.map +1 -1
  250. package/dist/core/middleware/built-in/validation/index.js.map +1 -1
  251. package/dist/core/middleware/built-in/validation/middleware.js.map +1 -1
  252. package/dist/core/middleware/index.js +2 -2
  253. package/dist/core/middleware/index.js.map +1 -1
  254. package/dist/core/modules/auto-discovery.js +11 -7
  255. package/dist/core/modules/auto-discovery.js.map +1 -1
  256. package/dist/core/modules/index.js.map +1 -1
  257. package/dist/core/modules/modules.js +18 -13
  258. package/dist/core/modules/modules.js.map +1 -1
  259. package/dist/core/networking/adapters/engine-adapter.d.ts +23 -0
  260. package/dist/core/networking/adapters/engine-adapter.js +365 -0
  261. package/dist/core/networking/adapters/engine-adapter.js.map +1 -0
  262. package/dist/core/networking/adapters/index.d.ts +1 -0
  263. package/dist/core/networking/adapters/index.js +1 -0
  264. package/dist/core/networking/adapters/index.js.map +1 -1
  265. package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -0
  266. package/dist/core/networking/adapters/socketio-adapter.js +12 -1
  267. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  268. package/dist/core/networking/adapters/uws-adapter.js +27 -16
  269. package/dist/core/networking/adapters/uws-adapter.js.map +1 -1
  270. package/dist/core/networking/adapters/ws-adapter.d.ts +15 -0
  271. package/dist/core/networking/adapters/ws-adapter.js +120 -6
  272. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  273. package/dist/core/networking/index.js.map +1 -1
  274. package/dist/core/networking/service-discovery.js +7 -5
  275. package/dist/core/networking/service-discovery.js.map +1 -1
  276. package/dist/core/networking/websocket-adapter.d.ts +22 -3
  277. package/dist/core/networking/websocket-adapter.js.map +1 -1
  278. package/dist/core/networking/websocket-manager.js +70 -67
  279. package/dist/core/networking/websocket-manager.js.map +1 -1
  280. package/dist/core/pooling/object-pool-manager.js +6 -0
  281. package/dist/core/pooling/object-pool-manager.js.map +1 -1
  282. package/dist/core/queue/adapters/bull-adapter.js.map +1 -1
  283. package/dist/core/queue/adapters/index.js.map +1 -1
  284. package/dist/core/queue/adapters/kafka-adapter.js +2 -2
  285. package/dist/core/queue/adapters/kafka-adapter.js.map +1 -1
  286. package/dist/core/queue/adapters/memory-adapter.js +6 -6
  287. package/dist/core/queue/adapters/memory-adapter.js.map +1 -1
  288. package/dist/core/queue/adapters/rabbitmq-adapter.d.ts +50 -0
  289. package/dist/core/queue/adapters/rabbitmq-adapter.js +176 -20
  290. package/dist/core/queue/adapters/rabbitmq-adapter.js.map +1 -1
  291. package/dist/core/queue/adapters/sqs-adapter.d.ts +12 -2
  292. package/dist/core/queue/adapters/sqs-adapter.js +75 -24
  293. package/dist/core/queue/adapters/sqs-adapter.js.map +1 -1
  294. package/dist/core/queue/index.js.map +1 -1
  295. package/dist/core/queue/middleware/index.js.map +1 -1
  296. package/dist/core/queue/middleware/monitoring.d.ts +1 -1
  297. package/dist/core/queue/middleware/monitoring.js.map +1 -1
  298. package/dist/core/queue/middleware/priority.js +2 -1
  299. package/dist/core/queue/middleware/priority.js.map +1 -1
  300. package/dist/core/queue/middleware/rate-limit.js.map +1 -1
  301. package/dist/core/queue/queue-adapter.js.map +1 -1
  302. package/dist/core/queue/queue-manager.js.map +1 -1
  303. package/dist/core/queue/types.d.ts +8 -8
  304. package/dist/core/queue/types.js.map +1 -1
  305. package/dist/core/routing/app-integration.js.map +1 -1
  306. package/dist/core/routing/create-router.js.map +1 -1
  307. package/dist/core/routing/index.js.map +1 -1
  308. package/dist/core/routing/path-matcher.js.map +1 -1
  309. package/dist/core/routing/radix-tree.js.map +1 -1
  310. package/dist/core/routing/router.js.map +1 -1
  311. package/dist/core/routing/unified-router.js +12 -4
  312. package/dist/core/routing/unified-router.js.map +1 -1
  313. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
  314. package/dist/core/runtime/base-adapter.js +2 -2
  315. package/dist/core/runtime/base-adapter.js.map +1 -1
  316. package/dist/core/runtime/cloudflare-workers-adapter.js +2 -0
  317. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  318. package/dist/core/runtime/index.js.map +1 -1
  319. package/dist/core/runtime/node-adapter.js +19 -17
  320. package/dist/core/runtime/node-adapter.js.map +1 -1
  321. package/dist/core/runtime/vercel-edge-adapter.js +2 -0
  322. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  323. package/dist/core/utilities/circuit-breaker.d.ts +1 -0
  324. package/dist/core/utilities/circuit-breaker.js +25 -2
  325. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  326. package/dist/core/utilities/container.js +9 -9
  327. package/dist/core/utilities/container.js.map +1 -1
  328. package/dist/core/utilities/hooks.js +28 -6
  329. package/dist/core/utilities/hooks.js.map +1 -1
  330. package/dist/core/utilities/index.js.map +1 -1
  331. package/dist/core/utilities/module-path.js.map +1 -1
  332. package/dist/core/utilities/package-utils.d.ts +68 -0
  333. package/dist/core/utilities/package-utils.js +198 -1
  334. package/dist/core/utilities/package-utils.js.map +1 -1
  335. package/dist/core/utilities/response-helpers.js +1 -1
  336. package/dist/core/utilities/response-helpers.js.map +1 -1
  337. package/dist/core/validation/adapters.js.map +1 -1
  338. package/dist/core/validation/error-handler.js.map +1 -1
  339. package/dist/core/validation/index.js.map +1 -1
  340. package/dist/core/validation/schema-interface.js.map +1 -1
  341. package/dist/core/workers/facade.js.map +1 -1
  342. package/dist/core/workers/index.js.map +1 -1
  343. package/dist/core/workers/worker-entry.d.ts +1 -0
  344. package/dist/core/workers/worker-entry.js +12 -0
  345. package/dist/core/workers/worker-entry.js.map +1 -0
  346. package/dist/core/workers/worker-manager.d.ts +23 -2
  347. package/dist/core/workers/worker-manager.js +117 -17
  348. package/dist/core/workers/worker-manager.js.map +1 -1
  349. package/dist/core/workers/worker.js +8 -6
  350. package/dist/core/workers/worker.js.map +1 -1
  351. package/dist/index.d.ts +2 -2
  352. package/dist/index.js +5 -2
  353. package/dist/index.js.map +1 -1
  354. package/dist/moro.d.ts +20 -1
  355. package/dist/moro.js +230 -70
  356. package/dist/moro.js.map +1 -1
  357. package/dist/types/auth.d.ts +4 -4
  358. package/dist/types/auth.js.map +1 -1
  359. package/dist/types/cache.js.map +1 -1
  360. package/dist/types/cdn.js.map +1 -1
  361. package/dist/types/config.d.ts +100 -15
  362. package/dist/types/config.js.map +1 -1
  363. package/dist/types/core.js.map +1 -1
  364. package/dist/types/database.js.map +1 -1
  365. package/dist/types/discovery.js.map +1 -1
  366. package/dist/types/events.js.map +1 -1
  367. package/dist/types/hooks.js.map +1 -1
  368. package/dist/types/http.js.map +1 -1
  369. package/dist/types/logger.js.map +1 -1
  370. package/dist/types/module.js.map +1 -1
  371. package/dist/types/runtime.js.map +1 -1
  372. package/dist/types/session.js.map +1 -1
  373. package/package.json +32 -17
@@ -0,0 +1,69 @@
1
+ // Minimal Node-compatible event emitter with lazy listener storage: nothing
2
+ // allocates until the first listener is added, so request/response objects on
3
+ // the plain JSON fast path pay a single null field for the capability.
4
+ // Backs req.on('close') (SSE/monitor cleanup) and the response lifecycle
5
+ // events ('finish'/'close'/'drain') that stream-oriented middleware needs.
6
+ //
7
+ // Shared, transport-neutral: used by both the uWS adapter (uws-http-server.ts)
8
+ // and the Moro engine adapter (moro-engine-server.ts).
9
+ export class LazyEventEmitter {
10
+ _events = null;
11
+ on(event, listener) {
12
+ const events = (this._events ??= {});
13
+ (events[event] ??= []).push(listener);
14
+ return this;
15
+ }
16
+ addListener(event, listener) {
17
+ return this.on(event, listener);
18
+ }
19
+ once(event, listener) {
20
+ const wrapper = (...args) => {
21
+ this.removeListener(event, wrapper);
22
+ listener(...args);
23
+ };
24
+ wrapper._original = listener;
25
+ return this.on(event, wrapper);
26
+ }
27
+ emit(event, ...args) {
28
+ const listeners = this._events?.[event];
29
+ if (!listeners || listeners.length === 0) {
30
+ // Node EventEmitter contract: an unhandled 'error' event throws instead
31
+ // of vanishing - code relying on that backstop must not silently no-op.
32
+ if (event === 'error') {
33
+ throw args[0] instanceof Error
34
+ ? args[0]
35
+ : new Error(`Unhandled 'error' event: ${String(args[0])}`);
36
+ }
37
+ return false;
38
+ }
39
+ // Copy so listeners removing themselves (once) don't skip siblings
40
+ for (const listener of listeners.slice())
41
+ listener(...args);
42
+ return true;
43
+ }
44
+ removeListener(event, listener) {
45
+ const listeners = this._events?.[event];
46
+ if (listeners) {
47
+ const index = listeners.findIndex(l => l === listener || l._original === listener);
48
+ if (index !== -1)
49
+ listeners.splice(index, 1);
50
+ }
51
+ return this;
52
+ }
53
+ off(event, listener) {
54
+ return this.removeListener(event, listener);
55
+ }
56
+ removeAllListeners(event) {
57
+ if (this._events) {
58
+ if (event)
59
+ delete this._events[event];
60
+ else
61
+ this._events = null;
62
+ }
63
+ return this;
64
+ }
65
+ listenerCount(event) {
66
+ return this._events?.[event]?.length ?? 0;
67
+ }
68
+ }
69
+ //# sourceMappingURL=lazy-event-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-event-emitter.js","sourceRoot":"","sources":["../../../../src/core/http/utils/lazy-event-emitter.ts"],"names":[],"mappings":"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","sourcesContent":["// Minimal Node-compatible event emitter with lazy listener storage: nothing\n// allocates until the first listener is added, so request/response objects on\n// the plain JSON fast path pay a single null field for the capability.\n// Backs req.on('close') (SSE/monitor cleanup) and the response lifecycle\n// events ('finish'/'close'/'drain') that stream-oriented middleware needs.\n//\n// Shared, transport-neutral: used by both the uWS adapter (uws-http-server.ts)\n// and the Moro engine adapter (moro-engine-server.ts).\nexport class LazyEventEmitter {\n _events: Record<string, Array<(...args: any[]) => void>> | null = null;\n\n on(event: string, listener: (...args: any[]) => void): this {\n const events = (this._events ??= {});\n (events[event] ??= []).push(listener);\n return this;\n }\n\n addListener(event: string, listener: (...args: any[]) => void): this {\n return this.on(event, listener);\n }\n\n once(event: string, listener: (...args: any[]) => void): this {\n const wrapper = (...args: any[]) => {\n this.removeListener(event, wrapper);\n listener(...args);\n };\n (wrapper as any)._original = listener;\n return this.on(event, wrapper);\n }\n\n emit(event: string, ...args: any[]): boolean {\n const listeners = this._events?.[event];\n if (!listeners || listeners.length === 0) {\n // Node EventEmitter contract: an unhandled 'error' event throws instead\n // of vanishing - code relying on that backstop must not silently no-op.\n if (event === 'error') {\n throw args[0] instanceof Error\n ? args[0]\n : new Error(`Unhandled 'error' event: ${String(args[0])}`);\n }\n return false;\n }\n // Copy so listeners removing themselves (once) don't skip siblings\n for (const listener of listeners.slice()) listener(...args);\n return true;\n }\n\n removeListener(event: string, listener: (...args: any[]) => void): this {\n const listeners = this._events?.[event];\n if (listeners) {\n const index = listeners.findIndex(l => l === listener || (l as any)._original === listener);\n if (index !== -1) listeners.splice(index, 1);\n }\n return this;\n }\n\n off(event: string, listener: (...args: any[]) => void): this {\n return this.removeListener(event, listener);\n }\n\n removeAllListeners(event?: string): this {\n if (this._events) {\n if (event) delete this._events[event];\n else this._events = null;\n }\n return this;\n }\n\n listenerCount(event: string): number {\n return this._events?.[event]?.length ?? 0;\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ export interface ParsedMultipart {
2
+ fields: Record<string, string>;
3
+ files: Record<string, {
4
+ filename: string;
5
+ mimetype: string;
6
+ data: Buffer;
7
+ size: number;
8
+ }>;
9
+ }
10
+ export interface MultipartLimits {
11
+ /** Maximum number of parts (fields + files) before parsing aborts */
12
+ maxParts?: number;
13
+ /** Maximum size of one part's header block in bytes */
14
+ maxPartHeaderBytes?: number;
15
+ /** Maximum number of file parts before parsing aborts (0/undefined = no limit) */
16
+ maxFiles?: number;
17
+ /** Maximum size in bytes of a single file part (0/undefined = no limit) */
18
+ maxFileSize?: number;
19
+ }
20
+ /** Error thrown when a multipart limit is exceeded; carries a 413 statusCode
21
+ * so every server's existing entity-too-large handling picks it up. */
22
+ export declare class MultipartLimitError extends Error {
23
+ statusCode: number;
24
+ constructor(message: string);
25
+ }
26
+ /**
27
+ * Parse a buffered multipart/form-data payload into fields and files.
28
+ * Duplicate part names are last-wins (matching URLSearchParams-style access).
29
+ * @throws Error when the content type carries no boundary or the part count
30
+ * exceeds the limit
31
+ */
32
+ export declare function parseMultipart(buffer: Buffer, contentType: string, limits?: MultipartLimits): ParsedMultipart;
@@ -0,0 +1,215 @@
1
+ // Shared multipart/form-data parser used by both the Node http server and the
2
+ // native engine server, so uploads behave identically on either transport.
3
+ // Operates on Buffers throughout - converting the payload to a string would
4
+ // corrupt binary file content.
5
+ //
6
+ // RFC 7578 (multipart/form-data) over RFC 2046 §5.1.1 framing:
7
+ // - boundary parameter may be quoted and may be followed by other
8
+ // Content-Type parameters
9
+ // - parts are delimited by CRLF "--" boundary; the first delimiter may
10
+ // appear without the leading CRLF (no preamble)
11
+ // - Content-Disposition parameters are parsed with real quoted-string
12
+ // handling (a `filename` containing `name=` must not corrupt the field
13
+ // name) and RFC 5987 `filename*` extended values are honored
14
+ // - part/header counts are capped so a crafted body cannot amplify one
15
+ // bounded upload into millions of allocations
16
+ const DEFAULT_MAX_PARTS = 1000;
17
+ const DEFAULT_MAX_PART_HEADER_BYTES = 16 * 1024;
18
+ /** Error thrown when a multipart limit is exceeded; carries a 413 statusCode
19
+ * so every server's existing entity-too-large handling picks it up. */
20
+ export class MultipartLimitError extends Error {
21
+ statusCode = 413;
22
+ constructor(message) {
23
+ super(message);
24
+ this.name = 'MultipartLimitError';
25
+ }
26
+ }
27
+ const HEADER_SEPARATOR = Buffer.from('\r\n\r\n');
28
+ const CRLF_BUF = Buffer.from('\r\n');
29
+ /**
30
+ * Extract the boundary parameter from a Content-Type value, honoring quoted
31
+ * boundaries and ignoring any parameters that follow it.
32
+ */
33
+ function extractBoundary(contentType) {
34
+ const match = /;\s*boundary\s*=\s*(?:"([^"]*)"|([^;]+))/i.exec(contentType);
35
+ if (!match)
36
+ return null;
37
+ const raw = (match[1] ?? match[2] ?? '').trim();
38
+ return raw || null;
39
+ }
40
+ /**
41
+ * Parse the parameters of a Content-Disposition value with quoted-string and
42
+ * quoted-pair handling. Returns a Map (not a plain object) so parameter names
43
+ * like __proto__ cannot interfere with lookups. First occurrence wins.
44
+ */
45
+ function parseDispositionParams(value) {
46
+ const params = new Map();
47
+ let i = value.indexOf(';');
48
+ while (i !== -1 && i < value.length) {
49
+ i++; // past ';'
50
+ while (i < value.length && (value[i] === ' ' || value[i] === '\t'))
51
+ i++;
52
+ const eq = value.indexOf('=', i);
53
+ if (eq === -1)
54
+ break;
55
+ const key = value.slice(i, eq).trim().toLowerCase();
56
+ let val;
57
+ let j = eq + 1;
58
+ while (j < value.length && (value[j] === ' ' || value[j] === '\t'))
59
+ j++;
60
+ if (value[j] === '"') {
61
+ j++;
62
+ const start = j;
63
+ while (j < value.length && value[j] !== '"') {
64
+ if (value[j] === '\\' && j + 1 < value.length)
65
+ j++; // quoted-pair
66
+ j++;
67
+ }
68
+ val = value.slice(start, j).replace(/\\(.)/g, '$1');
69
+ i = value.indexOf(';', j + 1);
70
+ }
71
+ else {
72
+ const end = value.indexOf(';', j);
73
+ val = (end === -1 ? value.slice(j) : value.slice(j, end)).trim();
74
+ i = end;
75
+ }
76
+ if (key && !params.has(key))
77
+ params.set(key, val);
78
+ }
79
+ return params;
80
+ }
81
+ /** Decode an RFC 5987 extended value (charset'lang'percent-encoded). */
82
+ function decodeExtendedValue(value) {
83
+ const match = /^(utf-8|iso-8859-1)'[^']*'(.+)$/i.exec(value);
84
+ if (!match)
85
+ return null;
86
+ const charset = match[1];
87
+ const encoded = match[2];
88
+ if (charset === undefined || encoded === undefined)
89
+ return null;
90
+ try {
91
+ if (charset.toLowerCase() === 'utf-8') {
92
+ return decodeURIComponent(encoded);
93
+ }
94
+ return encoded.replace(/%([0-9a-fA-F]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ /**
101
+ * Parse a buffered multipart/form-data payload into fields and files.
102
+ * Duplicate part names are last-wins (matching URLSearchParams-style access).
103
+ * @throws Error when the content type carries no boundary or the part count
104
+ * exceeds the limit
105
+ */
106
+ export function parseMultipart(buffer, contentType, limits) {
107
+ const boundary = extractBoundary(contentType);
108
+ if (!boundary) {
109
+ throw new Error('Invalid multipart boundary');
110
+ }
111
+ const maxParts = limits?.maxParts ?? DEFAULT_MAX_PARTS;
112
+ const maxHeaderBytes = limits?.maxPartHeaderBytes ?? DEFAULT_MAX_PART_HEADER_BYTES;
113
+ const maxFiles = limits?.maxFiles ?? 0; // 0 = no limit
114
+ const maxFileSize = limits?.maxFileSize ?? 0; // 0 = no limit
115
+ const fileCount = { n: 0 };
116
+ // Null-prototype objects: a part named "__proto__" is stored as a plain own
117
+ // key instead of silently vanishing into the prototype setter.
118
+ const fields = Object.create(null);
119
+ const files = Object.create(null);
120
+ const dashBoundary = Buffer.from(`--${boundary}`);
121
+ const delimiter = Buffer.from(`\r\n--${boundary}`);
122
+ // Locate the first delimiter: at the very start it appears without the
123
+ // leading CRLF; otherwise a preamble precedes it (RFC 2046 §5.1.1).
124
+ let pos;
125
+ if (buffer.subarray(0, dashBoundary.length).equals(dashBoundary)) {
126
+ pos = dashBoundary.length;
127
+ }
128
+ else {
129
+ const first = buffer.indexOf(delimiter);
130
+ if (first === -1)
131
+ return { fields, files };
132
+ pos = first + delimiter.length;
133
+ }
134
+ let partCount = 0;
135
+ for (;;) {
136
+ // After the boundary token: "--" marks the closing delimiter; otherwise
137
+ // optional padding then CRLF starts the part.
138
+ if (buffer[pos] === 0x2d && buffer[pos + 1] === 0x2d)
139
+ break;
140
+ const lineEnd = buffer.indexOf(CRLF_BUF, pos);
141
+ if (lineEnd === -1)
142
+ break;
143
+ const partStart = lineEnd + 2;
144
+ const next = buffer.indexOf(delimiter, partStart);
145
+ const partEnd = next === -1 ? buffer.length : next;
146
+ if (++partCount > maxParts) {
147
+ throw new MultipartLimitError(`Multipart payload exceeds ${maxParts} parts`);
148
+ }
149
+ // The delimiter includes the part's trailing CRLF, so the slice is the
150
+ // exact content - no trailing-byte trimming needed.
151
+ parsePart(buffer.subarray(partStart, partEnd), fields, files, maxHeaderBytes, {
152
+ maxFiles,
153
+ maxFileSize,
154
+ fileCount,
155
+ });
156
+ if (next === -1)
157
+ break;
158
+ pos = next + delimiter.length;
159
+ }
160
+ return { fields, files };
161
+ }
162
+ function parsePart(part, fields, files, maxHeaderBytes, fileLimits) {
163
+ const headerEndPos = part.indexOf(HEADER_SEPARATOR);
164
+ if (headerEndPos === -1 || headerEndPos > maxHeaderBytes)
165
+ return;
166
+ // Headers are always text - safe to convert to string
167
+ const headerText = part.subarray(0, headerEndPos).toString('utf8');
168
+ // Content stays as Buffer to preserve binary data
169
+ const content = part.subarray(headerEndPos + HEADER_SEPARATOR.length);
170
+ let disposition;
171
+ let partContentType;
172
+ for (const line of headerText.split('\r\n')) {
173
+ const colon = line.indexOf(':');
174
+ if (colon === -1)
175
+ continue;
176
+ const headerName = line.slice(0, colon).trim().toLowerCase();
177
+ if (headerName === 'content-disposition') {
178
+ disposition = line.slice(colon + 1).trim();
179
+ }
180
+ else if (headerName === 'content-type') {
181
+ partContentType = line.slice(colon + 1).trim();
182
+ }
183
+ }
184
+ if (!disposition)
185
+ return;
186
+ const params = parseDispositionParams(disposition);
187
+ const name = params.get('name');
188
+ // A part without a name cannot be keyed - never fall back to the
189
+ // (attacker-controlled) filename as the key.
190
+ if (!name)
191
+ return;
192
+ // filename* (RFC 5987) takes precedence over filename (RFC 6266 §4.3)
193
+ const extendedFilename = params.has('filename*')
194
+ ? decodeExtendedValue(params.get('filename*'))
195
+ : null;
196
+ const filename = extendedFilename ?? params.get('filename');
197
+ if (filename !== undefined && filename !== null) {
198
+ if (fileLimits.maxFileSize && content.length > fileLimits.maxFileSize) {
199
+ throw new MultipartLimitError(`Uploaded file '${filename}' exceeds ${fileLimits.maxFileSize} bytes`);
200
+ }
201
+ if (fileLimits.maxFiles && ++fileLimits.fileCount.n > fileLimits.maxFiles) {
202
+ throw new MultipartLimitError(`Multipart payload exceeds ${fileLimits.maxFiles} files`);
203
+ }
204
+ files[name] = {
205
+ filename,
206
+ mimetype: partContentType || 'application/octet-stream',
207
+ data: content,
208
+ size: content.length,
209
+ };
210
+ }
211
+ else {
212
+ fields[name] = content.toString('utf8');
213
+ }
214
+ }
215
+ //# sourceMappingURL=multipart-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-parser.js","sourceRoot":"","sources":["../../../../src/core/http/utils/multipart-parser.ts"],"names":[],"mappings":"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","sourcesContent":["// Shared multipart/form-data parser used by both the Node http server and the\n// native engine server, so uploads behave identically on either transport.\n// Operates on Buffers throughout - converting the payload to a string would\n// corrupt binary file content.\n//\n// RFC 7578 (multipart/form-data) over RFC 2046 §5.1.1 framing:\n// - boundary parameter may be quoted and may be followed by other\n// Content-Type parameters\n// - parts are delimited by CRLF \"--\" boundary; the first delimiter may\n// appear without the leading CRLF (no preamble)\n// - Content-Disposition parameters are parsed with real quoted-string\n// handling (a `filename` containing `name=` must not corrupt the field\n// name) and RFC 5987 `filename*` extended values are honored\n// - part/header counts are capped so a crafted body cannot amplify one\n// bounded upload into millions of allocations\n\nexport interface ParsedMultipart {\n fields: Record<string, string>;\n files: Record<\n string,\n {\n filename: string;\n mimetype: string;\n data: Buffer;\n size: number;\n }\n >;\n}\n\nexport interface MultipartLimits {\n /** Maximum number of parts (fields + files) before parsing aborts */\n maxParts?: number;\n /** Maximum size of one part's header block in bytes */\n maxPartHeaderBytes?: number;\n /** Maximum number of file parts before parsing aborts (0/undefined = no limit) */\n maxFiles?: number;\n /** Maximum size in bytes of a single file part (0/undefined = no limit) */\n maxFileSize?: number;\n}\n\nconst DEFAULT_MAX_PARTS = 1000;\nconst DEFAULT_MAX_PART_HEADER_BYTES = 16 * 1024;\n\n/** Error thrown when a multipart limit is exceeded; carries a 413 statusCode\n * so every server's existing entity-too-large handling picks it up. */\nexport class MultipartLimitError extends Error {\n statusCode = 413;\n constructor(message: string) {\n super(message);\n this.name = 'MultipartLimitError';\n }\n}\n\nconst HEADER_SEPARATOR = Buffer.from('\\r\\n\\r\\n');\nconst CRLF_BUF = Buffer.from('\\r\\n');\n\n/**\n * Extract the boundary parameter from a Content-Type value, honoring quoted\n * boundaries and ignoring any parameters that follow it.\n */\nfunction extractBoundary(contentType: string): string | null {\n const match = /;\\s*boundary\\s*=\\s*(?:\"([^\"]*)\"|([^;]+))/i.exec(contentType);\n if (!match) return null;\n const raw = (match[1] ?? match[2] ?? '').trim();\n return raw || null;\n}\n\n/**\n * Parse the parameters of a Content-Disposition value with quoted-string and\n * quoted-pair handling. Returns a Map (not a plain object) so parameter names\n * like __proto__ cannot interfere with lookups. First occurrence wins.\n */\nfunction parseDispositionParams(value: string): Map<string, string> {\n const params = new Map<string, string>();\n let i = value.indexOf(';');\n while (i !== -1 && i < value.length) {\n i++; // past ';'\n while (i < value.length && (value[i] === ' ' || value[i] === '\\t')) i++;\n const eq = value.indexOf('=', i);\n if (eq === -1) break;\n const key = value.slice(i, eq).trim().toLowerCase();\n let val: string;\n let j = eq + 1;\n while (j < value.length && (value[j] === ' ' || value[j] === '\\t')) j++;\n if (value[j] === '\"') {\n j++;\n const start = j;\n while (j < value.length && value[j] !== '\"') {\n if (value[j] === '\\\\' && j + 1 < value.length) j++; // quoted-pair\n j++;\n }\n val = value.slice(start, j).replace(/\\\\(.)/g, '$1');\n i = value.indexOf(';', j + 1);\n } else {\n const end = value.indexOf(';', j);\n val = (end === -1 ? value.slice(j) : value.slice(j, end)).trim();\n i = end;\n }\n if (key && !params.has(key)) params.set(key, val);\n }\n return params;\n}\n\n/** Decode an RFC 5987 extended value (charset'lang'percent-encoded). */\nfunction decodeExtendedValue(value: string): string | null {\n const match = /^(utf-8|iso-8859-1)'[^']*'(.+)$/i.exec(value);\n if (!match) return null;\n const charset = match[1];\n const encoded = match[2];\n if (charset === undefined || encoded === undefined) return null;\n try {\n if (charset.toLowerCase() === 'utf-8') {\n return decodeURIComponent(encoded);\n }\n return encoded.replace(/%([0-9a-fA-F]{2})/g, (_, hex: string) =>\n String.fromCharCode(parseInt(hex, 16))\n );\n } catch {\n return null;\n }\n}\n\n/**\n * Parse a buffered multipart/form-data payload into fields and files.\n * Duplicate part names are last-wins (matching URLSearchParams-style access).\n * @throws Error when the content type carries no boundary or the part count\n * exceeds the limit\n */\nexport function parseMultipart(\n buffer: Buffer,\n contentType: string,\n limits?: MultipartLimits\n): ParsedMultipart {\n const boundary = extractBoundary(contentType);\n if (!boundary) {\n throw new Error('Invalid multipart boundary');\n }\n const maxParts = limits?.maxParts ?? DEFAULT_MAX_PARTS;\n const maxHeaderBytes = limits?.maxPartHeaderBytes ?? DEFAULT_MAX_PART_HEADER_BYTES;\n const maxFiles = limits?.maxFiles ?? 0; // 0 = no limit\n const maxFileSize = limits?.maxFileSize ?? 0; // 0 = no limit\n const fileCount = { n: 0 };\n\n // Null-prototype objects: a part named \"__proto__\" is stored as a plain own\n // key instead of silently vanishing into the prototype setter.\n const fields: ParsedMultipart['fields'] = Object.create(null);\n const files: ParsedMultipart['files'] = Object.create(null);\n\n const dashBoundary = Buffer.from(`--${boundary}`);\n const delimiter = Buffer.from(`\\r\\n--${boundary}`);\n\n // Locate the first delimiter: at the very start it appears without the\n // leading CRLF; otherwise a preamble precedes it (RFC 2046 §5.1.1).\n let pos: number;\n if (buffer.subarray(0, dashBoundary.length).equals(dashBoundary)) {\n pos = dashBoundary.length;\n } else {\n const first = buffer.indexOf(delimiter);\n if (first === -1) return { fields, files };\n pos = first + delimiter.length;\n }\n\n let partCount = 0;\n for (;;) {\n // After the boundary token: \"--\" marks the closing delimiter; otherwise\n // optional padding then CRLF starts the part.\n if (buffer[pos] === 0x2d && buffer[pos + 1] === 0x2d) break;\n const lineEnd = buffer.indexOf(CRLF_BUF, pos);\n if (lineEnd === -1) break;\n const partStart = lineEnd + 2;\n const next = buffer.indexOf(delimiter, partStart);\n const partEnd = next === -1 ? buffer.length : next;\n\n if (++partCount > maxParts) {\n throw new MultipartLimitError(`Multipart payload exceeds ${maxParts} parts`);\n }\n // The delimiter includes the part's trailing CRLF, so the slice is the\n // exact content - no trailing-byte trimming needed.\n parsePart(buffer.subarray(partStart, partEnd), fields, files, maxHeaderBytes, {\n maxFiles,\n maxFileSize,\n fileCount,\n });\n\n if (next === -1) break;\n pos = next + delimiter.length;\n }\n\n return { fields, files };\n}\n\nfunction parsePart(\n part: Buffer,\n fields: ParsedMultipart['fields'],\n files: ParsedMultipart['files'],\n maxHeaderBytes: number,\n fileLimits: { maxFiles: number; maxFileSize: number; fileCount: { n: number } }\n): void {\n const headerEndPos = part.indexOf(HEADER_SEPARATOR);\n if (headerEndPos === -1 || headerEndPos > maxHeaderBytes) return;\n\n // Headers are always text - safe to convert to string\n const headerText = part.subarray(0, headerEndPos).toString('utf8');\n // Content stays as Buffer to preserve binary data\n const content = part.subarray(headerEndPos + HEADER_SEPARATOR.length);\n\n let disposition: string | undefined;\n let partContentType: string | undefined;\n for (const line of headerText.split('\\r\\n')) {\n const colon = line.indexOf(':');\n if (colon === -1) continue;\n const headerName = line.slice(0, colon).trim().toLowerCase();\n if (headerName === 'content-disposition') {\n disposition = line.slice(colon + 1).trim();\n } else if (headerName === 'content-type') {\n partContentType = line.slice(colon + 1).trim();\n }\n }\n if (!disposition) return;\n\n const params = parseDispositionParams(disposition);\n const name = params.get('name');\n // A part without a name cannot be keyed - never fall back to the\n // (attacker-controlled) filename as the key.\n if (!name) return;\n\n // filename* (RFC 5987) takes precedence over filename (RFC 6266 §4.3)\n const extendedFilename = params.has('filename*')\n ? decodeExtendedValue(params.get('filename*') as string)\n : null;\n const filename = extendedFilename ?? params.get('filename');\n\n if (filename !== undefined && filename !== null) {\n if (fileLimits.maxFileSize && content.length > fileLimits.maxFileSize) {\n throw new MultipartLimitError(\n `Uploaded file '${filename}' exceeds ${fileLimits.maxFileSize} bytes`\n );\n }\n if (fileLimits.maxFiles && ++fileLimits.fileCount.n > fileLimits.maxFiles) {\n throw new MultipartLimitError(`Multipart payload exceeds ${fileLimits.maxFiles} files`);\n }\n files[name] = {\n filename,\n mimetype: partContentType || 'application/octet-stream',\n data: content,\n size: content.length,\n };\n } else {\n fields[name] = content.toString('utf8');\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function parseRawQueryString(queryString: string): Record<string, string>;
@@ -0,0 +1,44 @@
1
+ // Parse a raw query string ("a=1&b=2") into an object. Transport-neutral: the
2
+ // single canonical implementation for the Node http server, the uWS adapter,
3
+ // and the Moro engine adapter, so req.query is identical on every transport.
4
+ //
5
+ // Semantics follow application/x-www-form-urlencoded (WHATWG):
6
+ // - '+' decodes to a space in keys and values
7
+ // - malformed percent-escapes never throw (the raw text is kept)
8
+ // - a key without '=' yields '' ("?flag" -> { flag: '' })
9
+ // - duplicate keys are last-wins
10
+ // The result has a null prototype (like node:querystring), so a key named
11
+ // "__proto__" is stored as an own property instead of vanishing.
12
+ function decodeComponent(component) {
13
+ const plusDecoded = component.indexOf('+') === -1 ? component : component.replace(/\+/g, ' ');
14
+ if (plusDecoded.indexOf('%') === -1)
15
+ return plusDecoded;
16
+ try {
17
+ return decodeURIComponent(plusDecoded);
18
+ }
19
+ catch {
20
+ return plusDecoded;
21
+ }
22
+ }
23
+ export function parseRawQueryString(queryString) {
24
+ const result = Object.create(null);
25
+ if (!queryString)
26
+ return result;
27
+ if (queryString[0] === '?')
28
+ queryString = queryString.substring(1);
29
+ const pairs = queryString.split('&');
30
+ for (let i = 0; i < pairs.length; i++) {
31
+ const pair = pairs[i];
32
+ if (!pair)
33
+ continue;
34
+ const eqIdx = pair.indexOf('=');
35
+ if (eqIdx === -1) {
36
+ result[decodeComponent(pair)] = '';
37
+ }
38
+ else {
39
+ result[decodeComponent(pair.substring(0, eqIdx))] = decodeComponent(pair.substring(eqIdx + 1));
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+ //# sourceMappingURL=query-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-parser.js","sourceRoot":"","sources":["../../../../src/core/http/utils/query-parser.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,EAAE;AACF,+DAA+D;AAC/D,gDAAgD;AAChD,mEAAmE;AACnE,4DAA4D;AAC5D,mCAAmC;AACnC,0EAA0E;AAC1E,iEAAiE;AAEjE,SAAS,eAAe,CAAC,SAAiB;IACxC,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9F,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,WAAW,CAAC;IACxD,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,MAAM,MAAM,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,eAAe,CACjE,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// Parse a raw query string (\"a=1&b=2\") into an object. Transport-neutral: the\n// single canonical implementation for the Node http server, the uWS adapter,\n// and the Moro engine adapter, so req.query is identical on every transport.\n//\n// Semantics follow application/x-www-form-urlencoded (WHATWG):\n// - '+' decodes to a space in keys and values\n// - malformed percent-escapes never throw (the raw text is kept)\n// - a key without '=' yields '' (\"?flag\" -> { flag: '' })\n// - duplicate keys are last-wins\n// The result has a null prototype (like node:querystring), so a key named\n// \"__proto__\" is stored as an own property instead of vanishing.\n\nfunction decodeComponent(component: string): string {\n const plusDecoded = component.indexOf('+') === -1 ? component : component.replace(/\\+/g, ' ');\n if (plusDecoded.indexOf('%') === -1) return plusDecoded;\n try {\n return decodeURIComponent(plusDecoded);\n } catch {\n return plusDecoded;\n }\n}\n\nexport function parseRawQueryString(queryString: string): Record<string, string> {\n const result: Record<string, string> = Object.create(null);\n if (!queryString) return result;\n if (queryString[0] === '?') queryString = queryString.substring(1);\n const pairs = queryString.split('&');\n for (let i = 0; i < pairs.length; i++) {\n const pair = pairs[i];\n if (!pair) continue;\n const eqIdx = pair.indexOf('=');\n if (eqIdx === -1) {\n result[decodeComponent(pair)] = '';\n } else {\n result[decodeComponent(pair.substring(0, eqIdx))] = decodeComponent(\n pair.substring(eqIdx + 1)\n );\n }\n }\n return result;\n}\n"]}
@@ -0,0 +1,33 @@
1
+ export declare function parseSizeToBytes(size: string | number, fallback?: number): number;
2
+ /**
3
+ * Flattened, size-resolved runtime limits passed from the framework to every
4
+ * HTTP server. undefined = use that server's own documented default. Mirrors
5
+ * the RuntimeLimits built in framework.ts (kept here so the servers can import
6
+ * it without depending on framework.ts).
7
+ */
8
+ export interface HttpRuntimeLimits {
9
+ maxBodySize?: number;
10
+ maxUploadSize?: number;
11
+ maxConnections?: number;
12
+ backlog?: number;
13
+ timeouts?: {
14
+ request?: number;
15
+ idle?: number;
16
+ keepAlive?: number;
17
+ headers?: number;
18
+ };
19
+ maxHeaderSize?: number;
20
+ maxHeaders?: number;
21
+ wsMaxMessageSize?: number;
22
+ wsBackpressureLimit?: number;
23
+ writeHighWaterMark?: number;
24
+ maxPendingBytes?: number;
25
+ multipart?: {
26
+ maxParts?: number;
27
+ maxPartHeaderBytes?: number;
28
+ maxFiles?: number;
29
+ maxFileSize?: number;
30
+ };
31
+ }
32
+ /** True when `size` is a number, or a string parseable by parseSizeToBytes. */
33
+ export declare function isValidSize(size: unknown): boolean;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Parse a human size string ("10mb", "5gb", "16kb") or a raw number of bytes
3
+ * into bytes. Shared by config validation, the runtime-limits builder, and
4
+ * every HTTP server so `bodySizeLimit: '10mb'` means the same thing
5
+ * everywhere.
6
+ *
7
+ * A number passes through unchanged. An unparseable string falls back to
8
+ * `fallback` (10 MB by default) so a typo degrades to a safe default rather
9
+ * than 0/NaN.
10
+ */
11
+ const UNITS = {
12
+ b: 1,
13
+ kb: 1024,
14
+ mb: 1024 * 1024,
15
+ gb: 1024 * 1024 * 1024,
16
+ };
17
+ export function parseSizeToBytes(size, fallback = 10 * 1024 * 1024) {
18
+ if (typeof size === 'number')
19
+ return size;
20
+ if (typeof size !== 'string')
21
+ return fallback;
22
+ const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);
23
+ if (!match)
24
+ return fallback;
25
+ const value = parseFloat(match[1] ?? '');
26
+ const unit = match[2] || 'b';
27
+ return Math.round(value * (UNITS[unit] ?? 1));
28
+ }
29
+ /** True when `size` is a number, or a string parseable by parseSizeToBytes. */
30
+ export function isValidSize(size) {
31
+ if (typeof size === 'number')
32
+ return Number.isFinite(size) && size >= 0;
33
+ if (typeof size !== 'string')
34
+ return false;
35
+ return /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/i.test(size.trim());
36
+ }
37
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","sourceRoot":"","sources":["../../../../src/core/http/utils/size.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,KAAK,GAA8B;IACvC,CAAC,EAAE,CAAC;IACJ,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI,GAAG,IAAI;IACf,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI;CACvB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAC9B,IAAqB,EACrB,WAAmB,EAAE,GAAG,IAAI,GAAG,IAAI;IAEnC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAE5B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAiCD,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IACxE,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3C,OAAO,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAChE,CAAC","sourcesContent":["/**\n * Parse a human size string (\"10mb\", \"5gb\", \"16kb\") or a raw number of bytes\n * into bytes. Shared by config validation, the runtime-limits builder, and\n * every HTTP server so `bodySizeLimit: '10mb'` means the same thing\n * everywhere.\n *\n * A number passes through unchanged. An unparseable string falls back to\n * `fallback` (10 MB by default) so a typo degrades to a safe default rather\n * than 0/NaN.\n */\nconst UNITS: { [key: string]: number } = {\n b: 1,\n kb: 1024,\n mb: 1024 * 1024,\n gb: 1024 * 1024 * 1024,\n};\n\nexport function parseSizeToBytes(\n size: string | number,\n fallback: number = 10 * 1024 * 1024\n): number {\n if (typeof size === 'number') return size;\n if (typeof size !== 'string') return fallback;\n\n const match = size.toLowerCase().match(/^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb)?$/);\n if (!match) return fallback;\n\n const value = parseFloat(match[1] ?? '');\n const unit = match[2] || 'b';\n return Math.round(value * (UNITS[unit] ?? 1));\n}\n\n/**\n * Flattened, size-resolved runtime limits passed from the framework to every\n * HTTP server. undefined = use that server's own documented default. Mirrors\n * the RuntimeLimits built in framework.ts (kept here so the servers can import\n * it without depending on framework.ts).\n */\nexport interface HttpRuntimeLimits {\n maxBodySize?: number;\n maxUploadSize?: number;\n maxConnections?: number;\n backlog?: number;\n timeouts?: {\n request?: number;\n idle?: number;\n keepAlive?: number;\n headers?: number;\n };\n maxHeaderSize?: number;\n maxHeaders?: number;\n wsMaxMessageSize?: number;\n wsBackpressureLimit?: number;\n writeHighWaterMark?: number;\n maxPendingBytes?: number;\n multipart?: {\n maxParts?: number;\n maxPartHeaderBytes?: number;\n maxFiles?: number;\n maxFileSize?: number;\n };\n}\n\n/** True when `size` is a number, or a string parseable by parseSizeToBytes. */\nexport function isValidSize(size: unknown): boolean {\n if (typeof size === 'number') return Number.isFinite(size) && size >= 0;\n if (typeof size !== 'string') return false;\n return /^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb)?$/i.test(size.trim());\n}\n"]}
@@ -0,0 +1,69 @@
1
+ import type { MoroLogger } from '../../logger/index.js';
2
+ /** Raw, un-normalized SSL config as a user may supply it (either shape). */
3
+ export interface SSLConfigInput {
4
+ key_file_name?: string;
5
+ cert_file_name?: string;
6
+ ca_file_name?: string | string[];
7
+ keyFile?: string;
8
+ certFile?: string;
9
+ caFile?: string | string[];
10
+ key?: string | Buffer;
11
+ cert?: string | Buffer;
12
+ ca?: string | Buffer | Array<string | Buffer>;
13
+ passphrase?: string;
14
+ minVersion?: 'TLSv1.2' | 'TLSv1.3';
15
+ requestCert?: boolean;
16
+ rejectUnauthorized?: boolean;
17
+ }
18
+ /** Canonical internal SSL config after normalization. */
19
+ export interface NormalizedSSLConfig {
20
+ keyFile?: string | undefined;
21
+ certFile?: string | undefined;
22
+ caFile?: string[] | undefined;
23
+ key?: string | Buffer | undefined;
24
+ cert?: string | Buffer | undefined;
25
+ ca?: Array<string | Buffer> | undefined;
26
+ passphrase?: string | undefined;
27
+ minVersion?: 'TLSv1.2' | 'TLSv1.3' | undefined;
28
+ requestCert?: boolean | undefined;
29
+ rejectUnauthorized?: boolean | undefined;
30
+ }
31
+ /**
32
+ * Normalize the two historical SSL shapes into one. `serverSsl`
33
+ * (config.server.ssl) wins over `optionsHttps` (options.https) when both are
34
+ * present, matching the pre-existing precedence in framework.ts. Returns null
35
+ * when neither carries any key/cert material (TLS simply off).
36
+ */
37
+ export declare function normalizeSSLConfig(serverSsl?: SSLConfigInput | null, optionsHttps?: SSLConfigInput | null, logger?: MoroLogger): NormalizedSSLConfig | null;
38
+ /** True when the config actually carries a key+cert (complete TLS material). */
39
+ export declare function sslIsComplete(ssl: NormalizedSSLConfig): boolean;
40
+ /**
41
+ * Project for the Node http/https and HTTP/2 servers: node's tls API wants
42
+ * key/cert/ca as strings or Buffers, so any file paths are read here.
43
+ */
44
+ export declare function sslForNode(ssl: NormalizedSSLConfig): {
45
+ key: string | Buffer;
46
+ cert: string | Buffer;
47
+ ca?: Array<string | Buffer>;
48
+ passphrase?: string;
49
+ minVersion?: string;
50
+ requestCert?: boolean;
51
+ rejectUnauthorized?: boolean;
52
+ };
53
+ /**
54
+ * Project for uWebSockets.js SSLApp, which requires FILE PATHS (it has no
55
+ * inline-PEM option). Returns null when only inline PEM is available so the
56
+ * caller can log a clear error instead of silently booting plain HTTP.
57
+ */
58
+ export declare function sslForUws(ssl: NormalizedSSLConfig): {
59
+ key_file_name: string;
60
+ cert_file_name: string;
61
+ ca_file_name?: string;
62
+ passphrase?: string;
63
+ } | null;
64
+ /**
65
+ * Project for the native @morojs/engine serve() options.ssl, which accepts
66
+ * BOTH shapes (file paths and inline PEM) and prefers inline. Pass everything
67
+ * through; the engine decides.
68
+ */
69
+ export declare function sslForEngine(ssl: NormalizedSSLConfig): Record<string, unknown>;