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,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":"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","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("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
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
|