@c9up/ream 0.1.3

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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/Application.d.ts +71 -0
  4. package/dist/Application.d.ts.map +1 -0
  5. package/dist/Application.js +151 -0
  6. package/dist/Application.js.map +1 -0
  7. package/dist/Codemods.d.ts +16 -0
  8. package/dist/Codemods.d.ts.map +1 -0
  9. package/dist/Codemods.js +277 -0
  10. package/dist/Codemods.js.map +1 -0
  11. package/dist/ConfigLoader.d.ts +29 -0
  12. package/dist/ConfigLoader.d.ts.map +1 -0
  13. package/dist/ConfigLoader.js +43 -0
  14. package/dist/ConfigLoader.js.map +1 -0
  15. package/dist/ErrorBoundary.d.ts +51 -0
  16. package/dist/ErrorBoundary.d.ts.map +1 -0
  17. package/dist/ErrorBoundary.js +122 -0
  18. package/dist/ErrorBoundary.js.map +1 -0
  19. package/dist/GracefulShutdown.d.ts +28 -0
  20. package/dist/GracefulShutdown.d.ts.map +1 -0
  21. package/dist/GracefulShutdown.js +55 -0
  22. package/dist/GracefulShutdown.js.map +1 -0
  23. package/dist/HealthCheck.d.ts +42 -0
  24. package/dist/HealthCheck.d.ts.map +1 -0
  25. package/dist/HealthCheck.js +65 -0
  26. package/dist/HealthCheck.js.map +1 -0
  27. package/dist/HotReload.d.ts +28 -0
  28. package/dist/HotReload.d.ts.map +1 -0
  29. package/dist/HotReload.js +60 -0
  30. package/dist/HotReload.js.map +1 -0
  31. package/dist/HttpKernel.d.ts +62 -0
  32. package/dist/HttpKernel.d.ts.map +1 -0
  33. package/dist/HttpKernel.js +210 -0
  34. package/dist/HttpKernel.js.map +1 -0
  35. package/dist/Ignitor.d.ts +195 -0
  36. package/dist/Ignitor.d.ts.map +1 -0
  37. package/dist/Ignitor.js +505 -0
  38. package/dist/Ignitor.js.map +1 -0
  39. package/dist/Provider.d.ts +54 -0
  40. package/dist/Provider.d.ts.map +1 -0
  41. package/dist/Provider.js +37 -0
  42. package/dist/Provider.js.map +1 -0
  43. package/dist/bodyparser/BodyParserMiddleware.d.ts +38 -0
  44. package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -0
  45. package/dist/bodyparser/BodyParserMiddleware.js +143 -0
  46. package/dist/bodyparser/BodyParserMiddleware.js.map +1 -0
  47. package/dist/bodyparser/MultipartFile.d.ts +77 -0
  48. package/dist/bodyparser/MultipartFile.d.ts.map +1 -0
  49. package/dist/bodyparser/MultipartFile.js +138 -0
  50. package/dist/bodyparser/MultipartFile.js.map +1 -0
  51. package/dist/bodyparser/parseSize.d.ts +6 -0
  52. package/dist/bodyparser/parseSize.d.ts.map +1 -0
  53. package/dist/bodyparser/parseSize.js +21 -0
  54. package/dist/bodyparser/parseSize.js.map +1 -0
  55. package/dist/bootstrap/hyper-server.d.ts +27 -0
  56. package/dist/bootstrap/hyper-server.d.ts.map +1 -0
  57. package/dist/bootstrap/hyper-server.js +63 -0
  58. package/dist/bootstrap/hyper-server.js.map +1 -0
  59. package/dist/console/CommandRunner.d.ts +18 -0
  60. package/dist/console/CommandRunner.d.ts.map +1 -0
  61. package/dist/console/CommandRunner.js +65 -0
  62. package/dist/console/CommandRunner.js.map +1 -0
  63. package/dist/container/Container.d.ts +60 -0
  64. package/dist/container/Container.d.ts.map +1 -0
  65. package/dist/container/Container.js +329 -0
  66. package/dist/container/Container.js.map +1 -0
  67. package/dist/container/types.d.ts +25 -0
  68. package/dist/container/types.d.ts.map +1 -0
  69. package/dist/container/types.js +6 -0
  70. package/dist/container/types.js.map +1 -0
  71. package/dist/decorators/Lazy.d.ts +19 -0
  72. package/dist/decorators/Lazy.d.ts.map +1 -0
  73. package/dist/decorators/Lazy.js +53 -0
  74. package/dist/decorators/Lazy.js.map +1 -0
  75. package/dist/decorators/Service.d.ts +48 -0
  76. package/dist/decorators/Service.d.ts.map +1 -0
  77. package/dist/decorators/Service.js +70 -0
  78. package/dist/decorators/Service.js.map +1 -0
  79. package/dist/errors/FuzzyMatcher.d.ts +41 -0
  80. package/dist/errors/FuzzyMatcher.d.ts.map +1 -0
  81. package/dist/errors/FuzzyMatcher.js +81 -0
  82. package/dist/errors/FuzzyMatcher.js.map +1 -0
  83. package/dist/errors/ModuleErrors.d.ts +41 -0
  84. package/dist/errors/ModuleErrors.d.ts.map +1 -0
  85. package/dist/errors/ModuleErrors.js +65 -0
  86. package/dist/errors/ModuleErrors.js.map +1 -0
  87. package/dist/errors/PipelineStageError.d.ts +31 -0
  88. package/dist/errors/PipelineStageError.d.ts.map +1 -0
  89. package/dist/errors/PipelineStageError.js +77 -0
  90. package/dist/errors/PipelineStageError.js.map +1 -0
  91. package/dist/errors/ReamError.d.ts +50 -0
  92. package/dist/errors/ReamError.d.ts.map +1 -0
  93. package/dist/errors/ReamError.js +108 -0
  94. package/dist/errors/ReamError.js.map +1 -0
  95. package/dist/events/Emitter.d.ts +124 -0
  96. package/dist/events/Emitter.d.ts.map +1 -0
  97. package/dist/events/Emitter.js +271 -0
  98. package/dist/events/Emitter.js.map +1 -0
  99. package/dist/events/EventsProvider.d.ts +28 -0
  100. package/dist/events/EventsProvider.d.ts.map +1 -0
  101. package/dist/events/EventsProvider.js +36 -0
  102. package/dist/events/EventsProvider.js.map +1 -0
  103. package/dist/events/config.d.ts +8 -0
  104. package/dist/events/config.d.ts.map +1 -0
  105. package/dist/events/config.js +4 -0
  106. package/dist/events/config.js.map +1 -0
  107. package/dist/events/configure.d.ts +10 -0
  108. package/dist/events/configure.d.ts.map +1 -0
  109. package/dist/events/configure.js +11 -0
  110. package/dist/events/configure.js.map +1 -0
  111. package/dist/events/helix/helpers.d.ts +62 -0
  112. package/dist/events/helix/helpers.d.ts.map +1 -0
  113. package/dist/events/helix/helpers.js +187 -0
  114. package/dist/events/helix/helpers.js.map +1 -0
  115. package/dist/events/index.d.ts +17 -0
  116. package/dist/events/index.d.ts.map +1 -0
  117. package/dist/events/index.js +15 -0
  118. package/dist/events/index.js.map +1 -0
  119. package/dist/events/native.d.ts +21 -0
  120. package/dist/events/native.d.ts.map +1 -0
  121. package/dist/events/native.js +17 -0
  122. package/dist/events/native.js.map +1 -0
  123. package/dist/events/services/main.d.ts +18 -0
  124. package/dist/events/services/main.d.ts.map +1 -0
  125. package/dist/events/services/main.js +31 -0
  126. package/dist/events/services/main.js.map +1 -0
  127. package/dist/events/testing/FakeBus.d.ts +66 -0
  128. package/dist/events/testing/FakeBus.d.ts.map +1 -0
  129. package/dist/events/testing/FakeBus.js +356 -0
  130. package/dist/events/testing/FakeBus.js.map +1 -0
  131. package/dist/graphql/GraphQLEngine.d.ts +69 -0
  132. package/dist/graphql/GraphQLEngine.d.ts.map +1 -0
  133. package/dist/graphql/GraphQLEngine.js +309 -0
  134. package/dist/graphql/GraphQLEngine.js.map +1 -0
  135. package/dist/graphql/GraphQLProvider.d.ts +32 -0
  136. package/dist/graphql/GraphQLProvider.d.ts.map +1 -0
  137. package/dist/graphql/GraphQLProvider.js +49 -0
  138. package/dist/graphql/GraphQLProvider.js.map +1 -0
  139. package/dist/helpers/base64.d.ts +40 -0
  140. package/dist/helpers/base64.d.ts.map +1 -0
  141. package/dist/helpers/base64.js +70 -0
  142. package/dist/helpers/base64.js.map +1 -0
  143. package/dist/helpers/index.d.ts +7 -0
  144. package/dist/helpers/index.d.ts.map +1 -0
  145. package/dist/helpers/index.js +5 -0
  146. package/dist/helpers/index.js.map +1 -0
  147. package/dist/helpers/is.d.ts +101 -0
  148. package/dist/helpers/is.d.ts.map +1 -0
  149. package/dist/helpers/is.js +151 -0
  150. package/dist/helpers/is.js.map +1 -0
  151. package/dist/helpers/napi-loader.d.ts +46 -0
  152. package/dist/helpers/napi-loader.d.ts.map +1 -0
  153. package/dist/helpers/napi-loader.js +69 -0
  154. package/dist/helpers/napi-loader.js.map +1 -0
  155. package/dist/helpers/safeEqual.d.ts +9 -0
  156. package/dist/helpers/safeEqual.d.ts.map +1 -0
  157. package/dist/helpers/safeEqual.js +16 -0
  158. package/dist/helpers/safeEqual.js.map +1 -0
  159. package/dist/helpers/string.d.ts +161 -0
  160. package/dist/helpers/string.d.ts.map +1 -0
  161. package/dist/helpers/string.js +429 -0
  162. package/dist/helpers/string.js.map +1 -0
  163. package/dist/helpers/types.d.ts +83 -0
  164. package/dist/helpers/types.d.ts.map +1 -0
  165. package/dist/helpers/types.js +6 -0
  166. package/dist/helpers/types.js.map +1 -0
  167. package/dist/http/Exception.d.ts +103 -0
  168. package/dist/http/Exception.d.ts.map +1 -0
  169. package/dist/http/Exception.js +228 -0
  170. package/dist/http/Exception.js.map +1 -0
  171. package/dist/http/HttpContext.d.ts +69 -0
  172. package/dist/http/HttpContext.d.ts.map +1 -0
  173. package/dist/http/HttpContext.js +55 -0
  174. package/dist/http/HttpContext.js.map +1 -0
  175. package/dist/http/RedirectBuilder.d.ts +31 -0
  176. package/dist/http/RedirectBuilder.d.ts.map +1 -0
  177. package/dist/http/RedirectBuilder.js +75 -0
  178. package/dist/http/RedirectBuilder.js.map +1 -0
  179. package/dist/http/Request.d.ts +160 -0
  180. package/dist/http/Request.d.ts.map +1 -0
  181. package/dist/http/Request.js +484 -0
  182. package/dist/http/Request.js.map +1 -0
  183. package/dist/http/Response.d.ts +114 -0
  184. package/dist/http/Response.d.ts.map +1 -0
  185. package/dist/http/Response.js +303 -0
  186. package/dist/http/Response.js.map +1 -0
  187. package/dist/http/SseStream.d.ts +89 -0
  188. package/dist/http/SseStream.d.ts.map +1 -0
  189. package/dist/http/SseStream.js +228 -0
  190. package/dist/http/SseStream.js.map +1 -0
  191. package/dist/http/urlDecode.d.ts +8 -0
  192. package/dist/http/urlDecode.d.ts.map +1 -0
  193. package/dist/http/urlDecode.js +18 -0
  194. package/dist/http/urlDecode.js.map +1 -0
  195. package/dist/index.d.ts +92 -0
  196. package/dist/index.d.ts.map +1 -0
  197. package/dist/index.js +67 -0
  198. package/dist/index.js.map +1 -0
  199. package/dist/middleware/Pipeline.d.ts +36 -0
  200. package/dist/middleware/Pipeline.d.ts.map +1 -0
  201. package/dist/middleware/Pipeline.js +104 -0
  202. package/dist/middleware/Pipeline.js.map +1 -0
  203. package/dist/openapi/OpenApiGenerator.d.ts +58 -0
  204. package/dist/openapi/OpenApiGenerator.d.ts.map +1 -0
  205. package/dist/openapi/OpenApiGenerator.js +192 -0
  206. package/dist/openapi/OpenApiGenerator.js.map +1 -0
  207. package/dist/openapi/OpenApiMiddleware.d.ts +24 -0
  208. package/dist/openapi/OpenApiMiddleware.d.ts.map +1 -0
  209. package/dist/openapi/OpenApiMiddleware.js +78 -0
  210. package/dist/openapi/OpenApiMiddleware.js.map +1 -0
  211. package/dist/openapi/OpenApiProvider.d.ts +36 -0
  212. package/dist/openapi/OpenApiProvider.d.ts.map +1 -0
  213. package/dist/openapi/OpenApiProvider.js +42 -0
  214. package/dist/openapi/OpenApiProvider.js.map +1 -0
  215. package/dist/resources/ApiResource.d.ts +45 -0
  216. package/dist/resources/ApiResource.d.ts.map +1 -0
  217. package/dist/resources/ApiResource.js +58 -0
  218. package/dist/resources/ApiResource.js.map +1 -0
  219. package/dist/router/Router.d.ts +205 -0
  220. package/dist/router/Router.d.ts.map +1 -0
  221. package/dist/router/Router.js +552 -0
  222. package/dist/router/Router.js.map +1 -0
  223. package/dist/rpc/RpcProvider.d.ts +34 -0
  224. package/dist/rpc/RpcProvider.d.ts.map +1 -0
  225. package/dist/rpc/RpcProvider.js +37 -0
  226. package/dist/rpc/RpcProvider.js.map +1 -0
  227. package/dist/rpc/RpcRouter.d.ts +61 -0
  228. package/dist/rpc/RpcRouter.d.ts.map +1 -0
  229. package/dist/rpc/RpcRouter.js +187 -0
  230. package/dist/rpc/RpcRouter.js.map +1 -0
  231. package/dist/scheduler/Schedule.d.ts +53 -0
  232. package/dist/scheduler/Schedule.d.ts.map +1 -0
  233. package/dist/scheduler/Schedule.js +76 -0
  234. package/dist/scheduler/Schedule.js.map +1 -0
  235. package/dist/scheduler/ScheduleProvider.d.ts +56 -0
  236. package/dist/scheduler/ScheduleProvider.d.ts.map +1 -0
  237. package/dist/scheduler/ScheduleProvider.js +145 -0
  238. package/dist/scheduler/ScheduleProvider.js.map +1 -0
  239. package/dist/scheduler/Scheduler.d.ts +209 -0
  240. package/dist/scheduler/Scheduler.d.ts.map +1 -0
  241. package/dist/scheduler/Scheduler.js +432 -0
  242. package/dist/scheduler/Scheduler.js.map +1 -0
  243. package/dist/scheduler/index.d.ts +14 -0
  244. package/dist/scheduler/index.d.ts.map +1 -0
  245. package/dist/scheduler/index.js +6 -0
  246. package/dist/scheduler/index.js.map +1 -0
  247. package/dist/scheduler/locks/LockBackend.d.ts +37 -0
  248. package/dist/scheduler/locks/LockBackend.d.ts.map +1 -0
  249. package/dist/scheduler/locks/LockBackend.js +13 -0
  250. package/dist/scheduler/locks/LockBackend.js.map +1 -0
  251. package/dist/scheduler/locks/MemoryLockBackend.d.ts +39 -0
  252. package/dist/scheduler/locks/MemoryLockBackend.d.ts.map +1 -0
  253. package/dist/scheduler/locks/MemoryLockBackend.js +71 -0
  254. package/dist/scheduler/locks/MemoryLockBackend.js.map +1 -0
  255. package/dist/scheduler/observability/ErrorReporter.d.ts +15 -0
  256. package/dist/scheduler/observability/ErrorReporter.d.ts.map +1 -0
  257. package/dist/scheduler/observability/ErrorReporter.js +13 -0
  258. package/dist/scheduler/observability/ErrorReporter.js.map +1 -0
  259. package/dist/scheduler/observability/ScheduleEvent.d.ts +57 -0
  260. package/dist/scheduler/observability/ScheduleEvent.d.ts.map +1 -0
  261. package/dist/scheduler/observability/ScheduleEvent.js +12 -0
  262. package/dist/scheduler/observability/ScheduleEvent.js.map +1 -0
  263. package/dist/scheduler/observability/ScheduleEventSink.d.ts +20 -0
  264. package/dist/scheduler/observability/ScheduleEventSink.d.ts.map +1 -0
  265. package/dist/scheduler/observability/ScheduleEventSink.js +17 -0
  266. package/dist/scheduler/observability/ScheduleEventSink.js.map +1 -0
  267. package/dist/scheduler/observability/StatsTracker.d.ts +50 -0
  268. package/dist/scheduler/observability/StatsTracker.d.ts.map +1 -0
  269. package/dist/scheduler/observability/StatsTracker.js +96 -0
  270. package/dist/scheduler/observability/StatsTracker.js.map +1 -0
  271. package/dist/security/CookieSigner.d.ts +13 -0
  272. package/dist/security/CookieSigner.d.ts.map +1 -0
  273. package/dist/security/CookieSigner.js +51 -0
  274. package/dist/security/CookieSigner.js.map +1 -0
  275. package/dist/security/SignedUrl.d.ts +17 -0
  276. package/dist/security/SignedUrl.d.ts.map +1 -0
  277. package/dist/security/SignedUrl.js +63 -0
  278. package/dist/security/SignedUrl.js.map +1 -0
  279. package/dist/security/crypto.d.ts +25 -0
  280. package/dist/security/crypto.d.ts.map +1 -0
  281. package/dist/security/crypto.js +82 -0
  282. package/dist/security/crypto.js.map +1 -0
  283. package/dist/server/HyperServer.d.ts +64 -0
  284. package/dist/server/HyperServer.d.ts.map +1 -0
  285. package/dist/server/HyperServer.js +54 -0
  286. package/dist/server/HyperServer.js.map +1 -0
  287. package/dist/server/Server.d.ts +68 -0
  288. package/dist/server/Server.d.ts.map +1 -0
  289. package/dist/server/Server.js +113 -0
  290. package/dist/server/Server.js.map +1 -0
  291. package/dist/services/app.d.ts +14 -0
  292. package/dist/services/app.d.ts.map +1 -0
  293. package/dist/services/app.js +27 -0
  294. package/dist/services/app.js.map +1 -0
  295. package/dist/services/router.d.ts +21 -0
  296. package/dist/services/router.d.ts.map +1 -0
  297. package/dist/services/router.js +36 -0
  298. package/dist/services/router.js.map +1 -0
  299. package/dist/services/server.d.ts +16 -0
  300. package/dist/services/server.d.ts.map +1 -0
  301. package/dist/services/server.js +32 -0
  302. package/dist/services/server.js.map +1 -0
  303. package/dist/session/Session.d.ts +88 -0
  304. package/dist/session/Session.d.ts.map +1 -0
  305. package/dist/session/Session.js +186 -0
  306. package/dist/session/Session.js.map +1 -0
  307. package/dist/session/SessionMiddleware.d.ts +16 -0
  308. package/dist/session/SessionMiddleware.d.ts.map +1 -0
  309. package/dist/session/SessionMiddleware.js +132 -0
  310. package/dist/session/SessionMiddleware.js.map +1 -0
  311. package/dist/session/drivers/CookieDriver.d.ts +17 -0
  312. package/dist/session/drivers/CookieDriver.d.ts.map +1 -0
  313. package/dist/session/drivers/CookieDriver.js +42 -0
  314. package/dist/session/drivers/CookieDriver.js.map +1 -0
  315. package/dist/session/drivers/MemoryDriver.d.ts +9 -0
  316. package/dist/session/drivers/MemoryDriver.d.ts.map +1 -0
  317. package/dist/session/drivers/MemoryDriver.js +24 -0
  318. package/dist/session/drivers/MemoryDriver.js.map +1 -0
  319. package/dist/storage/S3Driver.d.ts +27 -0
  320. package/dist/storage/S3Driver.d.ts.map +1 -0
  321. package/dist/storage/S3Driver.js +135 -0
  322. package/dist/storage/S3Driver.js.map +1 -0
  323. package/dist/storage/StaticMiddleware.d.ts +27 -0
  324. package/dist/storage/StaticMiddleware.d.ts.map +1 -0
  325. package/dist/storage/StaticMiddleware.js +153 -0
  326. package/dist/storage/StaticMiddleware.js.map +1 -0
  327. package/dist/storage/StaticProvider.d.ts +26 -0
  328. package/dist/storage/StaticProvider.d.ts.map +1 -0
  329. package/dist/storage/StaticProvider.js +31 -0
  330. package/dist/storage/StaticProvider.js.map +1 -0
  331. package/dist/storage/StorageManager.d.ts +31 -0
  332. package/dist/storage/StorageManager.d.ts.map +1 -0
  333. package/dist/storage/StorageManager.js +120 -0
  334. package/dist/storage/StorageManager.js.map +1 -0
  335. package/dist/testing/RequestBuilder.d.ts +67 -0
  336. package/dist/testing/RequestBuilder.d.ts.map +1 -0
  337. package/dist/testing/RequestBuilder.js +202 -0
  338. package/dist/testing/RequestBuilder.js.map +1 -0
  339. package/dist/testing/TestClient.d.ts +96 -0
  340. package/dist/testing/TestClient.d.ts.map +1 -0
  341. package/dist/testing/TestClient.js +263 -0
  342. package/dist/testing/TestClient.js.map +1 -0
  343. package/dist/types/helpers.d.ts +47 -0
  344. package/dist/types/helpers.d.ts.map +1 -0
  345. package/dist/types/helpers.js +5 -0
  346. package/dist/types/helpers.js.map +1 -0
  347. package/events.darwin-arm64.node +0 -0
  348. package/events.darwin-x64.node +0 -0
  349. package/events.linux-arm64-gnu.node +0 -0
  350. package/events.linux-x64-gnu.node +0 -0
  351. package/events.win32-x64-msvc.node +0 -0
  352. package/index.darwin-arm64.node +0 -0
  353. package/index.darwin-x64.node +0 -0
  354. package/index.linux-arm64-gnu.node +0 -0
  355. package/index.linux-x64-gnu.node +0 -0
  356. package/index.win32-x64-msvc.node +0 -0
  357. package/package.json +106 -0
  358. package/scheduler.darwin-arm64.node +0 -0
  359. package/scheduler.darwin-x64.node +0 -0
  360. package/scheduler.linux-arm64-gnu.node +0 -0
  361. package/scheduler.linux-x64-gnu.node +0 -0
  362. package/scheduler.win32-x64-msvc.node +0 -0
  363. package/scripts/copy-napi.mjs +113 -0
  364. package/src/Application.ts +177 -0
  365. package/src/Codemods.ts +343 -0
  366. package/src/ConfigLoader.ts +49 -0
  367. package/src/ErrorBoundary.ts +157 -0
  368. package/src/GracefulShutdown.ts +80 -0
  369. package/src/HealthCheck.ts +96 -0
  370. package/src/HotReload.ts +78 -0
  371. package/src/HttpKernel.ts +305 -0
  372. package/src/Ignitor.ts +656 -0
  373. package/src/Provider.ts +74 -0
  374. package/src/bodyparser/BodyParserMiddleware.ts +183 -0
  375. package/src/bodyparser/MultipartFile.ts +181 -0
  376. package/src/bodyparser/parseSize.ts +19 -0
  377. package/src/bootstrap/hyper-server.ts +78 -0
  378. package/src/console/CommandRunner.ts +82 -0
  379. package/src/container/Container.ts +383 -0
  380. package/src/container/types.ts +30 -0
  381. package/src/decorators/Lazy.ts +57 -0
  382. package/src/decorators/Service.ts +85 -0
  383. package/src/errors/FuzzyMatcher.ts +93 -0
  384. package/src/errors/ModuleErrors.ts +73 -0
  385. package/src/errors/PipelineStageError.ts +97 -0
  386. package/src/errors/ReamError.ts +138 -0
  387. package/src/events/Emitter.ts +333 -0
  388. package/src/events/EventsProvider.ts +58 -0
  389. package/src/events/config.ts +10 -0
  390. package/src/events/configure.ts +19 -0
  391. package/src/events/helix/helpers.ts +260 -0
  392. package/src/events/index.ts +22 -0
  393. package/src/events/native.ts +37 -0
  394. package/src/events/services/main.ts +39 -0
  395. package/src/events/testing/FakeBus.ts +420 -0
  396. package/src/graphql/GraphQLEngine.ts +421 -0
  397. package/src/graphql/GraphQLProvider.ts +59 -0
  398. package/src/helpers/base64.ts +72 -0
  399. package/src/helpers/index.ts +6 -0
  400. package/src/helpers/is.ts +162 -0
  401. package/src/helpers/napi-loader.ts +106 -0
  402. package/src/helpers/safeEqual.ts +15 -0
  403. package/src/helpers/string.ts +469 -0
  404. package/src/helpers/types.ts +100 -0
  405. package/src/http/Exception.ts +272 -0
  406. package/src/http/HttpContext.ts +108 -0
  407. package/src/http/RedirectBuilder.ts +89 -0
  408. package/src/http/Request.ts +540 -0
  409. package/src/http/Response.ts +351 -0
  410. package/src/http/SseStream.ts +250 -0
  411. package/src/http/urlDecode.ts +18 -0
  412. package/src/index.ts +263 -0
  413. package/src/middleware/Pipeline.ts +136 -0
  414. package/src/openapi/OpenApiGenerator.ts +254 -0
  415. package/src/openapi/OpenApiMiddleware.ts +101 -0
  416. package/src/openapi/OpenApiProvider.ts +67 -0
  417. package/src/resources/ApiResource.ts +79 -0
  418. package/src/router/Router.ts +733 -0
  419. package/src/rpc/RpcProvider.ts +54 -0
  420. package/src/rpc/RpcRouter.ts +243 -0
  421. package/src/scheduler/Schedule.ts +96 -0
  422. package/src/scheduler/ScheduleProvider.ts +177 -0
  423. package/src/scheduler/Scheduler.ts +601 -0
  424. package/src/scheduler/index.ts +24 -0
  425. package/src/scheduler/locks/LockBackend.ts +38 -0
  426. package/src/scheduler/locks/MemoryLockBackend.ts +85 -0
  427. package/src/scheduler/observability/ErrorReporter.ts +13 -0
  428. package/src/scheduler/observability/ScheduleEvent.ts +61 -0
  429. package/src/scheduler/observability/ScheduleEventSink.ts +21 -0
  430. package/src/scheduler/observability/StatsTracker.ts +134 -0
  431. package/src/security/CookieSigner.ts +54 -0
  432. package/src/security/SignedUrl.ts +71 -0
  433. package/src/security/crypto.ts +98 -0
  434. package/src/server/HyperServer.ts +121 -0
  435. package/src/server/Server.ts +147 -0
  436. package/src/services/app.ts +34 -0
  437. package/src/services/router.ts +44 -0
  438. package/src/services/server.ts +40 -0
  439. package/src/session/Session.ts +231 -0
  440. package/src/session/SessionMiddleware.ts +153 -0
  441. package/src/session/drivers/CookieDriver.ts +48 -0
  442. package/src/session/drivers/MemoryDriver.ts +29 -0
  443. package/src/storage/S3Driver.ts +171 -0
  444. package/src/storage/StaticMiddleware.ts +182 -0
  445. package/src/storage/StaticProvider.ts +40 -0
  446. package/src/storage/StorageManager.ts +142 -0
  447. package/src/testing/RequestBuilder.ts +275 -0
  448. package/src/testing/TestClient.ts +344 -0
  449. package/src/types/helpers.ts +52 -0
  450. package/swcrc.app.json +17 -0
  451. package/tsconfig.app.json +21 -0
