@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
@@ -1,9 +1,12 @@
1
1
  // src/core/http-server.ts
2
2
  import { IncomingMessage, ServerResponse, createServer } from 'http';
3
+ import { createServer as createHttpsServer } from 'https';
3
4
  import * as zlib from 'zlib';
4
5
  import { promisify } from 'util';
5
6
  import { randomUUID } from 'crypto';
6
7
  import { createFrameworkLogger } from '../logger/index.js';
8
+ import { parseMultipart as parseMultipartBuffer, } from './utils/multipart-parser.js';
9
+ import { parseRawQueryString } from './utils/query-parser.js';
7
10
  import { PathMatcher } from '../routing/path-matcher.js';
8
11
  import { ObjectPoolManager } from '../pooling/object-pool-manager.js';
9
12
  const gzip = promisify(zlib.gzip);
@@ -39,26 +42,9 @@ const TYPE_SHORTHANDS = {
39
42
  css: 'text/css; charset=utf-8',
40
43
  form: 'application/x-www-form-urlencoded',
41
44
  };
42
- function parseQueryString(queryString) {
43
- const result = {};
44
- if (!queryString)
45
- return result;
46
- const pairs = queryString.split('&');
47
- const pairsLen = pairs.length;
48
- for (let i = 0; i < pairsLen; i++) {
49
- const pair = pairs[i];
50
- const equalIndex = pair.indexOf('=');
51
- if (equalIndex === -1) {
52
- result[decodeURIComponent(pair)] = '';
53
- }
54
- else {
55
- const key = decodeURIComponent(pair.substring(0, equalIndex));
56
- const value = decodeURIComponent(pair.substring(equalIndex + 1));
57
- result[key] = value;
58
- }
59
- }
60
- return result;
61
- }
45
+ // Canonical query parsing shared with the uWS/engine transports - identical
46
+ // req.query semantics everywhere ('+' as space, malformed escapes tolerated).
47
+ const parseQueryString = parseRawQueryString;
62
48
  function parseCookieHeader(cookieHeader) {
63
49
  const cookies = {};
64
50
  if (!cookieHeader)
@@ -67,6 +53,8 @@ function parseCookieHeader(cookieHeader) {
67
53
  const cookiePartsLen = cookieParts.length;
68
54
  for (let i = 0; i < cookiePartsLen; i++) {
69
55
  const cookie = cookieParts[i];
56
+ if (cookie === undefined)
57
+ continue;
70
58
  const equalIndex = cookie.indexOf('=');
71
59
  if (equalIndex > 0) {
72
60
  const name = cookie.substring(0, equalIndex).trim();
@@ -197,7 +185,7 @@ export class MoroIncomingMessage extends IncomingMessage {
197
185
  if (v === undefined) {
198
186
  const forwardedProto = this.headers['x-forwarded-proto'];
199
187
  v = forwardedProto
200
- ? forwardedProto.split(',')[0].trim()
188
+ ? (forwardedProto.split(',')[0] ?? '').trim()
201
189
  : this.socket?.encrypted
202
190
  ? 'https'
203
191
  : 'http';
@@ -277,7 +265,7 @@ export class MoroIncomingMessage extends IncomingMessage {
277
265
  const ct = (this.headers['content-type'] || '');
278
266
  if (!ct)
279
267
  return false;
280
- const mime = ct.split(';')[0].trim().toLowerCase();
268
+ const mime = (ct.split(';')[0] ?? '').trim().toLowerCase();
281
269
  const t = type.toLowerCase();
282
270
  if (t.indexOf('/') === -1) {
283
271
  // e.g. 'json' → match */json or +json suffix
@@ -295,7 +283,7 @@ export class MoroIncomingMessage extends IncomingMessage {
295
283
  const wanted = Array.isArray(types) ? types : [types];
296
284
  if (accept === '*/*' || accept === '')
297
285
  return wanted[0] || false;
298
- const acceptTypes = accept.split(',').map(s => s.split(';')[0].trim().toLowerCase());
286
+ const acceptTypes = accept.split(',').map(s => (s.split(';')[0] ?? '').trim().toLowerCase());
299
287
  for (const w of wanted) {
300
288
  const wl = w.toLowerCase();
301
289
  const wMime = wl.indexOf('/') === -1 ? `application/${wl}` : wl;
@@ -322,7 +310,7 @@ export class MoroIncomingMessage extends IncomingMessage {
322
310
  .split(',')
323
311
  .map(s => {
324
312
  const parts = s.trim().split(';');
325
- const tag = parts[0].toLowerCase();
313
+ const tag = (parts[0] ?? '').toLowerCase();
326
314
  const qPart = parts.find(p => p.trim().startsWith('q='));
327
315
  const q = qPart ? parseFloat(qPart.trim().slice(2)) : 1;
328
316
  return { tag, q: isNaN(q) ? 0 : q };
@@ -485,7 +473,8 @@ export class MoroServerResponse extends ServerResponse {
485
473
  }
486
474
  const cookieValue = encodeURIComponent(value);
487
475
  let cookieString = `${name}=${cookieValue}`;
488
- if (options.maxAge)
476
+ // maxAge: 0 is meaningful (immediate expiry - clearCookie relies on it)
477
+ if (options.maxAge !== undefined && options.maxAge !== null)
489
478
  cookieString += `; Max-Age=${options.maxAge}`;
490
479
  if (options.expires)
491
480
  cookieString += `; Expires=${options.expires.toUTCString()}`;
@@ -497,8 +486,9 @@ export class MoroServerResponse extends ServerResponse {
497
486
  cookieString += `; SameSite=${options.sameSite}`;
498
487
  if (options.domain)
499
488
  cookieString += `; Domain=${options.domain}`;
500
- if (options.path)
501
- cookieString += `; Path=${options.path}`;
489
+ // Path defaults to '/' (Express behavior) so clearCookie() from a nested
490
+ // route can clear a cookie originally set at the site root.
491
+ cookieString += `; Path=${options.path ?? '/'}`;
502
492
  const existingCookies = this.getHeader('Set-Cookie') || [];
503
493
  // Avoid spread operator - direct array manipulation
504
494
  const cookies = Array.isArray(existingCookies) ? existingCookies : [existingCookies];
@@ -708,7 +698,9 @@ export class MoroServerResponse extends ServerResponse {
708
698
  return this;
709
699
  }
710
700
  for (const key in headers) {
711
- this.setHeader(key, headers[key]);
701
+ const value = headers[key];
702
+ if (value !== undefined)
703
+ this.setHeader(key, value);
712
704
  }
713
705
  return this;
714
706
  }
@@ -804,10 +796,15 @@ export class MoroServerResponse extends ServerResponse {
804
796
  // Set Content-Type from extension if not already set
805
797
  if (!this.getHeader('Content-Type')) {
806
798
  // fire-and-forget mime lookup; not awaited to keep signature chainable
807
- this._server.getMimeType(filename.substring(filename.lastIndexOf('.'))).then(mime => {
799
+ void this._server
800
+ .getMimeType(filename.substring(filename.lastIndexOf('.')))
801
+ .then(mime => {
808
802
  if (!this.getHeader('Content-Type') && !this.headersSent) {
809
803
  this.setHeader('Content-Type', mime);
810
804
  }
805
+ })
806
+ .catch(() => {
807
+ // best-effort content-type inference
811
808
  });
812
809
  }
813
810
  }
@@ -866,6 +863,10 @@ export class MoroServerResponse extends ServerResponse {
866
863
  }
867
864
  export class MoroHttpServer {
868
865
  server;
866
+ /** Multipart limits threaded to parseMultipart at the call site. */
867
+ multipartLimits;
868
+ /** TCP backlog for listen(), when configured. */
869
+ listenBacklog;
869
870
  routes = [];
870
871
  globalMiddleware = [];
871
872
  /** @internal read by MoroServerResponse prototype methods */
@@ -923,7 +924,23 @@ export class MoroHttpServer {
923
924
  BoundResponse.prototype._server = boundServer;
924
925
  this.RequestClass = BoundRequest;
925
926
  this.ResponseClass = BoundResponse;
926
- this.server = createServer({ IncomingMessage: BoundRequest, ServerResponse: BoundResponse }, this.handleRequest.bind(this));
927
+ const limits = options?.limits;
928
+ // maxHeaderSize is a createServer option (not a mutable property), so it
929
+ // must be passed here.
930
+ const serverOpts = {
931
+ IncomingMessage: BoundRequest,
932
+ ServerResponse: BoundResponse,
933
+ ...(limits?.maxHeaderSize && { maxHeaderSize: limits.maxHeaderSize }),
934
+ };
935
+ if (options?.ssl) {
936
+ // In-process HTTPS. The https ServerOptions extends the http one, so the
937
+ // IncomingMessage/ServerResponse subclass injection carries over.
938
+ this.server = createHttpsServer({ ...serverOpts, ...options.ssl }, this.handleRequest.bind(this));
939
+ this.logger.info('HTTPS server created (in-process TLS)', 'HttpServer');
940
+ }
941
+ else {
942
+ this.server = createServer(serverOpts, this.handleRequest.bind(this));
943
+ }
927
944
  // Configure body size limits from options
928
945
  if (options?.maxBodySize) {
929
946
  this.maxBodySize = options.maxBodySize;
@@ -931,15 +948,25 @@ export class MoroHttpServer {
931
948
  if (options?.maxUploadSize) {
932
949
  this.maxUploadSize = options.maxUploadSize;
933
950
  }
934
- // Optimize server for high performance (conservative settings for compatibility)
935
- this.server.keepAliveTimeout = 5000; // 5 seconds
936
- this.server.headersTimeout = 6000; // 6 seconds
937
- // Socket inactivity timeout stays at Node's default (0 = disabled). A
938
- // non-zero value arms/refreshes a timer on every request, which shows up
939
- // in CPU profiles (setStreamTimeout + timer churn) under load; slowloris
940
- // protection is already covered by headersTimeout + keepAliveTimeout, and
941
- // this matches Node's own default connectionTimeout: 0.
942
- this.server.timeout = 0;
951
+ if (limits?.multipart)
952
+ this.multipartLimits = limits.multipart;
953
+ // Timeouts: the previous hardcodes (keepAlive 5000, headers 6000) become
954
+ // the documented defaults; a configured value overrides them. Socket idle
955
+ // timeout stays 0 (disabled) unless set - a non-zero value arms a
956
+ // per-request timer that shows up in CPU profiles under load.
957
+ const t = limits?.timeouts ?? {};
958
+ this.server.keepAliveTimeout = t.keepAlive ?? 5000;
959
+ this.server.headersTimeout = t.headers ?? 6000;
960
+ this.server.timeout = t.idle ?? 0;
961
+ if (t.request)
962
+ this.server.requestTimeout = t.request;
963
+ if (limits?.maxConnections && limits.maxConnections > 0) {
964
+ this.server.maxConnections = limits.maxConnections;
965
+ }
966
+ if (limits?.maxHeaders)
967
+ this.server.maxHeadersCount = limits.maxHeaders;
968
+ if (limits?.backlog !== undefined)
969
+ this.listenBacklog = limits.backlog;
943
970
  }
944
971
  // Direct router dispatch - called after global middleware, before the legacy
945
972
  // route table. Returning true (or a promise of true) means the request was handled.
@@ -1218,7 +1245,11 @@ export class MoroHttpServer {
1218
1245
  const paramNames = route.paramNames;
1219
1246
  const paramNamesLen = paramNames.length;
1220
1247
  for (let i = 0; i < paramNamesLen; i++) {
1221
- params[paramNames[i]] = matches[i + 1];
1248
+ const paramName = paramNames[i];
1249
+ const value = matches[i + 1];
1250
+ if (paramName !== undefined && value !== undefined) {
1251
+ params[paramName] = value;
1252
+ }
1222
1253
  }
1223
1254
  httpReq.params = params;
1224
1255
  }
@@ -1284,18 +1315,23 @@ export class MoroHttpServer {
1284
1315
  }
1285
1316
  }
1286
1317
  if (!httpRes.headersSent) {
1318
+ // A malformed body is a client error: default to 400 (parity with the
1319
+ // engine/uWS transports), not the generic 500.
1320
+ const isBadRequest = error?.statusCode === 400;
1321
+ const defaultStatus = isBadRequest ? 400 : 500;
1322
+ const defaultError = isBadRequest ? 'Invalid request body' : 'Internal server error';
1287
1323
  // Ensure response is properly enhanced before using custom methods
1288
1324
  if (typeof httpRes.status === 'function' && typeof httpRes.json === 'function') {
1289
- httpRes.status(500).json({
1325
+ httpRes.status(defaultStatus).json({
1290
1326
  success: false,
1291
- error: 'Internal server error',
1327
+ error: defaultError,
1292
1328
  requestId: httpReq.requestId,
1293
1329
  });
1294
1330
  }
1295
1331
  else {
1296
1332
  // Defensive fallback - check each method individually
1297
1333
  if (typeof httpRes.setHeader === 'function') {
1298
- httpRes.statusCode = 500;
1334
+ httpRes.statusCode = defaultStatus;
1299
1335
  httpRes.setHeader('Content-Type', 'application/json');
1300
1336
  }
1301
1337
  else {
@@ -1308,7 +1344,7 @@ export class MoroHttpServer {
1308
1344
  if (typeof httpRes.end === 'function') {
1309
1345
  httpRes.end(JSON.stringify({
1310
1346
  success: false,
1311
- error: 'Internal server error',
1347
+ error: defaultError,
1312
1348
  requestId: httpReq.requestId,
1313
1349
  }));
1314
1350
  }
@@ -1447,12 +1483,12 @@ export class MoroHttpServer {
1447
1483
  error.received = contentLength;
1448
1484
  return Promise.reject(error);
1449
1485
  }
1450
- // For very large payloads, return a streaming interface instead of buffering
1451
- if (contentLength > maxSize / 2) {
1452
- // Stream for payloads > 50MB (uploads) or > 5MB (JSON/form)
1453
- return this.createStreamingBodyParser(req, contentType, maxSize);
1454
- }
1455
- // Standard buffered parsing for smaller payloads
1486
+ // Buffer every body up to maxSize and parse it into its real shape. The
1487
+ // incremental limit check below already bounds memory, and every other
1488
+ // backend (uWS, engine) returns the parsed body here - previously bodies
1489
+ // between maxSize/2 and maxSize resolved to a { type, parser } descriptor
1490
+ // object instead, so handlers/validation on the Node backend silently saw
1491
+ // a bogus shape for the exact same request that parsed normally elsewhere.
1456
1492
  return new Promise((resolve, reject) => {
1457
1493
  const chunks = [];
1458
1494
  let totalLength = 0;
@@ -1474,9 +1510,14 @@ export class MoroHttpServer {
1474
1510
  try {
1475
1511
  // Single-chunk fast path (most JSON bodies arrive in one chunk);
1476
1512
  // otherwise concat with the known total length to avoid a re-scan
1477
- const body = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, totalLength);
1513
+ const firstChunk = chunks[0];
1514
+ const body = chunks.length === 1 && firstChunk !== undefined
1515
+ ? firstChunk
1516
+ : Buffer.concat(chunks, totalLength);
1478
1517
  if (contentType.includes('application/json')) {
1479
- resolve(JSON.parse(body.toString()));
1518
+ // Empty JSON body -> null (parity with the engine/uWS servers, and
1519
+ // avoids JSON.parse('') throwing and 500ing an empty POST).
1520
+ resolve(totalLength === 0 ? null : JSON.parse(body.toString()));
1480
1521
  }
1481
1522
  else if (contentType.includes('application/x-www-form-urlencoded')) {
1482
1523
  resolve(this.parseUrlEncoded(body.toString()));
@@ -1489,132 +1530,12 @@ export class MoroHttpServer {
1489
1530
  }
1490
1531
  }
1491
1532
  catch (error) {
1492
- reject(error);
1493
- }
1494
- });
1495
- req.on('error', reject);
1496
- });
1497
- }
1498
- /**
1499
- * Create a streaming body parser for large payloads
1500
- * Returns a streaming interface instead of buffering
1501
- */
1502
- createStreamingBodyParser(req, contentType, maxSize) {
1503
- let totalLength = 0;
1504
- const chunks = [];
1505
- return new Promise((resolve, reject) => {
1506
- const streamParser = {
1507
- // Streaming JSON parser for large JSON payloads
1508
- json: () => this.streamJsonParse(req, maxSize),
1509
- // Streaming form data parser
1510
- form: () => this.streamFormParse(req, maxSize),
1511
- // Raw stream access
1512
- stream: () => ({
1513
- onData: (callback) => {
1514
- req.on('data', (chunk) => {
1515
- totalLength += chunk.length;
1516
- if (totalLength > maxSize) {
1517
- reject(new Error('Request body too large'));
1518
- return;
1519
- }
1520
- callback(chunk);
1521
- });
1522
- },
1523
- onEnd: (callback) => {
1524
- req.on('end', callback);
1525
- },
1526
- onError: (callback) => {
1527
- req.on('error', callback);
1528
- },
1529
- }),
1530
- // Traditional buffered parsing (fallback)
1531
- buffer: async () => {
1532
- return new Promise((resolveBuffer, rejectBuffer) => {
1533
- req.on('data', (chunk) => {
1534
- totalLength += chunk.length;
1535
- if (totalLength > maxSize) {
1536
- rejectBuffer(new Error('Request body too large'));
1537
- return;
1538
- }
1539
- chunks.push(chunk);
1540
- });
1541
- req.on('end', () => {
1542
- try {
1543
- const body = Buffer.concat(chunks);
1544
- if (contentType.includes('application/json')) {
1545
- resolveBuffer(JSON.parse(body.toString()));
1546
- }
1547
- else {
1548
- resolveBuffer(body.toString());
1549
- }
1550
- }
1551
- catch (error) {
1552
- rejectBuffer(error);
1553
- }
1554
- });
1555
- req.on('error', rejectBuffer);
1556
- });
1557
- },
1558
- };
1559
- // Auto-detect and return appropriate parser
1560
- if (contentType.includes('application/json')) {
1561
- resolve({ type: 'json', parser: streamParser.json });
1562
- }
1563
- else if (contentType.includes('application/x-www-form-urlencoded')) {
1564
- resolve({ type: 'form', parser: streamParser.form });
1565
- }
1566
- else {
1567
- resolve({ type: 'stream', parser: streamParser.stream });
1568
- }
1569
- });
1570
- }
1571
- /**
1572
- * Streaming JSON parser for large payloads
1573
- */
1574
- async streamJsonParse(req, maxSize) {
1575
- return new Promise((resolve, reject) => {
1576
- let jsonString = '';
1577
- let totalLength = 0;
1578
- req.on('data', (chunk) => {
1579
- totalLength += chunk.length;
1580
- if (totalLength > maxSize) {
1581
- reject(new Error('Request body too large'));
1582
- return;
1583
- }
1584
- jsonString += chunk.toString();
1585
- });
1586
- req.on('end', () => {
1587
- try {
1588
- // For very large JSON, consider streaming JSON parsing in the future
1589
- resolve(JSON.parse(jsonString));
1590
- }
1591
- catch (error) {
1592
- reject(error);
1593
- }
1594
- });
1595
- req.on('error', reject);
1596
- });
1597
- }
1598
- /**
1599
- * Streaming form data parser
1600
- */
1601
- async streamFormParse(req, maxSize) {
1602
- return new Promise((resolve, reject) => {
1603
- let formData = '';
1604
- let totalLength = 0;
1605
- req.on('data', (chunk) => {
1606
- totalLength += chunk.length;
1607
- if (totalLength > maxSize) {
1608
- reject(new Error('Request body too large'));
1609
- return;
1610
- }
1611
- formData += chunk.toString();
1612
- });
1613
- req.on('end', () => {
1614
- try {
1615
- resolve(this.parseUrlEncoded(formData));
1616
- }
1617
- catch (error) {
1533
+ // A malformed body is a client error (400), not a server error (500).
1534
+ // Tag it so the request-error path answers 400, matching the engine
1535
+ // and uWS transports.
1536
+ if (error instanceof Error && error.statusCode === undefined) {
1537
+ error.statusCode = 400;
1538
+ }
1618
1539
  reject(error);
1619
1540
  }
1620
1541
  });
@@ -1622,76 +1543,9 @@ export class MoroHttpServer {
1622
1543
  });
1623
1544
  }
1624
1545
  parseMultipart(buffer, contentType) {
1625
- const boundary = contentType.split('boundary=')[1];
1626
- if (!boundary) {
1627
- throw new Error('Invalid multipart boundary');
1628
- }
1629
- // Work with Buffer directly - don't convert to string (corrupts binary data)
1630
- const boundaryBuffer = Buffer.from(`--${boundary}`);
1631
- const parts = this.splitBuffer(buffer, boundaryBuffer);
1632
- const fields = {};
1633
- const files = {};
1634
- // Skip first (empty) and last (closing boundary) parts
1635
- const partsLen = parts.length - 1;
1636
- for (let i = 1; i < partsLen; i++) {
1637
- const part = parts[i];
1638
- // Find the double CRLF that separates headers from content
1639
- const headerEndPos = this.findBufferSequence(part, Buffer.from('\r\n\r\n'));
1640
- if (headerEndPos === -1)
1641
- continue;
1642
- // Headers are always text - safe to convert to string
1643
- const headers = part.slice(0, headerEndPos).toString('utf8');
1644
- // Content stays as Buffer to preserve binary data
1645
- const content = part.slice(headerEndPos + 4); // Skip the \r\n\r\n
1646
- const nameMatch = headers.match(/name="([^"]+)"/);
1647
- const filenameMatch = headers.match(/filename="([^"]+)"/);
1648
- const contentTypeMatch = headers.match(/Content-Type: ([^\r\n]+)/);
1649
- if (nameMatch) {
1650
- const name = nameMatch[1];
1651
- if (filenameMatch) {
1652
- // This is a file - keep as Buffer to preserve binary data
1653
- const filename = filenameMatch[1];
1654
- const mimeType = contentTypeMatch ? contentTypeMatch[1] : 'application/octet-stream';
1655
- // Remove trailing \r\n (2 bytes) from the end
1656
- const fileData = content.slice(0, content.length - 2);
1657
- files[name] = {
1658
- filename,
1659
- mimetype: mimeType,
1660
- data: fileData, // Already a Buffer - preserves binary integrity
1661
- size: fileData.length,
1662
- };
1663
- }
1664
- else {
1665
- // This is a regular field - convert to string
1666
- const fieldContent = content.slice(0, content.length - 2); // Remove trailing \r\n
1667
- fields[name] = fieldContent.toString('utf8');
1668
- }
1669
- }
1670
- }
1671
- return { fields, files };
1672
- }
1673
- /**
1674
- * Split a Buffer by a delimiter Buffer
1675
- * Used for multipart boundary splitting without corrupting binary data
1676
- */
1677
- splitBuffer(buffer, delimiter) {
1678
- const parts = [];
1679
- let start = 0;
1680
- let pos = 0;
1681
- while ((pos = buffer.indexOf(delimiter, start)) !== -1) {
1682
- parts.push(buffer.slice(start, pos));
1683
- start = pos + delimiter.length;
1684
- }
1685
- // Add the remaining part
1686
- parts.push(buffer.slice(start));
1687
- return parts;
1688
- }
1689
- /**
1690
- * Find the position of a sequence within a Buffer
1691
- * Returns -1 if not found
1692
- */
1693
- findBufferSequence(buffer, sequence) {
1694
- return buffer.indexOf(sequence);
1546
+ // Shared implementation - the native engine server parses uploads with
1547
+ // the exact same code so both transports agree on body/files shape
1548
+ return parseMultipartBuffer(buffer, contentType, this.multipartLimits);
1695
1549
  }
1696
1550
  parseUrlEncoded(body) {
1697
1551
  const params = new URLSearchParams(body);
@@ -1755,6 +1609,8 @@ export class MoroHttpServer {
1755
1609
  // Only test routes with matching method and segment count
1756
1610
  for (let i = 0; i < candidateLen; i++) {
1757
1611
  const candidateRoute = candidateRoutes[i];
1612
+ if (candidateRoute === undefined)
1613
+ continue;
1758
1614
  if (candidateRoute.method === method && candidateRoute.pattern.test(normalizedPath)) {
1759
1615
  route = candidateRoute;
1760
1616
  break;
@@ -1864,7 +1720,11 @@ export class MoroHttpServer {
1864
1720
  callback = host;
1865
1721
  host = undefined;
1866
1722
  }
1867
- if (host) {
1723
+ const backlog = this.listenBacklog;
1724
+ if (host && backlog) {
1725
+ this.server.listen(port, host, backlog, callback);
1726
+ }
1727
+ else if (host) {
1868
1728
  this.server.listen(port, host, callback);
1869
1729
  }
1870
1730
  else {