@c9up/ream 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/Application.d.ts +71 -0
- package/dist/Application.d.ts.map +1 -0
- package/dist/Application.js +151 -0
- package/dist/Application.js.map +1 -0
- package/dist/Codemods.d.ts +16 -0
- package/dist/Codemods.d.ts.map +1 -0
- package/dist/Codemods.js +277 -0
- package/dist/Codemods.js.map +1 -0
- package/dist/ConfigLoader.d.ts +29 -0
- package/dist/ConfigLoader.d.ts.map +1 -0
- package/dist/ConfigLoader.js +43 -0
- package/dist/ConfigLoader.js.map +1 -0
- package/dist/ErrorBoundary.d.ts +51 -0
- package/dist/ErrorBoundary.d.ts.map +1 -0
- package/dist/ErrorBoundary.js +122 -0
- package/dist/ErrorBoundary.js.map +1 -0
- package/dist/GracefulShutdown.d.ts +28 -0
- package/dist/GracefulShutdown.d.ts.map +1 -0
- package/dist/GracefulShutdown.js +55 -0
- package/dist/GracefulShutdown.js.map +1 -0
- package/dist/HealthCheck.d.ts +42 -0
- package/dist/HealthCheck.d.ts.map +1 -0
- package/dist/HealthCheck.js +65 -0
- package/dist/HealthCheck.js.map +1 -0
- package/dist/HotReload.d.ts +28 -0
- package/dist/HotReload.d.ts.map +1 -0
- package/dist/HotReload.js +60 -0
- package/dist/HotReload.js.map +1 -0
- package/dist/HttpKernel.d.ts +62 -0
- package/dist/HttpKernel.d.ts.map +1 -0
- package/dist/HttpKernel.js +210 -0
- package/dist/HttpKernel.js.map +1 -0
- package/dist/Ignitor.d.ts +195 -0
- package/dist/Ignitor.d.ts.map +1 -0
- package/dist/Ignitor.js +505 -0
- package/dist/Ignitor.js.map +1 -0
- package/dist/Provider.d.ts +54 -0
- package/dist/Provider.d.ts.map +1 -0
- package/dist/Provider.js +37 -0
- package/dist/Provider.js.map +1 -0
- package/dist/bodyparser/BodyParserMiddleware.d.ts +38 -0
- package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -0
- package/dist/bodyparser/BodyParserMiddleware.js +143 -0
- package/dist/bodyparser/BodyParserMiddleware.js.map +1 -0
- package/dist/bodyparser/MultipartFile.d.ts +77 -0
- package/dist/bodyparser/MultipartFile.d.ts.map +1 -0
- package/dist/bodyparser/MultipartFile.js +138 -0
- package/dist/bodyparser/MultipartFile.js.map +1 -0
- package/dist/bodyparser/parseSize.d.ts +6 -0
- package/dist/bodyparser/parseSize.d.ts.map +1 -0
- package/dist/bodyparser/parseSize.js +21 -0
- package/dist/bodyparser/parseSize.js.map +1 -0
- package/dist/bootstrap/hyper-server.d.ts +27 -0
- package/dist/bootstrap/hyper-server.d.ts.map +1 -0
- package/dist/bootstrap/hyper-server.js +63 -0
- package/dist/bootstrap/hyper-server.js.map +1 -0
- package/dist/console/CommandRunner.d.ts +18 -0
- package/dist/console/CommandRunner.d.ts.map +1 -0
- package/dist/console/CommandRunner.js +65 -0
- package/dist/console/CommandRunner.js.map +1 -0
- package/dist/container/Container.d.ts +60 -0
- package/dist/container/Container.d.ts.map +1 -0
- package/dist/container/Container.js +329 -0
- package/dist/container/Container.js.map +1 -0
- package/dist/container/types.d.ts +25 -0
- package/dist/container/types.d.ts.map +1 -0
- package/dist/container/types.js +6 -0
- package/dist/container/types.js.map +1 -0
- package/dist/decorators/Lazy.d.ts +19 -0
- package/dist/decorators/Lazy.d.ts.map +1 -0
- package/dist/decorators/Lazy.js +53 -0
- package/dist/decorators/Lazy.js.map +1 -0
- package/dist/decorators/Service.d.ts +48 -0
- package/dist/decorators/Service.d.ts.map +1 -0
- package/dist/decorators/Service.js +70 -0
- package/dist/decorators/Service.js.map +1 -0
- package/dist/errors/FuzzyMatcher.d.ts +41 -0
- package/dist/errors/FuzzyMatcher.d.ts.map +1 -0
- package/dist/errors/FuzzyMatcher.js +81 -0
- package/dist/errors/FuzzyMatcher.js.map +1 -0
- package/dist/errors/ModuleErrors.d.ts +41 -0
- package/dist/errors/ModuleErrors.d.ts.map +1 -0
- package/dist/errors/ModuleErrors.js +65 -0
- package/dist/errors/ModuleErrors.js.map +1 -0
- package/dist/errors/PipelineStageError.d.ts +31 -0
- package/dist/errors/PipelineStageError.d.ts.map +1 -0
- package/dist/errors/PipelineStageError.js +77 -0
- package/dist/errors/PipelineStageError.js.map +1 -0
- package/dist/errors/ReamError.d.ts +50 -0
- package/dist/errors/ReamError.d.ts.map +1 -0
- package/dist/errors/ReamError.js +108 -0
- package/dist/errors/ReamError.js.map +1 -0
- package/dist/events/Emitter.d.ts +124 -0
- package/dist/events/Emitter.d.ts.map +1 -0
- package/dist/events/Emitter.js +271 -0
- package/dist/events/Emitter.js.map +1 -0
- package/dist/events/EventsProvider.d.ts +28 -0
- package/dist/events/EventsProvider.d.ts.map +1 -0
- package/dist/events/EventsProvider.js +36 -0
- package/dist/events/EventsProvider.js.map +1 -0
- package/dist/events/config.d.ts +8 -0
- package/dist/events/config.d.ts.map +1 -0
- package/dist/events/config.js +4 -0
- package/dist/events/config.js.map +1 -0
- package/dist/events/configure.d.ts +10 -0
- package/dist/events/configure.d.ts.map +1 -0
- package/dist/events/configure.js +11 -0
- package/dist/events/configure.js.map +1 -0
- package/dist/events/helix/helpers.d.ts +62 -0
- package/dist/events/helix/helpers.d.ts.map +1 -0
- package/dist/events/helix/helpers.js +187 -0
- package/dist/events/helix/helpers.js.map +1 -0
- package/dist/events/index.d.ts +17 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +15 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/native.d.ts +21 -0
- package/dist/events/native.d.ts.map +1 -0
- package/dist/events/native.js +17 -0
- package/dist/events/native.js.map +1 -0
- package/dist/events/services/main.d.ts +18 -0
- package/dist/events/services/main.d.ts.map +1 -0
- package/dist/events/services/main.js +31 -0
- package/dist/events/services/main.js.map +1 -0
- package/dist/events/testing/FakeBus.d.ts +66 -0
- package/dist/events/testing/FakeBus.d.ts.map +1 -0
- package/dist/events/testing/FakeBus.js +356 -0
- package/dist/events/testing/FakeBus.js.map +1 -0
- package/dist/graphql/GraphQLEngine.d.ts +69 -0
- package/dist/graphql/GraphQLEngine.d.ts.map +1 -0
- package/dist/graphql/GraphQLEngine.js +309 -0
- package/dist/graphql/GraphQLEngine.js.map +1 -0
- package/dist/graphql/GraphQLProvider.d.ts +32 -0
- package/dist/graphql/GraphQLProvider.d.ts.map +1 -0
- package/dist/graphql/GraphQLProvider.js +49 -0
- package/dist/graphql/GraphQLProvider.js.map +1 -0
- package/dist/helpers/base64.d.ts +40 -0
- package/dist/helpers/base64.d.ts.map +1 -0
- package/dist/helpers/base64.js +70 -0
- package/dist/helpers/base64.js.map +1 -0
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +5 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/is.d.ts +101 -0
- package/dist/helpers/is.d.ts.map +1 -0
- package/dist/helpers/is.js +151 -0
- package/dist/helpers/is.js.map +1 -0
- package/dist/helpers/napi-loader.d.ts +46 -0
- package/dist/helpers/napi-loader.d.ts.map +1 -0
- package/dist/helpers/napi-loader.js +69 -0
- package/dist/helpers/napi-loader.js.map +1 -0
- package/dist/helpers/safeEqual.d.ts +9 -0
- package/dist/helpers/safeEqual.d.ts.map +1 -0
- package/dist/helpers/safeEqual.js +16 -0
- package/dist/helpers/safeEqual.js.map +1 -0
- package/dist/helpers/string.d.ts +161 -0
- package/dist/helpers/string.d.ts.map +1 -0
- package/dist/helpers/string.js +429 -0
- package/dist/helpers/string.js.map +1 -0
- package/dist/helpers/types.d.ts +83 -0
- package/dist/helpers/types.d.ts.map +1 -0
- package/dist/helpers/types.js +6 -0
- package/dist/helpers/types.js.map +1 -0
- package/dist/http/Exception.d.ts +103 -0
- package/dist/http/Exception.d.ts.map +1 -0
- package/dist/http/Exception.js +228 -0
- package/dist/http/Exception.js.map +1 -0
- package/dist/http/HttpContext.d.ts +69 -0
- package/dist/http/HttpContext.d.ts.map +1 -0
- package/dist/http/HttpContext.js +55 -0
- package/dist/http/HttpContext.js.map +1 -0
- package/dist/http/RedirectBuilder.d.ts +31 -0
- package/dist/http/RedirectBuilder.d.ts.map +1 -0
- package/dist/http/RedirectBuilder.js +75 -0
- package/dist/http/RedirectBuilder.js.map +1 -0
- package/dist/http/Request.d.ts +160 -0
- package/dist/http/Request.d.ts.map +1 -0
- package/dist/http/Request.js +484 -0
- package/dist/http/Request.js.map +1 -0
- package/dist/http/Response.d.ts +114 -0
- package/dist/http/Response.d.ts.map +1 -0
- package/dist/http/Response.js +303 -0
- package/dist/http/Response.js.map +1 -0
- package/dist/http/SseStream.d.ts +89 -0
- package/dist/http/SseStream.d.ts.map +1 -0
- package/dist/http/SseStream.js +228 -0
- package/dist/http/SseStream.js.map +1 -0
- package/dist/http/urlDecode.d.ts +8 -0
- package/dist/http/urlDecode.d.ts.map +1 -0
- package/dist/http/urlDecode.js +18 -0
- package/dist/http/urlDecode.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/Pipeline.d.ts +36 -0
- package/dist/middleware/Pipeline.d.ts.map +1 -0
- package/dist/middleware/Pipeline.js +104 -0
- package/dist/middleware/Pipeline.js.map +1 -0
- package/dist/openapi/OpenApiGenerator.d.ts +58 -0
- package/dist/openapi/OpenApiGenerator.d.ts.map +1 -0
- package/dist/openapi/OpenApiGenerator.js +192 -0
- package/dist/openapi/OpenApiGenerator.js.map +1 -0
- package/dist/openapi/OpenApiMiddleware.d.ts +24 -0
- package/dist/openapi/OpenApiMiddleware.d.ts.map +1 -0
- package/dist/openapi/OpenApiMiddleware.js +78 -0
- package/dist/openapi/OpenApiMiddleware.js.map +1 -0
- package/dist/openapi/OpenApiProvider.d.ts +36 -0
- package/dist/openapi/OpenApiProvider.d.ts.map +1 -0
- package/dist/openapi/OpenApiProvider.js +42 -0
- package/dist/openapi/OpenApiProvider.js.map +1 -0
- package/dist/resources/ApiResource.d.ts +45 -0
- package/dist/resources/ApiResource.d.ts.map +1 -0
- package/dist/resources/ApiResource.js +58 -0
- package/dist/resources/ApiResource.js.map +1 -0
- package/dist/router/Router.d.ts +205 -0
- package/dist/router/Router.d.ts.map +1 -0
- package/dist/router/Router.js +552 -0
- package/dist/router/Router.js.map +1 -0
- package/dist/rpc/RpcProvider.d.ts +34 -0
- package/dist/rpc/RpcProvider.d.ts.map +1 -0
- package/dist/rpc/RpcProvider.js +37 -0
- package/dist/rpc/RpcProvider.js.map +1 -0
- package/dist/rpc/RpcRouter.d.ts +61 -0
- package/dist/rpc/RpcRouter.d.ts.map +1 -0
- package/dist/rpc/RpcRouter.js +187 -0
- package/dist/rpc/RpcRouter.js.map +1 -0
- package/dist/scheduler/Schedule.d.ts +53 -0
- package/dist/scheduler/Schedule.d.ts.map +1 -0
- package/dist/scheduler/Schedule.js +76 -0
- package/dist/scheduler/Schedule.js.map +1 -0
- package/dist/scheduler/ScheduleProvider.d.ts +56 -0
- package/dist/scheduler/ScheduleProvider.d.ts.map +1 -0
- package/dist/scheduler/ScheduleProvider.js +145 -0
- package/dist/scheduler/ScheduleProvider.js.map +1 -0
- package/dist/scheduler/Scheduler.d.ts +209 -0
- package/dist/scheduler/Scheduler.d.ts.map +1 -0
- package/dist/scheduler/Scheduler.js +432 -0
- package/dist/scheduler/Scheduler.js.map +1 -0
- package/dist/scheduler/index.d.ts +14 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +6 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/locks/LockBackend.d.ts +37 -0
- package/dist/scheduler/locks/LockBackend.d.ts.map +1 -0
- package/dist/scheduler/locks/LockBackend.js +13 -0
- package/dist/scheduler/locks/LockBackend.js.map +1 -0
- package/dist/scheduler/locks/MemoryLockBackend.d.ts +39 -0
- package/dist/scheduler/locks/MemoryLockBackend.d.ts.map +1 -0
- package/dist/scheduler/locks/MemoryLockBackend.js +71 -0
- package/dist/scheduler/locks/MemoryLockBackend.js.map +1 -0
- package/dist/scheduler/observability/ErrorReporter.d.ts +15 -0
- package/dist/scheduler/observability/ErrorReporter.d.ts.map +1 -0
- package/dist/scheduler/observability/ErrorReporter.js +13 -0
- package/dist/scheduler/observability/ErrorReporter.js.map +1 -0
- package/dist/scheduler/observability/ScheduleEvent.d.ts +57 -0
- package/dist/scheduler/observability/ScheduleEvent.d.ts.map +1 -0
- package/dist/scheduler/observability/ScheduleEvent.js +12 -0
- package/dist/scheduler/observability/ScheduleEvent.js.map +1 -0
- package/dist/scheduler/observability/ScheduleEventSink.d.ts +20 -0
- package/dist/scheduler/observability/ScheduleEventSink.d.ts.map +1 -0
- package/dist/scheduler/observability/ScheduleEventSink.js +17 -0
- package/dist/scheduler/observability/ScheduleEventSink.js.map +1 -0
- package/dist/scheduler/observability/StatsTracker.d.ts +50 -0
- package/dist/scheduler/observability/StatsTracker.d.ts.map +1 -0
- package/dist/scheduler/observability/StatsTracker.js +96 -0
- package/dist/scheduler/observability/StatsTracker.js.map +1 -0
- package/dist/security/CookieSigner.d.ts +13 -0
- package/dist/security/CookieSigner.d.ts.map +1 -0
- package/dist/security/CookieSigner.js +51 -0
- package/dist/security/CookieSigner.js.map +1 -0
- package/dist/security/SignedUrl.d.ts +17 -0
- package/dist/security/SignedUrl.d.ts.map +1 -0
- package/dist/security/SignedUrl.js +63 -0
- package/dist/security/SignedUrl.js.map +1 -0
- package/dist/security/crypto.d.ts +25 -0
- package/dist/security/crypto.d.ts.map +1 -0
- package/dist/security/crypto.js +82 -0
- package/dist/security/crypto.js.map +1 -0
- package/dist/server/HyperServer.d.ts +64 -0
- package/dist/server/HyperServer.d.ts.map +1 -0
- package/dist/server/HyperServer.js +54 -0
- package/dist/server/HyperServer.js.map +1 -0
- package/dist/server/Server.d.ts +68 -0
- package/dist/server/Server.d.ts.map +1 -0
- package/dist/server/Server.js +113 -0
- package/dist/server/Server.js.map +1 -0
- package/dist/services/app.d.ts +14 -0
- package/dist/services/app.d.ts.map +1 -0
- package/dist/services/app.js +27 -0
- package/dist/services/app.js.map +1 -0
- package/dist/services/router.d.ts +21 -0
- package/dist/services/router.d.ts.map +1 -0
- package/dist/services/router.js +36 -0
- package/dist/services/router.js.map +1 -0
- package/dist/services/server.d.ts +16 -0
- package/dist/services/server.d.ts.map +1 -0
- package/dist/services/server.js +32 -0
- package/dist/services/server.js.map +1 -0
- package/dist/session/Session.d.ts +88 -0
- package/dist/session/Session.d.ts.map +1 -0
- package/dist/session/Session.js +186 -0
- package/dist/session/Session.js.map +1 -0
- package/dist/session/SessionMiddleware.d.ts +16 -0
- package/dist/session/SessionMiddleware.d.ts.map +1 -0
- package/dist/session/SessionMiddleware.js +132 -0
- package/dist/session/SessionMiddleware.js.map +1 -0
- package/dist/session/drivers/CookieDriver.d.ts +17 -0
- package/dist/session/drivers/CookieDriver.d.ts.map +1 -0
- package/dist/session/drivers/CookieDriver.js +42 -0
- package/dist/session/drivers/CookieDriver.js.map +1 -0
- package/dist/session/drivers/MemoryDriver.d.ts +9 -0
- package/dist/session/drivers/MemoryDriver.d.ts.map +1 -0
- package/dist/session/drivers/MemoryDriver.js +24 -0
- package/dist/session/drivers/MemoryDriver.js.map +1 -0
- package/dist/storage/S3Driver.d.ts +27 -0
- package/dist/storage/S3Driver.d.ts.map +1 -0
- package/dist/storage/S3Driver.js +135 -0
- package/dist/storage/S3Driver.js.map +1 -0
- package/dist/storage/StaticMiddleware.d.ts +27 -0
- package/dist/storage/StaticMiddleware.d.ts.map +1 -0
- package/dist/storage/StaticMiddleware.js +153 -0
- package/dist/storage/StaticMiddleware.js.map +1 -0
- package/dist/storage/StaticProvider.d.ts +26 -0
- package/dist/storage/StaticProvider.d.ts.map +1 -0
- package/dist/storage/StaticProvider.js +31 -0
- package/dist/storage/StaticProvider.js.map +1 -0
- package/dist/storage/StorageManager.d.ts +31 -0
- package/dist/storage/StorageManager.d.ts.map +1 -0
- package/dist/storage/StorageManager.js +120 -0
- package/dist/storage/StorageManager.js.map +1 -0
- package/dist/testing/RequestBuilder.d.ts +67 -0
- package/dist/testing/RequestBuilder.d.ts.map +1 -0
- package/dist/testing/RequestBuilder.js +202 -0
- package/dist/testing/RequestBuilder.js.map +1 -0
- package/dist/testing/TestClient.d.ts +96 -0
- package/dist/testing/TestClient.d.ts.map +1 -0
- package/dist/testing/TestClient.js +263 -0
- package/dist/testing/TestClient.js.map +1 -0
- package/dist/types/helpers.d.ts +47 -0
- package/dist/types/helpers.d.ts.map +1 -0
- package/dist/types/helpers.js +5 -0
- package/dist/types/helpers.js.map +1 -0
- package/events.darwin-arm64.node +0 -0
- package/events.darwin-x64.node +0 -0
- package/events.linux-arm64-gnu.node +0 -0
- package/events.linux-x64-gnu.node +0 -0
- package/events.win32-x64-msvc.node +0 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +106 -0
- package/scheduler.darwin-arm64.node +0 -0
- package/scheduler.darwin-x64.node +0 -0
- package/scheduler.linux-arm64-gnu.node +0 -0
- package/scheduler.linux-x64-gnu.node +0 -0
- package/scheduler.win32-x64-msvc.node +0 -0
- package/scripts/copy-napi.mjs +113 -0
- package/src/Application.ts +177 -0
- package/src/Codemods.ts +343 -0
- package/src/ConfigLoader.ts +49 -0
- package/src/ErrorBoundary.ts +157 -0
- package/src/GracefulShutdown.ts +80 -0
- package/src/HealthCheck.ts +96 -0
- package/src/HotReload.ts +78 -0
- package/src/HttpKernel.ts +305 -0
- package/src/Ignitor.ts +656 -0
- package/src/Provider.ts +74 -0
- package/src/bodyparser/BodyParserMiddleware.ts +183 -0
- package/src/bodyparser/MultipartFile.ts +181 -0
- package/src/bodyparser/parseSize.ts +19 -0
- package/src/bootstrap/hyper-server.ts +78 -0
- package/src/console/CommandRunner.ts +82 -0
- package/src/container/Container.ts +383 -0
- package/src/container/types.ts +30 -0
- package/src/decorators/Lazy.ts +57 -0
- package/src/decorators/Service.ts +85 -0
- package/src/errors/FuzzyMatcher.ts +93 -0
- package/src/errors/ModuleErrors.ts +73 -0
- package/src/errors/PipelineStageError.ts +97 -0
- package/src/errors/ReamError.ts +138 -0
- package/src/events/Emitter.ts +333 -0
- package/src/events/EventsProvider.ts +58 -0
- package/src/events/config.ts +10 -0
- package/src/events/configure.ts +19 -0
- package/src/events/helix/helpers.ts +260 -0
- package/src/events/index.ts +22 -0
- package/src/events/native.ts +37 -0
- package/src/events/services/main.ts +39 -0
- package/src/events/testing/FakeBus.ts +420 -0
- package/src/graphql/GraphQLEngine.ts +421 -0
- package/src/graphql/GraphQLProvider.ts +59 -0
- package/src/helpers/base64.ts +72 -0
- package/src/helpers/index.ts +6 -0
- package/src/helpers/is.ts +162 -0
- package/src/helpers/napi-loader.ts +106 -0
- package/src/helpers/safeEqual.ts +15 -0
- package/src/helpers/string.ts +469 -0
- package/src/helpers/types.ts +100 -0
- package/src/http/Exception.ts +272 -0
- package/src/http/HttpContext.ts +108 -0
- package/src/http/RedirectBuilder.ts +89 -0
- package/src/http/Request.ts +540 -0
- package/src/http/Response.ts +351 -0
- package/src/http/SseStream.ts +250 -0
- package/src/http/urlDecode.ts +18 -0
- package/src/index.ts +263 -0
- package/src/middleware/Pipeline.ts +136 -0
- package/src/openapi/OpenApiGenerator.ts +254 -0
- package/src/openapi/OpenApiMiddleware.ts +101 -0
- package/src/openapi/OpenApiProvider.ts +67 -0
- package/src/resources/ApiResource.ts +79 -0
- package/src/router/Router.ts +733 -0
- package/src/rpc/RpcProvider.ts +54 -0
- package/src/rpc/RpcRouter.ts +243 -0
- package/src/scheduler/Schedule.ts +96 -0
- package/src/scheduler/ScheduleProvider.ts +177 -0
- package/src/scheduler/Scheduler.ts +601 -0
- package/src/scheduler/index.ts +24 -0
- package/src/scheduler/locks/LockBackend.ts +38 -0
- package/src/scheduler/locks/MemoryLockBackend.ts +85 -0
- package/src/scheduler/observability/ErrorReporter.ts +13 -0
- package/src/scheduler/observability/ScheduleEvent.ts +61 -0
- package/src/scheduler/observability/ScheduleEventSink.ts +21 -0
- package/src/scheduler/observability/StatsTracker.ts +134 -0
- package/src/security/CookieSigner.ts +54 -0
- package/src/security/SignedUrl.ts +71 -0
- package/src/security/crypto.ts +98 -0
- package/src/server/HyperServer.ts +121 -0
- package/src/server/Server.ts +147 -0
- package/src/services/app.ts +34 -0
- package/src/services/router.ts +44 -0
- package/src/services/server.ts +40 -0
- package/src/session/Session.ts +231 -0
- package/src/session/SessionMiddleware.ts +153 -0
- package/src/session/drivers/CookieDriver.ts +48 -0
- package/src/session/drivers/MemoryDriver.ts +29 -0
- package/src/storage/S3Driver.ts +171 -0
- package/src/storage/StaticMiddleware.ts +182 -0
- package/src/storage/StaticProvider.ts +40 -0
- package/src/storage/StorageManager.ts +142 -0
- package/src/testing/RequestBuilder.ts +275 -0
- package/src/testing/TestClient.ts +344 -0
- package/src/types/helpers.ts +52 -0
- package/swcrc.app.json +17 -0
- package/tsconfig.app.json +21 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exception system — AdonisJS-compatible exception handling.
|
|
3
|
+
*
|
|
4
|
+
* - Exception: base class with self-handling support
|
|
5
|
+
* - ExceptionHandler: global exception handler with content negotiation
|
|
6
|
+
* - Built-in E_* exceptions
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { HttpContext } from './HttpContext.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base exception class. Extend this to create self-handling exceptions.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* throw new Exception('Something went wrong', { status: 400, code: 'E_BAD_REQUEST' })
|
|
16
|
+
*
|
|
17
|
+
* Self-handled exception:
|
|
18
|
+
* class PaymentFailed extends Exception {
|
|
19
|
+
* static status = 402
|
|
20
|
+
* static code = 'E_PAYMENT_FAILED'
|
|
21
|
+
* async handle(error: this, ctx: HttpContext) {
|
|
22
|
+
* ctx.response.status(402).json({ error: 'Payment failed' })
|
|
23
|
+
* }
|
|
24
|
+
* async report(error: this, ctx: HttpContext) {
|
|
25
|
+
* logger.error('Payment failed', { userId: ctx.auth.user?.id })
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
export class Exception extends Error {
|
|
30
|
+
static status = 500
|
|
31
|
+
static code = 'E_UNKNOWN'
|
|
32
|
+
|
|
33
|
+
status: number
|
|
34
|
+
code: string
|
|
35
|
+
|
|
36
|
+
constructor(message: string, options?: { status?: number; code?: string }) {
|
|
37
|
+
super(message)
|
|
38
|
+
this.name = this.constructor.name
|
|
39
|
+
// biome-ignore lint/suspicious/noExplicitAny: this.constructor is typed as Function; subclass pattern requires the cast
|
|
40
|
+
const ctor = this.constructor as any as typeof Exception
|
|
41
|
+
this.status = options?.status ?? ctor.status
|
|
42
|
+
this.code = options?.code ?? ctor.code
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Override to self-handle the exception (convert to HTTP response). */
|
|
46
|
+
handle?(error: this, ctx: HttpContext): Promise<void> | void
|
|
47
|
+
|
|
48
|
+
/** Override to report the exception (logging, monitoring). Never send HTTP from here. */
|
|
49
|
+
report?(error: this, ctx: HttpContext): Promise<void> | void
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ─── Built-in exceptions ──────────────────────────────────
|
|
53
|
+
|
|
54
|
+
export class E_ROUTE_NOT_FOUND extends Exception {
|
|
55
|
+
static override status = 404
|
|
56
|
+
static override code = 'E_ROUTE_NOT_FOUND'
|
|
57
|
+
|
|
58
|
+
constructor(method: string, path: string) {
|
|
59
|
+
super(`Route not found: ${method} ${path}`, { status: 404, code: 'E_ROUTE_NOT_FOUND' })
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class E_UNAUTHORIZED extends Exception {
|
|
64
|
+
static override status = 401
|
|
65
|
+
static override code = 'E_UNAUTHORIZED'
|
|
66
|
+
|
|
67
|
+
constructor(message = 'Authentication required') {
|
|
68
|
+
super(message, { status: 401, code: 'E_UNAUTHORIZED' })
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override handle(_error: this, ctx: HttpContext): void {
|
|
72
|
+
ctx.response.status(401).json({ error: { code: 'E_UNAUTHORIZED', message: this.message } })
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export class E_FORBIDDEN extends Exception {
|
|
77
|
+
static override status = 403
|
|
78
|
+
static override code = 'E_FORBIDDEN'
|
|
79
|
+
|
|
80
|
+
required?: string[]
|
|
81
|
+
|
|
82
|
+
constructor(message = 'Insufficient permissions', required?: string[]) {
|
|
83
|
+
super(message, { status: 403, code: 'E_FORBIDDEN' })
|
|
84
|
+
this.required = required
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
override handle(_error: this, ctx: HttpContext): void {
|
|
88
|
+
ctx.response.status(403).json({
|
|
89
|
+
error: {
|
|
90
|
+
code: 'E_FORBIDDEN',
|
|
91
|
+
message: this.message,
|
|
92
|
+
...(this.required ? { required: this.required } : {}),
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export class E_VALIDATION_ERROR extends Exception {
|
|
99
|
+
static override status = 422
|
|
100
|
+
static override code = 'E_VALIDATION_ERROR'
|
|
101
|
+
|
|
102
|
+
errors: unknown[]
|
|
103
|
+
|
|
104
|
+
constructor(errors: unknown[]) {
|
|
105
|
+
super('Validation failed', { status: 422, code: 'E_VALIDATION_ERROR' })
|
|
106
|
+
this.errors = errors
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
override handle(_error: this, ctx: HttpContext): void {
|
|
110
|
+
ctx.response.status(422).json({ errors: this.errors })
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export class E_ROW_NOT_FOUND extends Exception {
|
|
115
|
+
static override status = 404
|
|
116
|
+
static override code = 'E_ROW_NOT_FOUND'
|
|
117
|
+
|
|
118
|
+
constructor(model?: string) {
|
|
119
|
+
super(model ? `${model} not found` : 'Resource not found', {
|
|
120
|
+
status: 404,
|
|
121
|
+
code: 'E_ROW_NOT_FOUND',
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override handle(_error: this, ctx: HttpContext): void {
|
|
126
|
+
ctx.response.status(404).json({ error: { code: 'E_ROW_NOT_FOUND', message: this.message } })
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export class E_HTTP_EXCEPTION extends Exception {
|
|
131
|
+
constructor(message: string, status: number) {
|
|
132
|
+
super(message, { status, code: 'E_HTTP_EXCEPTION' })
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ─── ExceptionHandler ─────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Global exception handler — catches all unhandled exceptions and converts
|
|
140
|
+
* them to HTTP responses.
|
|
141
|
+
*
|
|
142
|
+
* Extend this in your app:
|
|
143
|
+
* export default class Handler extends ExceptionHandler {
|
|
144
|
+
* protected debug = app.inDev
|
|
145
|
+
* protected ignoreStatuses = [400, 401, 404, 422]
|
|
146
|
+
* }
|
|
147
|
+
*
|
|
148
|
+
* Flow:
|
|
149
|
+
* 1. If exception has handle() → self-handled (bypass global)
|
|
150
|
+
* 2. Else → this.handle() → content negotiation (JSON or HTML)
|
|
151
|
+
* 3. Then → this.report() → logging/monitoring
|
|
152
|
+
*/
|
|
153
|
+
export class ExceptionHandler {
|
|
154
|
+
protected debug: boolean
|
|
155
|
+
protected ignoreStatuses: number[] = [400, 401, 404, 422]
|
|
156
|
+
protected ignoreCodes: string[] = []
|
|
157
|
+
|
|
158
|
+
constructor(debug = false) {
|
|
159
|
+
this.debug = debug
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Convert an exception to an HTTP response. */
|
|
163
|
+
async handle(error: unknown, ctx: HttpContext): Promise<void> {
|
|
164
|
+
// Self-handled exceptions take over entirely.
|
|
165
|
+
if (error instanceof Exception && typeof error.handle === 'function') {
|
|
166
|
+
await error.handle(error, ctx)
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const { status, code } = extractErrorMeta(error)
|
|
171
|
+
const message = this.#errorMessage(error)
|
|
172
|
+
if (wantsJson(ctx)) {
|
|
173
|
+
this.#sendJsonError(ctx, status, code, message, error)
|
|
174
|
+
} else {
|
|
175
|
+
this.#sendHtmlError(ctx, status, message)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Pick the user-facing message — full detail only in debug mode. */
|
|
180
|
+
#errorMessage(error: unknown): string {
|
|
181
|
+
if (this.debug && error instanceof Error) return error.message
|
|
182
|
+
if (error instanceof Exception) return error.message
|
|
183
|
+
return 'An internal error occurred'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
#sendJsonError(
|
|
187
|
+
ctx: HttpContext,
|
|
188
|
+
status: number,
|
|
189
|
+
code: string,
|
|
190
|
+
message: string,
|
|
191
|
+
error: unknown,
|
|
192
|
+
): void {
|
|
193
|
+
const errorPayload: Record<string, unknown> = { code, message }
|
|
194
|
+
if (this.debug && error instanceof Error && error.stack) {
|
|
195
|
+
errorPayload.stack = error.stack
|
|
196
|
+
}
|
|
197
|
+
ctx.response.status(status).json({ error: errorPayload })
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
#sendHtmlError(ctx: HttpContext, status: number, message: string): void {
|
|
201
|
+
ctx.response
|
|
202
|
+
.status(status)
|
|
203
|
+
.type('text/html; charset=utf-8')
|
|
204
|
+
.send(
|
|
205
|
+
`<!DOCTYPE html><html><head><title>Error ${status}</title></head>` +
|
|
206
|
+
`<body><h1>${status}</h1><p>${escapeHtml(message)}</p></body></html>`,
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Log/report an exception. Override for custom monitoring. */
|
|
211
|
+
async report(error: unknown, ctx: HttpContext): Promise<void> {
|
|
212
|
+
if (error instanceof Exception) {
|
|
213
|
+
if (this.ignoreStatuses.includes(error.status)) return
|
|
214
|
+
if (this.ignoreCodes.includes(error.code)) return
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Self-reported exceptions
|
|
218
|
+
if (error instanceof Exception && typeof error.report === 'function') {
|
|
219
|
+
await error.report(error, ctx)
|
|
220
|
+
return
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Default: log to stderr
|
|
224
|
+
const context = this.context(ctx)
|
|
225
|
+
if (error instanceof Error) {
|
|
226
|
+
console.error(`[${new Date().toISOString()}] ${error.message}`, context, error.stack)
|
|
227
|
+
} else {
|
|
228
|
+
console.error(`[${new Date().toISOString()}] Unknown error:`, error, context)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Provide additional context for error reports. Override for custom data. */
|
|
233
|
+
protected context(ctx: HttpContext): Record<string, unknown> {
|
|
234
|
+
return {
|
|
235
|
+
requestId: ctx.id,
|
|
236
|
+
method: ctx.request.method(),
|
|
237
|
+
url: ctx.request.url(),
|
|
238
|
+
userId: ctx.auth.user?.id,
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Extract status + code from an Exception, ReamError, or duck-typed error. */
|
|
244
|
+
function extractErrorMeta(error: unknown): { status: number; code: string } {
|
|
245
|
+
let status = 500
|
|
246
|
+
let code = 'E_UNKNOWN'
|
|
247
|
+
if (error instanceof Exception) {
|
|
248
|
+
status = error.status
|
|
249
|
+
code = error.code
|
|
250
|
+
} else if (error !== null && typeof error === 'object') {
|
|
251
|
+
if ('status' in error && typeof error.status === 'number') status = error.status
|
|
252
|
+
if ('code' in error && typeof error.code === 'string') code = error.code
|
|
253
|
+
}
|
|
254
|
+
return { status, code }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Content negotiation: JSON unless the client explicitly prefers HTML. */
|
|
258
|
+
function wantsJson(ctx: HttpContext): boolean {
|
|
259
|
+
return (
|
|
260
|
+
ctx.request.accepts(['json', 'html']) === 'json' ||
|
|
261
|
+
(ctx.request.header('accept')?.includes('application/json') ?? false) ||
|
|
262
|
+
!ctx.request.header('accept')?.includes('text/html')
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function escapeHtml(str: string): string {
|
|
267
|
+
return str
|
|
268
|
+
.replace(/&/g, '&')
|
|
269
|
+
.replace(/</g, '<')
|
|
270
|
+
.replace(/>/g, '>')
|
|
271
|
+
.replace(/"/g, '"')
|
|
272
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpContext — fully typed HTTP context for handlers, middleware, and controllers.
|
|
3
|
+
*
|
|
4
|
+
* Replaces Context.http() for HTTP transport. Always has request + response (no ! assertions).
|
|
5
|
+
* Compatible with AdonisJS destructuring: { request, response, auth, params }
|
|
6
|
+
*
|
|
7
|
+
* @implements FR21
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Emitter } from '../events/Emitter.js'
|
|
11
|
+
import type { RouteUrlResolver } from './RedirectBuilder.js'
|
|
12
|
+
import { RedirectBuilder } from './RedirectBuilder.js'
|
|
13
|
+
import type { RawRequest } from './Request.js'
|
|
14
|
+
import { Request } from './Request.js'
|
|
15
|
+
import { Response } from './Response.js'
|
|
16
|
+
|
|
17
|
+
export interface AuthState {
|
|
18
|
+
authenticated: boolean
|
|
19
|
+
user?: {
|
|
20
|
+
id: string
|
|
21
|
+
email?: string
|
|
22
|
+
roles?: string[]
|
|
23
|
+
permissions?: string[]
|
|
24
|
+
[key: string]: unknown
|
|
25
|
+
}
|
|
26
|
+
roles?: string[]
|
|
27
|
+
permissions?: string[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface RouteInfo {
|
|
31
|
+
pattern: string
|
|
32
|
+
name?: string
|
|
33
|
+
middleware: string[]
|
|
34
|
+
/**
|
|
35
|
+
* Controller class + method that owns this route, when the route was
|
|
36
|
+
* registered as `router.get('/x', SomeController, 'method')` (vs an
|
|
37
|
+
* inline arrow handler). Middleware that reads decorator metadata —
|
|
38
|
+
* `@Guard`, `@Permission`, `@Role` (Warden), `@Meta` (Photon) —
|
|
39
|
+
* needs both fields. Absent when the route handler is an inline
|
|
40
|
+
* function. Populated by `HttpKernel` from `match.route.controller`.
|
|
41
|
+
*/
|
|
42
|
+
controller?: object
|
|
43
|
+
action?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class HttpContext {
|
|
47
|
+
/** Unique request/correlation ID. */
|
|
48
|
+
readonly id: string
|
|
49
|
+
|
|
50
|
+
/** Typed HTTP request. */
|
|
51
|
+
readonly request: Request
|
|
52
|
+
|
|
53
|
+
/** Typed HTTP response builder. */
|
|
54
|
+
readonly response: Response
|
|
55
|
+
|
|
56
|
+
/** Route parameters extracted from the URL pattern. */
|
|
57
|
+
readonly params: Record<string, string>
|
|
58
|
+
|
|
59
|
+
/** Information about the matched route. */
|
|
60
|
+
readonly route: RouteInfo
|
|
61
|
+
|
|
62
|
+
/** Authentication state — populated by auth middleware. */
|
|
63
|
+
auth: AuthState = { authenticated: false }
|
|
64
|
+
|
|
65
|
+
/** Detected locale. */
|
|
66
|
+
locale = 'en'
|
|
67
|
+
|
|
68
|
+
/** Per-request key-value store (for middleware to pass data downstream). */
|
|
69
|
+
readonly store: Map<string, unknown> = new Map()
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The event bus emitter, when the app registered `EventsProvider`. Lets a
|
|
73
|
+
* handler emit/subscribe without resolving from the container:
|
|
74
|
+
* `ctx.events?.emit('user:updated', user)`. Undefined when events aren't wired.
|
|
75
|
+
*/
|
|
76
|
+
events?: Emitter
|
|
77
|
+
|
|
78
|
+
/** Route URL resolver for redirect().toRoute(). */
|
|
79
|
+
#routeUrlResolver?: RouteUrlResolver
|
|
80
|
+
|
|
81
|
+
constructor(
|
|
82
|
+
id: string,
|
|
83
|
+
rawRequest: RawRequest,
|
|
84
|
+
params: Record<string, string>,
|
|
85
|
+
route: RouteInfo,
|
|
86
|
+
) {
|
|
87
|
+
this.id = id
|
|
88
|
+
this.params = params
|
|
89
|
+
this.route = route
|
|
90
|
+
this.request = new Request(rawRequest, params)
|
|
91
|
+
this.response = new Response()
|
|
92
|
+
|
|
93
|
+
// Wire redirect builder with request context
|
|
94
|
+
this.response.setRedirectFactory(
|
|
95
|
+
() =>
|
|
96
|
+
new RedirectBuilder(this.response, {
|
|
97
|
+
requestUrl: this.request.url(),
|
|
98
|
+
requestReferer: this.request.header('referer'),
|
|
99
|
+
routeUrlResolver: this.#routeUrlResolver,
|
|
100
|
+
}),
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** @internal Set the route URL resolver (injected by HttpKernel from Router). */
|
|
105
|
+
setRouteUrlResolver(resolver: RouteUrlResolver): void {
|
|
106
|
+
this.#routeUrlResolver = resolver
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RedirectBuilder — fluent API for building redirect responses.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* response.redirect().toPath('/login')
|
|
6
|
+
* response.redirect().status(301).toPath('/new-url')
|
|
7
|
+
* response.redirect().back()
|
|
8
|
+
* response.redirect().withQs({ page: '2' }).toPath('/results')
|
|
9
|
+
* response.redirect().toRoute('posts.show', { id: '42' })
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Response } from './Response.js'
|
|
13
|
+
|
|
14
|
+
export type RouteUrlResolver = (name: string, params?: Record<string, string>) => string
|
|
15
|
+
|
|
16
|
+
export class RedirectBuilder {
|
|
17
|
+
#response: Response
|
|
18
|
+
#status = 302
|
|
19
|
+
#qs: Record<string, string> | null = null
|
|
20
|
+
#forwardQs = false
|
|
21
|
+
#requestUrl?: string
|
|
22
|
+
#requestReferer?: string
|
|
23
|
+
#routeUrlResolver?: RouteUrlResolver
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
response: Response,
|
|
27
|
+
options?: {
|
|
28
|
+
requestUrl?: string
|
|
29
|
+
requestReferer?: string
|
|
30
|
+
routeUrlResolver?: RouteUrlResolver
|
|
31
|
+
},
|
|
32
|
+
) {
|
|
33
|
+
this.#response = response
|
|
34
|
+
this.#requestUrl = options?.requestUrl
|
|
35
|
+
this.#requestReferer = options?.requestReferer
|
|
36
|
+
this.#routeUrlResolver = options?.routeUrlResolver
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Set redirect status code. */
|
|
40
|
+
status(code: number): this {
|
|
41
|
+
this.#status = code
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Forward current query string to the redirect target. */
|
|
46
|
+
withQs(qs?: Record<string, string>): this {
|
|
47
|
+
if (qs) {
|
|
48
|
+
this.#qs = qs
|
|
49
|
+
} else {
|
|
50
|
+
this.#forwardQs = true
|
|
51
|
+
}
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Redirect to an absolute or relative path. */
|
|
56
|
+
toPath(path: string): void {
|
|
57
|
+
const url = this.#appendQs(path)
|
|
58
|
+
this.#response.status(this.#status)
|
|
59
|
+
this.#response.header('location', url)
|
|
60
|
+
this.#response.setBody('')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Redirect to a named route. */
|
|
64
|
+
toRoute(name: string, params?: Record<string, string>): void {
|
|
65
|
+
if (!this.#routeUrlResolver) {
|
|
66
|
+
throw new Error('Route URL resolver not configured. Cannot redirect to named route.')
|
|
67
|
+
}
|
|
68
|
+
const path = this.#routeUrlResolver(name, params)
|
|
69
|
+
this.toPath(path)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Redirect back to the previous page (Referer header). */
|
|
73
|
+
back(fallback = '/'): void {
|
|
74
|
+
const referer = this.#requestReferer ?? fallback
|
|
75
|
+
this.toPath(referer)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#appendQs(path: string): string {
|
|
79
|
+
let qs = ''
|
|
80
|
+
if (this.#qs) {
|
|
81
|
+
qs = new URLSearchParams(this.#qs).toString()
|
|
82
|
+
} else if (this.#forwardQs && this.#requestUrl) {
|
|
83
|
+
const qsIdx = this.#requestUrl.indexOf('?')
|
|
84
|
+
if (qsIdx !== -1) qs = this.#requestUrl.slice(qsIdx + 1)
|
|
85
|
+
}
|
|
86
|
+
if (!qs) return path
|
|
87
|
+
return path.includes('?') ? `${path}&${qs}` : `${path}?${qs}`
|
|
88
|
+
}
|
|
89
|
+
}
|