imposters 0.1.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 (426) hide show
  1. package/LICENSE +21 -0
  2. package/Program/package.json +6 -0
  3. package/README.md +365 -0
  4. package/api/AdminApi/package.json +6 -0
  5. package/api/ApiErrors/package.json +6 -0
  6. package/api/ApiSchemas/package.json +6 -0
  7. package/api/Conversions/package.json +6 -0
  8. package/api/ImpostersGroup/package.json +6 -0
  9. package/api/ImpostersHandlers/package.json +6 -0
  10. package/api/SystemGroup/package.json +6 -0
  11. package/api/SystemHandlers/package.json +6 -0
  12. package/bin/imposters +47 -0
  13. package/cli/Commands/package.json +6 -0
  14. package/cli/ConfigLoader/package.json +6 -0
  15. package/client/HandlerHttpClient/package.json +6 -0
  16. package/client/ImpostersClient/package.json +6 -0
  17. package/client/testing/package.json +6 -0
  18. package/dist/cjs/Program.js +4 -0
  19. package/dist/cjs/Program.js.map +1 -0
  20. package/dist/cjs/api/AdminApi.js +11 -0
  21. package/dist/cjs/api/AdminApi.js.map +1 -0
  22. package/dist/cjs/api/ApiErrors.js +30 -0
  23. package/dist/cjs/api/ApiErrors.js.map +1 -0
  24. package/dist/cjs/api/ApiSchemas.js +36 -0
  25. package/dist/cjs/api/ApiSchemas.js.map +1 -0
  26. package/dist/cjs/api/Conversions.js +41 -0
  27. package/dist/cjs/api/Conversions.js.map +1 -0
  28. package/dist/cjs/api/ImpostersGroup.js +37 -0
  29. package/dist/cjs/api/ImpostersGroup.js.map +1 -0
  30. package/dist/cjs/api/ImpostersHandlers.js +361 -0
  31. package/dist/cjs/api/ImpostersHandlers.js.map +1 -0
  32. package/dist/cjs/api/SystemGroup.js +12 -0
  33. package/dist/cjs/api/SystemGroup.js.map +1 -0
  34. package/dist/cjs/api/SystemHandlers.js +74 -0
  35. package/dist/cjs/api/SystemHandlers.js.map +1 -0
  36. package/dist/cjs/cli/Commands.js +104 -0
  37. package/dist/cjs/cli/Commands.js.map +1 -0
  38. package/dist/cjs/cli/ConfigLoader.js +34 -0
  39. package/dist/cjs/cli/ConfigLoader.js.map +1 -0
  40. package/dist/cjs/client/HandlerHttpClient.js +50 -0
  41. package/dist/cjs/client/HandlerHttpClient.js.map +1 -0
  42. package/dist/cjs/client/ImpostersClient.js +20 -0
  43. package/dist/cjs/client/ImpostersClient.js.map +1 -0
  44. package/dist/cjs/client/index.js +57 -0
  45. package/dist/cjs/client/index.js.map +1 -0
  46. package/dist/cjs/client/testing.js +94 -0
  47. package/dist/cjs/client/testing.js.map +1 -0
  48. package/dist/cjs/domain/imposter.js +125 -0
  49. package/dist/cjs/domain/imposter.js.map +1 -0
  50. package/dist/cjs/domain/route.js +185 -0
  51. package/dist/cjs/domain/route.js.map +1 -0
  52. package/dist/cjs/index.js +106 -0
  53. package/dist/cjs/index.js.map +1 -0
  54. package/dist/cjs/layers/ApiLayer.js +18 -0
  55. package/dist/cjs/layers/ApiLayer.js.map +1 -0
  56. package/dist/cjs/layers/MainLayer.js +27 -0
  57. package/dist/cjs/layers/MainLayer.js.map +1 -0
  58. package/dist/cjs/matching/ExpressionEvaluator.js +103 -0
  59. package/dist/cjs/matching/ExpressionEvaluator.js.map +1 -0
  60. package/dist/cjs/matching/RequestMatcher.js +145 -0
  61. package/dist/cjs/matching/RequestMatcher.js.map +1 -0
  62. package/dist/cjs/matching/ResponseGenerator.js +80 -0
  63. package/dist/cjs/matching/ResponseGenerator.js.map +1 -0
  64. package/dist/cjs/matching/TemplateEngine.js +55 -0
  65. package/dist/cjs/matching/TemplateEngine.js.map +1 -0
  66. package/dist/cjs/repositories/ImposterRepository.js +118 -0
  67. package/dist/cjs/repositories/ImposterRepository.js.map +1 -0
  68. package/dist/cjs/schemas/ConfigFileSchema.js +44 -0
  69. package/dist/cjs/schemas/ConfigFileSchema.js.map +1 -0
  70. package/dist/cjs/schemas/ImposterSchema.js +202 -0
  71. package/dist/cjs/schemas/ImposterSchema.js.map +1 -0
  72. package/dist/cjs/schemas/RequestLogSchema.js +51 -0
  73. package/dist/cjs/schemas/RequestLogSchema.js.map +1 -0
  74. package/dist/cjs/schemas/StubSchema.js +84 -0
  75. package/dist/cjs/schemas/StubSchema.js.map +1 -0
  76. package/dist/cjs/schemas/common.js +67 -0
  77. package/dist/cjs/schemas/common.js.map +1 -0
  78. package/dist/cjs/server/AdminServer.js +36 -0
  79. package/dist/cjs/server/AdminServer.js.map +1 -0
  80. package/dist/cjs/server/BunServer.js +13 -0
  81. package/dist/cjs/server/BunServer.js.map +1 -0
  82. package/dist/cjs/server/FiberManager.js +21 -0
  83. package/dist/cjs/server/FiberManager.js.map +1 -0
  84. package/dist/cjs/server/ImposterServer.js +234 -0
  85. package/dist/cjs/server/ImposterServer.js.map +1 -0
  86. package/dist/cjs/services/AppConfig.js +18 -0
  87. package/dist/cjs/services/AppConfig.js.map +1 -0
  88. package/dist/cjs/services/MetricsService.js +113 -0
  89. package/dist/cjs/services/MetricsService.js.map +1 -0
  90. package/dist/cjs/services/PortAllocator.js +50 -0
  91. package/dist/cjs/services/PortAllocator.js.map +1 -0
  92. package/dist/cjs/services/ProxyService.js +109 -0
  93. package/dist/cjs/services/ProxyService.js.map +1 -0
  94. package/dist/cjs/services/RequestLogger.js +60 -0
  95. package/dist/cjs/services/RequestLogger.js.map +1 -0
  96. package/dist/cjs/services/Uuid.js +10 -0
  97. package/dist/cjs/services/Uuid.js.map +1 -0
  98. package/dist/cjs/services/UuidLive.js +16 -0
  99. package/dist/cjs/services/UuidLive.js.map +1 -0
  100. package/dist/cjs/ui/UiRouter.js +242 -0
  101. package/dist/cjs/ui/UiRouter.js.map +1 -0
  102. package/dist/cjs/ui/admin/AdminLayout.js +36 -0
  103. package/dist/cjs/ui/admin/AdminLayout.js.map +1 -0
  104. package/dist/cjs/ui/admin/AdminUiRouter.js +155 -0
  105. package/dist/cjs/ui/admin/AdminUiRouter.js.map +1 -0
  106. package/dist/cjs/ui/admin/pages/AdminDashboard.js +55 -0
  107. package/dist/cjs/ui/admin/pages/AdminDashboard.js.map +1 -0
  108. package/dist/cjs/ui/admin/partials.js +64 -0
  109. package/dist/cjs/ui/admin/partials.js.map +1 -0
  110. package/dist/cjs/ui/html.js +42 -0
  111. package/dist/cjs/ui/html.js.map +1 -0
  112. package/dist/cjs/ui/layout.js +39 -0
  113. package/dist/cjs/ui/layout.js.map +1 -0
  114. package/dist/cjs/ui/pages/dashboard.js +51 -0
  115. package/dist/cjs/ui/pages/dashboard.js.map +1 -0
  116. package/dist/cjs/ui/pages/request-detail.js +119 -0
  117. package/dist/cjs/ui/pages/request-detail.js.map +1 -0
  118. package/dist/cjs/ui/pages/requests.js +120 -0
  119. package/dist/cjs/ui/pages/requests.js.map +1 -0
  120. package/dist/cjs/ui/pages/stubs.js +46 -0
  121. package/dist/cjs/ui/pages/stubs.js.map +1 -0
  122. package/dist/cjs/ui/partials.js +104 -0
  123. package/dist/cjs/ui/partials.js.map +1 -0
  124. package/dist/dts/Program.d.ts +2 -0
  125. package/dist/dts/Program.d.ts.map +1 -0
  126. package/dist/dts/api/AdminApi.d.ts +490 -0
  127. package/dist/dts/api/AdminApi.d.ts.map +1 -0
  128. package/dist/dts/api/ApiErrors.d.ts +26 -0
  129. package/dist/dts/api/ApiErrors.d.ts.map +1 -0
  130. package/dist/dts/api/ApiSchemas.d.ts +36 -0
  131. package/dist/dts/api/ApiSchemas.d.ts.map +1 -0
  132. package/dist/dts/api/Conversions.d.ts +7 -0
  133. package/dist/dts/api/Conversions.d.ts.map +1 -0
  134. package/dist/dts/api/ImpostersGroup.d.ts +448 -0
  135. package/dist/dts/api/ImpostersGroup.d.ts.map +1 -0
  136. package/dist/dts/api/ImpostersHandlers.d.ts +9 -0
  137. package/dist/dts/api/ImpostersHandlers.d.ts.map +1 -0
  138. package/dist/dts/api/SystemGroup.d.ts +46 -0
  139. package/dist/dts/api/SystemGroup.d.ts.map +1 -0
  140. package/dist/dts/api/SystemHandlers.d.ts +4 -0
  141. package/dist/dts/api/SystemHandlers.d.ts.map +1 -0
  142. package/dist/dts/cli/Commands.d.ts +4 -0
  143. package/dist/dts/cli/Commands.d.ts.map +1 -0
  144. package/dist/dts/cli/ConfigLoader.d.ts +13 -0
  145. package/dist/dts/cli/ConfigLoader.d.ts.map +1 -0
  146. package/dist/dts/client/HandlerHttpClient.d.ts +5 -0
  147. package/dist/dts/client/HandlerHttpClient.d.ts.map +1 -0
  148. package/dist/dts/client/ImpostersClient.d.ts +1868 -0
  149. package/dist/dts/client/ImpostersClient.d.ts.map +1 -0
  150. package/dist/dts/client/index.d.ts +6 -0
  151. package/dist/dts/client/index.d.ts.map +1 -0
  152. package/dist/dts/client/testing.d.ts +35 -0
  153. package/dist/dts/client/testing.d.ts.map +1 -0
  154. package/dist/dts/domain/imposter.d.ts +123 -0
  155. package/dist/dts/domain/imposter.d.ts.map +1 -0
  156. package/dist/dts/domain/route.d.ts +128 -0
  157. package/dist/dts/domain/route.d.ts.map +1 -0
  158. package/dist/dts/index.d.ts +60 -0
  159. package/dist/dts/index.d.ts.map +1 -0
  160. package/dist/dts/layers/ApiLayer.d.ts +3 -0
  161. package/dist/dts/layers/ApiLayer.d.ts.map +1 -0
  162. package/dist/dts/layers/MainLayer.d.ts +3 -0
  163. package/dist/dts/layers/MainLayer.d.ts.map +1 -0
  164. package/dist/dts/matching/ExpressionEvaluator.d.ts +11 -0
  165. package/dist/dts/matching/ExpressionEvaluator.d.ts.map +1 -0
  166. package/dist/dts/matching/RequestMatcher.d.ts +13 -0
  167. package/dist/dts/matching/RequestMatcher.d.ts.map +1 -0
  168. package/dist/dts/matching/ResponseGenerator.d.ts +9 -0
  169. package/dist/dts/matching/ResponseGenerator.d.ts.map +1 -0
  170. package/dist/dts/matching/TemplateEngine.d.ts +4 -0
  171. package/dist/dts/matching/TemplateEngine.d.ts.map +1 -0
  172. package/dist/dts/repositories/ImposterRepository.d.ts +33 -0
  173. package/dist/dts/repositories/ImposterRepository.d.ts.map +1 -0
  174. package/dist/dts/schemas/ConfigFileSchema.d.ts +142 -0
  175. package/dist/dts/schemas/ConfigFileSchema.d.ts.map +1 -0
  176. package/dist/dts/schemas/ImposterSchema.d.ts +368 -0
  177. package/dist/dts/schemas/ImposterSchema.d.ts.map +1 -0
  178. package/dist/dts/schemas/RequestLogSchema.d.ts +36 -0
  179. package/dist/dts/schemas/RequestLogSchema.d.ts.map +1 -0
  180. package/dist/dts/schemas/StubSchema.d.ts +112 -0
  181. package/dist/dts/schemas/StubSchema.d.ts.map +1 -0
  182. package/dist/dts/schemas/common.d.ts +56 -0
  183. package/dist/dts/schemas/common.d.ts.map +1 -0
  184. package/dist/dts/server/AdminServer.d.ts +11 -0
  185. package/dist/dts/server/AdminServer.d.ts.map +1 -0
  186. package/dist/dts/server/BunServer.d.ts +17 -0
  187. package/dist/dts/server/BunServer.d.ts.map +1 -0
  188. package/dist/dts/server/FiberManager.d.ts +12 -0
  189. package/dist/dts/server/FiberManager.d.ts.map +1 -0
  190. package/dist/dts/server/ImposterServer.d.ts +29 -0
  191. package/dist/dts/server/ImposterServer.d.ts.map +1 -0
  192. package/dist/dts/services/AppConfig.d.ts +14 -0
  193. package/dist/dts/services/AppConfig.d.ts.map +1 -0
  194. package/dist/dts/services/MetricsService.d.ts +26 -0
  195. package/dist/dts/services/MetricsService.d.ts.map +1 -0
  196. package/dist/dts/services/PortAllocator.d.ts +29 -0
  197. package/dist/dts/services/PortAllocator.d.ts.map +1 -0
  198. package/dist/dts/services/ProxyService.d.ts +24 -0
  199. package/dist/dts/services/ProxyService.d.ts.map +1 -0
  200. package/dist/dts/services/RequestLogger.d.ts +23 -0
  201. package/dist/dts/services/RequestLogger.d.ts.map +1 -0
  202. package/dist/dts/services/Uuid.d.ts +9 -0
  203. package/dist/dts/services/Uuid.d.ts.map +1 -0
  204. package/dist/dts/services/UuidLive.d.ts +4 -0
  205. package/dist/dts/services/UuidLive.d.ts.map +1 -0
  206. package/dist/dts/ui/UiRouter.d.ts +15 -0
  207. package/dist/dts/ui/UiRouter.d.ts.map +1 -0
  208. package/dist/dts/ui/admin/AdminLayout.d.ts +7 -0
  209. package/dist/dts/ui/admin/AdminLayout.d.ts.map +1 -0
  210. package/dist/dts/ui/admin/AdminUiRouter.d.ts +6 -0
  211. package/dist/dts/ui/admin/AdminUiRouter.d.ts.map +1 -0
  212. package/dist/dts/ui/admin/pages/AdminDashboard.d.ts +7 -0
  213. package/dist/dts/ui/admin/pages/AdminDashboard.d.ts.map +1 -0
  214. package/dist/dts/ui/admin/partials.d.ts +14 -0
  215. package/dist/dts/ui/admin/partials.d.ts.map +1 -0
  216. package/dist/dts/ui/html.d.ts +12 -0
  217. package/dist/dts/ui/html.d.ts.map +1 -0
  218. package/dist/dts/ui/layout.d.ts +9 -0
  219. package/dist/dts/ui/layout.d.ts.map +1 -0
  220. package/dist/dts/ui/pages/dashboard.d.ts +10 -0
  221. package/dist/dts/ui/pages/dashboard.d.ts.map +1 -0
  222. package/dist/dts/ui/pages/request-detail.d.ts +11 -0
  223. package/dist/dts/ui/pages/request-detail.d.ts.map +1 -0
  224. package/dist/dts/ui/pages/requests.d.ts +15 -0
  225. package/dist/dts/ui/pages/requests.d.ts.map +1 -0
  226. package/dist/dts/ui/pages/stubs.d.ts +8 -0
  227. package/dist/dts/ui/pages/stubs.d.ts.map +1 -0
  228. package/dist/dts/ui/partials.d.ts +13 -0
  229. package/dist/dts/ui/partials.d.ts.map +1 -0
  230. package/dist/esm/Program.js +2 -0
  231. package/dist/esm/Program.js.map +1 -0
  232. package/dist/esm/api/AdminApi.js +5 -0
  233. package/dist/esm/api/AdminApi.js.map +1 -0
  234. package/dist/esm/api/ApiErrors.js +20 -0
  235. package/dist/esm/api/ApiErrors.js.map +1 -0
  236. package/dist/esm/api/ApiSchemas.js +29 -0
  237. package/dist/esm/api/ApiSchemas.js.map +1 -0
  238. package/dist/esm/api/Conversions.js +32 -0
  239. package/dist/esm/api/Conversions.js.map +1 -0
  240. package/dist/esm/api/ImpostersGroup.js +30 -0
  241. package/dist/esm/api/ImpostersGroup.js.map +1 -0
  242. package/dist/esm/api/ImpostersHandlers.js +354 -0
  243. package/dist/esm/api/ImpostersHandlers.js.map +1 -0
  244. package/dist/esm/api/SystemGroup.js +6 -0
  245. package/dist/esm/api/SystemGroup.js.map +1 -0
  246. package/dist/esm/api/SystemHandlers.js +67 -0
  247. package/dist/esm/api/SystemHandlers.js.map +1 -0
  248. package/dist/esm/cli/Commands.js +98 -0
  249. package/dist/esm/cli/Commands.js.map +1 -0
  250. package/dist/esm/cli/ConfigLoader.js +25 -0
  251. package/dist/esm/cli/ConfigLoader.js.map +1 -0
  252. package/dist/esm/client/HandlerHttpClient.js +42 -0
  253. package/dist/esm/client/HandlerHttpClient.js.map +1 -0
  254. package/dist/esm/client/ImpostersClient.js +10 -0
  255. package/dist/esm/client/ImpostersClient.js.map +1 -0
  256. package/dist/esm/client/index.js +4 -0
  257. package/dist/esm/client/index.js.map +1 -0
  258. package/dist/esm/client/testing.js +86 -0
  259. package/dist/esm/client/testing.js.map +1 -0
  260. package/dist/esm/domain/imposter.js +103 -0
  261. package/dist/esm/domain/imposter.js.map +1 -0
  262. package/dist/esm/domain/route.js +164 -0
  263. package/dist/esm/domain/route.js.map +1 -0
  264. package/dist/esm/index.js +60 -0
  265. package/dist/esm/index.js.map +1 -0
  266. package/dist/esm/layers/ApiLayer.js +11 -0
  267. package/dist/esm/layers/ApiLayer.js.map +1 -0
  268. package/dist/esm/layers/MainLayer.js +20 -0
  269. package/dist/esm/layers/MainLayer.js.map +1 -0
  270. package/dist/esm/matching/ExpressionEvaluator.js +94 -0
  271. package/dist/esm/matching/ExpressionEvaluator.js.map +1 -0
  272. package/dist/esm/matching/RequestMatcher.js +135 -0
  273. package/dist/esm/matching/RequestMatcher.js.map +1 -0
  274. package/dist/esm/matching/ResponseGenerator.js +71 -0
  275. package/dist/esm/matching/ResponseGenerator.js.map +1 -0
  276. package/dist/esm/matching/TemplateEngine.js +47 -0
  277. package/dist/esm/matching/TemplateEngine.js.map +1 -0
  278. package/dist/esm/package.json +4 -0
  279. package/dist/esm/repositories/ImposterRepository.js +110 -0
  280. package/dist/esm/repositories/ImposterRepository.js.map +1 -0
  281. package/dist/esm/schemas/ConfigFileSchema.js +37 -0
  282. package/dist/esm/schemas/ConfigFileSchema.js.map +1 -0
  283. package/dist/esm/schemas/ImposterSchema.js +195 -0
  284. package/dist/esm/schemas/ImposterSchema.js.map +1 -0
  285. package/dist/esm/schemas/RequestLogSchema.js +44 -0
  286. package/dist/esm/schemas/RequestLogSchema.js.map +1 -0
  287. package/dist/esm/schemas/StubSchema.js +77 -0
  288. package/dist/esm/schemas/StubSchema.js.map +1 -0
  289. package/dist/esm/schemas/common.js +59 -0
  290. package/dist/esm/schemas/common.js.map +1 -0
  291. package/dist/esm/server/AdminServer.js +27 -0
  292. package/dist/esm/server/AdminServer.js.map +1 -0
  293. package/dist/esm/server/BunServer.js +6 -0
  294. package/dist/esm/server/BunServer.js.map +1 -0
  295. package/dist/esm/server/FiberManager.js +14 -0
  296. package/dist/esm/server/FiberManager.js.map +1 -0
  297. package/dist/esm/server/ImposterServer.js +225 -0
  298. package/dist/esm/server/ImposterServer.js.map +1 -0
  299. package/dist/esm/services/AppConfig.js +11 -0
  300. package/dist/esm/services/AppConfig.js.map +1 -0
  301. package/dist/esm/services/MetricsService.js +105 -0
  302. package/dist/esm/services/MetricsService.js.map +1 -0
  303. package/dist/esm/services/PortAllocator.js +41 -0
  304. package/dist/esm/services/PortAllocator.js.map +1 -0
  305. package/dist/esm/services/ProxyService.js +101 -0
  306. package/dist/esm/services/ProxyService.js.map +1 -0
  307. package/dist/esm/services/RequestLogger.js +53 -0
  308. package/dist/esm/services/RequestLogger.js.map +1 -0
  309. package/dist/esm/services/Uuid.js +3 -0
  310. package/dist/esm/services/Uuid.js.map +1 -0
  311. package/dist/esm/services/UuidLive.js +9 -0
  312. package/dist/esm/services/UuidLive.js.map +1 -0
  313. package/dist/esm/ui/UiRouter.js +235 -0
  314. package/dist/esm/ui/UiRouter.js.map +1 -0
  315. package/dist/esm/ui/admin/AdminLayout.js +29 -0
  316. package/dist/esm/ui/admin/AdminLayout.js.map +1 -0
  317. package/dist/esm/ui/admin/AdminUiRouter.js +148 -0
  318. package/dist/esm/ui/admin/AdminUiRouter.js.map +1 -0
  319. package/dist/esm/ui/admin/pages/AdminDashboard.js +48 -0
  320. package/dist/esm/ui/admin/pages/AdminDashboard.js.map +1 -0
  321. package/dist/esm/ui/admin/partials.js +54 -0
  322. package/dist/esm/ui/admin/partials.js.map +1 -0
  323. package/dist/esm/ui/html.js +32 -0
  324. package/dist/esm/ui/html.js.map +1 -0
  325. package/dist/esm/ui/layout.js +32 -0
  326. package/dist/esm/ui/layout.js.map +1 -0
  327. package/dist/esm/ui/pages/dashboard.js +44 -0
  328. package/dist/esm/ui/pages/dashboard.js.map +1 -0
  329. package/dist/esm/ui/pages/request-detail.js +112 -0
  330. package/dist/esm/ui/pages/request-detail.js.map +1 -0
  331. package/dist/esm/ui/pages/requests.js +112 -0
  332. package/dist/esm/ui/pages/requests.js.map +1 -0
  333. package/dist/esm/ui/pages/stubs.js +39 -0
  334. package/dist/esm/ui/pages/stubs.js.map +1 -0
  335. package/dist/esm/ui/partials.js +91 -0
  336. package/dist/esm/ui/partials.js.map +1 -0
  337. package/domain/imposter/package.json +6 -0
  338. package/domain/route/package.json +6 -0
  339. package/layers/ApiLayer/package.json +6 -0
  340. package/layers/MainLayer/package.json +6 -0
  341. package/matching/ExpressionEvaluator/package.json +6 -0
  342. package/matching/RequestMatcher/package.json +6 -0
  343. package/matching/ResponseGenerator/package.json +6 -0
  344. package/matching/TemplateEngine/package.json +6 -0
  345. package/package.json +435 -0
  346. package/repositories/ImposterRepository/package.json +6 -0
  347. package/schemas/ConfigFileSchema/package.json +6 -0
  348. package/schemas/ImposterSchema/package.json +6 -0
  349. package/schemas/RequestLogSchema/package.json +6 -0
  350. package/schemas/StubSchema/package.json +6 -0
  351. package/schemas/common/package.json +6 -0
  352. package/server/AdminServer/package.json +6 -0
  353. package/server/BunServer/package.json +6 -0
  354. package/server/FiberManager/package.json +6 -0
  355. package/server/ImposterServer/package.json +6 -0
  356. package/services/AppConfig/package.json +6 -0
  357. package/services/MetricsService/package.json +6 -0
  358. package/services/PortAllocator/package.json +6 -0
  359. package/services/ProxyService/package.json +6 -0
  360. package/services/RequestLogger/package.json +6 -0
  361. package/services/Uuid/package.json +6 -0
  362. package/services/UuidLive/package.json +6 -0
  363. package/src/Program.ts +1 -0
  364. package/src/api/AdminApi.ts +7 -0
  365. package/src/api/ApiErrors.ts +20 -0
  366. package/src/api/ApiSchemas.ts +36 -0
  367. package/src/api/Conversions.ts +34 -0
  368. package/src/api/ImpostersGroup.ts +103 -0
  369. package/src/api/ImpostersHandlers.ts +387 -0
  370. package/src/api/SystemGroup.ts +12 -0
  371. package/src/api/SystemHandlers.ts +76 -0
  372. package/src/cli/Commands.ts +119 -0
  373. package/src/cli/ConfigLoader.ts +41 -0
  374. package/src/client/HandlerHttpClient.ts +50 -0
  375. package/src/client/ImpostersClient.ts +21 -0
  376. package/src/client/index.ts +9 -0
  377. package/src/client/testing.ts +105 -0
  378. package/src/domain/imposter.ts +186 -0
  379. package/src/domain/route.ts +255 -0
  380. package/src/index.ts +153 -0
  381. package/src/layers/ApiLayer.ts +21 -0
  382. package/src/layers/MainLayer.ts +43 -0
  383. package/src/matching/ExpressionEvaluator.ts +102 -0
  384. package/src/matching/RequestMatcher.ts +162 -0
  385. package/src/matching/ResponseGenerator.ts +86 -0
  386. package/src/matching/TemplateEngine.ts +54 -0
  387. package/src/repositories/ImposterRepository.ts +145 -0
  388. package/src/schemas/ConfigFileSchema.ts +32 -0
  389. package/src/schemas/ImposterSchema.ts +232 -0
  390. package/src/schemas/RequestLogSchema.ts +38 -0
  391. package/src/schemas/StubSchema.ts +90 -0
  392. package/src/schemas/common.ts +95 -0
  393. package/src/server/AdminServer.ts +22 -0
  394. package/src/server/BunServer.ts +19 -0
  395. package/src/server/FiberManager.ts +25 -0
  396. package/src/server/ImposterServer.ts +244 -0
  397. package/src/services/AppConfig.ts +22 -0
  398. package/src/services/MetricsService.ts +157 -0
  399. package/src/services/PortAllocator.ts +68 -0
  400. package/src/services/ProxyService.ts +139 -0
  401. package/src/services/RequestLogger.ts +87 -0
  402. package/src/services/Uuid.ts +9 -0
  403. package/src/services/UuidLive.ts +9 -0
  404. package/src/types/bun.d.ts +6 -0
  405. package/src/ui/UiRouter.ts +278 -0
  406. package/src/ui/admin/AdminLayout.ts +36 -0
  407. package/src/ui/admin/AdminUiRouter.ts +170 -0
  408. package/src/ui/admin/pages/AdminDashboard.ts +54 -0
  409. package/src/ui/admin/partials.ts +83 -0
  410. package/src/ui/html.ts +37 -0
  411. package/src/ui/layout.ts +44 -0
  412. package/src/ui/pages/dashboard.ts +64 -0
  413. package/src/ui/pages/request-detail.ts +142 -0
  414. package/src/ui/pages/requests.ts +141 -0
  415. package/src/ui/pages/stubs.ts +52 -0
  416. package/src/ui/partials.ts +133 -0
  417. package/ui/UiRouter/package.json +6 -0
  418. package/ui/admin/AdminLayout/package.json +6 -0
  419. package/ui/admin/AdminUiRouter/package.json +6 -0
  420. package/ui/admin/pages/AdminDashboard/package.json +6 -0
  421. package/ui/admin/partials/package.json +6 -0
  422. package/ui/html/package.json +6 -0
  423. package/ui/layout/package.json +6 -0
  424. package/ui/pages/dashboard/package.json +6 -0
  425. package/ui/pages/requests/package.json +6 -0
  426. package/ui/pages/stubs/package.json +6 -0