package/src/Ignitor.ts ADDED
@@ -0,0 +1,656 @@
1
+ /**
2
+ * Ignitor — AdonisJS-compatible application bootstrap.
3
+ *
4
+ * Usage (like AdonisJS):
5
+ * new Ignitor(APP_ROOT, { importer: IMPORTER })
6
+ * .tap((app) => {
7
+ * app.booting(async () => { await import('#start/env') })
8
+ * app.listen('SIGTERM', () => app.terminate())
9
+ * })
10
+ * .httpServer()
11
+ * .start()
12
+ *
13
+ * @implements FR17, FR20, FR23
14
+ */
15
+
16
+ import { Application } from './Application.js'
17
+ import type { ErrorEvent } from './ErrorBoundary.js'
18
+ import { ErrorBoundary } from './ErrorBoundary.js'
19
+ import { ReamError } from './errors/ReamError.js'
20
+ import type { Emitter } from './events/Emitter.js'
21
+ import { startHotReload } from './HotReload.js'
22
+ import type { HttpKernelRequest, HttpKernelResponse } from './HttpKernel.js'
23
+ import { createHttpKernel } from './HttpKernel.js'
24
+ import { ExceptionHandler } from './http/Exception.js'
25
+ import type { MiddlewareFunction } from './middleware/Pipeline.js'
26
+ import { MiddlewareRegistry } from './middleware/Pipeline.js'
27
+ import type { AppContext, ProviderContract } from './Provider.js'
28
+ import { callProviderPhase } from './Provider.js'
29
+ import { Router } from './router/Router.js'
30
+ import { Server } from './server/Server.js'
31
+ import { setApp } from './services/app.js'
32
+ import { setRouter } from './services/router.js'
33
+ import { setServer } from './services/server.js'
34
+
35
+ /** Application environment. */
36
+ export type AppEnvironment = 'web' | 'console' | 'test' | 'unknown'
37
+
38
+ /**
39
+ * Reamrc config — like AdonisJS adonisrc.ts with defineConfig().
40
+ */
41
+ export interface ReamrcConfig {
42
+ providers?: Array<
43
+ | (() => Promise<{ default: new (app: AppContext) => ProviderContract }>)
44
+ | {
45
+ file: () => Promise<{ default: new (app: AppContext) => ProviderContract }>
46
+ environment?: string[]
47
+ }
48
+ >
49
+ preloads?: Array<
50
+ | (() => Promise<unknown>)
51
+ | {
52
+ file: () => Promise<unknown>
53
+ environment?: string[]
54
+ }
55
+ >
56
+ commands?: Array<() => Promise<unknown>>
57
+ modules?: {
58
+ /** Path to the modules directory (relative to app root). Default: './app/modules' */
59
+ path?: string
60
+ /** Auto-loaded files in each module directory. Default: ['routes'] */
61
+ autoload?: string[]
62
+ }
63
+ tests?: {
64
+ suites?: Array<{ name: string; files: string[]; timeout?: number }>
65
+ forceExit?: boolean
66
+ }
67
+ }
68
+
69
+ /** defineConfig helper — like AdonisJS defineConfig(). */
70
+ export function defineConfig(config: ReamrcConfig): ReamrcConfig {
71
+ return config
72
+ }
73
+
74
+ /** Minimal interface for the HTTP server (NAPI or mock). */
75
+ export interface HyperServerLike {
76
+ onRequest(callback: (request: HttpKernelRequest) => Promise<HttpKernelResponse>): void
77
+ /**
78
+ * Optional — present on the real `HyperServer` (Rust-backed), absent on
79
+ * trivial test mocks. Ignitor only calls it when a shield config is set.
80
+ */
81
+ configureShield?(config: { pathTraversal: boolean; paramPollution: boolean }): void
82
+ /** Optional — same lifecycle as `configureShield`. */
83
+ configureTrustedProxies?(cidrs: string[]): void
84
+ /** Optional — same lifecycle as `configureShield`. */
85
+ configureRateLimit?(config: { max: number; windowSecs: number } | null): void
86
+ listen(): Promise<void>
87
+ port(): Promise<number>
88
+ close(): Promise<void>
89
+ // Streaming primitives — optional so mock servers (no NAPI) opt out
90
+ // by simply not implementing them; the `response.sse()` helper throws
91
+ // a clean `STREAMING_UNSUPPORTED` error when called on such a host.
92
+ registerStream?(streamId: string): Promise<boolean>
93
+ writeStream?(streamId: string, chunk: string): Promise<boolean>
94
+ closeStream?(streamId: string): Promise<boolean>
95
+ onStreamDisconnect?(streamId: string, callback: () => void): void
96
+ }
97
+
98
+ export interface IgnitorConfig {
99
+ port?: number
100
+ serverFactory?: (port: number) => HyperServerLike
101
+ importer?: (filePath: string) => Promise<unknown>
102
+ watchDirs?: string[]
103
+ }
104
+
105
+ /**
106
+ * Ignitor — boots and wires the Ream framework.
107
+ *
108
+ * Lifecycle: register → boot → start → ready → shutdown
109
+ */
110
+ export class Ignitor {
111
+ private app: Application
112
+ private router: Router
113
+ private server: Server
114
+ private middleware: MiddlewareRegistry
115
+ private errorBoundary: ErrorBoundary
116
+ private _httpServer?: HyperServerLike
117
+ private config: IgnitorConfig
118
+ private appRoot?: URL
119
+ private environment: AppEnvironment = 'unknown'
120
+ private reamrc?: ReamrcConfig
121
+ private providers: ProviderContract[] = []
122
+ private errorListeners: Array<(event: ErrorEvent) => void> = []
123
+ private phase: 'created' | 'registered' | 'booted' | 'started' | 'ready' | 'shutdown' = 'created'
124
+ private hotReloadCleanup?: () => void
125
+
126
+ // Inline configuration (for simple use or testing)
127
+ private inlineRoutes?: (router: Router) => void
128
+ private inlineMiddleware: MiddlewareFunction[] = []
129
+ private inlineNamedMiddleware: Array<[string, MiddlewareFunction]> = []
130
+ private inlineProviderFactories: Array<(app: Application) => ProviderContract> = []
131
+
132
+ /**
133
+ * Create the Ignitor.
134
+ *
135
+ * AdonisJS-style:
136
+ * new Ignitor(APP_ROOT, { importer: IMPORTER })
137
+ *
138
+ * Simple-style:
139
+ * new Ignitor({ port: 3000, serverFactory: ... })
140
+ */
141
+ constructor(appRootOrConfig?: URL | IgnitorConfig, config?: IgnitorConfig) {
142
+ if (appRootOrConfig instanceof URL) {
143
+ this.appRoot = appRootOrConfig
144
+ this.config = config ?? {}
145
+ } else {
146
+ this.config = appRootOrConfig ?? {}
147
+ }
148
+
149
+ this.app = new Application()
150
+ this.router = new Router()
151
+ this.server = new Server(this.router)
152
+ this.middleware = new MiddlewareRegistry()
153
+ this.errorBoundary = new ErrorBoundary((event) => this.handleError(event), this.isDevMode())
154
+
155
+ // Register framework services in container
156
+ this.app.container.singleton('router', () => this.router)
157
+ this.app.container.singleton('server', () => this.server)
158
+ this.app.container.singleton('middleware', () => this.middleware)
159
+ this.app.container.singleton('app', () => this.app)
160
+ // `appRoot` is the URL passed to `new Ignitor(new URL('../', import.meta.url))`.
161
+ // Providers resolve it through the container so they can interpret
162
+ // relative paths in config files (e.g. `pages.root: './resources/pages'`)
163
+ // against the project root — same convention `modules.path` uses.
164
+ if (this.appRoot) {
165
+ const root = this.appRoot
166
+ this.app.container.singleton('appRoot', () => root)
167
+ }
168
+
169
+ // Set service singletons so route/kernel files can import them
170
+ setApp(this.app)
171
+ setRouter(this.router)
172
+ setServer(this.server)
173
+ }
174
+
175
+ // ─── Configuration ────────────────────────────────────────
176
+
177
+ /**
178
+ * Access the Application instance before start.
179
+ * Like AdonisJS: .tap((app) => { app.booting(...) })
180
+ */
181
+ tap(callback: (app: Application) => void): this {
182
+ callback(this.app)
183
+ return this
184
+ }
185
+
186
+ /** Set the application environment. */
187
+ setEnvironment(env: AppEnvironment): this {
188
+ this.environment = env
189
+ return this
190
+ }
191
+
192
+ getEnvironment(): AppEnvironment {
193
+ return this.environment
194
+ }
195
+
196
+ /**
197
+ * Load the reamrc config (equivalent to adonisrc.ts).
198
+ */
199
+ useRcFile(reamrc: ReamrcConfig): this {
200
+ this.reamrc = reamrc
201
+ return this
202
+ }
203
+
204
+ // === Inline configuration (simple mode / testing) ===
205
+
206
+ /** Define routes inline (simple mode). */
207
+ routes(callback: (router: Router) => void): this {
208
+ this.inlineRoutes = callback
209
+ return this
210
+ }
211
+
212
+ /** Add global middleware inline. */
213
+ use(mw: MiddlewareFunction): this {
214
+ this.inlineMiddleware.push(mw)
215
+ return this
216
+ }
217
+
218
+ /** Register a named middleware inline. */
219
+ named(name: string, mw: MiddlewareFunction): this {
220
+ this.inlineNamedMiddleware.push([name, mw])
221
+ return this
222
+ }
223
+
224
+ /** Register a provider inline (for testing or simple apps). */
225
+ provider(factory: (app: Application) => ProviderContract): this {
226
+ this.inlineProviderFactories.push(factory)
227
+ return this
228
+ }
229
+
230
+ /** Listen for error events. */
231
+ onError(listener: (event: ErrorEvent) => void): this {
232
+ this.errorListeners.push(listener)
233
+ return this
234
+ }
235
+
236
+ /** Set a config value. */
237
+ configure(key: string, value: unknown): this {
238
+ this.app.config.set(key, value)
239
+ return this
240
+ }
241
+
242
+ // ─── Mode selection ───────────────────────────────────────
243
+
244
+ /** Configure for HTTP server mode. */
245
+ httpServer(): this {
246
+ this.environment = 'web'
247
+ return this
248
+ }
249
+
250
+ /** Configure for CLI/console mode. Returns a ConsoleKernel for dispatching commands. */
251
+ console(): ConsoleKernel {
252
+ this.environment = 'console'
253
+ return new ConsoleKernel(this)
254
+ }
255
+
256
+ /** Configure for test mode. */
257
+ testMode(): this {
258
+ this.environment = 'test'
259
+ return this
260
+ }
261
+
262
+ // ─── Lifecycle ────────────────────────────────────────────
263
+
264
+ async start(): Promise<Ignitor> {
265
+ await this.phaseRegister()
266
+ await this.phaseBoot()
267
+ await this.phaseStart()
268
+ await this.phaseReady()
269
+ return this
270
+ }
271
+
272
+ private async phaseRegister(): Promise<void> {
273
+ // Auto-load config/*.ts files into app.config
274
+ await this.autoloadConfig()
275
+
276
+ // Load providers from reamrc
277
+ if (this.reamrc?.providers) {
278
+ for (const providerEntry of this.reamrc.providers) {
279
+ const providerImport =
280
+ typeof providerEntry === 'function' ? providerEntry : providerEntry.file
281
+ const env = typeof providerEntry === 'function' ? undefined : providerEntry.environment
282
+
283
+ // Skip providers not matching current environment
284
+ if (env && !env.includes(this.environment)) continue
285
+
286
+ const mod = await providerImport()
287
+ const ProviderClass = mod.default
288
+ const instance = new ProviderClass(this.app)
289
+ this.providers.push(instance)
290
+ this.app.register(instance)
291
+ }
292
+ }
293
+
294
+ // Register inline providers
295
+ for (const factory of this.inlineProviderFactories) {
296
+ const instance = factory(this.app)
297
+ this.providers.push(instance)
298
+ this.app.register(instance)
299
+ }
300
+
301
+ this.phase = 'registered'
302
+ }
303
+
304
+ private async phaseBoot(): Promise<void> {
305
+ await this.app.boot()
306
+ this.phase = 'booted'
307
+ }
308
+
309
+ private async phaseStart(): Promise<void> {
310
+ // Import preload files (routes.ts, kernel.ts, etc.)
311
+ if (this.reamrc?.preloads) {
312
+ for (const preloadEntry of this.reamrc.preloads) {
313
+ const preloadImport = typeof preloadEntry === 'function' ? preloadEntry : preloadEntry.file
314
+ const env =
315
+ typeof preloadEntry === 'function'
316
+ ? undefined
317
+ : (preloadEntry as { environment?: string[] }).environment
318
+
319
+ if (env && !env.includes(this.environment)) continue
320
+ await preloadImport()
321
+ }
322
+ }
323
+
324
+ // Auto-load module files (routes.ts, etc.) from modules directory
325
+ await this.autoloadModules()
326
+
327
+ // Apply inline configuration
328
+ for (const mw of this.inlineMiddleware) {
329
+ this.middleware.use(mw)
330
+ }
331
+ for (const [name, mw] of this.inlineNamedMiddleware) {
332
+ this.middleware.register(name, mw)
333
+ }
334
+ if (this.inlineRoutes) {
335
+ this.inlineRoutes(this.router)
336
+ }
337
+
338
+ // Call start() on providers
339
+ for (const provider of this.providers) {
340
+ await callProviderPhase(provider, 'start')
341
+ }
342
+
343
+ this.phase = 'started'
344
+ }
345
+
346
+ private async phaseReady(): Promise<void> {
347
+ // Boot the Server (resolves lazy error handler etc.)
348
+ await this.server.boot()
349
+
350
+ // Start HTTP server if in web mode
351
+ if (this.environment === 'web' && this.config.serverFactory) {
352
+ // Build the HttpKernel with server middleware + router middleware.
353
+ // The streaming backend is resolved lazily — the HyperServer is
354
+ // created a few lines down, after the kernel — so the kernel
355
+ // closes over the `this._httpServer` slot and reads it on every
356
+ // request through the factory.
357
+ const kernel = createHttpKernel({
358
+ router: this.router,
359
+ middleware: this.middleware,
360
+ container: this.app.container,
361
+ exceptionHandler:
362
+ this.server.getErrorHandler() ?? new ExceptionHandler(!this.app.inProduction),
363
+ serverMiddleware: this.server.getServerMiddleware(),
364
+ routerMiddleware: this.router.getRouterMiddleware(),
365
+ onError: (error, ctx) => {
366
+ this.errorBoundary.serviceError('HttpKernel', error, ctx.id)
367
+ },
368
+ streamBackend: () => {
369
+ const server = this._httpServer
370
+ if (
371
+ server &&
372
+ typeof server.registerStream === 'function' &&
373
+ typeof server.writeStream === 'function' &&
374
+ typeof server.closeStream === 'function' &&
375
+ typeof server.onStreamDisconnect === 'function'
376
+ ) {
377
+ // Narrow to a backend-shaped record. All four methods are
378
+ // present at this point — the check above guards mocked
379
+ // servers without forcing a structural cast.
380
+ return {
381
+ registerStream: server.registerStream.bind(server),
382
+ writeStream: server.writeStream.bind(server),
383
+ closeStream: server.closeStream.bind(server),
384
+ onStreamDisconnect: server.onStreamDisconnect.bind(server),
385
+ }
386
+ }
387
+ return undefined
388
+ },
389
+ })
390
+
391
+ const desiredPort = this.config.port ?? 3000
392
+ const availablePort = await findAvailablePort(desiredPort)
393
+ this._httpServer = this.config.serverFactory(availablePort)
394
+ this._httpServer.onRequest(kernel)
395
+ // Pre-resolve client IPs in Rust from the trusted-proxy CIDRs before
396
+ // listen. Security filtering itself lives in @c9up/blackhole.
397
+ const trustedProxies = this.server.getTrustedProxies()
398
+ if (
399
+ trustedProxies.length > 0 &&
400
+ typeof this._httpServer.configureTrustedProxies === 'function'
401
+ ) {
402
+ this._httpServer.configureTrustedProxies([...trustedProxies])
403
+ }
404
+ await this._httpServer.listen()
405
+ } else if (this.environment === 'web' && !this.config.serverFactory) {
406
+ throw new ReamError(
407
+ 'IGNITOR_NO_SERVER_FACTORY',
408
+ 'httpServer() requires a serverFactory in config',
409
+ {
410
+ hint: 'Example: new Ignitor({ serverFactory: (port) => new HyperServer(port) })',
411
+ },
412
+ )
413
+ }
414
+
415
+ // Install error boundary
416
+ this.errorBoundary.install()
417
+
418
+ // Call ready() on providers
419
+ for (const provider of this.providers) {
420
+ await callProviderPhase(provider, 'ready')
421
+ }
422
+
423
+ // Core domain event: the app finished booting (all providers ready).
424
+ // Emitted once through the bus when events are wired — zero hot-path cost.
425
+ if (this.app.container.has('events')) {
426
+ this.app.container
427
+ .resolve<Emitter>('events')
428
+ .emit('app:ready', { environment: this.environment })
429
+ }
430
+
431
+ // Hot-reload in dev mode
432
+ if (this.isDevMode()) {
433
+ const watchDirs = this.config.watchDirs ?? ['app', 'start']
434
+ this.hotReloadCleanup = startHotReload({
435
+ watchDirs,
436
+ onReload: async () => {
437
+ const { clearServiceRegistry } = await import('./decorators/Service.js')
438
+ clearServiceRegistry()
439
+ this.router.clear()
440
+ if (this.inlineRoutes) this.inlineRoutes(this.router)
441
+ if (this.reamrc?.preloads) {
442
+ for (const preloadEntry of this.reamrc.preloads) {
443
+ const preloadImport =
444
+ typeof preloadEntry === 'function' ? preloadEntry : preloadEntry.file
445
+ await preloadImport()
446
+ }
447
+ }
448
+ },
449
+ logger: {
450
+ info: (msg) =>
451
+ this.handleError({
452
+ type: 'system.info',
453
+ source: 'HotReload',
454
+ message: msg,
455
+ severity: 'info',
456
+ timestamp: new Date().toISOString(),
457
+ } as ErrorEvent),
458
+ },
459
+ })
460
+ }
461
+
462
+ this.phase = 'ready'
463
+ }
464
+
465
+ /**
466
+ * Auto-load config/*.ts files into app.config store.
467
+ * Each file's default export is stored under its filename (without extension).
468
+ * e.g. config/database.ts → app.config.get('database')
469
+ */
470
+ private async autoloadConfig(): Promise<void> {
471
+ const { readdirSync, existsSync } = await import('node:fs')
472
+ const { join, basename } = await import('node:path')
473
+ const { fileURLToPath, pathToFileURL } = await import('node:url')
474
+
475
+ const configDir = this.appRoot
476
+ ? join(fileURLToPath(this.appRoot), 'config')
477
+ : join(process.cwd(), 'config')
478
+
479
+ if (!existsSync(configDir)) return
480
+
481
+ const files = readdirSync(configDir)
482
+ .filter((f: string) => (f.endsWith('.ts') || f.endsWith('.js')) && !f.startsWith('.'))
483
+ .sort()
484
+
485
+ for (const file of files) {
486
+ const key = basename(file).replace(/\.(ts|js)$/, '')
487
+ const mod = await import(pathToFileURL(join(configDir, file)).href)
488
+ this.app.config.set(key, mod.default ?? mod)
489
+ }
490
+ }
491
+
492
+ /**
493
+ * Auto-load module files (routes.ts, etc.) from the modules directory.
494
+ * Scans modules.path for subdirectories and imports matching files.
495
+ */
496
+ private async autoloadModules(): Promise<void> {
497
+ const modulesConfig = this.reamrc?.modules
498
+ if (!modulesConfig?.path) return
499
+
500
+ const { readdirSync, existsSync } = await import('node:fs')
501
+ const { join, resolve } = await import('node:path')
502
+ const { fileURLToPath } = await import('node:url')
503
+ const { pathToFileURL } = await import('node:url')
504
+
505
+ // Resolve modules path relative to app root or cwd
506
+ const basePath = this.appRoot
507
+ ? join(fileURLToPath(this.appRoot), modulesConfig.path)
508
+ : resolve(modulesConfig.path)
509
+
510
+ if (!existsSync(basePath)) return
511
+
512
+ const autoloadFiles = modulesConfig.autoload ?? ['routes', 'events']
513
+ const moduleDirs = readdirSync(basePath, { withFileTypes: true })
514
+ .filter((d) => d.isDirectory())
515
+ .map((d) => d.name)
516
+ .sort()
517
+
518
+ for (const moduleDir of moduleDirs) {
519
+ for (const fileName of autoloadFiles) {
520
+ const tsPath = join(basePath, moduleDir, `${fileName}.ts`)
521
+ const jsPath = join(basePath, moduleDir, `${fileName}.js`)
522
+ const filePath = existsSync(tsPath) ? tsPath : existsSync(jsPath) ? jsPath : null
523
+ if (filePath) {
524
+ await import(pathToFileURL(filePath).href)
525
+ }
526
+ }
527
+ }
528
+ }
529
+
530
+ /** Graceful shutdown. */
531
+ async stop(): Promise<void> {
532
+ if (this.hotReloadCleanup) this.hotReloadCleanup()
533
+ if (this._httpServer) await this._httpServer.close()
534
+ this.errorBoundary.uninstall()
535
+ await this.app.shutdown()
536
+ this.phase = 'shutdown'
537
+ }
538
+
539
+ // ─── Accessors ────────────────────────────────────────────
540
+
541
+ async port(): Promise<number> {
542
+ return this._httpServer ? this._httpServer.port() : 0
543
+ }
544
+
545
+ getApp(): Application {
546
+ return this.app
547
+ }
548
+
549
+ getRouter(): Router {
550
+ return this.router
551
+ }
552
+
553
+ getServer(): Server {
554
+ return this.server
555
+ }
556
+
557
+ /** Get the kernel callback (for serverless / testing). */
558
+ getKernel(): (request: HttpKernelRequest) => Promise<HttpKernelResponse> {
559
+ return createHttpKernel({
560
+ router: this.router,
561
+ middleware: this.middleware,
562
+ container: this.app.container,
563
+ exceptionHandler:
564
+ this.server.getErrorHandler() ?? new ExceptionHandler(!this.app.inProduction),
565
+ serverMiddleware: this.server.getServerMiddleware(),
566
+ routerMiddleware: this.router.getRouterMiddleware(),
567
+ })
568
+ }
569
+
570
+ isDevMode(): boolean {
571
+ return this.app.inDev
572
+ }
573
+
574
+ getPhase(): string {
575
+ return this.phase
576
+ }
577
+
578
+ private handleError(event: ErrorEvent): void {
579
+ for (const listener of this.errorListeners) {
580
+ try {
581
+ listener(event)
582
+ } catch {
583
+ /* Don't let listeners crash */
584
+ }
585
+ }
586
+ }
587
+ }
588
+
589
+ /**
590
+ * Pretty-print an error (like AdonisJS prettyPrintError).
591
+ */
592
+ export function prettyPrintError(error: unknown): void {
593
+ if (error instanceof ReamError) {
594
+ console.error(error.toDevString())
595
+ } else if (error instanceof Error) {
596
+ console.error(`\n ${error.message}\n`)
597
+ if (error.stack) console.error(error.stack)
598
+ } else {
599
+ console.error(error)
600
+ }
601
+ }
602
+
603
+ /**
604
+ * ConsoleKernel — handles CLI command dispatching.
605
+ * Like AdonisJS: new Ignitor(...).console().handle(process.argv.splice(2))
606
+ */
607
+ export class ConsoleKernel {
608
+ private ignitor: Ignitor
609
+
610
+ constructor(ignitor: Ignitor) {
611
+ this.ignitor = ignitor
612
+ }
613
+
614
+ async handle(argv: string[]): Promise<void> {
615
+ await this.ignitor.start()
616
+ const { CommandRunner } = await import('./console/CommandRunner.js')
617
+ const runner = new CommandRunner()
618
+
619
+ // Auto-register commands from reamrc
620
+ const reamrc = (this.ignitor as unknown as { reamrc?: ReamrcConfig }).reamrc
621
+ if (reamrc?.commands) {
622
+ for (const commandImport of reamrc.commands) {
623
+ const mod = await commandImport()
624
+ const cmd = (
625
+ mod as {
626
+ default: {
627
+ name: string
628
+ description: string
629
+ run: (args: string[], flags: Record<string, string | boolean>) => Promise<void>
630
+ }
631
+ }
632
+ ).default
633
+ if (cmd?.name && typeof cmd?.run === 'function') {
634
+ runner.register(cmd)
635
+ }
636
+ }
637
+ }
638
+
639
+ this.ignitor.getApp().container.singleton('console', () => runner)
640
+ await runner.handle(argv)
641
+ await this.ignitor.stop()
642
+ }
643
+ }
644
+
645
+ async function findAvailablePort(desired: number): Promise<number> {
646
+ const net = await import('node:net')
647
+ for (let port = desired; port < desired + 20; port++) {
648
+ const available = await new Promise<boolean>((resolve) => {
649
+ const server = net.createServer()
650
+ server.listen(port, () => server.close(() => resolve(true)))
651
+ server.on('error', () => resolve(false))
652
+ })
653
+ if (available) return port
654
+ }
655
+ return desired
656
+ }