@morojs/moro 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/dist/core/config/index.d.ts +19 -0
  4. package/dist/core/config/index.js +59 -0
  5. package/dist/core/config/index.js.map +1 -0
  6. package/dist/core/config/loader.d.ts +6 -0
  7. package/dist/core/config/loader.js +288 -0
  8. package/dist/core/config/loader.js.map +1 -0
  9. package/dist/core/config/schema.d.ts +335 -0
  10. package/dist/core/config/schema.js +286 -0
  11. package/dist/core/config/schema.js.map +1 -0
  12. package/dist/core/config/utils.d.ts +50 -0
  13. package/dist/core/config/utils.js +185 -0
  14. package/dist/core/config/utils.js.map +1 -0
  15. package/dist/core/database/adapters/drizzle.d.ts +29 -0
  16. package/dist/core/database/adapters/drizzle.js +366 -0
  17. package/dist/core/database/adapters/drizzle.js.map +1 -0
  18. package/dist/core/database/adapters/index.d.ts +8 -0
  19. package/dist/core/database/adapters/index.js +48 -0
  20. package/dist/core/database/adapters/index.js.map +1 -0
  21. package/dist/core/database/adapters/mongodb.d.ts +35 -0
  22. package/dist/core/database/adapters/mongodb.js +215 -0
  23. package/dist/core/database/adapters/mongodb.js.map +1 -0
  24. package/dist/core/database/adapters/mysql.d.ts +23 -0
  25. package/dist/core/database/adapters/mysql.js +149 -0
  26. package/dist/core/database/adapters/mysql.js.map +1 -0
  27. package/dist/core/database/adapters/postgresql.d.ts +24 -0
  28. package/dist/core/database/adapters/postgresql.js +160 -0
  29. package/dist/core/database/adapters/postgresql.js.map +1 -0
  30. package/dist/core/database/adapters/redis.d.ts +50 -0
  31. package/dist/core/database/adapters/redis.js +266 -0
  32. package/dist/core/database/adapters/redis.js.map +1 -0
  33. package/dist/core/database/adapters/sqlite.d.ts +23 -0
  34. package/dist/core/database/adapters/sqlite.js +194 -0
  35. package/dist/core/database/adapters/sqlite.js.map +1 -0
  36. package/dist/core/database/index.d.ts +2 -0
  37. package/dist/core/database/index.js +20 -0
  38. package/dist/core/database/index.js.map +1 -0
  39. package/dist/core/docs/index.d.ts +63 -0
  40. package/dist/core/docs/index.js +170 -0
  41. package/dist/core/docs/index.js.map +1 -0
  42. package/dist/core/docs/openapi-generator.d.ts +124 -0
  43. package/dist/core/docs/openapi-generator.js +413 -0
  44. package/dist/core/docs/openapi-generator.js.map +1 -0
  45. package/dist/core/docs/simple-docs.d.ts +21 -0
  46. package/dist/core/docs/simple-docs.js +268 -0
  47. package/dist/core/docs/simple-docs.js.map +1 -0
  48. package/dist/core/docs/swagger-ui.d.ts +28 -0
  49. package/dist/core/docs/swagger-ui.js +317 -0
  50. package/dist/core/docs/swagger-ui.js.map +1 -0
  51. package/dist/core/docs/zod-to-openapi.d.ts +29 -0
  52. package/dist/core/docs/zod-to-openapi.js +414 -0
  53. package/dist/core/docs/zod-to-openapi.js.map +1 -0
  54. package/dist/core/events/event-bus.d.ts +27 -0
  55. package/dist/core/events/event-bus.js +193 -0
  56. package/dist/core/events/event-bus.js.map +1 -0
  57. package/dist/core/events/index.d.ts +2 -0
  58. package/dist/core/events/index.js +7 -0
  59. package/dist/core/events/index.js.map +1 -0
  60. package/dist/core/framework.d.ts +57 -0
  61. package/dist/core/framework.js +432 -0
  62. package/dist/core/framework.js.map +1 -0
  63. package/dist/core/http/http-server.d.ts +114 -0
  64. package/dist/core/http/http-server.js +1154 -0
  65. package/dist/core/http/http-server.js.map +1 -0
  66. package/dist/core/http/index.d.ts +3 -0
  67. package/dist/core/http/index.js +10 -0
  68. package/dist/core/http/index.js.map +1 -0
  69. package/dist/core/http/router.d.ts +14 -0
  70. package/dist/core/http/router.js +113 -0
  71. package/dist/core/http/router.js.map +1 -0
  72. package/dist/core/logger/filters.d.ts +9 -0
  73. package/dist/core/logger/filters.js +134 -0
  74. package/dist/core/logger/filters.js.map +1 -0
  75. package/dist/core/logger/index.d.ts +3 -0
  76. package/dist/core/logger/index.js +26 -0
  77. package/dist/core/logger/index.js.map +1 -0
  78. package/dist/core/logger/logger.d.ts +49 -0
  79. package/dist/core/logger/logger.js +332 -0
  80. package/dist/core/logger/logger.js.map +1 -0
  81. package/dist/core/logger/outputs.d.ts +42 -0
  82. package/dist/core/logger/outputs.js +110 -0
  83. package/dist/core/logger/outputs.js.map +1 -0
  84. package/dist/core/middleware/built-in/adapters/cache/file.d.ts +15 -0
  85. package/dist/core/middleware/built-in/adapters/cache/file.js +128 -0
  86. package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -0
  87. package/dist/core/middleware/built-in/adapters/cache/index.d.ts +5 -0
  88. package/dist/core/middleware/built-in/adapters/cache/index.js +28 -0
  89. package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -0
  90. package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +11 -0
  91. package/dist/core/middleware/built-in/adapters/cache/memory.js +65 -0
  92. package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -0
  93. package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +17 -0
  94. package/dist/core/middleware/built-in/adapters/cache/redis.js +91 -0
  95. package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -0
  96. package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +21 -0
  97. package/dist/core/middleware/built-in/adapters/cdn/azure.js +40 -0
  98. package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -0
  99. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +14 -0
  100. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +77 -0
  101. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -0
  102. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +15 -0
  103. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +73 -0
  104. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -0
  105. package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +5 -0
  106. package/dist/core/middleware/built-in/adapters/cdn/index.js +28 -0
  107. package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -0
  108. package/dist/core/middleware/built-in/adapters/index.d.ts +4 -0
  109. package/dist/core/middleware/built-in/adapters/index.js +26 -0
  110. package/dist/core/middleware/built-in/adapters/index.js.map +1 -0
  111. package/dist/core/middleware/built-in/auth.d.ts +2 -0
  112. package/dist/core/middleware/built-in/auth.js +38 -0
  113. package/dist/core/middleware/built-in/auth.js.map +1 -0
  114. package/dist/core/middleware/built-in/cache.d.ts +3 -0
  115. package/dist/core/middleware/built-in/cache.js +188 -0
  116. package/dist/core/middleware/built-in/cache.js.map +1 -0
  117. package/dist/core/middleware/built-in/cdn.d.ts +3 -0
  118. package/dist/core/middleware/built-in/cdn.js +115 -0
  119. package/dist/core/middleware/built-in/cdn.js.map +1 -0
  120. package/dist/core/middleware/built-in/cookie.d.ts +14 -0
  121. package/dist/core/middleware/built-in/cookie.js +68 -0
  122. package/dist/core/middleware/built-in/cookie.js.map +1 -0
  123. package/dist/core/middleware/built-in/cors.d.ts +2 -0
  124. package/dist/core/middleware/built-in/cors.js +29 -0
  125. package/dist/core/middleware/built-in/cors.js.map +1 -0
  126. package/dist/core/middleware/built-in/csp.d.ts +22 -0
  127. package/dist/core/middleware/built-in/csp.js +74 -0
  128. package/dist/core/middleware/built-in/csp.js.map +1 -0
  129. package/dist/core/middleware/built-in/csrf.d.ts +9 -0
  130. package/dist/core/middleware/built-in/csrf.js +66 -0
  131. package/dist/core/middleware/built-in/csrf.js.map +1 -0
  132. package/dist/core/middleware/built-in/error-tracker.d.ts +1 -0
  133. package/dist/core/middleware/built-in/error-tracker.js +19 -0
  134. package/dist/core/middleware/built-in/error-tracker.js.map +1 -0
  135. package/dist/core/middleware/built-in/index.d.ts +70 -0
  136. package/dist/core/middleware/built-in/index.js +70 -0
  137. package/dist/core/middleware/built-in/index.js.map +1 -0
  138. package/dist/core/middleware/built-in/performance-monitor.d.ts +1 -0
  139. package/dist/core/middleware/built-in/performance-monitor.js +22 -0
  140. package/dist/core/middleware/built-in/performance-monitor.js.map +1 -0
  141. package/dist/core/middleware/built-in/rate-limit.d.ts +6 -0
  142. package/dist/core/middleware/built-in/rate-limit.js +47 -0
  143. package/dist/core/middleware/built-in/rate-limit.js.map +1 -0
  144. package/dist/core/middleware/built-in/request-logger.d.ts +1 -0
  145. package/dist/core/middleware/built-in/request-logger.js +15 -0
  146. package/dist/core/middleware/built-in/request-logger.js.map +1 -0
  147. package/dist/core/middleware/built-in/session.d.ts +41 -0
  148. package/dist/core/middleware/built-in/session.js +209 -0
  149. package/dist/core/middleware/built-in/session.js.map +1 -0
  150. package/dist/core/middleware/built-in/sse.d.ts +6 -0
  151. package/dist/core/middleware/built-in/sse.js +73 -0
  152. package/dist/core/middleware/built-in/sse.js.map +1 -0
  153. package/dist/core/middleware/built-in/validation.d.ts +2 -0
  154. package/dist/core/middleware/built-in/validation.js +31 -0
  155. package/dist/core/middleware/built-in/validation.js.map +1 -0
  156. package/dist/core/middleware/index.d.ts +21 -0
  157. package/dist/core/middleware/index.js +152 -0
  158. package/dist/core/middleware/index.js.map +1 -0
  159. package/dist/core/modules/auto-discovery.d.ts +27 -0
  160. package/dist/core/modules/auto-discovery.js +255 -0
  161. package/dist/core/modules/auto-discovery.js.map +1 -0
  162. package/dist/core/modules/index.d.ts +2 -0
  163. package/dist/core/modules/index.js +11 -0
  164. package/dist/core/modules/index.js.map +1 -0
  165. package/dist/core/modules/modules.d.ts +10 -0
  166. package/dist/core/modules/modules.js +137 -0
  167. package/dist/core/modules/modules.js.map +1 -0
  168. package/dist/core/networking/index.d.ts +2 -0
  169. package/dist/core/networking/index.js +9 -0
  170. package/dist/core/networking/index.js.map +1 -0
  171. package/dist/core/networking/service-discovery.d.ts +38 -0
  172. package/dist/core/networking/service-discovery.js +233 -0
  173. package/dist/core/networking/service-discovery.js.map +1 -0
  174. package/dist/core/networking/websocket-manager.d.ts +27 -0
  175. package/dist/core/networking/websocket-manager.js +211 -0
  176. package/dist/core/networking/websocket-manager.js.map +1 -0
  177. package/dist/core/routing/app-integration.d.ts +42 -0
  178. package/dist/core/routing/app-integration.js +152 -0
  179. package/dist/core/routing/app-integration.js.map +1 -0
  180. package/dist/core/routing/index.d.ts +106 -0
  181. package/dist/core/routing/index.js +343 -0
  182. package/dist/core/routing/index.js.map +1 -0
  183. package/dist/core/runtime/aws-lambda-adapter.d.ts +43 -0
  184. package/dist/core/runtime/aws-lambda-adapter.js +108 -0
  185. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -0
  186. package/dist/core/runtime/base-adapter.d.ts +16 -0
  187. package/dist/core/runtime/base-adapter.js +105 -0
  188. package/dist/core/runtime/base-adapter.js.map +1 -0
  189. package/dist/core/runtime/cloudflare-workers-adapter.d.ts +18 -0
  190. package/dist/core/runtime/cloudflare-workers-adapter.js +131 -0
  191. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -0
  192. package/dist/core/runtime/index.d.ts +14 -0
  193. package/dist/core/runtime/index.js +56 -0
  194. package/dist/core/runtime/index.js.map +1 -0
  195. package/dist/core/runtime/node-adapter.d.ts +15 -0
  196. package/dist/core/runtime/node-adapter.js +204 -0
  197. package/dist/core/runtime/node-adapter.js.map +1 -0
  198. package/dist/core/runtime/vercel-edge-adapter.d.ts +10 -0
  199. package/dist/core/runtime/vercel-edge-adapter.js +106 -0
  200. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -0
  201. package/dist/core/utilities/circuit-breaker.d.ts +14 -0
  202. package/dist/core/utilities/circuit-breaker.js +42 -0
  203. package/dist/core/utilities/circuit-breaker.js.map +1 -0
  204. package/dist/core/utilities/container.d.ts +116 -0
  205. package/dist/core/utilities/container.js +529 -0
  206. package/dist/core/utilities/container.js.map +1 -0
  207. package/dist/core/utilities/hooks.d.ts +24 -0
  208. package/dist/core/utilities/hooks.js +131 -0
  209. package/dist/core/utilities/hooks.js.map +1 -0
  210. package/dist/core/utilities/index.d.ts +4 -0
  211. package/dist/core/utilities/index.js +22 -0
  212. package/dist/core/utilities/index.js.map +1 -0
  213. package/dist/core/validation/index.d.ts +30 -0
  214. package/dist/core/validation/index.js +144 -0
  215. package/dist/core/validation/index.js.map +1 -0
  216. package/dist/index.d.ts +30 -0
  217. package/dist/index.js +72 -0
  218. package/dist/index.js.map +1 -0
  219. package/dist/moro.d.ts +82 -0
  220. package/dist/moro.js +679 -0
  221. package/dist/moro.js.map +1 -0
  222. package/dist/types/cache.d.ts +34 -0
  223. package/dist/types/cache.js +3 -0
  224. package/dist/types/cache.js.map +1 -0
  225. package/dist/types/cdn.d.ts +19 -0
  226. package/dist/types/cdn.js +3 -0
  227. package/dist/types/cdn.js.map +1 -0
  228. package/dist/types/core.d.ts +13 -0
  229. package/dist/types/core.js +3 -0
  230. package/dist/types/core.js.map +1 -0
  231. package/dist/types/database.d.ts +29 -0
  232. package/dist/types/database.js +3 -0
  233. package/dist/types/database.js.map +1 -0
  234. package/dist/types/discovery.d.ts +6 -0
  235. package/dist/types/discovery.js +3 -0
  236. package/dist/types/discovery.js.map +1 -0
  237. package/dist/types/events.d.ts +116 -0
  238. package/dist/types/events.js +3 -0
  239. package/dist/types/events.js.map +1 -0
  240. package/dist/types/hooks.d.ts +38 -0
  241. package/dist/types/hooks.js +3 -0
  242. package/dist/types/hooks.js.map +1 -0
  243. package/dist/types/http.d.ts +51 -0
  244. package/dist/types/http.js +3 -0
  245. package/dist/types/http.js.map +1 -0
  246. package/dist/types/logger.d.ts +77 -0
  247. package/dist/types/logger.js +3 -0
  248. package/dist/types/logger.js.map +1 -0
  249. package/dist/types/module.d.ts +91 -0
  250. package/dist/types/module.js +3 -0
  251. package/dist/types/module.js.map +1 -0
  252. package/dist/types/runtime.d.ts +48 -0
  253. package/dist/types/runtime.js +3 -0
  254. package/dist/types/runtime.js.map +1 -0
  255. package/dist/types/session.d.ts +66 -0
  256. package/dist/types/session.js +3 -0
  257. package/dist/types/session.js.map +1 -0
  258. package/package.json +176 -0
  259. package/src/core/config/index.ts +47 -0
  260. package/src/core/config/loader.ts +366 -0
  261. package/src/core/config/schema.ts +346 -0
  262. package/src/core/config/utils.ts +220 -0
  263. package/src/core/database/README.md +228 -0
  264. package/src/core/database/adapters/drizzle.ts +425 -0
  265. package/src/core/database/adapters/index.ts +45 -0
  266. package/src/core/database/adapters/mongodb.ts +292 -0
  267. package/src/core/database/adapters/mysql.ts +217 -0
  268. package/src/core/database/adapters/postgresql.ts +211 -0
  269. package/src/core/database/adapters/redis.ts +331 -0
  270. package/src/core/database/adapters/sqlite.ts +255 -0
  271. package/src/core/database/index.ts +3 -0
  272. package/src/core/docs/index.ts +245 -0
  273. package/src/core/docs/openapi-generator.ts +588 -0
  274. package/src/core/docs/simple-docs.ts +305 -0
  275. package/src/core/docs/swagger-ui.ts +370 -0
  276. package/src/core/docs/zod-to-openapi.ts +532 -0
  277. package/src/core/events/event-bus.ts +249 -0
  278. package/src/core/events/index.ts +12 -0
  279. package/src/core/framework.ts +621 -0
  280. package/src/core/http/http-server.ts +1421 -0
  281. package/src/core/http/index.ts +11 -0
  282. package/src/core/http/router.ts +153 -0
  283. package/src/core/logger/filters.ts +148 -0
  284. package/src/core/logger/index.ts +20 -0
  285. package/src/core/logger/logger.ts +434 -0
  286. package/src/core/logger/outputs.ts +136 -0
  287. package/src/core/middleware/built-in/adapters/cache/file.ts +106 -0
  288. package/src/core/middleware/built-in/adapters/cache/index.ts +26 -0
  289. package/src/core/middleware/built-in/adapters/cache/memory.ts +73 -0
  290. package/src/core/middleware/built-in/adapters/cache/redis.ts +103 -0
  291. package/src/core/middleware/built-in/adapters/cdn/azure.ts +68 -0
  292. package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +100 -0
  293. package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +92 -0
  294. package/src/core/middleware/built-in/adapters/cdn/index.ts +23 -0
  295. package/src/core/middleware/built-in/adapters/index.ts +7 -0
  296. package/src/core/middleware/built-in/auth.ts +39 -0
  297. package/src/core/middleware/built-in/cache.ts +228 -0
  298. package/src/core/middleware/built-in/cdn.ts +151 -0
  299. package/src/core/middleware/built-in/cookie.ts +90 -0
  300. package/src/core/middleware/built-in/cors.ts +38 -0
  301. package/src/core/middleware/built-in/csp.ts +107 -0
  302. package/src/core/middleware/built-in/csrf.ts +87 -0
  303. package/src/core/middleware/built-in/error-tracker.ts +16 -0
  304. package/src/core/middleware/built-in/index.ts +57 -0
  305. package/src/core/middleware/built-in/performance-monitor.ts +25 -0
  306. package/src/core/middleware/built-in/rate-limit.ts +60 -0
  307. package/src/core/middleware/built-in/request-logger.ts +14 -0
  308. package/src/core/middleware/built-in/session.ts +311 -0
  309. package/src/core/middleware/built-in/sse.ts +91 -0
  310. package/src/core/middleware/built-in/validation.ts +33 -0
  311. package/src/core/middleware/index.ts +188 -0
  312. package/src/core/modules/auto-discovery.ts +265 -0
  313. package/src/core/modules/index.ts +6 -0
  314. package/src/core/modules/modules.ts +125 -0
  315. package/src/core/networking/index.ts +7 -0
  316. package/src/core/networking/service-discovery.ts +309 -0
  317. package/src/core/networking/websocket-manager.ts +259 -0
  318. package/src/core/routing/app-integration.ts +229 -0
  319. package/src/core/routing/index.ts +519 -0
  320. package/src/core/runtime/aws-lambda-adapter.ts +157 -0
  321. package/src/core/runtime/base-adapter.ts +140 -0
  322. package/src/core/runtime/cloudflare-workers-adapter.ts +166 -0
  323. package/src/core/runtime/index.ts +74 -0
  324. package/src/core/runtime/node-adapter.ts +210 -0
  325. package/src/core/runtime/vercel-edge-adapter.ts +125 -0
  326. package/src/core/utilities/circuit-breaker.ts +46 -0
  327. package/src/core/utilities/container.ts +760 -0
  328. package/src/core/utilities/hooks.ts +148 -0
  329. package/src/core/utilities/index.ts +16 -0
  330. package/src/core/validation/index.ts +216 -0
  331. package/src/index.ts +120 -0
  332. package/src/moro.ts +842 -0
  333. package/src/types/cache.ts +38 -0
  334. package/src/types/cdn.ts +22 -0
  335. package/src/types/core.ts +17 -0
  336. package/src/types/database.ts +40 -0
  337. package/src/types/discovery.ts +7 -0
  338. package/src/types/events.ts +90 -0
  339. package/src/types/hooks.ts +47 -0
  340. package/src/types/http.ts +70 -0
  341. package/src/types/logger.ts +109 -0
  342. package/src/types/module.ts +87 -0
  343. package/src/types/runtime.ts +91 -0
  344. package/src/types/session.ts +89 -0
  345. package/tsconfig.json +21 -0