@@ -0,0 +1,59 @@
1
+ import { Clock, DateTime, Effect } from "effect";
2
+ import * as Duration from "effect/Duration";
3
+ import * as Schema from "effect/Schema";
4
+ // Common enums
5
+ export const ImposterStatus = /*#__PURE__*/Schema.Literal("running", "stopped", "starting", "stopping");
6
+ export const Protocol = /*#__PURE__*/Schema.Literal("HTTP");
7
+ // Utility schemas for validation
8
+ export const PositiveInteger = /*#__PURE__*/Schema.Number.pipe(/*#__PURE__*/Schema.int(), /*#__PURE__*/Schema.positive(), /*#__PURE__*/Schema.brand("PositiveInteger"));
9
+ export const NonEmptyString = /*#__PURE__*/Schema.String.pipe(/*#__PURE__*/Schema.minLength(1), /*#__PURE__*/Schema.brand("NonEmptyString"));
10
+ export const PortNumber = /*#__PURE__*/Schema.Number.pipe(/*#__PURE__*/Schema.int(), /*#__PURE__*/Schema.between(1024, 65535), /*#__PURE__*/Schema.brand("PortNumber"));
11
+ export const PaginationQuery = /*#__PURE__*/Schema.Struct({
12
+ // PositiveInteger.make() is safe here — 50 is a compile-time constant that always passes validation
13
+ limit: /*#__PURE__*/Schema.optionalWith(PositiveInteger, {
14
+ default: () => PositiveInteger.make(50)
15
+ }),
16
+ offset: /*#__PURE__*/Schema.optionalWith(/*#__PURE__*/Schema.Number.pipe(/*#__PURE__*/Schema.int(), /*#__PURE__*/Schema.nonNegative()), {
17
+ default: () => 0
18
+ })
19
+ });
20
+ export const PaginationMeta = /*#__PURE__*/Schema.Struct({
21
+ total: /*#__PURE__*/Schema.Number.pipe(/*#__PURE__*/Schema.int(), /*#__PURE__*/Schema.nonNegative()),
22
+ limit: PositiveInteger,
23
+ offset: /*#__PURE__*/Schema.Number.pipe(/*#__PURE__*/Schema.int(), /*#__PURE__*/Schema.nonNegative()),
24
+ hasMore: Schema.Boolean
25
+ });
26
+ export const ErrorCode = /*#__PURE__*/Schema.Union(/*#__PURE__*/
27
+ // Validation errors
28
+ Schema.Literal("VALIDATION_ERROR"), /*#__PURE__*/Schema.Literal("INVALID_ENDPOINT"), /*#__PURE__*/
29
+ // Resource errors
30
+ Schema.Literal("IMPOSTER_NOT_FOUND"), /*#__PURE__*/Schema.Literal("PORT_IN_USE"), /*#__PURE__*/Schema.Literal("IMPOSTER_BUSY"), /*#__PURE__*/
31
+ // System errors
32
+ Schema.Literal("SYSTEM_ERROR"), /*#__PURE__*/Schema.Literal("CONFIRMATION_REQUIRED"), /*#__PURE__*/
33
+ // Conflict errors
34
+ Schema.Literal("ENDPOINT_CONFLICT"));
35
+ export const ErrorDetails = /*#__PURE__*/Schema.Struct({
36
+ code: ErrorCode,
37
+ message: NonEmptyString,
38
+ field: /*#__PURE__*/Schema.optional(Schema.String),
39
+ value: /*#__PURE__*/Schema.optional(Schema.Unknown),
40
+ details: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Record({
41
+ key: Schema.String,
42
+ value: Schema.Unknown
43
+ }))
44
+ });
45
+ export const ErrorResponse = /*#__PURE__*/Schema.Struct({
46
+ error: ErrorDetails
47
+ });
48
+ // Common query filters
49
+ export const StatusFilter = /*#__PURE__*/Schema.optional(ImposterStatus);
50
+ export const ProtocolFilter = /*#__PURE__*/Schema.optional(Protocol);
51
+ // DateTime schemas using Effect's DateTime
52
+ export const DateTimeSchema = Schema.DateTimeUtc;
53
+ // Helper to create current DateTime
54
+ export const currentDateTime = /*#__PURE__*/Effect.map(Clock.currentTimeMillis, ms => DateTime.unsafeMake(ms));
55
+ // Helper to format duration as uptime string (HH:MM:SS)
56
+ export const formatDurationAsUptime = duration => {
57
+ return Duration.format(duration);
58
+ };
59
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","names":["Clock","DateTime","Effect","Duration","Schema","ImposterStatus","Literal","Protocol","PositiveInteger","Number","pipe","int","positive","brand","NonEmptyString","String","minLength","PortNumber","between","PaginationQuery","Struct","limit","optionalWith","default","make","offset","nonNegative","PaginationMeta","total","hasMore","Boolean","ErrorCode","Union","ErrorDetails","code","message","field","optional","value","Unknown","details","Record","key","ErrorResponse","error","StatusFilter","ProtocolFilter","DateTimeSchema","DateTimeUtc","currentDateTime","map","currentTimeMillis","ms","unsafeMake","formatDurationAsUptime","duration","format"],"sources":["../../../src/schemas/common.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,27 @@
1
+ import { HttpApiBuilder } from "@effect/platform";
2
+ import * as Layer from "effect/Layer";
3
+ import { ApiLayer } from "../layers/ApiLayer";
4
+ import { MainLayer } from "../layers/MainLayer";
5
+ import { makeAdminUiRouter } from "../ui/admin/AdminUiRouter";
6
+ export const FullLayer = /*#__PURE__*/ApiLayer.pipe(/*#__PURE__*/Layer.provide(MainLayer));
7
+ export const makeWebHandler = () => HttpApiBuilder.toWebHandler(FullLayer);
8
+ export const makeCompositeHandler = adminPort => {
9
+ const {
10
+ dispose,
11
+ handler: apiHandler
12
+ } = HttpApiBuilder.toWebHandler(FullLayer);
13
+ const adminUiRouter = makeAdminUiRouter({
14
+ apiHandler,
15
+ adminPort
16
+ });
17
+ const handler = async request => {
18
+ const uiResponse = await adminUiRouter(request);
19
+ if (uiResponse !== null) return uiResponse;
20
+ return apiHandler(request);
21
+ };
22
+ return {
23
+ handler,
24
+ dispose
25
+ };
26
+ };
27
+ //# sourceMappingURL=AdminServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminServer.js","names":["HttpApiBuilder","Layer","ApiLayer","MainLayer","makeAdminUiRouter","FullLayer","pipe","provide","makeWebHandler","toWebHandler","makeCompositeHandler","adminPort","dispose","handler","apiHandler","adminUiRouter","request","uiResponse"],"sources":["../../../src/server/AdminServer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,cAAc,QAAQ,kBAAkB;AACjD,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,SAASC,QAAQ,QAAQ,oBAAoB;AAC7C,SAASC,SAAS,QAAQ,qBAAqB;AAC/C,SAASC,iBAAiB,QAAQ,2BAA2B;AAE7D,OAAO,MAAMC,SAAS,gBAAGH,QAAQ,CAACI,IAAI,cAACL,KAAK,CAACM,OAAO,CAACJ,SAAS,CAAC,CAAC;AAEhE,OAAO,MAAMK,cAAc,GAAGA,CAAA,KAAMR,cAAc,CAACS,YAAY,CAACJ,SAAS,CAAC;AAE1E,OAAO,MAAMK,oBAAoB,GAAIC,SAAiB,IAAI;EACxD,MAAM;IAAEC,OAAO;IAAEC,OAAO,EAAEC;EAAU,CAAE,GAAGd,cAAc,CAACS,YAAY,CAACJ,SAAS,CAAC;EAC/E,MAAMU,aAAa,GAAGX,iBAAiB,CAAC;IAAEU,UAAU;IAAEH;EAAS,CAAE,CAAC;EAElE,MAAME,OAAO,GAAG,MAAOG,OAAgB,IAAuB;IAC5D,MAAMC,UAAU,GAAG,MAAMF,aAAa,CAACC,OAAO,CAAC;IAC/C,IAAIC,UAAU,KAAK,IAAI,EAAE,OAAOA,UAAU;IAC1C,OAAOH,UAAU,CAACE,OAAO,CAAC;EAC5B,CAAC;EAED,OAAO;IAAEH,OAAO;IAAED;EAAO,CAAE;AAC7B,CAAC","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ import { Context, Layer } from "effect";
2
+ export class ServerFactory extends Context.Tag("ServerFactory")() {}
3
+ export const BunServerFactoryLive = /*#__PURE__*/Layer.succeed(ServerFactory, {
4
+ create: options => Bun.serve(options)
5
+ });
6
+ //# sourceMappingURL=BunServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunServer.js","names":["Context","Layer","ServerFactory","Tag","BunServerFactoryLive","succeed","create","options","Bun","serve"],"sources":["../../../src/server/BunServer.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,OAAO,EAAEC,KAAK,QAAQ,QAAQ;AAcvC,OAAM,MAAOC,aAAc,SAAQF,OAAO,CAACG,GAAG,CAAC,eAAe,CAAC,EAAqC;AAEpG,OAAO,MAAMC,oBAAoB,gBAAGH,KAAK,CAACI,OAAO,CAACH,aAAa,EAAE;EAC/DI,MAAM,EAAGC,OAAO,IAAKC,GAAG,CAACC,KAAK,CAACF,OAAO;CACvC,CAAC","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ import { Context, Effect, FiberMap, Layer } from "effect";
2
+ export class FiberManager extends Context.Tag("FiberManager")() {}
3
+ export const FiberManagerLive = /*#__PURE__*/Layer.scoped(FiberManager, /*#__PURE__*/Effect.gen(function* () {
4
+ const fiberMap = yield* FiberMap.make();
5
+ const start = (id, effect) => FiberMap.run(fiberMap, id, effect);
6
+ const stop = id => FiberMap.remove(fiberMap, id);
7
+ const isRunning = id => FiberMap.has(fiberMap, id);
8
+ return {
9
+ start,
10
+ stop,
11
+ isRunning
12
+ };
13
+ }));
14
+ //# sourceMappingURL=FiberManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FiberManager.js","names":["Context","Effect","FiberMap","Layer","FiberManager","Tag","FiberManagerLive","scoped","gen","fiberMap","make","start","id","effect","run","stop","remove","isRunning","has"],"sources":["../../../src/server/FiberManager.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,OAAO,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,QAAQ,QAAQ;AAQzD,OAAM,MAAOC,YAAa,SAAQJ,OAAO,CAACK,GAAG,CAAC,cAAc,CAAC,EAAmC;AAEhG,OAAO,MAAMC,gBAAgB,gBAAGH,KAAK,CAACI,MAAM,CAC1CH,YAAY,eACZH,MAAM,CAACO,GAAG,CAAC,aAAS;EAClB,MAAMC,QAAQ,GAAG,OAAOP,QAAQ,CAACQ,IAAI,EAAU;EAE/C,MAAMC,KAAK,GAAGA,CAACC,EAAU,EAAEC,MAAqC,KAC9DX,QAAQ,CAACY,GAAG,CAACL,QAAQ,EAAEG,EAAE,EAAEC,MAAM,CAAC;EAEpC,MAAME,IAAI,GAAIH,EAAU,IAA0BV,QAAQ,CAACc,MAAM,CAACP,QAAQ,EAAEG,EAAE,CAAC;EAE/E,MAAMK,SAAS,GAAIL,EAAU,IAA6BV,QAAQ,CAACgB,GAAG,CAACT,QAAQ,EAAEG,EAAE,CAAC;EAEpF,OAAO;IAAED,KAAK;IAAEI,IAAI;IAAEE;EAAS,CAAE;AACnC,CAAC,CAAC,CACH","ignoreList":[]}
@@ -0,0 +1,225 @@
1
+ import { Context, Data, Effect, HashMap, Layer, Ref, Runtime } from "effect";
2
+ import * as DateTime from "effect/DateTime";
3
+ import { ImposterConfig } from "../domain/imposter";
4
+ import { extractRequestContext, findMatchingStub } from "../matching/RequestMatcher";
5
+ import { buildResponse, makeResponseState } from "../matching/ResponseGenerator";
6
+ import { ImposterRepository } from "../repositories/ImposterRepository";
7
+ import { NonEmptyString } from "../schemas/common";
8
+ import { MetricsService } from "../services/MetricsService";
9
+ import { ProxyService } from "../services/ProxyService";
10
+ import { RequestLogger } from "../services/RequestLogger";
11
+ import { makeUiRouter } from "../ui/UiRouter";
12
+ import { ServerFactory } from "./BunServer";
13
+ import { FiberManager } from "./FiberManager";
14
+ export class ImposterServerError extends Data.TaggedError("ImposterServerError") {}
15
+ export class ImposterServer extends Context.Tag("ImposterServer")() {}
16
+ export const ImposterServerLive = /*#__PURE__*/Layer.effect(ImposterServer, /*#__PURE__*/Effect.gen(function* () {
17
+ const repo = yield* ImposterRepository;
18
+ const fiberManager = yield* FiberManager;
19
+ const serverFactory = yield* ServerFactory;
20
+ const requestLogger = yield* RequestLogger;
21
+ const metricsService = yield* MetricsService;
22
+ const proxyService = yield* ProxyService;
23
+ const stateMapRef = yield* Ref.make(HashMap.empty());
24
+ const start = id => Effect.gen(function* () {
25
+ const record = yield* repo.get(id);
26
+ const config = record.config;
27
+ // Create per-imposter state
28
+ const stubsRef = yield* Ref.make(record.stubs);
29
+ const proxyConfigRef = yield* Ref.make(config.proxy);
30
+ const responseState = yield* makeResponseState();
31
+ // Store state for hot-reload
32
+ yield* Ref.update(stateMapRef, HashMap.set(id, {
33
+ stubsRef,
34
+ proxyConfigRef
35
+ }));
36
+ // Capture runtime for running effects inside fetch handler
37
+ const rt = yield* Effect.runtime();
38
+ const runPromise = Runtime.runPromise(rt);
39
+ // UI router for /_admin pages
40
+ const uiRouter = makeUiRouter({
41
+ id,
42
+ config,
43
+ stubsRef,
44
+ repo,
45
+ requestLogger,
46
+ runPromise
47
+ });
48
+ const handler = async request => {
49
+ // Try UI router first (returns null if not a /_admin path)
50
+ const uiResponse = await uiRouter(request);
51
+ if (uiResponse !== null) return uiResponse;
52
+ return runPromise(Effect.gen(function* () {
53
+ const startTime = Date.now();
54
+ const stubs = yield* Ref.get(stubsRef);
55
+ const ctx = yield* Effect.promise(() => extractRequestContext(request));
56
+ const stub = findMatchingStub(ctx, stubs);
57
+ let response;
58
+ let proxied = false;
59
+ if (!stub) {
60
+ const proxyConfig = yield* Ref.get(proxyConfigRef);
61
+ if (proxyConfig) {
62
+ const url = new URL(request.url);
63
+ response = yield* proxyService.forward(ctx, proxyConfig, url).pipe(Effect.catchTag("ProxyError", err => Effect.succeed(new Response(JSON.stringify({
64
+ error: "Proxy failed",
65
+ target: err.targetUrl,
66
+ reason: err.reason
67
+ }), {
68
+ status: 502,
69
+ headers: {
70
+ "content-type": "application/json"
71
+ }
72
+ }))));
73
+ proxied = true;
74
+ // Record mode: save as stub + update stubsRef
75
+ if (proxyConfig.mode === "record" && response.status < 500) {
76
+ const responseClone = response.clone();
77
+ const newStub = yield* proxyService.recordAsStub(ctx, responseClone);
78
+ yield* repo.addStub(id, newStub).pipe(Effect.catchAll(() => Effect.void));
79
+ const freshStubs = yield* repo.getStubs(id).pipe(Effect.catchAll(() => Effect.succeed([])));
80
+ yield* Ref.set(stubsRef, freshStubs);
81
+ }
82
+ } else {
83
+ response = new Response(JSON.stringify({
84
+ error: "No matching stub found",
85
+ method: ctx.method,
86
+ path: ctx.path
87
+ }), {
88
+ status: 404,
89
+ headers: {
90
+ "content-type": "application/json"
91
+ }
92
+ });
93
+ }
94
+ } else {
95
+ const responses = stub.responses;
96
+ const index = yield* responseState.getNextIndex(id, stub.id, responses.length, stub.responseMode);
97
+ const responseConfig = responses[index];
98
+ const delay = responseConfig.delay;
99
+ if (delay !== undefined && delay > 0) {
100
+ yield* Effect.sleep(`${delay} millis`);
101
+ }
102
+ response = yield* Effect.promise(() => buildResponse(responseConfig, ctx));
103
+ }
104
+ // Capture response for logging
105
+ const respText = yield* Effect.promise(() => response.text());
106
+ const respHeaders = {};
107
+ response.headers.forEach((val, key) => {
108
+ respHeaders[key] = val;
109
+ });
110
+ // Reconstruct since .text() consumed body
111
+ response = new Response(respText, {
112
+ status: response.status,
113
+ headers: response.headers
114
+ });
115
+ const logBody = respText.length > 10240 ? respText.slice(0, 10240) : respText || undefined;
116
+ const duration = Date.now() - startTime;
117
+ const logEntry = {
118
+ id: NonEmptyString.make(crypto.randomUUID()),
119
+ imposterId: NonEmptyString.make(id),
120
+ timestamp: DateTime.unsafeMake(startTime),
121
+ request: {
122
+ method: ctx.method,
123
+ path: ctx.path,
124
+ headers: ctx.headers,
125
+ query: ctx.query,
126
+ body: ctx.body
127
+ },
128
+ response: {
129
+ status: response.status,
130
+ headers: respHeaders,
131
+ ...(logBody !== undefined ? {
132
+ body: logBody
133
+ } : {}),
134
+ ...(stub ? {
135
+ matchedStubId: NonEmptyString.make(stub.id)
136
+ } : {}),
137
+ proxied
138
+ },
139
+ duration
140
+ };
141
+ yield* requestLogger.log(logEntry).pipe(Effect.catchAll(() => Effect.void));
142
+ yield* metricsService.recordRequest(logEntry).pipe(Effect.catchAll(() => Effect.void));
143
+ return response;
144
+ }).pipe(Effect.catchAllCause(cause => Effect.succeed(new Response(JSON.stringify({
145
+ error: "Internal server error",
146
+ details: String(cause)
147
+ }), {
148
+ status: 500,
149
+ headers: {
150
+ "content-type": "application/json"
151
+ }
152
+ })))));
153
+ };
154
+ // Build the long-running fiber effect with acquireRelease
155
+ const fiberEffect = Effect.acquireRelease(Effect.try({
156
+ try: () => serverFactory.create({
157
+ port: config.port,
158
+ fetch: handler
159
+ }),
160
+ catch: err => new ImposterServerError({
161
+ imposterId: id,
162
+ reason: `Failed to bind port ${config.port}: ${err}`
163
+ })
164
+ }), server => Effect.sync(() => server.stop(true))).pipe(Effect.andThen(Effect.never), Effect.scoped);
165
+ // Wrap fiber in onError for crash supervision
166
+ const supervisedEffect = fiberEffect.pipe(Effect.onError(() => Effect.gen(function* () {
167
+ yield* Ref.update(stateMapRef, HashMap.remove(id));
168
+ yield* repo.update(id, r => ({
169
+ ...r,
170
+ config: ImposterConfig({
171
+ ...r.config,
172
+ status: "stopped"
173
+ })
174
+ })).pipe(Effect.catchAll(() => Effect.void));
175
+ yield* responseState.reset(id);
176
+ })));
177
+ yield* fiberManager.start(id, supervisedEffect);
178
+ // Update status to running
179
+ yield* repo.update(id, r => ({
180
+ ...r,
181
+ config: ImposterConfig({
182
+ ...r.config,
183
+ status: "running"
184
+ })
185
+ })).pipe(Effect.catchTag("ImposterNotFoundError", () => Effect.void));
186
+ });
187
+ const stop = id => Effect.gen(function* () {
188
+ yield* fiberManager.stop(id);
189
+ yield* Ref.update(stateMapRef, HashMap.remove(id));
190
+ yield* repo.update(id, r => ({
191
+ ...r,
192
+ config: ImposterConfig({
193
+ ...r.config,
194
+ status: "stopped"
195
+ })
196
+ })).pipe(Effect.catchAll(() => Effect.void));
197
+ yield* requestLogger.removeImposter(id);
198
+ });
199
+ const updateStubs = id => Effect.gen(function* () {
200
+ const stubs = yield* repo.getStubs(id).pipe(Effect.catchAll(() => Effect.succeed([])));
201
+ const stateMap = yield* Ref.get(stateMapRef);
202
+ const state = HashMap.get(stateMap, id);
203
+ if (state._tag === "Some") {
204
+ yield* Ref.set(state.value.stubsRef, stubs);
205
+ }
206
+ });
207
+ const updateProxyConfig = id => Effect.gen(function* () {
208
+ const record = yield* repo.get(id).pipe(Effect.catchAll(() => Effect.succeed(null)));
209
+ if (record === null) return;
210
+ const stateMap = yield* Ref.get(stateMapRef);
211
+ const state = HashMap.get(stateMap, id);
212
+ if (state._tag === "Some") {
213
+ yield* Ref.set(state.value.proxyConfigRef, record.config.proxy);
214
+ }
215
+ });
216
+ const isRunning = id => fiberManager.isRunning(id);
217
+ return {
218
+ start,
219
+ stop,
220
+ updateStubs,
221
+ updateProxyConfig,
222
+ isRunning
223
+ };
224
+ }));
225
+ //# sourceMappingURL=ImposterServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImposterServer.js","names":["Context","Data","Effect","HashMap","Layer","Ref","Runtime","DateTime","ImposterConfig","extractRequestContext","findMatchingStub","buildResponse","makeResponseState","ImposterRepository","NonEmptyString","MetricsService","ProxyService","RequestLogger","makeUiRouter","ServerFactory","FiberManager","ImposterServerError","TaggedError","ImposterServer","Tag","ImposterServerLive","effect","gen","repo","fiberManager","serverFactory","requestLogger","metricsService","proxyService","stateMapRef","make","empty","start","id","record","get","config","stubsRef","stubs","proxyConfigRef","proxy","responseState","update","set","rt","runtime","runPromise","uiRouter","handler","request","uiResponse","startTime","Date","now","ctx","promise","stub","response","proxied","proxyConfig","url","URL","forward","pipe","catchTag","err","succeed","Response","JSON","stringify","error","target","targetUrl","reason","status","headers","mode","responseClone","clone","newStub","recordAsStub","addStub","catchAll","void","freshStubs","getStubs","method","path","responses","index","getNextIndex","length","responseMode","responseConfig","delay","undefined","sleep","respText","text","respHeaders","forEach","val","key","logBody","slice","duration","logEntry","crypto","randomUUID","imposterId","timestamp","unsafeMake","query","body","matchedStubId","log","recordRequest","catchAllCause","cause","details","String","fiberEffect","acquireRelease","try","create","port","fetch","catch","server","sync","stop","andThen","never","scoped","supervisedEffect","onError","remove","r","reset","removeImposter","updateStubs","stateMap","state","_tag","value","updateProxyConfig","isRunning"],"sources":["../../../src/server/ImposterServer.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { Config, Context, Layer } from "effect";
2
+ export class AppConfig extends Context.Tag("AppConfig")() {}
3
+ const config = /*#__PURE__*/Config.all({
4
+ adminPort: /*#__PURE__*/Config.number("ADMIN_PORT").pipe(/*#__PURE__*/Config.withDefault(2525)),
5
+ portRangeMin: /*#__PURE__*/Config.number("PORT_RANGE_MIN").pipe(/*#__PURE__*/Config.withDefault(3000)),
6
+ portRangeMax: /*#__PURE__*/Config.number("PORT_RANGE_MAX").pipe(/*#__PURE__*/Config.withDefault(4000)),
7
+ maxImposters: /*#__PURE__*/Config.number("MAX_IMPOSTERS").pipe(/*#__PURE__*/Config.withDefault(100)),
8
+ logLevel: /*#__PURE__*/Config.literal("debug", "info", "warn", "error")("LOG_LEVEL").pipe(/*#__PURE__*/Config.withDefault("info"))
9
+ });
10
+ export const AppConfigLive = /*#__PURE__*/Layer.effect(AppConfig, config);
11
+ //# sourceMappingURL=AppConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppConfig.js","names":["Config","Context","Layer","AppConfig","Tag","config","all","adminPort","number","pipe","withDefault","portRangeMin","portRangeMax","maxImposters","logLevel","literal","AppConfigLive","effect"],"sources":["../../../src/services/AppConfig.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,MAAM,EAAEC,OAAO,EAAEC,KAAK,QAAQ,QAAQ;AAU/C,OAAM,MAAOC,SAAU,SAAQF,OAAO,CAACG,GAAG,CAAC,WAAW,CAAC,EAA6B;AAEpF,MAAMC,MAAM,gBAAGL,MAAM,CAACM,GAAG,CAAC;EACxBC,SAAS,eAAEP,MAAM,CAACQ,MAAM,CAAC,YAAY,CAAC,CAACC,IAAI,cAACT,MAAM,CAACU,WAAW,CAAC,IAAI,CAAC,CAAC;EACrEC,YAAY,eAAEX,MAAM,CAACQ,MAAM,CAAC,gBAAgB,CAAC,CAACC,IAAI,cAACT,MAAM,CAACU,WAAW,CAAC,IAAI,CAAC,CAAC;EAC5EE,YAAY,eAAEZ,MAAM,CAACQ,MAAM,CAAC,gBAAgB,CAAC,CAACC,IAAI,cAACT,MAAM,CAACU,WAAW,CAAC,IAAI,CAAC,CAAC;EAC5EG,YAAY,eAAEb,MAAM,CAACQ,MAAM,CAAC,eAAe,CAAC,CAACC,IAAI,cAACT,MAAM,CAACU,WAAW,CAAC,GAAG,CAAC,CAAC;EAC1EI,QAAQ,eAAEd,MAAM,CAACe,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CACpEN,IAAI,cAACT,MAAM,CAACU,WAAW,CAAC,MAAe,CAAC;CAC5C,CAAC;AAEF,OAAO,MAAMM,aAAa,gBAAGd,KAAK,CAACe,MAAM,CAACd,SAAS,EAAEE,MAAM,CAAC","ignoreList":[]}
@@ -0,0 +1,105 @@
1
+ import { Context, Effect, HashMap, Layer, Ref } from "effect";
2
+ import * as DateTime from "effect/DateTime";
3
+ const BUFFER_SIZE = 1000;
4
+ const makeEmptyMetrics = now => ({
5
+ totalRequests: 0,
6
+ requestsByMethod: {},
7
+ requestsByStatusCode: {},
8
+ responseTimes: new Float64Array(BUFFER_SIZE),
9
+ responseTimeIndex: 0,
10
+ responseTimeCount: 0,
11
+ firstRequestAt: now,
12
+ lastRequestAt: now,
13
+ errorCount: 0
14
+ });
15
+ const computePercentile = (sorted, p) => {
16
+ if (sorted.length === 0) return 0;
17
+ const index = Math.ceil(p / 100 * sorted.length) - 1;
18
+ return sorted[Math.max(0, index)];
19
+ };
20
+ const computeStats = metrics => {
21
+ const count = metrics.responseTimeCount;
22
+ const total = metrics.totalRequests;
23
+ // Compute average response time
24
+ let sumRT = 0;
25
+ for (let i = 0; i < Math.min(count, BUFFER_SIZE); i++) {
26
+ sumRT += metrics.responseTimes[i];
27
+ }
28
+ const avgRT = count > 0 ? sumRT / Math.min(count, BUFFER_SIZE) : 0;
29
+ // Compute requests per minute
30
+ const elapsedMs = DateTime.toEpochMillis(metrics.lastRequestAt) - DateTime.toEpochMillis(metrics.firstRequestAt);
31
+ const elapsedMinutes = elapsedMs / 60000;
32
+ const rpm = elapsedMinutes > 0 ? total / elapsedMinutes : total;
33
+ // Compute error rate
34
+ const errorRate = total > 0 ? metrics.errorCount / total : 0;
35
+ // Compute percentiles
36
+ const bufferLen = Math.min(count, BUFFER_SIZE);
37
+ const sorted = Array.from(metrics.responseTimes.subarray(0, bufferLen)).sort((a, b) => a - b);
38
+ return {
39
+ totalRequests: total,
40
+ requestsPerMinute: Math.round(rpm * 100) / 100,
41
+ averageResponseTime: Math.round(avgRT * 100) / 100,
42
+ errorRate: Math.round(errorRate * 10000) / 10000,
43
+ requestsByMethod: {
44
+ ...metrics.requestsByMethod
45
+ },
46
+ requestsByStatusCode: {
47
+ ...metrics.requestsByStatusCode
48
+ },
49
+ ...(total > 0 ? {
50
+ lastRequestAt: metrics.lastRequestAt
51
+ } : {}),
52
+ ...(bufferLen > 0 ? {
53
+ p50ResponseTime: computePercentile(sorted, 50),
54
+ p95ResponseTime: computePercentile(sorted, 95),
55
+ p99ResponseTime: computePercentile(sorted, 99)
56
+ } : {})
57
+ };
58
+ };
59
+ export class MetricsService extends Context.Tag("MetricsService")() {}
60
+ export const MetricsServiceLive = /*#__PURE__*/Layer.effect(MetricsService, /*#__PURE__*/Effect.gen(function* () {
61
+ const storeRef = yield* Ref.make(HashMap.empty());
62
+ const recordRequest = entry => Ref.update(storeRef, store => {
63
+ const existing = HashMap.get(store, entry.imposterId);
64
+ const now = entry.timestamp;
65
+ const metrics = existing._tag === "Some" ? existing.value : makeEmptyMetrics(now);
66
+ metrics.totalRequests += 1;
67
+ // Method counts
68
+ const method = entry.request.method.toUpperCase();
69
+ metrics.requestsByMethod[method] = (metrics.requestsByMethod[method] ?? 0) + 1;
70
+ // Status code counts
71
+ const statusKey = String(entry.response.status);
72
+ metrics.requestsByStatusCode[statusKey] = (metrics.requestsByStatusCode[statusKey] ?? 0) + 1;
73
+ // Response time circular buffer
74
+ metrics.responseTimes[metrics.responseTimeIndex % BUFFER_SIZE] = entry.duration;
75
+ metrics.responseTimeIndex = (metrics.responseTimeIndex + 1) % BUFFER_SIZE;
76
+ metrics.responseTimeCount += 1;
77
+ // Error tracking (4xx + 5xx)
78
+ if (entry.response.status >= 400) {
79
+ metrics.errorCount += 1;
80
+ }
81
+ metrics.lastRequestAt = now;
82
+ return HashMap.set(store, entry.imposterId, metrics);
83
+ });
84
+ const getStats = imposterId => Ref.get(storeRef).pipe(Effect.map(store => {
85
+ const existing = HashMap.get(store, imposterId);
86
+ if (existing._tag === "None") {
87
+ return {
88
+ totalRequests: 0,
89
+ requestsPerMinute: 0,
90
+ averageResponseTime: 0,
91
+ errorRate: 0,
92
+ requestsByMethod: {},
93
+ requestsByStatusCode: {}
94
+ };
95
+ }
96
+ return computeStats(existing.value);
97
+ }));
98
+ const resetStats = imposterId => Ref.update(storeRef, HashMap.remove(imposterId));
99
+ return {
100
+ recordRequest,
101
+ getStats,
102
+ resetStats
103
+ };
104
+ }));
105
+ //# sourceMappingURL=MetricsService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricsService.js","names":["Context","Effect","HashMap","Layer","Ref","DateTime","BUFFER_SIZE","makeEmptyMetrics","now","totalRequests","requestsByMethod","requestsByStatusCode","responseTimes","Float64Array","responseTimeIndex","responseTimeCount","firstRequestAt","lastRequestAt","errorCount","computePercentile","sorted","p","length","index","Math","ceil","max","computeStats","metrics","count","total","sumRT","i","min","avgRT","elapsedMs","toEpochMillis","elapsedMinutes","rpm","errorRate","bufferLen","Array","from","subarray","sort","a","b","requestsPerMinute","round","averageResponseTime","p50ResponseTime","p95ResponseTime","p99ResponseTime","MetricsService","Tag","MetricsServiceLive","effect","gen","storeRef","make","empty","recordRequest","entry","update","store","existing","get","imposterId","timestamp","_tag","value","method","request","toUpperCase","statusKey","String","response","status","duration","set","getStats","pipe","map","resetStats","remove"],"sources":["../../../src/services/MetricsService.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,41 @@
1
+ import { Context, Data, Effect, HashSet, Layer, Ref } from "effect";
2
+ import { AppConfig } from "./AppConfig";
3
+ export class PortAllocatorError extends Data.TaggedError("PortAllocatorError") {}
4
+ export class PortExhaustedError extends Data.TaggedError("PortExhaustedError") {}
5
+ export class PortAllocator extends Context.Tag("PortAllocator")() {}
6
+ export const PortAllocatorLive = /*#__PURE__*/Layer.effect(PortAllocator, /*#__PURE__*/Effect.gen(function* () {
7
+ const config = yield* AppConfig;
8
+ const portsRef = yield* Ref.make(HashSet.empty());
9
+ const allocate = preferred => {
10
+ if (preferred !== undefined) {
11
+ return Ref.modify(portsRef, ports => {
12
+ if (HashSet.has(ports, preferred)) {
13
+ return [Effect.fail(new PortAllocatorError({
14
+ reason: `Port ${preferred} is already allocated`,
15
+ port: preferred
16
+ })), ports];
17
+ }
18
+ return [Effect.succeed(preferred), HashSet.add(ports, preferred)];
19
+ }).pipe(Effect.flatten);
20
+ }
21
+ return Ref.modify(portsRef, ports => {
22
+ for (let port = config.portRangeMin; port <= config.portRangeMax; port++) {
23
+ if (!HashSet.has(ports, port)) {
24
+ return [Effect.succeed(port), HashSet.add(ports, port)];
25
+ }
26
+ }
27
+ return [Effect.fail(new PortExhaustedError({
28
+ rangeMin: config.portRangeMin,
29
+ rangeMax: config.portRangeMax
30
+ })), ports];
31
+ }).pipe(Effect.flatten);
32
+ };
33
+ const release = port => Ref.update(portsRef, HashSet.remove(port));
34
+ const isAvailable = port => Ref.get(portsRef).pipe(Effect.map(ports => !HashSet.has(ports, port)));
35
+ return {
36
+ allocate,
37
+ release,
38
+ isAvailable
39
+ };
40
+ }));
41
+ //# sourceMappingURL=PortAllocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortAllocator.js","names":["Context","Data","Effect","HashSet","Layer","Ref","AppConfig","PortAllocatorError","TaggedError","PortExhaustedError","PortAllocator","Tag","PortAllocatorLive","effect","gen","config","portsRef","make","empty","allocate","preferred","undefined","modify","ports","has","fail","reason","port","succeed","add","pipe","flatten","portRangeMin","portRangeMax","rangeMin","rangeMax","release","update","remove","isAvailable","get","map"],"sources":["../../../src/services/PortAllocator.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,OAAO,EAAEC,IAAI,EAAEC,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAEC,GAAG,QAAQ,QAAQ;AACnE,SAASC,SAAS,QAAQ,aAAa;AAEvC,OAAM,MAAOC,kBAAmB,SAAQN,IAAI,CAACO,WAAW,CAAC,oBAAoB,CAG3E;AAEF,OAAM,MAAOC,kBAAmB,SAAQR,IAAI,CAACO,WAAW,CAAC,oBAAoB,CAG3E;AAQF,OAAM,MAAOE,aAAc,SAAQV,OAAO,CAACW,GAAG,CAAC,eAAe,CAAC,EAAqC;AAEpG,OAAO,MAAMC,iBAAiB,gBAAGR,KAAK,CAACS,MAAM,CAC3CH,aAAa,eACbR,MAAM,CAACY,GAAG,CAAC,aAAS;EAClB,MAAMC,MAAM,GAAG,OAAOT,SAAS;EAC/B,MAAMU,QAAQ,GAAG,OAAOX,GAAG,CAACY,IAAI,CAACd,OAAO,CAACe,KAAK,EAAU,CAAC;EAOzD,MAAMC,QAAQ,GAAIC,SAAkB,IAAoE;IACtG,IAAIA,SAAS,KAAKC,SAAS,EAAE;MAC3B,OAAOhB,GAAG,CAACiB,MAAM,CAACN,QAAQ,EAAGO,KAAK,IAAoB;QACpD,IAAIpB,OAAO,CAACqB,GAAG,CAACD,KAAK,EAAEH,SAAS,CAAC,EAAE;UACjC,OAAO,CACLlB,MAAM,CAACuB,IAAI,CACT,IAAIlB,kBAAkB,CAAC;YAAEmB,MAAM,EAAE,QAAQN,SAAS,uBAAuB;YAAEO,IAAI,EAAEP;UAAS,CAAE,CAAC,CAC9F,EACDG,KAAK,CACN;QACH;QACA,OAAO,CAACrB,MAAM,CAAC0B,OAAO,CAACR,SAAS,CAAC,EAAEjB,OAAO,CAAC0B,GAAG,CAACN,KAAK,EAAEH,SAAS,CAAC,CAAC;MACnE,CAAC,CAAC,CAACU,IAAI,CAAC5B,MAAM,CAAC6B,OAAO,CAAC;IACzB;IAEA,OAAO1B,GAAG,CAACiB,MAAM,CAACN,QAAQ,EAAGO,KAAK,IAAoB;MACpD,KAAK,IAAII,IAAI,GAAGZ,MAAM,CAACiB,YAAY,EAAEL,IAAI,IAAIZ,MAAM,CAACkB,YAAY,EAAEN,IAAI,EAAE,EAAE;QACxE,IAAI,CAACxB,OAAO,CAACqB,GAAG,CAACD,KAAK,EAAEI,IAAI,CAAC,EAAE;UAC7B,OAAO,CAACzB,MAAM,CAAC0B,OAAO,CAACD,IAAI,CAAC,EAAExB,OAAO,CAAC0B,GAAG,CAACN,KAAK,EAAEI,IAAI,CAAC,CAAC;QACzD;MACF;MACA,OAAO,CACLzB,MAAM,CAACuB,IAAI,CAAC,IAAIhB,kBAAkB,CAAC;QAAEyB,QAAQ,EAAEnB,MAAM,CAACiB,YAAY;QAAEG,QAAQ,EAAEpB,MAAM,CAACkB;MAAY,CAAE,CAAC,CAAC,EACrGV,KAAK,CACN;IACH,CAAC,CAAC,CAACO,IAAI,CAAC5B,MAAM,CAAC6B,OAAO,CAAC;EACzB,CAAC;EAED,MAAMK,OAAO,GAAIT,IAAY,IAA0BtB,GAAG,CAACgC,MAAM,CAACrB,QAAQ,EAAEb,OAAO,CAACmC,MAAM,CAACX,IAAI,CAAC,CAAC;EAEjG,MAAMY,WAAW,GAAIZ,IAAY,IAC/BtB,GAAG,CAACmC,GAAG,CAACxB,QAAQ,CAAC,CAACc,IAAI,CAAC5B,MAAM,CAACuC,GAAG,CAAElB,KAAK,IAAK,CAACpB,OAAO,CAACqB,GAAG,CAACD,KAAK,EAAEI,IAAI,CAAC,CAAC,CAAC;EAE1E,OAAO;IAAER,QAAQ;IAAEiB,OAAO;IAAEG;EAAW,CAAE;AAC3C,CAAC,CAAC,CACH","ignoreList":[]}