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,242 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeUiRouter = void 0;
7
+ var _effect = require("effect");
8
+ var _common = require("../schemas/common");
9
+ var _dashboard = require("./pages/dashboard");
10
+ var _requestDetail = require("./pages/request-detail");
11
+ var _requests = require("./pages/requests");
12
+ var _stubs = require("./pages/stubs");
13
+ var _partials = require("./partials");
14
+ const htmlResponse = (body, status = 200) => new Response(body, {
15
+ status,
16
+ headers: {
17
+ "content-type": "text/html; charset=utf-8"
18
+ }
19
+ });
20
+ const parseStubIdFromPath = path => {
21
+ const match = path.match(/^\/stubs\/(.+)$/);
22
+ return match ? match[1] : null;
23
+ };
24
+ const makeUiRouter = deps => async request => {
25
+ const url = new URL(request.url);
26
+ if (!url.pathname.startsWith("/_admin")) return null;
27
+ const path = url.pathname.slice("/_admin".length) || "/";
28
+ const method = request.method.toUpperCase();
29
+ // GET / — dashboard
30
+ if (method === "GET" && (path === "/" || path === "")) {
31
+ return deps.runPromise(_effect.Effect.gen(function* () {
32
+ const stubs = yield* _effect.Ref.get(deps.stubsRef);
33
+ const requestCount = yield* deps.requestLogger.getCount(deps.id);
34
+ const recentRequests = yield* deps.requestLogger.getEntries(deps.id, {
35
+ limit: 10
36
+ });
37
+ return htmlResponse((0, _dashboard.dashboardPage)({
38
+ config: deps.config,
39
+ stubCount: stubs.length,
40
+ requestCount,
41
+ recentRequests: recentRequests.slice().reverse()
42
+ }).value);
43
+ }));
44
+ }
45
+ // GET /stubs — stubs page
46
+ if (method === "GET" && path === "/stubs") {
47
+ return deps.runPromise(_effect.Effect.gen(function* () {
48
+ const stubs = yield* _effect.Ref.get(deps.stubsRef);
49
+ return htmlResponse((0, _stubs.stubsPage)({
50
+ config: deps.config,
51
+ stubs
52
+ }).value);
53
+ }));
54
+ }
55
+ // POST /stubs — add stub
56
+ if (method === "POST" && path === "/stubs") {
57
+ try {
58
+ const formData = await request.formData();
59
+ const predicatesRaw = formData.get("predicates");
60
+ const responsesRaw = formData.get("responses");
61
+ const responseMode = formData.get("responseMode") || "sequential";
62
+ if (!responsesRaw) {
63
+ return htmlResponse((0, _partials.errorPartial)("Responses field is required.").value, 200);
64
+ }
65
+ let predicates;
66
+ let responses;
67
+ try {
68
+ predicates = JSON.parse(predicatesRaw || "[]");
69
+ responses = JSON.parse(responsesRaw);
70
+ } catch {
71
+ return htmlResponse((0, _partials.errorPartial)("Invalid JSON in predicates or responses.").value, 200);
72
+ }
73
+ if (!Array.isArray(responses) || responses.length === 0) {
74
+ return htmlResponse((0, _partials.errorPartial)("Responses must be a non-empty array.").value, 200);
75
+ }
76
+ const stubId = _common.NonEmptyString.make(crypto.randomUUID().slice(0, 8));
77
+ const stub = {
78
+ id: stubId,
79
+ predicates: predicates,
80
+ responses: responses,
81
+ responseMode: responseMode
82
+ };
83
+ return await deps.runPromise(_effect.Effect.gen(function* () {
84
+ yield* deps.repo.addStub(deps.id, stub).pipe(_effect.Effect.catchAll(() => _effect.Effect.void));
85
+ const updated = yield* deps.repo.getStubs(deps.id).pipe(_effect.Effect.catchAll(() => _effect.Effect.succeed([])));
86
+ yield* _effect.Ref.set(deps.stubsRef, updated);
87
+ return htmlResponse((0, _partials.stubListPartial)(updated).value);
88
+ }));
89
+ } catch {
90
+ return htmlResponse((0, _partials.errorPartial)("Failed to parse form data.").value, 200);
91
+ }
92
+ }
93
+ // DELETE /stubs/:id — delete stub
94
+ const deleteStubId = method === "DELETE" ? parseStubIdFromPath(path) : null;
95
+ if (deleteStubId !== null) {
96
+ return deps.runPromise(_effect.Effect.gen(function* () {
97
+ yield* deps.repo.removeStub(deps.id, deleteStubId).pipe(_effect.Effect.catchAll(() => _effect.Effect.void));
98
+ const updated = yield* deps.repo.getStubs(deps.id).pipe(_effect.Effect.catchAll(() => _effect.Effect.succeed([])));
99
+ yield* _effect.Ref.set(deps.stubsRef, updated);
100
+ return htmlResponse((0, _partials.stubListPartial)(updated).value);
101
+ }));
102
+ }
103
+ // PUT /stubs/:id — update stub
104
+ const putStubId = method === "PUT" ? parseStubIdFromPath(path) : null;
105
+ if (putStubId !== null) {
106
+ try {
107
+ const formData = await request.formData();
108
+ const predicatesRaw = formData.get("predicates");
109
+ const responsesRaw = formData.get("responses");
110
+ const responseMode = formData.get("responseMode");
111
+ return await deps.runPromise(_effect.Effect.gen(function* () {
112
+ yield* deps.repo.updateStub(deps.id, putStubId, existing => ({
113
+ ...existing,
114
+ ...(predicatesRaw ? {
115
+ predicates: JSON.parse(predicatesRaw)
116
+ } : {}),
117
+ ...(responsesRaw ? {
118
+ responses: JSON.parse(responsesRaw)
119
+ } : {}),
120
+ ...(responseMode ? {
121
+ responseMode: responseMode
122
+ } : {})
123
+ })).pipe(_effect.Effect.catchAll(() => _effect.Effect.void));
124
+ const updated = yield* deps.repo.getStubs(deps.id).pipe(_effect.Effect.catchAll(() => _effect.Effect.succeed([])));
125
+ yield* _effect.Ref.set(deps.stubsRef, updated);
126
+ return htmlResponse((0, _partials.stubListPartial)(updated).value);
127
+ }));
128
+ } catch {
129
+ return htmlResponse((0, _partials.errorPartial)("Failed to parse form data.").value, 200);
130
+ }
131
+ }
132
+ // GET /requests — full page
133
+ if (method === "GET" && path === "/requests") {
134
+ return deps.runPromise(_effect.Effect.gen(function* () {
135
+ const entries = yield* deps.requestLogger.getEntries(deps.id, {
136
+ limit: 100
137
+ });
138
+ return htmlResponse((0, _requests.requestsPage)({
139
+ config: deps.config,
140
+ entries
141
+ }).value);
142
+ }));
143
+ }
144
+ // GET /requests/list — HTMX partial (filtered table body)
145
+ if (method === "GET" && path === "/requests/list") {
146
+ const params = url.searchParams;
147
+ return deps.runPromise(_effect.Effect.gen(function* () {
148
+ const opts = {
149
+ limit: 100
150
+ };
151
+ const methodFilter = params.get("method");
152
+ if (methodFilter) opts.method = methodFilter;
153
+ const pathFilter = params.get("path");
154
+ if (pathFilter) opts.path = pathFilter;
155
+ const statusFilter = params.get("status");
156
+ if (statusFilter) opts.status = Number(statusFilter);
157
+ const entries = yield* deps.requestLogger.getEntries(deps.id, opts);
158
+ return htmlResponse((0, _partials.requestTablePartial)(entries.slice().reverse()).value);
159
+ }));
160
+ }
161
+ // POST /requests/test — send test request to own port
162
+ if (method === "POST" && path === "/requests/test") {
163
+ try {
164
+ const formData = await request.formData();
165
+ const testMethod = formData.get("method") || "GET";
166
+ const testPath = formData.get("path") || "/";
167
+ const testBody = formData.get("body");
168
+ const testContentType = formData.get("contentType") || "application/json";
169
+ const testHeadersRaw = formData.get("headers") || "";
170
+ const headers = {};
171
+ if (testContentType && testBody) {
172
+ headers["content-type"] = testContentType;
173
+ }
174
+ for (const line of testHeadersRaw.split("\n")) {
175
+ const colonIdx = line.indexOf(":");
176
+ if (colonIdx > 0) {
177
+ headers[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
178
+ }
179
+ }
180
+ const startTime = Date.now();
181
+ const testResp = await fetch(`http://localhost:${deps.config.port}${testPath}`, {
182
+ method: testMethod,
183
+ headers,
184
+ ...(testBody && testMethod !== "GET" && testMethod !== "HEAD" ? {
185
+ body: testBody
186
+ } : {})
187
+ });
188
+ const duration = Date.now() - startTime;
189
+ const respBody = await testResp.text();
190
+ const respHeaders = {};
191
+ testResp.headers.forEach((val, key) => {
192
+ respHeaders[key] = val;
193
+ });
194
+ return htmlResponse((0, _requests.testResultPartial)({
195
+ status: testResp.status,
196
+ headers: respHeaders,
197
+ body: respBody,
198
+ duration
199
+ }).value);
200
+ } catch (err) {
201
+ return htmlResponse(`<div class="bg-red-50 border border-red-200 text-red-700 rounded p-3">Request failed: ${String(err)}</div>`);
202
+ }
203
+ }
204
+ // DELETE /requests — clear log
205
+ if (method === "DELETE" && path === "/requests") {
206
+ return deps.runPromise(_effect.Effect.gen(function* () {
207
+ yield* deps.requestLogger.clear(deps.id);
208
+ return htmlResponse((0, _partials.requestTablePartial)([]).value);
209
+ }));
210
+ }
211
+ // GET /requests/:id — detail page
212
+ if (method === "GET" && path.startsWith("/requests/")) {
213
+ const entryId = path.slice("/requests/".length);
214
+ if (entryId && !entryId.includes("/")) {
215
+ return deps.runPromise(_effect.Effect.gen(function* () {
216
+ const entry = yield* deps.requestLogger.getEntryById(deps.id, entryId);
217
+ if (entry === null) {
218
+ return htmlResponse("<h1>Request not found</h1>", 404);
219
+ }
220
+ // Try to find matched stub
221
+ let matchedStub = null;
222
+ if (entry.response.matchedStubId) {
223
+ try {
224
+ const stubs = yield* deps.repo.getStubs(deps.id).pipe(_effect.Effect.catchAll(() => _effect.Effect.succeed([])));
225
+ matchedStub = stubs.find(s => s.id === entry.response.matchedStubId) ?? null;
226
+ } catch {
227
+ // ignore
228
+ }
229
+ }
230
+ return htmlResponse((0, _requestDetail.requestDetailPage)({
231
+ config: deps.config,
232
+ entry,
233
+ matchedStub
234
+ }).value);
235
+ }));
236
+ }
237
+ }
238
+ // Fallback: 404 within /_admin
239
+ return htmlResponse("<h1>Not Found</h1>", 404);
240
+ };
241
+ exports.makeUiRouter = makeUiRouter;
242
+ //# sourceMappingURL=UiRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UiRouter.js","names":["_effect","require","_common","_dashboard","_requestDetail","_requests","_stubs","_partials","htmlResponse","body","status","Response","headers","parseStubIdFromPath","path","match","makeUiRouter","deps","request","url","URL","pathname","startsWith","slice","length","method","toUpperCase","runPromise","Effect","gen","stubs","Ref","get","stubsRef","requestCount","requestLogger","getCount","id","recentRequests","getEntries","limit","dashboardPage","config","stubCount","reverse","value","stubsPage","formData","predicatesRaw","responsesRaw","responseMode","errorPartial","predicates","responses","JSON","parse","Array","isArray","stubId","NonEmptyString","make","crypto","randomUUID","stub","repo","addStub","pipe","catchAll","void","updated","getStubs","succeed","set","stubListPartial","deleteStubId","removeStub","putStubId","updateStub","existing","entries","requestsPage","params","searchParams","opts","methodFilter","pathFilter","statusFilter","Number","requestTablePartial","testMethod","testPath","testBody","testContentType","testHeadersRaw","line","split","colonIdx","indexOf","trim","startTime","Date","now","testResp","fetch","port","duration","respBody","text","respHeaders","forEach","val","key","testResultPartial","err","String","clear","entryId","includes","entry","getEntryById","matchedStub","response","matchedStubId","find","s","requestDetailPage","exports"],"sources":["../../../src/ui/UiRouter.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAGA,IAAAC,OAAA,GAAAD,OAAA;AAGA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,cAAA,GAAAH,OAAA;AACA,IAAAI,SAAA,GAAAJ,OAAA;AACA,IAAAK,MAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AAWA,MAAMO,YAAY,GAAGA,CAACC,IAAY,EAAEC,MAAM,GAAG,GAAG,KAC9C,IAAIC,QAAQ,CAACF,IAAI,EAAE;EACjBC,MAAM;EACNE,OAAO,EAAE;IAAE,cAAc,EAAE;EAA0B;CACtD,CAAC;AAEJ,MAAMC,mBAAmB,GAAIC,IAAY,IAAmB;EAC1D,MAAMC,KAAK,GAAGD,IAAI,CAACC,KAAK,CAAC,iBAAiB,CAAC;EAC3C,OAAOA,KAAK,GAAGA,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI;AACjC,CAAC;AAEM,MAAMC,YAAY,GAAIC,IAAY,IAAK,MAAOC,OAAgB,IAA8B;EACjG,MAAMC,GAAG,GAAG,IAAIC,GAAG,CAACF,OAAO,CAACC,GAAG,CAAC;EAChC,IAAI,CAACA,GAAG,CAACE,QAAQ,CAACC,UAAU,CAAC,SAAS,CAAC,EAAE,OAAO,IAAI;EAEpD,MAAMR,IAAI,GAAGK,GAAG,CAACE,QAAQ,CAACE,KAAK,CAAC,SAAS,CAACC,MAAM,CAAC,IAAI,GAAG;EACxD,MAAMC,MAAM,GAAGP,OAAO,CAACO,MAAM,CAACC,WAAW,EAAE;EAE3C;EACA,IAAID,MAAM,KAAK,KAAK,KAAKX,IAAI,KAAK,GAAG,IAAIA,IAAI,KAAK,EAAE,CAAC,EAAE;IACrD,OAAOG,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,MAAMC,KAAK,GAAG,OAAOC,WAAG,CAACC,GAAG,CAACf,IAAI,CAACgB,QAAQ,CAAC;MAC3C,MAAMC,YAAY,GAAG,OAAOjB,IAAI,CAACkB,aAAa,CAACC,QAAQ,CAACnB,IAAI,CAACoB,EAAE,CAAC;MAChE,MAAMC,cAAc,GAAG,OAAOrB,IAAI,CAACkB,aAAa,CAACI,UAAU,CAACtB,IAAI,CAACoB,EAAE,EAAE;QAAEG,KAAK,EAAE;MAAE,CAAE,CAAC;MACnF,OAAOhC,YAAY,CACjB,IAAAiC,wBAAa,EAAC;QACZC,MAAM,EAAEzB,IAAI,CAACyB,MAAM;QACnBC,SAAS,EAAEb,KAAK,CAACN,MAAM;QACvBU,YAAY;QACZI,cAAc,EAAEA,cAAc,CAACf,KAAK,EAAE,CAACqB,OAAO;OAC/C,CAAC,CAACC,KAAK,CACT;IACH,CAAC,CAAC,CACH;EACH;EAEA;EACA,IAAIpB,MAAM,KAAK,KAAK,IAAIX,IAAI,KAAK,QAAQ,EAAE;IACzC,OAAOG,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,MAAMC,KAAK,GAAG,OAAOC,WAAG,CAACC,GAAG,CAACf,IAAI,CAACgB,QAAQ,CAAC;MAC3C,OAAOzB,YAAY,CAAC,IAAAsC,gBAAS,EAAC;QAAEJ,MAAM,EAAEzB,IAAI,CAACyB,MAAM;QAAEZ;MAAK,CAAE,CAAC,CAACe,KAAK,CAAC;IACtE,CAAC,CAAC,CACH;EACH;EAEA;EACA,IAAIpB,MAAM,KAAK,MAAM,IAAIX,IAAI,KAAK,QAAQ,EAAE;IAC1C,IAAI;MACF,MAAMiC,QAAQ,GAAG,MAAM7B,OAAO,CAAC6B,QAAQ,EAAE;MACzC,MAAMC,aAAa,GAAGD,QAAQ,CAACf,GAAG,CAAC,YAAY,CAAkB;MACjE,MAAMiB,YAAY,GAAGF,QAAQ,CAACf,GAAG,CAAC,WAAW,CAAkB;MAC/D,MAAMkB,YAAY,GAAIH,QAAQ,CAACf,GAAG,CAAC,cAAc,CAAmB,IAAI,YAAY;MAEpF,IAAI,CAACiB,YAAY,EAAE;QACjB,OAAOzC,YAAY,CAAC,IAAA2C,sBAAY,EAAC,8BAA8B,CAAC,CAACN,KAAK,EAAE,GAAG,CAAC;MAC9E;MAEA,IAAIO,UAAmB;MACvB,IAAIC,SAAkB;MACtB,IAAI;QACFD,UAAU,GAAGE,IAAI,CAACC,KAAK,CAACP,aAAa,IAAI,IAAI,CAAC;QAC9CK,SAAS,GAAGC,IAAI,CAACC,KAAK,CAACN,YAAY,CAAC;MACtC,CAAC,CAAC,MAAM;QACN,OAAOzC,YAAY,CAAC,IAAA2C,sBAAY,EAAC,0CAA0C,CAAC,CAACN,KAAK,EAAE,GAAG,CAAC;MAC1F;MAEA,IAAI,CAACW,KAAK,CAACC,OAAO,CAACJ,SAAS,CAAC,IAAIA,SAAS,CAAC7B,MAAM,KAAK,CAAC,EAAE;QACvD,OAAOhB,YAAY,CAAC,IAAA2C,sBAAY,EAAC,sCAAsC,CAAC,CAACN,KAAK,EAAE,GAAG,CAAC;MACtF;MAEA,MAAMa,MAAM,GAAGC,sBAAc,CAACC,IAAI,CAACC,MAAM,CAACC,UAAU,EAAE,CAACvC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACnE,MAAMwC,IAAI,GAAS;QACjB1B,EAAE,EAAEqB,MAAM;QACVN,UAAU,EAAEA,UAAgC;QAC5CC,SAAS,EAAEA,SAAyC;QACpDH,YAAY,EAAEA;OACf;MAED,OAAO,MAAMjC,IAAI,CAACU,UAAU,CAC1BC,cAAM,CAACC,GAAG,CAAC,aAAS;QAClB,OAAOZ,IAAI,CAAC+C,IAAI,CAACC,OAAO,CAAChD,IAAI,CAACoB,EAAE,EAAE0B,IAAI,CAAC,CAACG,IAAI,CAC1CtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAACwC,IAAI,CAAC,CACnC;QACD,MAAMC,OAAO,GAAG,OAAOpD,IAAI,CAAC+C,IAAI,CAACM,QAAQ,CAACrD,IAAI,CAACoB,EAAE,CAAC,CAAC6B,IAAI,CACrDtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAAC2C,OAAO,CAAC,EAAyB,CAAC,CAAC,CACjE;QACD,OAAOxC,WAAG,CAACyC,GAAG,CAACvD,IAAI,CAACgB,QAAQ,EAAEoC,OAAO,CAAC;QACtC,OAAO7D,YAAY,CAAC,IAAAiE,yBAAe,EAACJ,OAAO,CAAC,CAACxB,KAAK,CAAC;MACrD,CAAC,CAAC,CACH;IACH,CAAC,CAAC,MAAM;MACN,OAAOrC,YAAY,CAAC,IAAA2C,sBAAY,EAAC,4BAA4B,CAAC,CAACN,KAAK,EAAE,GAAG,CAAC;IAC5E;EACF;EAEA;EACA,MAAM6B,YAAY,GAAGjD,MAAM,KAAK,QAAQ,GAAGZ,mBAAmB,CAACC,IAAI,CAAC,GAAG,IAAI;EAC3E,IAAI4D,YAAY,KAAK,IAAI,EAAE;IACzB,OAAOzD,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,OAAOZ,IAAI,CAAC+C,IAAI,CAACW,UAAU,CAAC1D,IAAI,CAACoB,EAAE,EAAEqC,YAAY,CAAC,CAACR,IAAI,CACrDtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAACwC,IAAI,CAAC,CACnC;MACD,MAAMC,OAAO,GAAG,OAAOpD,IAAI,CAAC+C,IAAI,CAACM,QAAQ,CAACrD,IAAI,CAACoB,EAAE,CAAC,CAAC6B,IAAI,CACrDtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAAC2C,OAAO,CAAC,EAAyB,CAAC,CAAC,CACjE;MACD,OAAOxC,WAAG,CAACyC,GAAG,CAACvD,IAAI,CAACgB,QAAQ,EAAEoC,OAAO,CAAC;MACtC,OAAO7D,YAAY,CAAC,IAAAiE,yBAAe,EAACJ,OAAO,CAAC,CAACxB,KAAK,CAAC;IACrD,CAAC,CAAC,CACH;EACH;EAEA;EACA,MAAM+B,SAAS,GAAGnD,MAAM,KAAK,KAAK,GAAGZ,mBAAmB,CAACC,IAAI,CAAC,GAAG,IAAI;EACrE,IAAI8D,SAAS,KAAK,IAAI,EAAE;IACtB,IAAI;MACF,MAAM7B,QAAQ,GAAG,MAAM7B,OAAO,CAAC6B,QAAQ,EAAE;MACzC,MAAMC,aAAa,GAAGD,QAAQ,CAACf,GAAG,CAAC,YAAY,CAAkB;MACjE,MAAMiB,YAAY,GAAGF,QAAQ,CAACf,GAAG,CAAC,WAAW,CAAkB;MAC/D,MAAMkB,YAAY,GAAGH,QAAQ,CAACf,GAAG,CAAC,cAAc,CAAkB;MAElE,OAAO,MAAMf,IAAI,CAACU,UAAU,CAC1BC,cAAM,CAACC,GAAG,CAAC,aAAS;QAClB,OAAOZ,IAAI,CAAC+C,IAAI,CAACa,UAAU,CAAC5D,IAAI,CAACoB,EAAE,EAAEuC,SAAS,EAAGE,QAAQ,KAAM;UAC7D,GAAGA,QAAQ;UACX,IAAI9B,aAAa,GAAG;YAAEI,UAAU,EAAEE,IAAI,CAACC,KAAK,CAACP,aAAa;UAAC,CAAE,GAAG,EAAE,CAAC;UACnE,IAAIC,YAAY,GAAG;YAAEI,SAAS,EAAEC,IAAI,CAACC,KAAK,CAACN,YAAY;UAAC,CAAE,GAAG,EAAE,CAAC;UAChE,IAAIC,YAAY,GAAG;YAAEA,YAAY,EAAEA;UAAoC,CAAE,GAAG,EAAE;SAC/E,CAAC,CAAC,CAACgB,IAAI,CAACtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAACwC,IAAI,CAAC,CAAC;QAC5C,MAAMC,OAAO,GAAG,OAAOpD,IAAI,CAAC+C,IAAI,CAACM,QAAQ,CAACrD,IAAI,CAACoB,EAAE,CAAC,CAAC6B,IAAI,CACrDtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAAC2C,OAAO,CAAC,EAAyB,CAAC,CAAC,CACjE;QACD,OAAOxC,WAAG,CAACyC,GAAG,CAACvD,IAAI,CAACgB,QAAQ,EAAEoC,OAAO,CAAC;QACtC,OAAO7D,YAAY,CAAC,IAAAiE,yBAAe,EAACJ,OAAO,CAAC,CAACxB,KAAK,CAAC;MACrD,CAAC,CAAC,CACH;IACH,CAAC,CAAC,MAAM;MACN,OAAOrC,YAAY,CAAC,IAAA2C,sBAAY,EAAC,4BAA4B,CAAC,CAACN,KAAK,EAAE,GAAG,CAAC;IAC5E;EACF;EAEA;EACA,IAAIpB,MAAM,KAAK,KAAK,IAAIX,IAAI,KAAK,WAAW,EAAE;IAC5C,OAAOG,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,MAAMkD,OAAO,GAAG,OAAO9D,IAAI,CAACkB,aAAa,CAACI,UAAU,CAACtB,IAAI,CAACoB,EAAE,EAAE;QAAEG,KAAK,EAAE;MAAG,CAAE,CAAC;MAC7E,OAAOhC,YAAY,CAAC,IAAAwE,sBAAY,EAAC;QAAEtC,MAAM,EAAEzB,IAAI,CAACyB,MAAM;QAAEqC;MAAO,CAAE,CAAC,CAAClC,KAAK,CAAC;IAC3E,CAAC,CAAC,CACH;EACH;EAEA;EACA,IAAIpB,MAAM,KAAK,KAAK,IAAIX,IAAI,KAAK,gBAAgB,EAAE;IACjD,MAAMmE,MAAM,GAAG9D,GAAG,CAAC+D,YAAY;IAC/B,OAAOjE,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,MAAMsD,IAAI,GAAwE;QAAE3C,KAAK,EAAE;MAAG,CAAE;MAChG,MAAM4C,YAAY,GAAGH,MAAM,CAACjD,GAAG,CAAC,QAAQ,CAAC;MACzC,IAAIoD,YAAY,EAAED,IAAI,CAAC1D,MAAM,GAAG2D,YAAY;MAC5C,MAAMC,UAAU,GAAGJ,MAAM,CAACjD,GAAG,CAAC,MAAM,CAAC;MACrC,IAAIqD,UAAU,EAAEF,IAAI,CAACrE,IAAI,GAAGuE,UAAU;MACtC,MAAMC,YAAY,GAAGL,MAAM,CAACjD,GAAG,CAAC,QAAQ,CAAC;MACzC,IAAIsD,YAAY,EAAEH,IAAI,CAACzE,MAAM,GAAG6E,MAAM,CAACD,YAAY,CAAC;MACpD,MAAMP,OAAO,GAAG,OAAO9D,IAAI,CAACkB,aAAa,CAACI,UAAU,CAACtB,IAAI,CAACoB,EAAE,EAAE8C,IAAI,CAAC;MACnE,OAAO3E,YAAY,CAAC,IAAAgF,6BAAmB,EAACT,OAAO,CAACxD,KAAK,EAAE,CAACqB,OAAO,EAAE,CAAC,CAACC,KAAK,CAAC;IAC3E,CAAC,CAAC,CACH;EACH;EAEA;EACA,IAAIpB,MAAM,KAAK,MAAM,IAAIX,IAAI,KAAK,gBAAgB,EAAE;IAClD,IAAI;MACF,MAAMiC,QAAQ,GAAG,MAAM7B,OAAO,CAAC6B,QAAQ,EAAE;MACzC,MAAM0C,UAAU,GAAI1C,QAAQ,CAACf,GAAG,CAAC,QAAQ,CAAY,IAAI,KAAK;MAC9D,MAAM0D,QAAQ,GAAI3C,QAAQ,CAACf,GAAG,CAAC,MAAM,CAAY,IAAI,GAAG;MACxD,MAAM2D,QAAQ,GAAG5C,QAAQ,CAACf,GAAG,CAAC,MAAM,CAAkB;MACtD,MAAM4D,eAAe,GAAI7C,QAAQ,CAACf,GAAG,CAAC,aAAa,CAAY,IAAI,kBAAkB;MACrF,MAAM6D,cAAc,GAAI9C,QAAQ,CAACf,GAAG,CAAC,SAAS,CAAY,IAAI,EAAE;MAEhE,MAAMpB,OAAO,GAA2B,EAAE;MAC1C,IAAIgF,eAAe,IAAID,QAAQ,EAAE;QAC/B/E,OAAO,CAAC,cAAc,CAAC,GAAGgF,eAAe;MAC3C;MACA,KAAK,MAAME,IAAI,IAAID,cAAc,CAACE,KAAK,CAAC,IAAI,CAAC,EAAE;QAC7C,MAAMC,QAAQ,GAAGF,IAAI,CAACG,OAAO,CAAC,GAAG,CAAC;QAClC,IAAID,QAAQ,GAAG,CAAC,EAAE;UAChBpF,OAAO,CAACkF,IAAI,CAACvE,KAAK,CAAC,CAAC,EAAEyE,QAAQ,CAAC,CAACE,IAAI,EAAE,CAAC,GAAGJ,IAAI,CAACvE,KAAK,CAACyE,QAAQ,GAAG,CAAC,CAAC,CAACE,IAAI,EAAE;QAC3E;MACF;MAEA,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAG,EAAE;MAC5B,MAAMC,QAAQ,GAAG,MAAMC,KAAK,CAAC,oBAAoBtF,IAAI,CAACyB,MAAM,CAAC8D,IAAI,GAAGd,QAAQ,EAAE,EAAE;QAC9EjE,MAAM,EAAEgE,UAAU;QAClB7E,OAAO;QACP,IAAI+E,QAAQ,IAAIF,UAAU,KAAK,KAAK,IAAIA,UAAU,KAAK,MAAM,GAAG;UAAEhF,IAAI,EAAEkF;QAAQ,CAAE,GAAG,EAAE;OACxF,CAAC;MACF,MAAMc,QAAQ,GAAGL,IAAI,CAACC,GAAG,EAAE,GAAGF,SAAS;MAEvC,MAAMO,QAAQ,GAAG,MAAMJ,QAAQ,CAACK,IAAI,EAAE;MACtC,MAAMC,WAAW,GAA2B,EAAE;MAC9CN,QAAQ,CAAC1F,OAAO,CAACiG,OAAO,CAAC,CAACC,GAAG,EAAEC,GAAG,KAAI;QACpCH,WAAW,CAACG,GAAG,CAAC,GAAGD,GAAG;MACxB,CAAC,CAAC;MAEF,OAAOtG,YAAY,CACjB,IAAAwG,2BAAiB,EAAC;QAAEtG,MAAM,EAAE4F,QAAQ,CAAC5F,MAAM;QAAEE,OAAO,EAAEgG,WAAW;QAAEnG,IAAI,EAAEiG,QAAQ;QAAED;MAAQ,CAAE,CAAC,CAAC5D,KAAK,CACrG;IACH,CAAC,CAAC,OAAOoE,GAAG,EAAE;MACZ,OAAOzG,YAAY,CACjB,yFAAyF0G,MAAM,CAACD,GAAG,CAAC,QAAQ,CAC7G;IACH;EACF;EAEA;EACA,IAAIxF,MAAM,KAAK,QAAQ,IAAIX,IAAI,KAAK,WAAW,EAAE;IAC/C,OAAOG,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,OAAOZ,IAAI,CAACkB,aAAa,CAACgF,KAAK,CAAClG,IAAI,CAACoB,EAAE,CAAC;MACxC,OAAO7B,YAAY,CAAC,IAAAgF,6BAAmB,EAAC,EAAE,CAAC,CAAC3C,KAAK,CAAC;IACpD,CAAC,CAAC,CACH;EACH;EAEA;EACA,IAAIpB,MAAM,KAAK,KAAK,IAAIX,IAAI,CAACQ,UAAU,CAAC,YAAY,CAAC,EAAE;IACrD,MAAM8F,OAAO,GAAGtG,IAAI,CAACS,KAAK,CAAC,YAAY,CAACC,MAAM,CAAC;IAC/C,IAAI4F,OAAO,IAAI,CAACA,OAAO,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;MACrC,OAAOpG,IAAI,CAACU,UAAU,CACpBC,cAAM,CAACC,GAAG,CAAC,aAAS;QAClB,MAAMyF,KAAK,GAAG,OAAOrG,IAAI,CAACkB,aAAa,CAACoF,YAAY,CAACtG,IAAI,CAACoB,EAAE,EAAE+E,OAAO,CAAC;QACtE,IAAIE,KAAK,KAAK,IAAI,EAAE;UAClB,OAAO9G,YAAY,CAAC,4BAA4B,EAAE,GAAG,CAAC;QACxD;QACA;QACA,IAAIgH,WAAW,GAAgB,IAAI;QACnC,IAAIF,KAAK,CAACG,QAAQ,CAACC,aAAa,EAAE;UAChC,IAAI;YACF,MAAM5F,KAAK,GAAG,OAAOb,IAAI,CAAC+C,IAAI,CAACM,QAAQ,CAACrD,IAAI,CAACoB,EAAE,CAAC,CAAC6B,IAAI,CACnDtC,cAAM,CAACuC,QAAQ,CAAC,MAAMvC,cAAM,CAAC2C,OAAO,CAAC,EAAyB,CAAC,CAAC,CACjE;YACDiD,WAAW,GAAG1F,KAAK,CAAC6F,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACvF,EAAE,KAAKiF,KAAK,CAACG,QAAQ,CAACC,aAAa,CAAC,IAAI,IAAI;UAChF,CAAC,CAAC,MAAM;YACN;UAAA;QAEJ;QACA,OAAOlH,YAAY,CAAC,IAAAqH,gCAAiB,EAAC;UAAEnF,MAAM,EAAEzB,IAAI,CAACyB,MAAM;UAAE4E,KAAK;UAAEE;QAAW,CAAE,CAAC,CAAC3E,KAAK,CAAC;MAC3F,CAAC,CAAC,CACH;IACH;EACF;EAEA;EACA,OAAOrC,YAAY,CAAC,oBAAoB,EAAE,GAAG,CAAC;AAChD,CAAC;AAAAsH,OAAA,CAAA9G,YAAA,GAAAA,YAAA","ignoreList":[]}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.adminLayout = void 0;
7
+ var _html = require("../html");
8
+ const adminLayout = (opts, content) => (0, _html.html)`<!DOCTYPE html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="utf-8">
12
+ <meta name="viewport" content="width=device-width, initial-scale=1">
13
+ <title>${opts.title}</title>
14
+ <script src="https://cdn.tailwindcss.com"></script>
15
+ <script src="https://unpkg.com/htmx.org@2.0.4"></script>
16
+ </head>
17
+ <body class="bg-gray-50 min-h-screen">
18
+ <nav class="bg-gray-800 text-white shadow-md">
19
+ <div class="max-w-6xl mx-auto px-4 py-3 flex items-center justify-between">
20
+ <div class="flex items-center gap-3">
21
+ <span class="text-lg font-bold">Imposters</span>
22
+ <span class="text-gray-400 text-sm">Admin</span>
23
+ </div>
24
+ <div class="flex gap-3 items-center">
25
+ <a href="/_ui" class="px-3 py-1.5 bg-gray-700 text-white rounded text-sm font-medium hover:bg-gray-600">Dashboard</a>
26
+ <a href="/docs" class="text-gray-400 hover:text-white text-sm">API Docs</a>
27
+ </div>
28
+ </div>
29
+ </nav>
30
+ <main class="max-w-6xl mx-auto px-4 py-6">
31
+ ${(0, _html.raw)(content.value)}
32
+ </main>
33
+ </body>
34
+ </html>`;
35
+ exports.adminLayout = adminLayout;
36
+ //# sourceMappingURL=AdminLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminLayout.js","names":["_html","require","adminLayout","opts","content","html","title","raw","value","exports"],"sources":["../../../../src/ui/admin/AdminLayout.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAQO,MAAMC,WAAW,GAAGA,CAACC,IAAqB,EAAEC,OAAiB,KAClE,IAAAC,UAAI;;;;;WAKKF,IAAI,CAACG,KAAK;;;;;;;;;;;;;;;;;;MAkBf,IAAAC,SAAG,EAACH,OAAO,CAACI,KAAK,CAAC;;;QAGhB;AAAAC,OAAA,CAAAP,WAAA,GAAAA,WAAA","ignoreList":[]}
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeAdminUiRouter = void 0;
7
+ var _AdminDashboard = require("./pages/AdminDashboard");
8
+ var _partials = require("./partials");
9
+ const htmlResponse = (body, status = 200) => new Response(body, {
10
+ status,
11
+ headers: {
12
+ "content-type": "text/html; charset=utf-8"
13
+ }
14
+ });
15
+ const toAdminData = imp => ({
16
+ id: imp.id,
17
+ name: imp.name ?? `imposter-${imp.id}`,
18
+ port: imp.port,
19
+ status: imp.status,
20
+ protocol: imp.protocol ?? "HTTP",
21
+ stubCount: imp.stubs?.length ?? imp.endpointCount ?? imp.stubCount ?? 0
22
+ });
23
+ const fetchImposters = async apiHandler => {
24
+ const resp = await apiHandler(new Request("http://localhost/imposters?limit=50", {
25
+ method: "GET"
26
+ }));
27
+ if (!resp.ok) return [];
28
+ const data = await resp.json();
29
+ const items = Array.isArray(data) ? data : data.imposters ?? data.items ?? [];
30
+ return items.map(toAdminData);
31
+ };
32
+ const fetchImposter = async (apiHandler, id) => {
33
+ const resp = await apiHandler(new Request(`http://localhost/imposters/${id}`, {
34
+ method: "GET"
35
+ }));
36
+ if (!resp.ok) return null;
37
+ const imp = await resp.json();
38
+ return toAdminData(imp);
39
+ };
40
+ const makeAdminUiRouter = deps => async request => {
41
+ const url = new URL(request.url);
42
+ if (!url.pathname.startsWith("/_ui")) return null;
43
+ const path = url.pathname.slice("/_ui".length) || "/";
44
+ const method = request.method.toUpperCase();
45
+ // GET / — dashboard
46
+ if (method === "GET" && (path === "/" || path === "")) {
47
+ const imposters = await fetchImposters(deps.apiHandler);
48
+ return htmlResponse((0, _AdminDashboard.adminDashboardPage)({
49
+ imposters
50
+ }).value);
51
+ }
52
+ // GET /imposters — HTMX partial (imposter list)
53
+ if (method === "GET" && path === "/imposters") {
54
+ const imposters = await fetchImposters(deps.apiHandler);
55
+ return htmlResponse((0, _partials.imposterListPartial)(imposters).value);
56
+ }
57
+ // POST /imposters — create imposter from form
58
+ if (method === "POST" && path === "/imposters") {
59
+ try {
60
+ const formData = await request.formData();
61
+ const name = formData.get("name");
62
+ const portStr = formData.get("port");
63
+ const autoStart = formData.get("autoStart") === "on";
64
+ const payload = {
65
+ protocol: "HTTP"
66
+ };
67
+ if (name && name.trim()) payload.name = name.trim();
68
+ if (portStr && portStr.trim()) payload.port = Number(portStr.trim());
69
+ const createResp = await deps.apiHandler(new Request("http://localhost/imposters", {
70
+ method: "POST",
71
+ headers: {
72
+ "content-type": "application/json"
73
+ },
74
+ body: JSON.stringify(payload)
75
+ }));
76
+ if (!createResp.ok) {
77
+ const errBody = await createResp.text();
78
+ const imposters = await fetchImposters(deps.apiHandler);
79
+ return htmlResponse((0, _partials.adminErrorPartial)(`Failed to create imposter: ${errBody}`).value + (0, _partials.imposterListPartial)(imposters).value);
80
+ }
81
+ const created = await createResp.json();
82
+ // Auto-start if requested
83
+ if (autoStart) {
84
+ await deps.apiHandler(new Request(`http://localhost/imposters/${created.id}`, {
85
+ method: "PATCH",
86
+ headers: {
87
+ "content-type": "application/json"
88
+ },
89
+ body: JSON.stringify({
90
+ status: "running"
91
+ })
92
+ }));
93
+ }
94
+ const imposters = await fetchImposters(deps.apiHandler);
95
+ return htmlResponse((0, _partials.imposterListPartial)(imposters).value);
96
+ } catch (err) {
97
+ const imposters = await fetchImposters(deps.apiHandler);
98
+ return htmlResponse((0, _partials.adminErrorPartial)(`Error: ${String(err)}`).value + (0, _partials.imposterListPartial)(imposters).value);
99
+ }
100
+ }
101
+ // POST /imposters/:id/start
102
+ const startMatch = path.match(/^\/imposters\/([^/]+)\/start$/);
103
+ if (method === "POST" && startMatch) {
104
+ const id = startMatch[1];
105
+ await deps.apiHandler(new Request(`http://localhost/imposters/${id}`, {
106
+ method: "PATCH",
107
+ headers: {
108
+ "content-type": "application/json"
109
+ },
110
+ body: JSON.stringify({
111
+ status: "running"
112
+ })
113
+ }));
114
+ // Small delay for the server to start
115
+ await new Promise(r => setTimeout(r, 100));
116
+ const imp = await fetchImposter(deps.apiHandler, id);
117
+ if (!imp) {
118
+ return htmlResponse((0, _partials.adminErrorPartial)("Imposter not found").value, 404);
119
+ }
120
+ return htmlResponse((0, _partials.imposterRowPartial)(imp).value);
121
+ }
122
+ // POST /imposters/:id/stop
123
+ const stopMatch = path.match(/^\/imposters\/([^/]+)\/stop$/);
124
+ if (method === "POST" && stopMatch) {
125
+ const id = stopMatch[1];
126
+ await deps.apiHandler(new Request(`http://localhost/imposters/${id}`, {
127
+ method: "PATCH",
128
+ headers: {
129
+ "content-type": "application/json"
130
+ },
131
+ body: JSON.stringify({
132
+ status: "stopped"
133
+ })
134
+ }));
135
+ await new Promise(r => setTimeout(r, 100));
136
+ const imp = await fetchImposter(deps.apiHandler, id);
137
+ if (!imp) {
138
+ return htmlResponse((0, _partials.adminErrorPartial)("Imposter not found").value, 404);
139
+ }
140
+ return htmlResponse((0, _partials.imposterRowPartial)(imp).value);
141
+ }
142
+ // DELETE /imposters/:id
143
+ const deleteMatch = path.match(/^\/imposters\/([^/]+)$/);
144
+ if (method === "DELETE" && deleteMatch) {
145
+ const id = deleteMatch[1];
146
+ await deps.apiHandler(new Request(`http://localhost/imposters/${id}?force=true`, {
147
+ method: "DELETE"
148
+ }));
149
+ const imposters = await fetchImposters(deps.apiHandler);
150
+ return htmlResponse((0, _partials.imposterListPartial)(imposters).value);
151
+ }
152
+ return null;
153
+ };
154
+ exports.makeAdminUiRouter = makeAdminUiRouter;
155
+ //# sourceMappingURL=AdminUiRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminUiRouter.js","names":["_AdminDashboard","require","_partials","htmlResponse","body","status","Response","headers","toAdminData","imp","id","name","port","protocol","stubCount","stubs","length","endpointCount","fetchImposters","apiHandler","resp","Request","method","ok","data","json","items","Array","isArray","imposters","map","fetchImposter","makeAdminUiRouter","deps","request","url","URL","pathname","startsWith","path","slice","toUpperCase","adminDashboardPage","value","imposterListPartial","formData","get","portStr","autoStart","payload","trim","Number","createResp","JSON","stringify","errBody","text","adminErrorPartial","created","err","String","startMatch","match","Promise","r","setTimeout","imposterRowPartial","stopMatch","deleteMatch","exports"],"sources":["../../../../src/ui/admin/AdminUiRouter.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.adminDashboardPage = void 0;
7
+ var _html = require("../../html");
8
+ var _AdminLayout = require("../AdminLayout");
9
+ var _partials = require("../partials");
10
+ const summaryBar = data => {
11
+ const total = data.imposters.length;
12
+ const running = data.imposters.filter(i => i.status === "running").length;
13
+ const stopped = total - running;
14
+ return (0, _html.html)`<div class="grid grid-cols-3 gap-4 mb-6">
15
+ <div class="bg-white rounded-lg shadow p-4">
16
+ <div class="text-sm text-gray-500">Total Imposters</div>
17
+ <div class="text-2xl font-bold text-gray-800">${String(total)}</div>
18
+ </div>
19
+ <div class="bg-white rounded-lg shadow p-4">
20
+ <div class="text-sm text-gray-500">Running</div>
21
+ <div class="text-2xl font-bold text-green-600">${String(running)}</div>
22
+ </div>
23
+ <div class="bg-white rounded-lg shadow p-4">
24
+ <div class="text-sm text-gray-500">Stopped</div>
25
+ <div class="text-2xl font-bold text-gray-500">${String(stopped)}</div>
26
+ </div>
27
+ </div>`;
28
+ };
29
+ const adminDashboardPage = data => {
30
+ const content = (0, _html.html)`
31
+ ${summaryBar(data)}
32
+ ${(0, _partials.createFormPartial)()}
33
+ <div class="bg-white rounded-lg shadow overflow-x-auto">
34
+ <table class="w-full text-left">
35
+ <thead>
36
+ <tr class="text-xs text-gray-500 uppercase border-b">
37
+ <th class="py-3 px-4">Name</th>
38
+ <th class="py-3 px-4">Port</th>
39
+ <th class="py-3 px-4">Status</th>
40
+ <th class="py-3 px-4">Protocol</th>
41
+ <th class="py-3 px-4">Stubs</th>
42
+ <th class="py-3 px-4">Actions</th>
43
+ </tr>
44
+ </thead>
45
+ <tbody id="imposter-list">
46
+ ${(0, _html.raw)((0, _partials.imposterListPartial)(data.imposters).value)}
47
+ </tbody>
48
+ </table>
49
+ </div>`;
50
+ return (0, _AdminLayout.adminLayout)({
51
+ title: "Imposters — Admin Dashboard"
52
+ }, content);
53
+ };
54
+ exports.adminDashboardPage = adminDashboardPage;
55
+ //# sourceMappingURL=AdminDashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminDashboard.js","names":["_html","require","_AdminLayout","_partials","summaryBar","data","total","imposters","length","running","filter","i","status","stopped","html","String","adminDashboardPage","content","createFormPartial","raw","imposterListPartial","value","adminLayout","title","exports"],"sources":["../../../../../src/ui/admin/pages/AdminDashboard.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAEA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,SAAA,GAAAF,OAAA;AAMA,MAAMG,UAAU,GAAIC,IAAwB,IAAc;EACxD,MAAMC,KAAK,GAAGD,IAAI,CAACE,SAAS,CAACC,MAAM;EACnC,MAAMC,OAAO,GAAGJ,IAAI,CAACE,SAAS,CAACG,MAAM,CAAEC,CAAC,IAAKA,CAAC,CAACC,MAAM,KAAK,SAAS,CAAC,CAACJ,MAAM;EAC3E,MAAMK,OAAO,GAAGP,KAAK,GAAGG,OAAO;EAC/B,OAAO,IAAAK,UAAI;;;sDAGyCC,MAAM,CAACT,KAAK,CAAC;;;;uDAIZS,MAAM,CAACN,OAAO,CAAC;;;;sDAIhBM,MAAM,CAACF,OAAO,CAAC;;SAE5D;AACT,CAAC;AAEM,MAAMG,kBAAkB,GAAIX,IAAwB,IAAc;EACvE,MAAMY,OAAO,GAAG,IAAAH,UAAI;MAChBV,UAAU,CAACC,IAAI,CAAC;MAChB,IAAAa,2BAAiB,GAAE;;;;;;;;;;;;;;YAcb,IAAAC,SAAG,EAAC,IAAAC,6BAAmB,EAACf,IAAI,CAACE,SAAS,CAAC,CAACc,KAAK,CAAC;;;WAG/C;EAET,OAAO,IAAAC,wBAAW,EAAC;IAAEC,KAAK,EAAE;EAA6B,CAAE,EAAEN,OAAO,CAAC;AACvE,CAAC;AAAAO,OAAA,CAAAR,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.imposterRowPartial = exports.imposterListPartial = exports.createFormPartial = exports.adminErrorPartial = void 0;
7
+ var _html = require("../html");
8
+ const statusBadge = status => {
9
+ if (status === "running") {
10
+ return (0, _html.html)`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-green-100 text-green-700">running</span>`;
11
+ }
12
+ if (status === "stopped") {
13
+ return (0, _html.html)`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-gray-100 text-gray-600">stopped</span>`;
14
+ }
15
+ return (0, _html.html)`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-yellow-100 text-yellow-700">${status}</span>`;
16
+ };
17
+ const imposterRowPartial = imp => {
18
+ const isRunning = imp.status === "running";
19
+ return (0, _html.html)`<tr id="row-${imp.id}" class="border-t hover:bg-gray-50">
20
+ <td class="py-3 px-4 font-medium">${imp.name}</td>
21
+ <td class="py-3 px-4 font-mono text-sm">${String(imp.port)}</td>
22
+ <td class="py-3 px-4">${statusBadge(imp.status)}</td>
23
+ <td class="py-3 px-4 text-sm text-gray-600">${imp.protocol}</td>
24
+ <td class="py-3 px-4 text-sm">${String(imp.stubCount)}</td>
25
+ <td class="py-3 px-4">
26
+ <div class="flex gap-2 items-center">
27
+ ${isRunning ? (0, _html.html)`<button hx-post="/_ui/imposters/${imp.id}/stop" hx-target="#row-${imp.id}" hx-swap="outerHTML" class="text-orange-600 hover:text-orange-800 text-sm font-medium">Stop</button>` : (0, _html.html)`<button hx-post="/_ui/imposters/${imp.id}/start" hx-target="#row-${imp.id}" hx-swap="outerHTML" class="text-green-600 hover:text-green-800 text-sm font-medium">Start</button>`}
28
+ <button hx-delete="/_ui/imposters/${imp.id}" hx-target="#imposter-list" hx-swap="innerHTML" hx-confirm="Delete this imposter?" class="text-red-500 hover:text-red-700 text-sm">Delete</button>
29
+ ${isRunning ? (0, _html.html)`<a href="http://localhost:${String(imp.port)}/_admin" target="_blank" class="text-indigo-600 hover:text-indigo-800 text-sm">Open UI</a>` : (0, _html.html)``}
30
+ </div>
31
+ </td>
32
+ </tr>`;
33
+ };
34
+ exports.imposterRowPartial = imposterRowPartial;
35
+ const imposterListPartial = imposters => {
36
+ if (imposters.length === 0) {
37
+ return (0, _html.html)`<tr><td colspan="6" class="text-center py-8 text-gray-400">No imposters. Create one above.</td></tr>`;
38
+ }
39
+ return imposters.reduce((acc, imp) => (0, _html.html)`${acc}${imposterRowPartial(imp)}`, (0, _html.html)``);
40
+ };
41
+ exports.imposterListPartial = imposterListPartial;
42
+ const createFormPartial = error => (0, _html.html)`<div class="bg-white rounded-lg shadow p-4 mb-6">
43
+ <h2 class="text-lg font-semibold mb-3">Create Imposter</h2>
44
+ ${error ? (0, _html.html)`<div class="bg-red-50 border border-red-200 text-red-700 rounded p-3 mb-3">${error}</div>` : (0, _html.html)``}
45
+ <form hx-post="/_ui/imposters" hx-target="#imposter-list" hx-swap="innerHTML" class="flex flex-wrap gap-3 items-end">
46
+ <div>
47
+ <label class="block text-xs text-gray-500 mb-1">Name (optional)</label>
48
+ <input name="name" type="text" class="border rounded p-2 text-sm w-40" placeholder="My Service" />
49
+ </div>
50
+ <div>
51
+ <label class="block text-xs text-gray-500 mb-1">Port (optional)</label>
52
+ <input name="port" type="number" class="border rounded p-2 text-sm w-24" placeholder="auto" />
53
+ </div>
54
+ <div class="flex items-center gap-2">
55
+ <input name="autoStart" type="checkbox" checked class="rounded" id="auto-start" />
56
+ <label for="auto-start" class="text-sm text-gray-700">Auto-start</label>
57
+ </div>
58
+ <button type="submit" class="bg-gray-800 text-white px-4 py-2 rounded hover:bg-gray-700 text-sm">Create</button>
59
+ </form>
60
+ </div>`;
61
+ exports.createFormPartial = createFormPartial;
62
+ const adminErrorPartial = message => (0, _html.html)`<div class="bg-red-50 border border-red-200 text-red-700 rounded p-3 mb-3">${message}</div>`;
63
+ exports.adminErrorPartial = adminErrorPartial;
64
+ //# sourceMappingURL=partials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partials.js","names":["_html","require","statusBadge","status","html","imposterRowPartial","imp","isRunning","id","name","String","port","protocol","stubCount","exports","imposterListPartial","imposters","length","reduce","acc","createFormPartial","error","adminErrorPartial","message"],"sources":["../../../../src/ui/admin/partials.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAYA,MAAMC,WAAW,GAAIC,MAAc,IAAc;EAC/C,IAAIA,MAAM,KAAK,SAAS,EAAE;IACxB,OAAO,IAAAC,UAAI,qGAAoG;EACjH;EACA,IAAID,MAAM,KAAK,SAAS,EAAE;IACxB,OAAO,IAAAC,UAAI,mGAAkG;EAC/G;EACA,OAAO,IAAAA,UAAI,0FAAyFD,MAAM,SAAS;AACrH,CAAC;AAEM,MAAME,kBAAkB,GAAIC,GAAsB,IAAc;EACrE,MAAMC,SAAS,GAAGD,GAAG,CAACH,MAAM,KAAK,SAAS;EAC1C,OAAO,IAAAC,UAAI,gBAAeE,GAAG,CAACE,EAAE;wCACMF,GAAG,CAACG,IAAI;8CACFC,MAAM,CAACJ,GAAG,CAACK,IAAI,CAAC;4BAClCT,WAAW,CAACI,GAAG,CAACH,MAAM,CAAC;kDACDG,GAAG,CAACM,QAAQ;oCAC1BF,MAAM,CAACJ,GAAG,CAACO,SAAS,CAAC;;;UAIrDN,SAAS,GACL,IAAAH,UAAI,oCAAmCE,GAAG,CAACE,EAAE,0BAA0BF,GAAG,CAACE,EAAE,uGAAuG,GACpL,IAAAJ,UAAI,oCAAmCE,GAAG,CAACE,EAAE,2BAA2BF,GAAG,CAACE,EAAE,sGACpF;4CAC0CF,GAAG,CAACE,EAAE;UAE9CD,SAAS,GACL,IAAAH,UAAI,8BACJM,MAAM,CAACJ,GAAG,CAACK,IAAI,CACjB,4FAA4F,GAC1F,IAAAP,UAAI,GACV;;;QAGM;AACR,CAAC;AAAAU,OAAA,CAAAT,kBAAA,GAAAA,kBAAA;AAEM,MAAMU,mBAAmB,GAAIC,SAA2C,IAAc;EAC3F,IAAIA,SAAS,CAACC,MAAM,KAAK,CAAC,EAAE;IAC1B,OAAO,IAAAb,UAAI,uGAAsG;EACnH;EACA,OAAOY,SAAS,CAACE,MAAM,CACrB,CAACC,GAAG,EAAEb,GAAG,KAAK,IAAAF,UAAI,IAAGe,GAAG,GAAGd,kBAAkB,CAACC,GAAG,CAAC,EAAE,EACpD,IAAAF,UAAI,GAAE,CACP;AACH,CAAC;AAAAU,OAAA,CAAAC,mBAAA,GAAAA,mBAAA;AAEM,MAAMK,iBAAiB,GAAIC,KAAc,IAC9C,IAAAjB,UAAI;;MAEAiB,KAAK,GAAG,IAAAjB,UAAI,+EAA8EiB,KAAK,QAAQ,GAAG,IAAAjB,UAAI,GAAE;;;;;;;;;;;;;;;;SAgB7G;AAAAU,OAAA,CAAAM,iBAAA,GAAAA,iBAAA;AAEF,MAAME,iBAAiB,GAAIC,OAAe,IAC/C,IAAAnB,UAAI,+EAA8EmB,OAAO,QAAQ;AAAAT,OAAA,CAAAQ,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.raw = exports.html = exports.escapeHtml = exports.SafeHtml = void 0;
7
+ /** Escapes &, <, >, ", ' → HTML entities */
8
+ const escapeHtml = s => s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
9
+ /** Marker class for pre-escaped HTML */
10
+ exports.escapeHtml = escapeHtml;
11
+ class SafeHtml {
12
+ value;
13
+ constructor(value) {
14
+ this.value = value;
15
+ }
16
+ }
17
+ /** Wrap a raw HTML string to skip auto-escaping */
18
+ exports.SafeHtml = SafeHtml;
19
+ const raw = s => new SafeHtml(s);
20
+ /** Tagged template: auto-escapes interpolations, passes SafeHtml through */
21
+ exports.raw = raw;
22
+ const html = (strings, ...values) => {
23
+ let result = "";
24
+ for (let i = 0; i < strings.length; i++) {
25
+ result += strings[i];
26
+ if (i < values.length) {
27
+ const v = values[i];
28
+ if (v instanceof SafeHtml) {
29
+ result += v.value;
30
+ } else if (v == null) {
31
+ result += "";
32
+ } else if (typeof v === "string") {
33
+ result += escapeHtml(v);
34
+ } else {
35
+ result += escapeHtml(String(v));
36
+ }
37
+ }
38
+ }
39
+ return new SafeHtml(result);
40
+ };
41
+ exports.html = html;
42
+ //# sourceMappingURL=html.js.map