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.
- package/LICENSE +21 -0
- package/Program/package.json +6 -0
- package/README.md +365 -0
- package/api/AdminApi/package.json +6 -0
- package/api/ApiErrors/package.json +6 -0
- package/api/ApiSchemas/package.json +6 -0
- package/api/Conversions/package.json +6 -0
- package/api/ImpostersGroup/package.json +6 -0
- package/api/ImpostersHandlers/package.json +6 -0
- package/api/SystemGroup/package.json +6 -0
- package/api/SystemHandlers/package.json +6 -0
- package/bin/imposters +47 -0
- package/cli/Commands/package.json +6 -0
- package/cli/ConfigLoader/package.json +6 -0
- package/client/HandlerHttpClient/package.json +6 -0
- package/client/ImpostersClient/package.json +6 -0
- package/client/testing/package.json +6 -0
- package/dist/cjs/Program.js +4 -0
- package/dist/cjs/Program.js.map +1 -0
- package/dist/cjs/api/AdminApi.js +11 -0
- package/dist/cjs/api/AdminApi.js.map +1 -0
- package/dist/cjs/api/ApiErrors.js +30 -0
- package/dist/cjs/api/ApiErrors.js.map +1 -0
- package/dist/cjs/api/ApiSchemas.js +36 -0
- package/dist/cjs/api/ApiSchemas.js.map +1 -0
- package/dist/cjs/api/Conversions.js +41 -0
- package/dist/cjs/api/Conversions.js.map +1 -0
- package/dist/cjs/api/ImpostersGroup.js +37 -0
- package/dist/cjs/api/ImpostersGroup.js.map +1 -0
- package/dist/cjs/api/ImpostersHandlers.js +361 -0
- package/dist/cjs/api/ImpostersHandlers.js.map +1 -0
- package/dist/cjs/api/SystemGroup.js +12 -0
- package/dist/cjs/api/SystemGroup.js.map +1 -0
- package/dist/cjs/api/SystemHandlers.js +74 -0
- package/dist/cjs/api/SystemHandlers.js.map +1 -0
- package/dist/cjs/cli/Commands.js +104 -0
- package/dist/cjs/cli/Commands.js.map +1 -0
- package/dist/cjs/cli/ConfigLoader.js +34 -0
- package/dist/cjs/cli/ConfigLoader.js.map +1 -0
- package/dist/cjs/client/HandlerHttpClient.js +50 -0
- package/dist/cjs/client/HandlerHttpClient.js.map +1 -0
- package/dist/cjs/client/ImpostersClient.js +20 -0
- package/dist/cjs/client/ImpostersClient.js.map +1 -0
- package/dist/cjs/client/index.js +57 -0
- package/dist/cjs/client/index.js.map +1 -0
- package/dist/cjs/client/testing.js +94 -0
- package/dist/cjs/client/testing.js.map +1 -0
- package/dist/cjs/domain/imposter.js +125 -0
- package/dist/cjs/domain/imposter.js.map +1 -0
- package/dist/cjs/domain/route.js +185 -0
- package/dist/cjs/domain/route.js.map +1 -0
- package/dist/cjs/index.js +106 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/layers/ApiLayer.js +18 -0
- package/dist/cjs/layers/ApiLayer.js.map +1 -0
- package/dist/cjs/layers/MainLayer.js +27 -0
- package/dist/cjs/layers/MainLayer.js.map +1 -0
- package/dist/cjs/matching/ExpressionEvaluator.js +103 -0
- package/dist/cjs/matching/ExpressionEvaluator.js.map +1 -0
- package/dist/cjs/matching/RequestMatcher.js +145 -0
- package/dist/cjs/matching/RequestMatcher.js.map +1 -0
- package/dist/cjs/matching/ResponseGenerator.js +80 -0
- package/dist/cjs/matching/ResponseGenerator.js.map +1 -0
- package/dist/cjs/matching/TemplateEngine.js +55 -0
- package/dist/cjs/matching/TemplateEngine.js.map +1 -0
- package/dist/cjs/repositories/ImposterRepository.js +118 -0
- package/dist/cjs/repositories/ImposterRepository.js.map +1 -0
- package/dist/cjs/schemas/ConfigFileSchema.js +44 -0
- package/dist/cjs/schemas/ConfigFileSchema.js.map +1 -0
- package/dist/cjs/schemas/ImposterSchema.js +202 -0
- package/dist/cjs/schemas/ImposterSchema.js.map +1 -0
- package/dist/cjs/schemas/RequestLogSchema.js +51 -0
- package/dist/cjs/schemas/RequestLogSchema.js.map +1 -0
- package/dist/cjs/schemas/StubSchema.js +84 -0
- package/dist/cjs/schemas/StubSchema.js.map +1 -0
- package/dist/cjs/schemas/common.js +67 -0
- package/dist/cjs/schemas/common.js.map +1 -0
- package/dist/cjs/server/AdminServer.js +36 -0
- package/dist/cjs/server/AdminServer.js.map +1 -0
- package/dist/cjs/server/BunServer.js +13 -0
- package/dist/cjs/server/BunServer.js.map +1 -0
- package/dist/cjs/server/FiberManager.js +21 -0
- package/dist/cjs/server/FiberManager.js.map +1 -0
- package/dist/cjs/server/ImposterServer.js +234 -0
- package/dist/cjs/server/ImposterServer.js.map +1 -0
- package/dist/cjs/services/AppConfig.js +18 -0
- package/dist/cjs/services/AppConfig.js.map +1 -0
- package/dist/cjs/services/MetricsService.js +113 -0
- package/dist/cjs/services/MetricsService.js.map +1 -0
- package/dist/cjs/services/PortAllocator.js +50 -0
- package/dist/cjs/services/PortAllocator.js.map +1 -0
- package/dist/cjs/services/ProxyService.js +109 -0
- package/dist/cjs/services/ProxyService.js.map +1 -0
- package/dist/cjs/services/RequestLogger.js +60 -0
- package/dist/cjs/services/RequestLogger.js.map +1 -0
- package/dist/cjs/services/Uuid.js +10 -0
- package/dist/cjs/services/Uuid.js.map +1 -0
- package/dist/cjs/services/UuidLive.js +16 -0
- package/dist/cjs/services/UuidLive.js.map +1 -0
- package/dist/cjs/ui/UiRouter.js +242 -0
- package/dist/cjs/ui/UiRouter.js.map +1 -0
- package/dist/cjs/ui/admin/AdminLayout.js +36 -0
- package/dist/cjs/ui/admin/AdminLayout.js.map +1 -0
- package/dist/cjs/ui/admin/AdminUiRouter.js +155 -0
- package/dist/cjs/ui/admin/AdminUiRouter.js.map +1 -0
- package/dist/cjs/ui/admin/pages/AdminDashboard.js +55 -0
- package/dist/cjs/ui/admin/pages/AdminDashboard.js.map +1 -0
- package/dist/cjs/ui/admin/partials.js +64 -0
- package/dist/cjs/ui/admin/partials.js.map +1 -0
- package/dist/cjs/ui/html.js +42 -0
- package/dist/cjs/ui/html.js.map +1 -0
- package/dist/cjs/ui/layout.js +39 -0
- package/dist/cjs/ui/layout.js.map +1 -0
- package/dist/cjs/ui/pages/dashboard.js +51 -0
- package/dist/cjs/ui/pages/dashboard.js.map +1 -0
- package/dist/cjs/ui/pages/request-detail.js +119 -0
- package/dist/cjs/ui/pages/request-detail.js.map +1 -0
- package/dist/cjs/ui/pages/requests.js +120 -0
- package/dist/cjs/ui/pages/requests.js.map +1 -0
- package/dist/cjs/ui/pages/stubs.js +46 -0
- package/dist/cjs/ui/pages/stubs.js.map +1 -0
- package/dist/cjs/ui/partials.js +104 -0
- package/dist/cjs/ui/partials.js.map +1 -0
- package/dist/dts/Program.d.ts +2 -0
- package/dist/dts/Program.d.ts.map +1 -0
- package/dist/dts/api/AdminApi.d.ts +490 -0
- package/dist/dts/api/AdminApi.d.ts.map +1 -0
- package/dist/dts/api/ApiErrors.d.ts +26 -0
- package/dist/dts/api/ApiErrors.d.ts.map +1 -0
- package/dist/dts/api/ApiSchemas.d.ts +36 -0
- package/dist/dts/api/ApiSchemas.d.ts.map +1 -0
- package/dist/dts/api/Conversions.d.ts +7 -0
- package/dist/dts/api/Conversions.d.ts.map +1 -0
- package/dist/dts/api/ImpostersGroup.d.ts +448 -0
- package/dist/dts/api/ImpostersGroup.d.ts.map +1 -0
- package/dist/dts/api/ImpostersHandlers.d.ts +9 -0
- package/dist/dts/api/ImpostersHandlers.d.ts.map +1 -0
- package/dist/dts/api/SystemGroup.d.ts +46 -0
- package/dist/dts/api/SystemGroup.d.ts.map +1 -0
- package/dist/dts/api/SystemHandlers.d.ts +4 -0
- package/dist/dts/api/SystemHandlers.d.ts.map +1 -0
- package/dist/dts/cli/Commands.d.ts +4 -0
- package/dist/dts/cli/Commands.d.ts.map +1 -0
- package/dist/dts/cli/ConfigLoader.d.ts +13 -0
- package/dist/dts/cli/ConfigLoader.d.ts.map +1 -0
- package/dist/dts/client/HandlerHttpClient.d.ts +5 -0
- package/dist/dts/client/HandlerHttpClient.d.ts.map +1 -0
- package/dist/dts/client/ImpostersClient.d.ts +1868 -0
- package/dist/dts/client/ImpostersClient.d.ts.map +1 -0
- package/dist/dts/client/index.d.ts +6 -0
- package/dist/dts/client/index.d.ts.map +1 -0
- package/dist/dts/client/testing.d.ts +35 -0
- package/dist/dts/client/testing.d.ts.map +1 -0
- package/dist/dts/domain/imposter.d.ts +123 -0
- package/dist/dts/domain/imposter.d.ts.map +1 -0
- package/dist/dts/domain/route.d.ts +128 -0
- package/dist/dts/domain/route.d.ts.map +1 -0
- package/dist/dts/index.d.ts +60 -0
- package/dist/dts/index.d.ts.map +1 -0
- package/dist/dts/layers/ApiLayer.d.ts +3 -0
- package/dist/dts/layers/ApiLayer.d.ts.map +1 -0
- package/dist/dts/layers/MainLayer.d.ts +3 -0
- package/dist/dts/layers/MainLayer.d.ts.map +1 -0
- package/dist/dts/matching/ExpressionEvaluator.d.ts +11 -0
- package/dist/dts/matching/ExpressionEvaluator.d.ts.map +1 -0
- package/dist/dts/matching/RequestMatcher.d.ts +13 -0
- package/dist/dts/matching/RequestMatcher.d.ts.map +1 -0
- package/dist/dts/matching/ResponseGenerator.d.ts +9 -0
- package/dist/dts/matching/ResponseGenerator.d.ts.map +1 -0
- package/dist/dts/matching/TemplateEngine.d.ts +4 -0
- package/dist/dts/matching/TemplateEngine.d.ts.map +1 -0
- package/dist/dts/repositories/ImposterRepository.d.ts +33 -0
- package/dist/dts/repositories/ImposterRepository.d.ts.map +1 -0
- package/dist/dts/schemas/ConfigFileSchema.d.ts +142 -0
- package/dist/dts/schemas/ConfigFileSchema.d.ts.map +1 -0
- package/dist/dts/schemas/ImposterSchema.d.ts +368 -0
- package/dist/dts/schemas/ImposterSchema.d.ts.map +1 -0
- package/dist/dts/schemas/RequestLogSchema.d.ts +36 -0
- package/dist/dts/schemas/RequestLogSchema.d.ts.map +1 -0
- package/dist/dts/schemas/StubSchema.d.ts +112 -0
- package/dist/dts/schemas/StubSchema.d.ts.map +1 -0
- package/dist/dts/schemas/common.d.ts +56 -0
- package/dist/dts/schemas/common.d.ts.map +1 -0
- package/dist/dts/server/AdminServer.d.ts +11 -0
- package/dist/dts/server/AdminServer.d.ts.map +1 -0
- package/dist/dts/server/BunServer.d.ts +17 -0
- package/dist/dts/server/BunServer.d.ts.map +1 -0
- package/dist/dts/server/FiberManager.d.ts +12 -0
- package/dist/dts/server/FiberManager.d.ts.map +1 -0
- package/dist/dts/server/ImposterServer.d.ts +29 -0
- package/dist/dts/server/ImposterServer.d.ts.map +1 -0
- package/dist/dts/services/AppConfig.d.ts +14 -0
- package/dist/dts/services/AppConfig.d.ts.map +1 -0
- package/dist/dts/services/MetricsService.d.ts +26 -0
- package/dist/dts/services/MetricsService.d.ts.map +1 -0
- package/dist/dts/services/PortAllocator.d.ts +29 -0
- package/dist/dts/services/PortAllocator.d.ts.map +1 -0
- package/dist/dts/services/ProxyService.d.ts +24 -0
- package/dist/dts/services/ProxyService.d.ts.map +1 -0
- package/dist/dts/services/RequestLogger.d.ts +23 -0
- package/dist/dts/services/RequestLogger.d.ts.map +1 -0
- package/dist/dts/services/Uuid.d.ts +9 -0
- package/dist/dts/services/Uuid.d.ts.map +1 -0
- package/dist/dts/services/UuidLive.d.ts +4 -0
- package/dist/dts/services/UuidLive.d.ts.map +1 -0
- package/dist/dts/ui/UiRouter.d.ts +15 -0
- package/dist/dts/ui/UiRouter.d.ts.map +1 -0
- package/dist/dts/ui/admin/AdminLayout.d.ts +7 -0
- package/dist/dts/ui/admin/AdminLayout.d.ts.map +1 -0
- package/dist/dts/ui/admin/AdminUiRouter.d.ts +6 -0
- package/dist/dts/ui/admin/AdminUiRouter.d.ts.map +1 -0
- package/dist/dts/ui/admin/pages/AdminDashboard.d.ts +7 -0
- package/dist/dts/ui/admin/pages/AdminDashboard.d.ts.map +1 -0
- package/dist/dts/ui/admin/partials.d.ts +14 -0
- package/dist/dts/ui/admin/partials.d.ts.map +1 -0
- package/dist/dts/ui/html.d.ts +12 -0
- package/dist/dts/ui/html.d.ts.map +1 -0
- package/dist/dts/ui/layout.d.ts +9 -0
- package/dist/dts/ui/layout.d.ts.map +1 -0
- package/dist/dts/ui/pages/dashboard.d.ts +10 -0
- package/dist/dts/ui/pages/dashboard.d.ts.map +1 -0
- package/dist/dts/ui/pages/request-detail.d.ts +11 -0
- package/dist/dts/ui/pages/request-detail.d.ts.map +1 -0
- package/dist/dts/ui/pages/requests.d.ts +15 -0
- package/dist/dts/ui/pages/requests.d.ts.map +1 -0
- package/dist/dts/ui/pages/stubs.d.ts +8 -0
- package/dist/dts/ui/pages/stubs.d.ts.map +1 -0
- package/dist/dts/ui/partials.d.ts +13 -0
- package/dist/dts/ui/partials.d.ts.map +1 -0
- package/dist/esm/Program.js +2 -0
- package/dist/esm/Program.js.map +1 -0
- package/dist/esm/api/AdminApi.js +5 -0
- package/dist/esm/api/AdminApi.js.map +1 -0
- package/dist/esm/api/ApiErrors.js +20 -0
- package/dist/esm/api/ApiErrors.js.map +1 -0
- package/dist/esm/api/ApiSchemas.js +29 -0
- package/dist/esm/api/ApiSchemas.js.map +1 -0
- package/dist/esm/api/Conversions.js +32 -0
- package/dist/esm/api/Conversions.js.map +1 -0
- package/dist/esm/api/ImpostersGroup.js +30 -0
- package/dist/esm/api/ImpostersGroup.js.map +1 -0
- package/dist/esm/api/ImpostersHandlers.js +354 -0
- package/dist/esm/api/ImpostersHandlers.js.map +1 -0
- package/dist/esm/api/SystemGroup.js +6 -0
- package/dist/esm/api/SystemGroup.js.map +1 -0
- package/dist/esm/api/SystemHandlers.js +67 -0
- package/dist/esm/api/SystemHandlers.js.map +1 -0
- package/dist/esm/cli/Commands.js +98 -0
- package/dist/esm/cli/Commands.js.map +1 -0
- package/dist/esm/cli/ConfigLoader.js +25 -0
- package/dist/esm/cli/ConfigLoader.js.map +1 -0
- package/dist/esm/client/HandlerHttpClient.js +42 -0
- package/dist/esm/client/HandlerHttpClient.js.map +1 -0
- package/dist/esm/client/ImpostersClient.js +10 -0
- package/dist/esm/client/ImpostersClient.js.map +1 -0
- package/dist/esm/client/index.js +4 -0
- package/dist/esm/client/index.js.map +1 -0
- package/dist/esm/client/testing.js +86 -0
- package/dist/esm/client/testing.js.map +1 -0
- package/dist/esm/domain/imposter.js +103 -0
- package/dist/esm/domain/imposter.js.map +1 -0
- package/dist/esm/domain/route.js +164 -0
- package/dist/esm/domain/route.js.map +1 -0
- package/dist/esm/index.js +60 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/layers/ApiLayer.js +11 -0
- package/dist/esm/layers/ApiLayer.js.map +1 -0
- package/dist/esm/layers/MainLayer.js +20 -0
- package/dist/esm/layers/MainLayer.js.map +1 -0
- package/dist/esm/matching/ExpressionEvaluator.js +94 -0
- package/dist/esm/matching/ExpressionEvaluator.js.map +1 -0
- package/dist/esm/matching/RequestMatcher.js +135 -0
- package/dist/esm/matching/RequestMatcher.js.map +1 -0
- package/dist/esm/matching/ResponseGenerator.js +71 -0
- package/dist/esm/matching/ResponseGenerator.js.map +1 -0
- package/dist/esm/matching/TemplateEngine.js +47 -0
- package/dist/esm/matching/TemplateEngine.js.map +1 -0
- package/dist/esm/package.json +4 -0
- package/dist/esm/repositories/ImposterRepository.js +110 -0
- package/dist/esm/repositories/ImposterRepository.js.map +1 -0
- package/dist/esm/schemas/ConfigFileSchema.js +37 -0
- package/dist/esm/schemas/ConfigFileSchema.js.map +1 -0
- package/dist/esm/schemas/ImposterSchema.js +195 -0
- package/dist/esm/schemas/ImposterSchema.js.map +1 -0
- package/dist/esm/schemas/RequestLogSchema.js +44 -0
- package/dist/esm/schemas/RequestLogSchema.js.map +1 -0
- package/dist/esm/schemas/StubSchema.js +77 -0
- package/dist/esm/schemas/StubSchema.js.map +1 -0
- package/dist/esm/schemas/common.js +59 -0
- package/dist/esm/schemas/common.js.map +1 -0
- package/dist/esm/server/AdminServer.js +27 -0
- package/dist/esm/server/AdminServer.js.map +1 -0
- package/dist/esm/server/BunServer.js +6 -0
- package/dist/esm/server/BunServer.js.map +1 -0
- package/dist/esm/server/FiberManager.js +14 -0
- package/dist/esm/server/FiberManager.js.map +1 -0
- package/dist/esm/server/ImposterServer.js +225 -0
- package/dist/esm/server/ImposterServer.js.map +1 -0
- package/dist/esm/services/AppConfig.js +11 -0
- package/dist/esm/services/AppConfig.js.map +1 -0
- package/dist/esm/services/MetricsService.js +105 -0
- package/dist/esm/services/MetricsService.js.map +1 -0
- package/dist/esm/services/PortAllocator.js +41 -0
- package/dist/esm/services/PortAllocator.js.map +1 -0
- package/dist/esm/services/ProxyService.js +101 -0
- package/dist/esm/services/ProxyService.js.map +1 -0
- package/dist/esm/services/RequestLogger.js +53 -0
- package/dist/esm/services/RequestLogger.js.map +1 -0
- package/dist/esm/services/Uuid.js +3 -0
- package/dist/esm/services/Uuid.js.map +1 -0
- package/dist/esm/services/UuidLive.js +9 -0
- package/dist/esm/services/UuidLive.js.map +1 -0
- package/dist/esm/ui/UiRouter.js +235 -0
- package/dist/esm/ui/UiRouter.js.map +1 -0
- package/dist/esm/ui/admin/AdminLayout.js +29 -0
- package/dist/esm/ui/admin/AdminLayout.js.map +1 -0
- package/dist/esm/ui/admin/AdminUiRouter.js +148 -0
- package/dist/esm/ui/admin/AdminUiRouter.js.map +1 -0
- package/dist/esm/ui/admin/pages/AdminDashboard.js +48 -0
- package/dist/esm/ui/admin/pages/AdminDashboard.js.map +1 -0
- package/dist/esm/ui/admin/partials.js +54 -0
- package/dist/esm/ui/admin/partials.js.map +1 -0
- package/dist/esm/ui/html.js +32 -0
- package/dist/esm/ui/html.js.map +1 -0
- package/dist/esm/ui/layout.js +32 -0
- package/dist/esm/ui/layout.js.map +1 -0
- package/dist/esm/ui/pages/dashboard.js +44 -0
- package/dist/esm/ui/pages/dashboard.js.map +1 -0
- package/dist/esm/ui/pages/request-detail.js +112 -0
- package/dist/esm/ui/pages/request-detail.js.map +1 -0
- package/dist/esm/ui/pages/requests.js +112 -0
- package/dist/esm/ui/pages/requests.js.map +1 -0
- package/dist/esm/ui/pages/stubs.js +39 -0
- package/dist/esm/ui/pages/stubs.js.map +1 -0
- package/dist/esm/ui/partials.js +91 -0
- package/dist/esm/ui/partials.js.map +1 -0
- package/domain/imposter/package.json +6 -0
- package/domain/route/package.json +6 -0
- package/layers/ApiLayer/package.json +6 -0
- package/layers/MainLayer/package.json +6 -0
- package/matching/ExpressionEvaluator/package.json +6 -0
- package/matching/RequestMatcher/package.json +6 -0
- package/matching/ResponseGenerator/package.json +6 -0
- package/matching/TemplateEngine/package.json +6 -0
- package/package.json +435 -0
- package/repositories/ImposterRepository/package.json +6 -0
- package/schemas/ConfigFileSchema/package.json +6 -0
- package/schemas/ImposterSchema/package.json +6 -0
- package/schemas/RequestLogSchema/package.json +6 -0
- package/schemas/StubSchema/package.json +6 -0
- package/schemas/common/package.json +6 -0
- package/server/AdminServer/package.json +6 -0
- package/server/BunServer/package.json +6 -0
- package/server/FiberManager/package.json +6 -0
- package/server/ImposterServer/package.json +6 -0
- package/services/AppConfig/package.json +6 -0
- package/services/MetricsService/package.json +6 -0
- package/services/PortAllocator/package.json +6 -0
- package/services/ProxyService/package.json +6 -0
- package/services/RequestLogger/package.json +6 -0
- package/services/Uuid/package.json +6 -0
- package/services/UuidLive/package.json +6 -0
- package/src/Program.ts +1 -0
- package/src/api/AdminApi.ts +7 -0
- package/src/api/ApiErrors.ts +20 -0
- package/src/api/ApiSchemas.ts +36 -0
- package/src/api/Conversions.ts +34 -0
- package/src/api/ImpostersGroup.ts +103 -0
- package/src/api/ImpostersHandlers.ts +387 -0
- package/src/api/SystemGroup.ts +12 -0
- package/src/api/SystemHandlers.ts +76 -0
- package/src/cli/Commands.ts +119 -0
- package/src/cli/ConfigLoader.ts +41 -0
- package/src/client/HandlerHttpClient.ts +50 -0
- package/src/client/ImpostersClient.ts +21 -0
- package/src/client/index.ts +9 -0
- package/src/client/testing.ts +105 -0
- package/src/domain/imposter.ts +186 -0
- package/src/domain/route.ts +255 -0
- package/src/index.ts +153 -0
- package/src/layers/ApiLayer.ts +21 -0
- package/src/layers/MainLayer.ts +43 -0
- package/src/matching/ExpressionEvaluator.ts +102 -0
- package/src/matching/RequestMatcher.ts +162 -0
- package/src/matching/ResponseGenerator.ts +86 -0
- package/src/matching/TemplateEngine.ts +54 -0
- package/src/repositories/ImposterRepository.ts +145 -0
- package/src/schemas/ConfigFileSchema.ts +32 -0
- package/src/schemas/ImposterSchema.ts +232 -0
- package/src/schemas/RequestLogSchema.ts +38 -0
- package/src/schemas/StubSchema.ts +90 -0
- package/src/schemas/common.ts +95 -0
- package/src/server/AdminServer.ts +22 -0
- package/src/server/BunServer.ts +19 -0
- package/src/server/FiberManager.ts +25 -0
- package/src/server/ImposterServer.ts +244 -0
- package/src/services/AppConfig.ts +22 -0
- package/src/services/MetricsService.ts +157 -0
- package/src/services/PortAllocator.ts +68 -0
- package/src/services/ProxyService.ts +139 -0
- package/src/services/RequestLogger.ts +87 -0
- package/src/services/Uuid.ts +9 -0
- package/src/services/UuidLive.ts +9 -0
- package/src/types/bun.d.ts +6 -0
- package/src/ui/UiRouter.ts +278 -0
- package/src/ui/admin/AdminLayout.ts +36 -0
- package/src/ui/admin/AdminUiRouter.ts +170 -0
- package/src/ui/admin/pages/AdminDashboard.ts +54 -0
- package/src/ui/admin/partials.ts +83 -0
- package/src/ui/html.ts +37 -0
- package/src/ui/layout.ts +44 -0
- package/src/ui/pages/dashboard.ts +64 -0
- package/src/ui/pages/request-detail.ts +142 -0
- package/src/ui/pages/requests.ts +141 -0
- package/src/ui/pages/stubs.ts +52 -0
- package/src/ui/partials.ts +133 -0
- package/ui/UiRouter/package.json +6 -0
- package/ui/admin/AdminLayout/package.json +6 -0
- package/ui/admin/AdminUiRouter/package.json +6 -0
- package/ui/admin/pages/AdminDashboard/package.json +6 -0
- package/ui/admin/partials/package.json +6 -0
- package/ui/html/package.json +6 -0
- package/ui/layout/package.json +6 -0
- package/ui/pages/dashboard/package.json +6 -0
- package/ui/pages/requests/package.json +6 -0
- package/ui/pages/stubs/package.json +6 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminUiRouter.js","names":["adminDashboardPage","adminErrorPartial","imposterListPartial","imposterRowPartial","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","value","formData","get","portStr","autoStart","payload","trim","Number","createResp","JSON","stringify","errBody","text","created","err","String","startMatch","match","Promise","r","setTimeout","stopMatch","deleteMatch"],"sources":["../../../../src/ui/admin/AdminUiRouter.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { html, raw } from "../../html";
|
|
2
|
+
import { adminLayout } from "../AdminLayout";
|
|
3
|
+
import { createFormPartial, imposterListPartial } from "../partials";
|
|
4
|
+
const summaryBar = data => {
|
|
5
|
+
const total = data.imposters.length;
|
|
6
|
+
const running = data.imposters.filter(i => i.status === "running").length;
|
|
7
|
+
const stopped = total - running;
|
|
8
|
+
return html`<div class="grid grid-cols-3 gap-4 mb-6">
|
|
9
|
+
<div class="bg-white rounded-lg shadow p-4">
|
|
10
|
+
<div class="text-sm text-gray-500">Total Imposters</div>
|
|
11
|
+
<div class="text-2xl font-bold text-gray-800">${String(total)}</div>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="bg-white rounded-lg shadow p-4">
|
|
14
|
+
<div class="text-sm text-gray-500">Running</div>
|
|
15
|
+
<div class="text-2xl font-bold text-green-600">${String(running)}</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="bg-white rounded-lg shadow p-4">
|
|
18
|
+
<div class="text-sm text-gray-500">Stopped</div>
|
|
19
|
+
<div class="text-2xl font-bold text-gray-500">${String(stopped)}</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>`;
|
|
22
|
+
};
|
|
23
|
+
export const adminDashboardPage = data => {
|
|
24
|
+
const content = html`
|
|
25
|
+
${summaryBar(data)}
|
|
26
|
+
${createFormPartial()}
|
|
27
|
+
<div class="bg-white rounded-lg shadow overflow-x-auto">
|
|
28
|
+
<table class="w-full text-left">
|
|
29
|
+
<thead>
|
|
30
|
+
<tr class="text-xs text-gray-500 uppercase border-b">
|
|
31
|
+
<th class="py-3 px-4">Name</th>
|
|
32
|
+
<th class="py-3 px-4">Port</th>
|
|
33
|
+
<th class="py-3 px-4">Status</th>
|
|
34
|
+
<th class="py-3 px-4">Protocol</th>
|
|
35
|
+
<th class="py-3 px-4">Stubs</th>
|
|
36
|
+
<th class="py-3 px-4">Actions</th>
|
|
37
|
+
</tr>
|
|
38
|
+
</thead>
|
|
39
|
+
<tbody id="imposter-list">
|
|
40
|
+
${raw(imposterListPartial(data.imposters).value)}
|
|
41
|
+
</tbody>
|
|
42
|
+
</table>
|
|
43
|
+
</div>`;
|
|
44
|
+
return adminLayout({
|
|
45
|
+
title: "Imposters — Admin Dashboard"
|
|
46
|
+
}, content);
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=AdminDashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminDashboard.js","names":["html","raw","adminLayout","createFormPartial","imposterListPartial","summaryBar","data","total","imposters","length","running","filter","i","status","stopped","String","adminDashboardPage","content","value","title"],"sources":["../../../../../src/ui/admin/pages/AdminDashboard.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,IAAI,EAAEC,GAAG,QAAQ,YAAY;AAEtC,SAASC,WAAW,QAAQ,gBAAgB;AAE5C,SAASC,iBAAiB,EAAEC,mBAAmB,QAAQ,aAAa;AAMpE,MAAMC,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,OAAOV,IAAI;;;sDAGyCe,MAAM,CAACR,KAAK,CAAC;;;;uDAIZQ,MAAM,CAACL,OAAO,CAAC;;;;sDAIhBK,MAAM,CAACD,OAAO,CAAC;;SAE5D;AACT,CAAC;AAED,OAAO,MAAME,kBAAkB,GAAIV,IAAwB,IAAc;EACvE,MAAMW,OAAO,GAAGjB,IAAI;MAChBK,UAAU,CAACC,IAAI,CAAC;MAChBH,iBAAiB,EAAE;;;;;;;;;;;;;;YAcbF,GAAG,CAACG,mBAAmB,CAACE,IAAI,CAACE,SAAS,CAAC,CAACU,KAAK,CAAC;;;WAG/C;EAET,OAAOhB,WAAW,CAAC;IAAEiB,KAAK,EAAE;EAA6B,CAAE,EAAEF,OAAO,CAAC;AACvE,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { html } from "../html";
|
|
2
|
+
const statusBadge = status => {
|
|
3
|
+
if (status === "running") {
|
|
4
|
+
return html`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-green-100 text-green-700">running</span>`;
|
|
5
|
+
}
|
|
6
|
+
if (status === "stopped") {
|
|
7
|
+
return html`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-gray-100 text-gray-600">stopped</span>`;
|
|
8
|
+
}
|
|
9
|
+
return html`<span class="px-2 py-0.5 rounded text-xs font-semibold bg-yellow-100 text-yellow-700">${status}</span>`;
|
|
10
|
+
};
|
|
11
|
+
export const imposterRowPartial = imp => {
|
|
12
|
+
const isRunning = imp.status === "running";
|
|
13
|
+
return html`<tr id="row-${imp.id}" class="border-t hover:bg-gray-50">
|
|
14
|
+
<td class="py-3 px-4 font-medium">${imp.name}</td>
|
|
15
|
+
<td class="py-3 px-4 font-mono text-sm">${String(imp.port)}</td>
|
|
16
|
+
<td class="py-3 px-4">${statusBadge(imp.status)}</td>
|
|
17
|
+
<td class="py-3 px-4 text-sm text-gray-600">${imp.protocol}</td>
|
|
18
|
+
<td class="py-3 px-4 text-sm">${String(imp.stubCount)}</td>
|
|
19
|
+
<td class="py-3 px-4">
|
|
20
|
+
<div class="flex gap-2 items-center">
|
|
21
|
+
${isRunning ? 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>` : 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>`}
|
|
22
|
+
<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>
|
|
23
|
+
${isRunning ? html`<a href="http://localhost:${String(imp.port)}/_admin" target="_blank" class="text-indigo-600 hover:text-indigo-800 text-sm">Open UI</a>` : html``}
|
|
24
|
+
</div>
|
|
25
|
+
</td>
|
|
26
|
+
</tr>`;
|
|
27
|
+
};
|
|
28
|
+
export const imposterListPartial = imposters => {
|
|
29
|
+
if (imposters.length === 0) {
|
|
30
|
+
return html`<tr><td colspan="6" class="text-center py-8 text-gray-400">No imposters. Create one above.</td></tr>`;
|
|
31
|
+
}
|
|
32
|
+
return imposters.reduce((acc, imp) => html`${acc}${imposterRowPartial(imp)}`, html``);
|
|
33
|
+
};
|
|
34
|
+
export const createFormPartial = error => html`<div class="bg-white rounded-lg shadow p-4 mb-6">
|
|
35
|
+
<h2 class="text-lg font-semibold mb-3">Create Imposter</h2>
|
|
36
|
+
${error ? html`<div class="bg-red-50 border border-red-200 text-red-700 rounded p-3 mb-3">${error}</div>` : html``}
|
|
37
|
+
<form hx-post="/_ui/imposters" hx-target="#imposter-list" hx-swap="innerHTML" class="flex flex-wrap gap-3 items-end">
|
|
38
|
+
<div>
|
|
39
|
+
<label class="block text-xs text-gray-500 mb-1">Name (optional)</label>
|
|
40
|
+
<input name="name" type="text" class="border rounded p-2 text-sm w-40" placeholder="My Service" />
|
|
41
|
+
</div>
|
|
42
|
+
<div>
|
|
43
|
+
<label class="block text-xs text-gray-500 mb-1">Port (optional)</label>
|
|
44
|
+
<input name="port" type="number" class="border rounded p-2 text-sm w-24" placeholder="auto" />
|
|
45
|
+
</div>
|
|
46
|
+
<div class="flex items-center gap-2">
|
|
47
|
+
<input name="autoStart" type="checkbox" checked class="rounded" id="auto-start" />
|
|
48
|
+
<label for="auto-start" class="text-sm text-gray-700">Auto-start</label>
|
|
49
|
+
</div>
|
|
50
|
+
<button type="submit" class="bg-gray-800 text-white px-4 py-2 rounded hover:bg-gray-700 text-sm">Create</button>
|
|
51
|
+
</form>
|
|
52
|
+
</div>`;
|
|
53
|
+
export const adminErrorPartial = message => html`<div class="bg-red-50 border border-red-200 text-red-700 rounded p-3 mb-3">${message}</div>`;
|
|
54
|
+
//# sourceMappingURL=partials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partials.js","names":["html","statusBadge","status","imposterRowPartial","imp","isRunning","id","name","String","port","protocol","stubCount","imposterListPartial","imposters","length","reduce","acc","createFormPartial","error","adminErrorPartial","message"],"sources":["../../../../src/ui/admin/partials.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,IAAI,QAAQ,SAAS;AAY9B,MAAMC,WAAW,GAAIC,MAAc,IAAc;EAC/C,IAAIA,MAAM,KAAK,SAAS,EAAE;IACxB,OAAOF,IAAI,oGAAoG;EACjH;EACA,IAAIE,MAAM,KAAK,SAAS,EAAE;IACxB,OAAOF,IAAI,kGAAkG;EAC/G;EACA,OAAOA,IAAI,yFAAyFE,MAAM,SAAS;AACrH,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAIC,GAAsB,IAAc;EACrE,MAAMC,SAAS,GAAGD,GAAG,CAACF,MAAM,KAAK,SAAS;EAC1C,OAAOF,IAAI,eAAeI,GAAG,CAACE,EAAE;wCACMF,GAAG,CAACG,IAAI;8CACFC,MAAM,CAACJ,GAAG,CAACK,IAAI,CAAC;4BAClCR,WAAW,CAACG,GAAG,CAACF,MAAM,CAAC;kDACDE,GAAG,CAACM,QAAQ;oCAC1BF,MAAM,CAACJ,GAAG,CAACO,SAAS,CAAC;;;UAIrDN,SAAS,GACLL,IAAI,mCAAmCI,GAAG,CAACE,EAAE,0BAA0BF,GAAG,CAACE,EAAE,uGAAuG,GACpLN,IAAI,mCAAmCI,GAAG,CAACE,EAAE,2BAA2BF,GAAG,CAACE,EAAE,sGACpF;4CAC0CF,GAAG,CAACE,EAAE;UAE9CD,SAAS,GACLL,IAAI,6BACJQ,MAAM,CAACJ,GAAG,CAACK,IAAI,CACjB,4FAA4F,GAC1FT,IAAI,EACV;;;QAGM;AACR,CAAC;AAED,OAAO,MAAMY,mBAAmB,GAAIC,SAA2C,IAAc;EAC3F,IAAIA,SAAS,CAACC,MAAM,KAAK,CAAC,EAAE;IAC1B,OAAOd,IAAI,sGAAsG;EACnH;EACA,OAAOa,SAAS,CAACE,MAAM,CACrB,CAACC,GAAG,EAAEZ,GAAG,KAAKJ,IAAI,GAAGgB,GAAG,GAAGb,kBAAkB,CAACC,GAAG,CAAC,EAAE,EACpDJ,IAAI,EAAE,CACP;AACH,CAAC;AAED,OAAO,MAAMiB,iBAAiB,GAAIC,KAAc,IAC9ClB,IAAI;;MAEAkB,KAAK,GAAGlB,IAAI,8EAA8EkB,KAAK,QAAQ,GAAGlB,IAAI,EAAE;;;;;;;;;;;;;;;;SAgB7G;AAET,OAAO,MAAMmB,iBAAiB,GAAIC,OAAe,IAC/CpB,IAAI,8EAA8EoB,OAAO,QAAQ","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Escapes &, <, >, ", ' → HTML entities */
|
|
2
|
+
export const escapeHtml = s => s.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
3
|
+
/** Marker class for pre-escaped HTML */
|
|
4
|
+
export class SafeHtml {
|
|
5
|
+
value;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Wrap a raw HTML string to skip auto-escaping */
|
|
11
|
+
export const raw = s => new SafeHtml(s);
|
|
12
|
+
/** Tagged template: auto-escapes interpolations, passes SafeHtml through */
|
|
13
|
+
export const html = (strings, ...values) => {
|
|
14
|
+
let result = "";
|
|
15
|
+
for (let i = 0; i < strings.length; i++) {
|
|
16
|
+
result += strings[i];
|
|
17
|
+
if (i < values.length) {
|
|
18
|
+
const v = values[i];
|
|
19
|
+
if (v instanceof SafeHtml) {
|
|
20
|
+
result += v.value;
|
|
21
|
+
} else if (v == null) {
|
|
22
|
+
result += "";
|
|
23
|
+
} else if (typeof v === "string") {
|
|
24
|
+
result += escapeHtml(v);
|
|
25
|
+
} else {
|
|
26
|
+
result += escapeHtml(String(v));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return new SafeHtml(result);
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","names":["escapeHtml","s","replaceAll","SafeHtml","value","constructor","raw","html","strings","values","result","i","length","v","String"],"sources":["../../../src/ui/html.ts"],"sourcesContent":[null],"mappings":"AAAA;AACA,OAAO,MAAMA,UAAU,GAAIC,CAAS,IAClCA,CAAC,CACEC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CACxBA,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CACvBA,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CACvBA,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAC1BA,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;AAE7B;AACA,OAAM,MAAOC,QAAQ;EACEC,KAAA;EAArBC,YAAqBD,KAAa;IAAb,KAAAA,KAAK,GAALA,KAAK;EAAW;;AAGvC;AACA,OAAO,MAAME,GAAG,GAAIL,CAAS,IAAe,IAAIE,QAAQ,CAACF,CAAC,CAAC;AAE3D;AACA,OAAO,MAAMM,IAAI,GAAGA,CAACC,OAA6B,EAAE,GAAGC,MAAsB,KAAc;EACzF,IAAIC,MAAM,GAAG,EAAE;EACf,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGH,OAAO,CAACI,MAAM,EAAED,CAAC,EAAE,EAAE;IACvCD,MAAM,IAAIF,OAAO,CAACG,CAAC,CAAC;IACpB,IAAIA,CAAC,GAAGF,MAAM,CAACG,MAAM,EAAE;MACrB,MAAMC,CAAC,GAAGJ,MAAM,CAACE,CAAC,CAAC;MACnB,IAAIE,CAAC,YAAYV,QAAQ,EAAE;QACzBO,MAAM,IAAIG,CAAC,CAACT,KAAK;MACnB,CAAC,MAAM,IAAIS,CAAC,IAAI,IAAI,EAAE;QACpBH,MAAM,IAAI,EAAE;MACd,CAAC,MAAM,IAAI,OAAOG,CAAC,KAAK,QAAQ,EAAE;QAChCH,MAAM,IAAIV,UAAU,CAACa,CAAC,CAAC;MACzB,CAAC,MAAM;QACLH,MAAM,IAAIV,UAAU,CAACc,MAAM,CAACD,CAAC,CAAC,CAAC;MACjC;IACF;EACF;EACA,OAAO,IAAIV,QAAQ,CAACO,MAAM,CAAC;AAC7B,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { html, raw } from "./html";
|
|
2
|
+
const navTab = (label, href, active) => active ? html`<a href="${href}" class="px-4 py-2 bg-white text-indigo-700 rounded-t font-semibold border-b-2 border-indigo-600">${label}</a>` : html`<a href="${href}" class="px-4 py-2 text-gray-300 hover:text-white hover:bg-indigo-500 rounded-t">${label}</a>`;
|
|
3
|
+
export const layout = (opts, content) => html`<!DOCTYPE html>
|
|
4
|
+
<html lang="en">
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="utf-8">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
<title>${opts.title}</title>
|
|
9
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
10
|
+
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
|
11
|
+
</head>
|
|
12
|
+
<body class="bg-gray-50 min-h-screen">
|
|
13
|
+
<nav class="bg-indigo-700 text-white shadow-md">
|
|
14
|
+
<div class="max-w-5xl mx-auto px-4 py-3 flex items-center justify-between">
|
|
15
|
+
<div>
|
|
16
|
+
<span class="text-indigo-200 text-sm font-medium mr-2">Imposters</span>
|
|
17
|
+
<span class="text-lg font-bold">${opts.imposterName}</span>
|
|
18
|
+
<span class="ml-2 text-indigo-200 text-sm">port ${String(opts.port)}</span>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="flex gap-1">
|
|
21
|
+
${navTab("Dashboard", "/_admin", opts.activeTab === "dashboard")}
|
|
22
|
+
${navTab("Stubs", "/_admin/stubs", opts.activeTab === "stubs")}
|
|
23
|
+
${navTab("Requests", "/_admin/requests", opts.activeTab === "requests")}
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</nav>
|
|
27
|
+
<main class="max-w-5xl mx-auto px-4 py-6">
|
|
28
|
+
${raw(content.value)}
|
|
29
|
+
</main>
|
|
30
|
+
</body>
|
|
31
|
+
</html>`;
|
|
32
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","names":["html","raw","navTab","label","href","active","layout","opts","content","title","imposterName","String","port","activeTab","value"],"sources":["../../../src/ui/layout.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,IAAI,EAAEC,GAAG,QAAuB,QAAQ;AASjD,MAAMC,MAAM,GAAGA,CAACC,KAAa,EAAEC,IAAY,EAAEC,MAAe,KAC1DA,MAAM,GACFL,IAAI,YAAYI,IAAI,qGAAqGD,KAAK,MAAM,GACpIH,IAAI,YAAYI,IAAI,oFAAoFD,KAAK,MAAM;AAEzH,OAAO,MAAMG,MAAM,GAAGA,CAACC,IAAgB,EAAEC,OAAiB,KACxDR,IAAI;;;;;WAKKO,IAAI,CAACE,KAAK;;;;;;;;;0CASqBF,IAAI,CAACG,YAAY;0DACDC,MAAM,CAACJ,IAAI,CAACK,IAAI,CAAC;;;UAGjEV,MAAM,CAAC,WAAW,EAAE,SAAS,EAAEK,IAAI,CAACM,SAAS,KAAK,WAAW,CAAC;UAC9DX,MAAM,CAAC,OAAO,EAAE,eAAe,EAAEK,IAAI,CAACM,SAAS,KAAK,OAAO,CAAC;UAC5DX,MAAM,CAAC,UAAU,EAAE,kBAAkB,EAAEK,IAAI,CAACM,SAAS,KAAK,UAAU,CAAC;;;;;MAKzEZ,GAAG,CAACO,OAAO,CAACM,KAAK,CAAC;;;QAGhB","ignoreList":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { html, raw } from "../html";
|
|
2
|
+
import { layout } from "../layout";
|
|
3
|
+
import { requestTablePartial } from "../partials";
|
|
4
|
+
const statCard = (label, value, color) => html`<div class="bg-white rounded-lg shadow p-4">
|
|
5
|
+
<div class="text-sm text-gray-500">${label}</div>
|
|
6
|
+
<div class="text-2xl font-bold ${color}">${value}</div>
|
|
7
|
+
</div>`;
|
|
8
|
+
export const dashboardPage = data => {
|
|
9
|
+
const statusColor = data.config.status === "running" ? "text-green-600" : "text-gray-500";
|
|
10
|
+
const content = html`
|
|
11
|
+
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
|
12
|
+
${statCard("Status", data.config.status, statusColor)}
|
|
13
|
+
${statCard("Port", String(data.config.port), "text-gray-800")}
|
|
14
|
+
${statCard("Stubs", String(data.stubCount), "text-indigo-600")}
|
|
15
|
+
${statCard("Requests", String(data.requestCount), "text-indigo-600")}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="bg-white rounded-lg shadow">
|
|
19
|
+
<h2 class="text-lg font-semibold px-4 pt-4 pb-2">
|
|
20
|
+
<a href="/_admin/requests" class="hover:text-indigo-600">Recent Requests →</a>
|
|
21
|
+
</h2>
|
|
22
|
+
${data.recentRequests.length === 0 ? html`<p class="px-4 pb-4 text-gray-400">No requests yet.</p>` : html`<table class="w-full text-left">
|
|
23
|
+
<thead>
|
|
24
|
+
<tr class="text-xs text-gray-500 uppercase border-b">
|
|
25
|
+
<th class="py-2 px-3">Time</th>
|
|
26
|
+
<th class="py-2 px-3">Method</th>
|
|
27
|
+
<th class="py-2 px-3">Path</th>
|
|
28
|
+
<th class="py-2 px-3">Status</th>
|
|
29
|
+
<th class="py-2 px-3">Stub</th>
|
|
30
|
+
<th class="py-2 px-3">Duration</th>
|
|
31
|
+
<th class="py-2 px-3"></th>
|
|
32
|
+
</tr>
|
|
33
|
+
</thead>
|
|
34
|
+
<tbody>${raw(requestTablePartial(data.recentRequests).value)}</tbody>
|
|
35
|
+
</table>`}
|
|
36
|
+
</div>`;
|
|
37
|
+
return layout({
|
|
38
|
+
title: `${data.config.name} — Dashboard`,
|
|
39
|
+
imposterName: data.config.name,
|
|
40
|
+
port: data.config.port,
|
|
41
|
+
activeTab: "dashboard"
|
|
42
|
+
}, content);
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","names":["html","raw","layout","requestTablePartial","statCard","label","value","color","dashboardPage","data","statusColor","config","status","content","String","port","stubCount","requestCount","recentRequests","length","title","name","imposterName","activeTab"],"sources":["../../../../src/ui/pages/dashboard.ts"],"sourcesContent":[null],"mappings":"AAEA,SAASA,IAAI,EAAEC,GAAG,QAAQ,SAAS;AACnC,SAASC,MAAM,QAAQ,WAAW;AAClC,SAASC,mBAAmB,QAAQ,aAAa;AASjD,MAAMC,QAAQ,GAAGA,CAACC,KAAa,EAAEC,KAAa,EAAEC,KAAa,KAC3DP,IAAI;yCACmCK,KAAK;qCACTE,KAAK,KAAKD,KAAK;SAC3C;AAET,OAAO,MAAME,aAAa,GAAIC,IAAmB,IAAI;EACnD,MAAMC,WAAW,GAAGD,IAAI,CAACE,MAAM,CAACC,MAAM,KAAK,SAAS,GAAG,gBAAgB,GAAG,eAAe;EAEzF,MAAMC,OAAO,GAAGb,IAAI;;QAEdI,QAAQ,CAAC,QAAQ,EAAEK,IAAI,CAACE,MAAM,CAACC,MAAM,EAAEF,WAAW,CAAC;QACnDN,QAAQ,CAAC,MAAM,EAAEU,MAAM,CAACL,IAAI,CAACE,MAAM,CAACI,IAAI,CAAC,EAAE,eAAe,CAAC;QAC3DX,QAAQ,CAAC,OAAO,EAAEU,MAAM,CAACL,IAAI,CAACO,SAAS,CAAC,EAAE,iBAAiB,CAAC;QAC5DZ,QAAQ,CAAC,UAAU,EAAEU,MAAM,CAACL,IAAI,CAACQ,YAAY,CAAC,EAAE,iBAAiB,CAAC;;;;;;;QAQtER,IAAI,CAACS,cAAc,CAACC,MAAM,KAAK,CAAC,GAC5BnB,IAAI,yDAAyD,GAC7DA,IAAI;;;;;;;;;;;;qBAYSC,GAAG,CAACE,mBAAmB,CAACM,IAAI,CAACS,cAAc,CAAC,CAACZ,KAAK,CAAC;mBAEtE;WACS;EAET,OAAOJ,MAAM,CACX;IACEkB,KAAK,EAAE,GAAGX,IAAI,CAACE,MAAM,CAACU,IAAI,cAAc;IACxCC,YAAY,EAAEb,IAAI,CAACE,MAAM,CAACU,IAAI;IAC9BN,IAAI,EAAEN,IAAI,CAACE,MAAM,CAACI,IAAI;IACtBQ,SAAS,EAAE;GACZ,EACDV,OAAO,CACR;AACH,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { html, raw } from "../html";
|
|
2
|
+
import { layout } from "../layout";
|
|
3
|
+
import { methodBadge, statusBadge, stubCardPartial } from "../partials";
|
|
4
|
+
const formatTimestamp = ts => {
|
|
5
|
+
try {
|
|
6
|
+
const d = typeof ts.epochMillis === "bigint" ? new Date(Number(ts.epochMillis)) : new Date(String(ts));
|
|
7
|
+
return d.toISOString();
|
|
8
|
+
} catch {
|
|
9
|
+
return String(ts);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const formatBody = body => {
|
|
13
|
+
if (body === undefined || body === null) return "(empty)";
|
|
14
|
+
if (typeof body === "string") {
|
|
15
|
+
try {
|
|
16
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
17
|
+
} catch {
|
|
18
|
+
return body;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return JSON.stringify(body, null, 2);
|
|
22
|
+
};
|
|
23
|
+
const headersTable = headers => {
|
|
24
|
+
const entries = Object.entries(headers);
|
|
25
|
+
if (entries.length === 0) return html`<p class="text-gray-400 text-sm italic">No headers</p>`;
|
|
26
|
+
const rows = entries.map(([k, v]) => html`<tr class="border-t"><td class="py-1 px-2 text-xs font-mono font-semibold text-gray-600">${k}</td><td class="py-1 px-2 text-xs font-mono">${v}</td></tr>`);
|
|
27
|
+
return html`<table class="w-full"><tbody>${rows.reduce((a, r) => html`${a}${r}`, html``)}</tbody></table>`;
|
|
28
|
+
};
|
|
29
|
+
const queryTable = query => {
|
|
30
|
+
const entries = Object.entries(query);
|
|
31
|
+
if (entries.length === 0) return html`<p class="text-gray-400 text-sm italic">No query parameters</p>`;
|
|
32
|
+
const rows = entries.map(([k, v]) => html`<tr class="border-t"><td class="py-1 px-2 text-xs font-mono font-semibold text-gray-600">${k}</td><td class="py-1 px-2 text-xs font-mono">${v}</td></tr>`);
|
|
33
|
+
return html`<table class="w-full"><tbody>${rows.reduce((a, r) => html`${a}${r}`, html``)}</tbody></table>`;
|
|
34
|
+
};
|
|
35
|
+
export const requestDetailPage = data => {
|
|
36
|
+
const {
|
|
37
|
+
entry,
|
|
38
|
+
matchedStub
|
|
39
|
+
} = data;
|
|
40
|
+
const timestamp = formatTimestamp(entry.timestamp);
|
|
41
|
+
const reqBody = formatBody(entry.request.body);
|
|
42
|
+
const respBody = formatBody(entry.response.body);
|
|
43
|
+
const respHeaders = entry.response.headers ?? {};
|
|
44
|
+
const content = html`
|
|
45
|
+
<div class="mb-4">
|
|
46
|
+
<a href="/_admin/requests" class="text-indigo-600 hover:underline text-sm">← Back to Requests</a>
|
|
47
|
+
<span class="text-gray-400 mx-2">/</span>
|
|
48
|
+
<span class="text-sm text-gray-500">Request ${entry.id}</span>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div class="bg-white rounded-lg shadow p-4 mb-6">
|
|
52
|
+
<div class="flex items-center gap-3 mb-3">
|
|
53
|
+
${methodBadge(entry.request.method)}
|
|
54
|
+
<span class="font-mono text-lg">${entry.request.path}</span>
|
|
55
|
+
${statusBadge(entry.response.status)}
|
|
56
|
+
<span class="text-sm text-gray-500">${String(entry.duration)}ms</span>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="text-sm text-gray-500">
|
|
59
|
+
<span>Timestamp: ${timestamp}</span>
|
|
60
|
+
${entry.response.matchedStubId ? html`<span class="ml-4">Matched Stub: <span class="font-mono text-indigo-600">${entry.response.matchedStubId}</span></span>` : html`<span class="ml-4 text-orange-500">No matching stub</span>`}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
|
65
|
+
<div>
|
|
66
|
+
<h3 class="text-lg font-semibold mb-3">Request</h3>
|
|
67
|
+
<div class="bg-white rounded-lg shadow p-4 space-y-3">
|
|
68
|
+
<div>
|
|
69
|
+
<h4 class="text-sm font-medium text-gray-700 mb-1">Headers</h4>
|
|
70
|
+
${headersTable(entry.request.headers)}
|
|
71
|
+
</div>
|
|
72
|
+
<div>
|
|
73
|
+
<h4 class="text-sm font-medium text-gray-700 mb-1">Query Parameters</h4>
|
|
74
|
+
${queryTable(entry.request.query)}
|
|
75
|
+
</div>
|
|
76
|
+
<div>
|
|
77
|
+
<h4 class="text-sm font-medium text-gray-700 mb-1">Body</h4>
|
|
78
|
+
<pre class="bg-gray-50 border rounded p-2 text-xs font-mono overflow-x-auto whitespace-pre-wrap max-h-64 overflow-y-auto">${reqBody}</pre>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div>
|
|
84
|
+
<h3 class="text-lg font-semibold mb-3">Response</h3>
|
|
85
|
+
<div class="bg-white rounded-lg shadow p-4 space-y-3">
|
|
86
|
+
<div class="flex items-center gap-2">
|
|
87
|
+
${statusBadge(entry.response.status)}
|
|
88
|
+
</div>
|
|
89
|
+
<div>
|
|
90
|
+
<h4 class="text-sm font-medium text-gray-700 mb-1">Headers</h4>
|
|
91
|
+
${headersTable(respHeaders)}
|
|
92
|
+
</div>
|
|
93
|
+
<div>
|
|
94
|
+
<h4 class="text-sm font-medium text-gray-700 mb-1">Body</h4>
|
|
95
|
+
<pre class="bg-gray-50 border rounded p-2 text-xs font-mono overflow-x-auto whitespace-pre-wrap max-h-64 overflow-y-auto">${respBody}</pre>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
${matchedStub !== null ? html`<div>
|
|
102
|
+
<h3 class="text-lg font-semibold mb-3">Matched Stub</h3>
|
|
103
|
+
${raw(stubCardPartial(matchedStub).value)}
|
|
104
|
+
</div>` : html``}`;
|
|
105
|
+
return layout({
|
|
106
|
+
title: `${data.config.name} — Request ${entry.id}`,
|
|
107
|
+
imposterName: data.config.name,
|
|
108
|
+
port: data.config.port,
|
|
109
|
+
activeTab: "requests"
|
|
110
|
+
}, content);
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=request-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-detail.js","names":["html","raw","layout","methodBadge","statusBadge","stubCardPartial","formatTimestamp","ts","d","epochMillis","Date","Number","String","toISOString","formatBody","body","undefined","JSON","stringify","parse","headersTable","headers","entries","Object","length","rows","map","k","v","reduce","a","r","queryTable","query","requestDetailPage","data","entry","matchedStub","timestamp","reqBody","request","respBody","response","respHeaders","content","id","method","path","status","duration","matchedStubId","value","title","config","name","imposterName","port","activeTab"],"sources":["../../../../src/ui/pages/request-detail.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { html, raw } from "../html";
|
|
2
|
+
import { layout } from "../layout";
|
|
3
|
+
import { requestTablePartial, statusBadge } from "../partials";
|
|
4
|
+
const testRequestForm = _port => html`<details class="bg-white rounded-lg shadow p-4 mb-6">
|
|
5
|
+
<summary class="text-lg font-semibold cursor-pointer">Send Test Request</summary>
|
|
6
|
+
<form hx-post="/_admin/requests/test" hx-target="#test-result" hx-swap="innerHTML" class="mt-3 space-y-3">
|
|
7
|
+
<div class="grid grid-cols-2 gap-3">
|
|
8
|
+
<div>
|
|
9
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Method</label>
|
|
10
|
+
<select name="method" class="w-full border rounded p-2 text-sm">
|
|
11
|
+
<option value="GET">GET</option>
|
|
12
|
+
<option value="POST">POST</option>
|
|
13
|
+
<option value="PUT">PUT</option>
|
|
14
|
+
<option value="PATCH">PATCH</option>
|
|
15
|
+
<option value="DELETE">DELETE</option>
|
|
16
|
+
<option value="HEAD">HEAD</option>
|
|
17
|
+
<option value="OPTIONS">OPTIONS</option>
|
|
18
|
+
</select>
|
|
19
|
+
</div>
|
|
20
|
+
<div>
|
|
21
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Path</label>
|
|
22
|
+
<input name="path" type="text" value="/" class="w-full border rounded p-2 text-sm font-mono" placeholder="/api/test" />
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<div>
|
|
26
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Content-Type</label>
|
|
27
|
+
<select name="contentType" class="w-full border rounded p-2 text-sm">
|
|
28
|
+
<option value="application/json">application/json</option>
|
|
29
|
+
<option value="text/plain">text/plain</option>
|
|
30
|
+
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
|
|
31
|
+
<option value="application/xml">application/xml</option>
|
|
32
|
+
</select>
|
|
33
|
+
</div>
|
|
34
|
+
<div>
|
|
35
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Headers (one per line: Key: Value)</label>
|
|
36
|
+
<textarea name="headers" rows="2" class="w-full border rounded p-2 text-sm font-mono" placeholder="Authorization: Bearer token123"></textarea>
|
|
37
|
+
</div>
|
|
38
|
+
<div>
|
|
39
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Body</label>
|
|
40
|
+
<textarea name="body" rows="3" class="w-full border rounded p-2 text-sm font-mono" placeholder='{"key": "value"}'></textarea>
|
|
41
|
+
</div>
|
|
42
|
+
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded hover:bg-indigo-700 text-sm">Send Request</button>
|
|
43
|
+
</form>
|
|
44
|
+
<div id="test-result" class="mt-3"></div>
|
|
45
|
+
</details>`;
|
|
46
|
+
const filterBar = () => html`<div class="bg-white rounded-lg shadow p-4 mb-6">
|
|
47
|
+
<form hx-get="/_admin/requests/list" hx-target="#request-table-body" hx-swap="innerHTML" class="flex flex-wrap gap-3 items-end">
|
|
48
|
+
<div>
|
|
49
|
+
<label class="block text-xs text-gray-500 mb-1">Method</label>
|
|
50
|
+
<select name="method" class="border rounded p-1.5 text-sm">
|
|
51
|
+
<option value="">All</option>
|
|
52
|
+
<option value="GET">GET</option>
|
|
53
|
+
<option value="POST">POST</option>
|
|
54
|
+
<option value="PUT">PUT</option>
|
|
55
|
+
<option value="PATCH">PATCH</option>
|
|
56
|
+
<option value="DELETE">DELETE</option>
|
|
57
|
+
</select>
|
|
58
|
+
</div>
|
|
59
|
+
<div>
|
|
60
|
+
<label class="block text-xs text-gray-500 mb-1">Path</label>
|
|
61
|
+
<input name="path" type="text" class="border rounded p-1.5 text-sm font-mono w-40" placeholder="/api/..." />
|
|
62
|
+
</div>
|
|
63
|
+
<div>
|
|
64
|
+
<label class="block text-xs text-gray-500 mb-1">Status</label>
|
|
65
|
+
<input name="status" type="text" class="border rounded p-1.5 text-sm font-mono w-20" placeholder="200" />
|
|
66
|
+
</div>
|
|
67
|
+
<button type="submit" class="bg-indigo-600 text-white px-3 py-1.5 rounded hover:bg-indigo-700 text-sm">Filter</button>
|
|
68
|
+
<button type="button" hx-delete="/_admin/requests" hx-target="#request-table-body" hx-swap="innerHTML" hx-confirm="Clear all request logs?" class="bg-red-50 text-red-600 border border-red-200 px-3 py-1.5 rounded hover:bg-red-100 text-sm ml-auto">Clear Log</button>
|
|
69
|
+
</form>
|
|
70
|
+
</div>`;
|
|
71
|
+
export const requestsPage = data => {
|
|
72
|
+
const content = html`
|
|
73
|
+
${testRequestForm(data.config.port)}
|
|
74
|
+
${filterBar()}
|
|
75
|
+
<div class="bg-white rounded-lg shadow overflow-x-auto">
|
|
76
|
+
<table class="w-full text-left">
|
|
77
|
+
<thead>
|
|
78
|
+
<tr class="text-xs text-gray-500 uppercase border-b">
|
|
79
|
+
<th class="py-2 px-3">Time</th>
|
|
80
|
+
<th class="py-2 px-3">Method</th>
|
|
81
|
+
<th class="py-2 px-3">Path</th>
|
|
82
|
+
<th class="py-2 px-3">Status</th>
|
|
83
|
+
<th class="py-2 px-3">Stub</th>
|
|
84
|
+
<th class="py-2 px-3">Duration</th>
|
|
85
|
+
<th class="py-2 px-3"></th>
|
|
86
|
+
</tr>
|
|
87
|
+
</thead>
|
|
88
|
+
<tbody id="request-table-body">
|
|
89
|
+
${raw(requestTablePartial(data.entries.slice().reverse()).value)}
|
|
90
|
+
</tbody>
|
|
91
|
+
</table>
|
|
92
|
+
</div>`;
|
|
93
|
+
return layout({
|
|
94
|
+
title: `${data.config.name} — Requests`,
|
|
95
|
+
imposterName: data.config.name,
|
|
96
|
+
port: data.config.port,
|
|
97
|
+
activeTab: "requests"
|
|
98
|
+
}, content);
|
|
99
|
+
};
|
|
100
|
+
export const testResultPartial = result => {
|
|
101
|
+
const headerRows = Object.entries(result.headers).map(([k, v]) => html`<tr class="border-t"><td class="py-1 px-2 text-xs font-mono text-gray-600">${k}</td><td class="py-1 px-2 text-xs font-mono">${v}</td></tr>`);
|
|
102
|
+
return html`<div class="bg-gray-50 rounded p-3 border">
|
|
103
|
+
<div class="flex items-center gap-3 mb-2">
|
|
104
|
+
<span class="font-semibold text-sm">Response</span>
|
|
105
|
+
${statusBadge(result.status)}
|
|
106
|
+
<span class="text-xs text-gray-500">${String(result.duration)}ms</span>
|
|
107
|
+
</div>
|
|
108
|
+
${headerRows.length > 0 ? html`<table class="w-full mb-2"><thead><tr class="text-xs text-gray-500"><th class="text-left px-2">Header</th><th class="text-left px-2">Value</th></tr></thead><tbody>${headerRows.reduce((a, r) => html`${a}${r}`, html``)}</tbody></table>` : html``}
|
|
109
|
+
<pre class="bg-white border rounded p-2 text-xs font-mono overflow-x-auto whitespace-pre-wrap max-h-64 overflow-y-auto">${result.body || "(empty body)"}</pre>
|
|
110
|
+
</div>`;
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","names":["html","raw","layout","requestTablePartial","statusBadge","testRequestForm","_port","filterBar","requestsPage","data","content","config","port","entries","slice","reverse","value","title","name","imposterName","activeTab","testResultPartial","result","headerRows","Object","headers","map","k","v","status","String","duration","length","reduce","a","r","body"],"sources":["../../../../src/ui/pages/requests.ts"],"sourcesContent":[null],"mappings":"AAEA,SAASA,IAAI,EAAEC,GAAG,QAAQ,SAAS;AAEnC,SAASC,MAAM,QAAQ,WAAW;AAClC,SAASC,mBAAmB,EAAEC,WAAW,QAAQ,aAAa;AAO9D,MAAMC,eAAe,GAAIC,KAAa,IACpCN,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyCO;AAEb,MAAMO,SAAS,GAAGA,CAAA,KAChBP,IAAI;;;;;;;;;;;;;;;;;;;;;;;;SAwBG;AAET,OAAO,MAAMQ,YAAY,GAAIC,IAAsB,IAAc;EAC/D,MAAMC,OAAO,GAAGV,IAAI;MAChBK,eAAe,CAACI,IAAI,CAACE,MAAM,CAACC,IAAI,CAAC;MACjCL,SAAS,EAAE;;;;;;;;;;;;;;;YAeLN,GAAG,CAACE,mBAAmB,CAACM,IAAI,CAACI,OAAO,CAACC,KAAK,EAAE,CAACC,OAAO,EAAE,CAAC,CAACC,KAAK,CAAC;;;WAG/D;EAET,OAAOd,MAAM,CACX;IACEe,KAAK,EAAE,GAAGR,IAAI,CAACE,MAAM,CAACO,IAAI,aAAa;IACvCC,YAAY,EAAEV,IAAI,CAACE,MAAM,CAACO,IAAI;IAC9BN,IAAI,EAAEH,IAAI,CAACE,MAAM,CAACC,IAAI;IACtBQ,SAAS,EAAE;GACZ,EACDV,OAAO,CACR;AACH,CAAC;AAED,OAAO,MAAMW,iBAAiB,GAC5BC,MAA2F,IAC/E;EACZ,MAAMC,UAAU,GAAGC,MAAM,CAACX,OAAO,CAACS,MAAM,CAACG,OAAO,CAAC,CAACC,GAAG,CAAC,CAAC,CAACC,CAAC,EAAEC,CAAC,CAAC,KAC3D5B,IAAI,8EAA8E2B,CAAC,gDAAgDC,CAAC,YAAY,CACjJ;EACD,OAAO5B,IAAI;;;QAGLI,WAAW,CAACkB,MAAM,CAACO,MAAM,CAAC;4CACUC,MAAM,CAACR,MAAM,CAACS,QAAQ,CAAC;;MAG/DR,UAAU,CAACS,MAAM,GAAG,CAAC,GACjBhC,IAAI,sKACJuB,UAAU,CAACU,MAAM,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKnC,IAAI,GAAGkC,CAAC,GAAGC,CAAC,EAAE,EAAEnC,IAAI,EAAE,CACpD,kBAAkB,GAChBA,IAAI,EACV;8HAEEsB,MAAM,CAACc,IAAI,IAAI,cACjB;SACO;AACT,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { html, raw } from "../html";
|
|
2
|
+
import { layout } from "../layout";
|
|
3
|
+
import { stubListPartial } from "../partials";
|
|
4
|
+
const addStubForm = () => html`<div class="bg-white rounded-lg shadow p-4 mb-6">
|
|
5
|
+
<h2 class="text-lg font-semibold mb-3">Add Stub</h2>
|
|
6
|
+
<form hx-post="/_admin/stubs" hx-target="#stub-list" hx-swap="innerHTML" hx-on::after-request="if(event.detail.successful) this.reset()">
|
|
7
|
+
<div class="mb-3">
|
|
8
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Predicates (JSON array)</label>
|
|
9
|
+
<textarea name="predicates" rows="3" class="w-full border rounded p-2 font-mono text-sm" placeholder="[]">[]</textarea>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="mb-3">
|
|
12
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Responses (JSON array, at least 1)</label>
|
|
13
|
+
<textarea name="responses" rows="4" class="w-full border rounded p-2 font-mono text-sm" placeholder='[{"status": 200, "body": {}}]'></textarea>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="mb-3">
|
|
16
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Response Mode</label>
|
|
17
|
+
<select name="responseMode" class="border rounded p-2 text-sm">
|
|
18
|
+
<option value="sequential">sequential</option>
|
|
19
|
+
<option value="random">random</option>
|
|
20
|
+
<option value="repeat">repeat</option>
|
|
21
|
+
</select>
|
|
22
|
+
</div>
|
|
23
|
+
<button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded hover:bg-indigo-700 text-sm">Add Stub</button>
|
|
24
|
+
</form>
|
|
25
|
+
</div>`;
|
|
26
|
+
export const stubsPage = data => {
|
|
27
|
+
const content = html`
|
|
28
|
+
${addStubForm()}
|
|
29
|
+
<div id="stub-list">
|
|
30
|
+
${raw(stubListPartial(data.stubs).value)}
|
|
31
|
+
</div>`;
|
|
32
|
+
return layout({
|
|
33
|
+
title: `${data.config.name} — Stubs`,
|
|
34
|
+
imposterName: data.config.name,
|
|
35
|
+
port: data.config.port,
|
|
36
|
+
activeTab: "stubs"
|
|
37
|
+
}, content);
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=stubs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stubs.js","names":["html","raw","layout","stubListPartial","addStubForm","stubsPage","data","content","stubs","value","title","config","name","imposterName","port","activeTab"],"sources":["../../../../src/ui/pages/stubs.ts"],"sourcesContent":[null],"mappings":"AAEA,SAASA,IAAI,EAAEC,GAAG,QAAQ,SAAS;AACnC,SAASC,MAAM,QAAQ,WAAW;AAClC,SAASC,eAAe,QAAQ,aAAa;AAO7C,MAAMC,WAAW,GAAGA,CAAA,KAClBJ,IAAI;;;;;;;;;;;;;;;;;;;;;SAqBG;AAET,OAAO,MAAMK,SAAS,GAAIC,IAAmB,IAAI;EAC/C,MAAMC,OAAO,GAAGP,IAAI;MAChBI,WAAW,EAAE;;QAEXH,GAAG,CAACE,eAAe,CAACG,IAAI,CAACE,KAAK,CAAC,CAACC,KAAK,CAAC;WACnC;EAET,OAAOP,MAAM,CACX;IACEQ,KAAK,EAAE,GAAGJ,IAAI,CAACK,MAAM,CAACC,IAAI,UAAU;IACpCC,YAAY,EAAEP,IAAI,CAACK,MAAM,CAACC,IAAI;IAC9BE,IAAI,EAAER,IAAI,CAACK,MAAM,CAACG,IAAI;IACtBC,SAAS,EAAE;GACZ,EACDR,OAAO,CACR;AACH,CAAC","ignoreList":[]}
|