@@ -0,0 +1,140 @@
1
+ // Base runtime adapter with common functionality
2
+ import {
3
+ RuntimeAdapter,
4
+ RuntimeType,
5
+ RuntimeHttpResponse,
6
+ } from "../../types/runtime";
7
+ import { HttpRequest, HttpResponse } from "../../types/http";
8
+ import { randomBytes } from "crypto";
9
+
10
+ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
11
+ abstract readonly type: RuntimeType;
12
+
13
+ abstract adaptRequest(
14
+ runtimeRequest: any,
15
+ ...args: any[]
16
+ ): Promise<HttpRequest>;
17
+ abstract adaptResponse(
18
+ moroResponse: HttpResponse | RuntimeHttpResponse,
19
+ runtimeRequest: any,
20
+ ): Promise<any>;
21
+ abstract createServer(
22
+ handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
23
+ ): any;
24
+
25
+ // Generate UUID without external dependency
26
+ protected generateUUID(): string {
27
+ return randomBytes(16)
28
+ .toString("hex")
29
+ .replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, "$1-$2-$3-$4-$5");
30
+ }
31
+
32
+ // Common request enhancement
33
+ protected enhanceRequest(baseRequest: Partial<HttpRequest>): HttpRequest {
34
+ const request = baseRequest as HttpRequest;
35
+
36
+ // Add common properties
37
+ request.requestId = request.requestId || this.generateUUID();
38
+ request.ip = request.ip || "unknown";
39
+ request.params = request.params || {};
40
+ request.query = request.query || {};
41
+ request.cookies = request.cookies || {};
42
+ request.files = request.files || {};
43
+
44
+ return request;
45
+ }
46
+
47
+ // Common response enhancement
48
+ protected createMockResponse(): RuntimeHttpResponse {
49
+ const response: RuntimeHttpResponse = {
50
+ statusCode: 200,
51
+ headers: {},
52
+ body: null,
53
+ headersSent: false,
54
+
55
+ status: function (code: number) {
56
+ this.statusCode = code;
57
+ return this;
58
+ },
59
+
60
+ json: function (data: any) {
61
+ this.headers["Content-Type"] = "application/json";
62
+ this.body = JSON.stringify(data);
63
+ this.headersSent = true;
64
+ },
65
+
66
+ send: function (data: string | Buffer) {
67
+ this.body = data;
68
+ this.headersSent = true;
69
+ },
70
+
71
+ cookie: function (name: string, value: string, options?: any) {
72
+ // Simple cookie implementation
73
+ const cookieString = `${name}=${value}`;
74
+ this.headers["Set-Cookie"] = cookieString;
75
+ return this;
76
+ },
77
+
78
+ clearCookie: function (name: string, options?: any) {
79
+ this.headers["Set-Cookie"] =
80
+ `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
81
+ return this;
82
+ },
83
+
84
+ redirect: function (url: string, status?: number) {
85
+ this.statusCode = status || 302;
86
+ this.headers["Location"] = url;
87
+ this.headersSent = true;
88
+ },
89
+
90
+ sendFile: async function (filePath: string) {
91
+ throw new Error("sendFile not implemented in this runtime");
92
+ },
93
+ };
94
+
95
+ return response;
96
+ }
97
+
98
+ // Parse URL and query parameters
99
+ protected parseUrl(url: string): {
100
+ pathname: string;
101
+ query: Record<string, string>;
102
+ } {
103
+ try {
104
+ const urlObj = new URL(url, "http://localhost");
105
+ const query: Record<string, string> = {};
106
+
107
+ urlObj.searchParams.forEach((value, key) => {
108
+ query[key] = value;
109
+ });
110
+
111
+ return {
112
+ pathname: urlObj.pathname,
113
+ query,
114
+ };
115
+ } catch {
116
+ return {
117
+ pathname: url,
118
+ query: {},
119
+ };
120
+ }
121
+ }
122
+
123
+ // Parse body based on content type
124
+ protected async parseBody(body: any, contentType?: string): Promise<any> {
125
+ if (!body) return undefined;
126
+
127
+ if (typeof body === "string") {
128
+ if (contentType?.includes("application/json")) {
129
+ try {
130
+ return JSON.parse(body);
131
+ } catch {
132
+ return body;
133
+ }
134
+ }
135
+ return body;
136
+ }
137
+
138
+ return body;
139
+ }
140
+ }
@@ -0,0 +1,166 @@
1
+ // Cloudflare Workers runtime adapter
2
+ import { BaseRuntimeAdapter } from "./base-adapter";
3
+ import { HttpRequest, HttpResponse } from "../../types/http";
4
+ import { RuntimeHttpResponse } from "../../types/runtime";
5
+
6
+ export interface WorkersEnv {
7
+ [key: string]: any;
8
+ }
9
+
10
+ export interface WorkersContext {
11
+ waitUntil(promise: Promise<any>): void;
12
+ passThroughOnException(): void;
13
+ }
14
+
15
+ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
16
+ readonly type = "cloudflare-workers" as const;
17
+
18
+ async adaptRequest(
19
+ request: Request,
20
+ env: WorkersEnv,
21
+ ctx: WorkersContext,
22
+ ): Promise<HttpRequest> {
23
+ const { pathname, query } = this.parseUrl(request.url);
24
+
25
+ // Parse body for POST/PUT/PATCH requests
26
+ let body: any;
27
+ if (["POST", "PUT", "PATCH"].includes(request.method)) {
28
+ const contentType = request.headers.get("content-type") || "";
29
+ if (contentType.includes("application/json")) {
30
+ try {
31
+ body = await request.json();
32
+ } catch {
33
+ body = await request.text();
34
+ }
35
+ } else if (contentType.includes("application/x-www-form-urlencoded")) {
36
+ body = await request.formData();
37
+ // Convert FormData to object
38
+ const formObject: Record<string, any> = {};
39
+ body.forEach((value: any, key: string) => {
40
+ formObject[key] = value;
41
+ });
42
+ body = formObject;
43
+ } else {
44
+ body = await request.text();
45
+ }
46
+ }
47
+
48
+ // Convert Headers to plain object
49
+ const headers: Record<string, string> = {};
50
+ request.headers.forEach((value, key) => {
51
+ headers[key] = value;
52
+ });
53
+
54
+ const baseRequest = {
55
+ method: request.method,
56
+ url: request.url,
57
+ path: pathname,
58
+ query,
59
+ body,
60
+ headers,
61
+ ip: this.getClientIP(headers, request),
62
+ params: {},
63
+ requestId: "",
64
+ cookies: this.parseCookies(headers.cookie || ""),
65
+ files: {},
66
+ // Add Workers-specific context
67
+ env,
68
+ ctx,
69
+ } as Partial<HttpRequest>;
70
+
71
+ return this.enhanceRequest(baseRequest);
72
+ }
73
+
74
+ async adaptResponse(
75
+ moroResponse: HttpResponse | RuntimeHttpResponse,
76
+ ): Promise<Response> {
77
+ const runtimeResponse = moroResponse as RuntimeHttpResponse;
78
+
79
+ // Handle different response states
80
+ let body = runtimeResponse.body;
81
+ let status = runtimeResponse.statusCode || 200;
82
+ const headers = runtimeResponse.headers || {};
83
+
84
+ // If it's a real HttpResponse, we need to extract the data differently
85
+ if (
86
+ "statusCode" in moroResponse &&
87
+ typeof moroResponse.statusCode === "number"
88
+ ) {
89
+ status = moroResponse.statusCode;
90
+ }
91
+
92
+ // Convert headers to Headers object
93
+ const responseHeaders = new Headers();
94
+ Object.entries(headers).forEach(([key, value]) => {
95
+ responseHeaders.set(key, value);
96
+ });
97
+
98
+ // Handle different body types
99
+ if (typeof body === "object" && body !== null) {
100
+ body = JSON.stringify(body);
101
+ responseHeaders.set("Content-Type", "application/json");
102
+ }
103
+
104
+ return new Response(body, {
105
+ status,
106
+ headers: responseHeaders,
107
+ });
108
+ }
109
+
110
+ createServer(
111
+ handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
112
+ ) {
113
+ // Return a Cloudflare Workers-compatible handler function
114
+ return async (request: Request, env: WorkersEnv, ctx: WorkersContext) => {
115
+ try {
116
+ const moroReq = await this.adaptRequest(request, env, ctx);
117
+ const moroRes = this.createMockResponse();
118
+
119
+ await handler(moroReq, moroRes as any);
120
+
121
+ return await this.adaptResponse(moroRes);
122
+ } catch (error) {
123
+ return new Response(
124
+ JSON.stringify({
125
+ success: false,
126
+ error: "Internal server error",
127
+ message: error instanceof Error ? error.message : "Unknown error",
128
+ }),
129
+ {
130
+ status: 500,
131
+ headers: { "Content-Type": "application/json" },
132
+ },
133
+ );
134
+ }
135
+ };
136
+ }
137
+
138
+ // Cloudflare Workers doesn't have a listen method - it's handled by the platform
139
+ // listen method is optional in the interface
140
+
141
+ private getClientIP(
142
+ headers: Record<string, string>,
143
+ request: Request,
144
+ ): string {
145
+ // Cloudflare provides the real IP in CF-Connecting-IP header
146
+ return (
147
+ headers["cf-connecting-ip"] ||
148
+ headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
149
+ headers["x-real-ip"] ||
150
+ "unknown"
151
+ );
152
+ }
153
+
154
+ private parseCookies(cookieHeader: string): Record<string, string> {
155
+ const cookies: Record<string, string> = {};
156
+ if (cookieHeader) {
157
+ cookieHeader.split(";").forEach((cookie) => {
158
+ const [name, ...rest] = cookie.trim().split("=");
159
+ if (name && rest.length > 0) {
160
+ cookies[name] = rest.join("=");
161
+ }
162
+ });
163
+ }
164
+ return cookies;
165
+ }
166
+ }
@@ -0,0 +1,74 @@
1
+ // Runtime adapters export
2
+ export { BaseRuntimeAdapter } from "./base-adapter";
3
+ export { NodeRuntimeAdapter } from "./node-adapter";
4
+ export { VercelEdgeAdapter } from "./vercel-edge-adapter";
5
+ export { AWSLambdaAdapter } from "./aws-lambda-adapter";
6
+ export { CloudflareWorkersAdapter } from "./cloudflare-workers-adapter";
7
+
8
+ // Re-export types
9
+ export type {
10
+ RuntimeType,
11
+ RuntimeAdapter,
12
+ RuntimeConfig,
13
+ RuntimeMoroOptions,
14
+ RuntimeHttpResponse,
15
+ } from "../../types/runtime";
16
+
17
+ // Re-export specific runtime types
18
+ export type {
19
+ LambdaEvent,
20
+ LambdaContext,
21
+ LambdaResponse,
22
+ } from "./aws-lambda-adapter";
23
+ export type { WorkersEnv, WorkersContext } from "./cloudflare-workers-adapter";
24
+
25
+ // Runtime factory functions
26
+ import { NodeRuntimeAdapter } from "./node-adapter";
27
+ import { VercelEdgeAdapter } from "./vercel-edge-adapter";
28
+ import { AWSLambdaAdapter } from "./aws-lambda-adapter";
29
+ import { CloudflareWorkersAdapter } from "./cloudflare-workers-adapter";
30
+ import { RuntimeType, RuntimeAdapter } from "../../types/runtime";
31
+
32
+ export function createRuntimeAdapter(type: RuntimeType): RuntimeAdapter {
33
+ switch (type) {
34
+ case "node":
35
+ return new NodeRuntimeAdapter();
36
+ case "vercel-edge":
37
+ return new VercelEdgeAdapter();
38
+ case "aws-lambda":
39
+ return new AWSLambdaAdapter();
40
+ case "cloudflare-workers":
41
+ return new CloudflareWorkersAdapter();
42
+ default:
43
+ throw new Error(`Unsupported runtime type: ${type}`);
44
+ }
45
+ }
46
+
47
+ // Convenience functions for creating runtime-specific handlers
48
+ export function createNodeHandler(
49
+ handler: (req: any, res: any) => Promise<void>,
50
+ ) {
51
+ const adapter = new NodeRuntimeAdapter();
52
+ return adapter.createServer(handler);
53
+ }
54
+
55
+ export function createEdgeHandler(
56
+ handler: (req: any, res: any) => Promise<void>,
57
+ ) {
58
+ const adapter = new VercelEdgeAdapter();
59
+ return adapter.createServer(handler);
60
+ }
61
+
62
+ export function createLambdaHandler(
63
+ handler: (req: any, res: any) => Promise<void>,
64
+ ) {
65
+ const adapter = new AWSLambdaAdapter();
66
+ return adapter.createServer(handler);
67
+ }
68
+
69
+ export function createWorkerHandler(
70
+ handler: (req: any, res: any) => Promise<void>,
71
+ ) {
72
+ const adapter = new CloudflareWorkersAdapter();
73
+ return adapter.createServer(handler);
74
+ }
@@ -0,0 +1,210 @@
1
+ // Node.js runtime adapter
2
+ import { IncomingMessage, ServerResponse } from "http";
3
+ import { BaseRuntimeAdapter } from "./base-adapter";
4
+ import { HttpRequest, HttpResponse } from "../../types/http";
5
+ import { RuntimeHttpResponse } from "../../types/runtime";
6
+ import { MoroHttpServer } from "../http/http-server";
7
+
8
+ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
9
+ readonly type = "node" as const;
10
+
11
+ async adaptRequest(req: IncomingMessage): Promise<HttpRequest> {
12
+ const { pathname, query } = this.parseUrl(req.url || "/");
13
+
14
+ // Parse body for POST/PUT/PATCH requests
15
+ let body: any;
16
+ if (["POST", "PUT", "PATCH"].includes(req.method!)) {
17
+ body = await this.parseRequestBody(req);
18
+ }
19
+
20
+ const baseRequest = {
21
+ // Copy IncomingMessage properties we need
22
+ method: req.method!,
23
+ url: req.url!,
24
+ headers: req.headers as Record<string, string>,
25
+ httpVersion: req.httpVersion,
26
+ httpVersionMajor: req.httpVersionMajor,
27
+ httpVersionMinor: req.httpVersionMinor,
28
+ socket: req.socket,
29
+
30
+ // Add MoroJS-specific properties
31
+ path: pathname,
32
+ query,
33
+ body,
34
+ ip: this.getClientIP(req),
35
+ params: {},
36
+ requestId: "",
37
+ cookies: {},
38
+ files: {},
39
+ } as Partial<HttpRequest>;
40
+
41
+ return this.enhanceRequest(baseRequest);
42
+ }
43
+
44
+ async adaptResponse(
45
+ moroResponse: HttpResponse | RuntimeHttpResponse,
46
+ req: IncomingMessage,
47
+ ): Promise<ServerResponse> {
48
+ // For Node.js, we typically work with the actual ServerResponse
49
+ // This method is mainly for converting mock responses back to real ones
50
+ return moroResponse as any;
51
+ }
52
+
53
+ createServer(
54
+ handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
55
+ ): MoroHttpServer {
56
+ const httpServer = new MoroHttpServer();
57
+
58
+ // Replace the default request handler with our runtime-aware handler
59
+ const originalServer = httpServer.getServer();
60
+ originalServer.removeAllListeners("request");
61
+
62
+ originalServer.on(
63
+ "request",
64
+ async (req: IncomingMessage, res: ServerResponse) => {
65
+ try {
66
+ const moroReq = await this.adaptRequest(req);
67
+ const moroRes = this.enhanceResponse(res);
68
+
69
+ await handler(moroReq, moroRes);
70
+ } catch (error) {
71
+ if (!res.headersSent) {
72
+ res.statusCode = 500;
73
+ res.setHeader("Content-Type", "application/json");
74
+ res.end(
75
+ JSON.stringify({
76
+ success: false,
77
+ error: "Internal server error",
78
+ message:
79
+ error instanceof Error ? error.message : "Unknown error",
80
+ }),
81
+ );
82
+ }
83
+ }
84
+ },
85
+ );
86
+
87
+ return httpServer;
88
+ }
89
+
90
+ listen(
91
+ server: MoroHttpServer,
92
+ port: number,
93
+ host?: string,
94
+ callback?: () => void,
95
+ ): void {
96
+ server.listen(port, host as any, callback);
97
+ }
98
+
99
+ // Helper methods
100
+ private async parseRequestBody(req: IncomingMessage): Promise<any> {
101
+ return new Promise((resolve, reject) => {
102
+ let body = "";
103
+ req.on("data", (chunk) => {
104
+ body += chunk.toString();
105
+ });
106
+ req.on("end", () => {
107
+ try {
108
+ const contentType = req.headers["content-type"] || "";
109
+ resolve(this.parseBody(body, contentType));
110
+ } catch (error) {
111
+ reject(error);
112
+ }
113
+ });
114
+ req.on("error", reject);
115
+ });
116
+ }
117
+
118
+ private getClientIP(req: IncomingMessage): string {
119
+ const forwarded = req.headers["x-forwarded-for"] as string;
120
+ if (forwarded) {
121
+ return forwarded.split(",")[0].trim();
122
+ }
123
+ return req.socket.remoteAddress || "unknown";
124
+ }
125
+
126
+ private enhanceResponse(res: ServerResponse): HttpResponse {
127
+ const enhanced = res as any;
128
+
129
+ // Add MoroJS response methods if they don't exist
130
+ if (!enhanced.json) {
131
+ enhanced.json = function (data: any) {
132
+ this.setHeader("Content-Type", "application/json");
133
+ this.end(JSON.stringify(data));
134
+ };
135
+ }
136
+
137
+ if (!enhanced.status) {
138
+ enhanced.status = function (code: number) {
139
+ this.statusCode = code;
140
+ return this;
141
+ };
142
+ }
143
+
144
+ if (!enhanced.send) {
145
+ enhanced.send = function (data: string | Buffer) {
146
+ this.end(data);
147
+ };
148
+ }
149
+
150
+ if (!enhanced.cookie) {
151
+ enhanced.cookie = function (name: string, value: string, options?: any) {
152
+ const cookieString = `${name}=${value}`;
153
+ this.setHeader("Set-Cookie", cookieString);
154
+ return this;
155
+ };
156
+ }
157
+
158
+ if (!enhanced.clearCookie) {
159
+ enhanced.clearCookie = function (name: string, options?: any) {
160
+ this.setHeader(
161
+ "Set-Cookie",
162
+ `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`,
163
+ );
164
+ return this;
165
+ };
166
+ }
167
+
168
+ if (!enhanced.redirect) {
169
+ enhanced.redirect = function (url: string, status?: number) {
170
+ this.statusCode = status || 302;
171
+ this.setHeader("Location", url);
172
+ this.end();
173
+ };
174
+ }
175
+
176
+ if (!enhanced.sendFile) {
177
+ enhanced.sendFile = async function (filePath: string) {
178
+ const fs = await import("fs");
179
+ const path = await import("path");
180
+
181
+ try {
182
+ const data = await fs.promises.readFile(filePath);
183
+ const ext = path.extname(filePath);
184
+
185
+ // Basic content type detection
186
+ const contentTypes: Record<string, string> = {
187
+ ".html": "text/html",
188
+ ".js": "application/javascript",
189
+ ".css": "text/css",
190
+ ".json": "application/json",
191
+ ".png": "image/png",
192
+ ".jpg": "image/jpeg",
193
+ ".jpeg": "image/jpeg",
194
+ ".gif": "image/gif",
195
+ ".svg": "image/svg+xml",
196
+ };
197
+
198
+ const contentType = contentTypes[ext] || "application/octet-stream";
199
+ this.setHeader("Content-Type", contentType);
200
+ this.end(data);
201
+ } catch (error) {
202
+ this.statusCode = 404;
203
+ this.end("File not found");
204
+ }
205
+ };
206
+ }
207
+
208
+ return enhanced;
209
+ }
210
+ }