@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,469 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto'
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Internal helpers
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Split an arbitrary-cased string into lowercase words.
|
|
9
|
+
* Handles camelCase, PascalCase, snake_case, kebab-case, and space-separated.
|
|
10
|
+
*/
|
|
11
|
+
function splitWords(s: string): string[] {
|
|
12
|
+
return (
|
|
13
|
+
s
|
|
14
|
+
// Insert space before uppercase letters that follow lowercase letters or digits
|
|
15
|
+
.replace(/([a-z\d])([A-Z])/g, '$1 $2')
|
|
16
|
+
// Insert space before uppercase letters followed by lowercase (handles "XMLParser" -> "XML Parser")
|
|
17
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
|
|
18
|
+
// Replace non-alphanumeric separators with space
|
|
19
|
+
.replace(/[\s\-_]+/g, ' ')
|
|
20
|
+
.trim()
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.split(' ')
|
|
23
|
+
.filter((w) => w.length > 0)
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Case conversion
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Converts a string to camelCase.
|
|
33
|
+
* @example camelCase('user_name') // 'userName'
|
|
34
|
+
*/
|
|
35
|
+
export function camelCase(s: string): string {
|
|
36
|
+
const words = splitWords(s)
|
|
37
|
+
return words.map((w, i) => (i === 0 ? w : w.charAt(0).toUpperCase() + w.slice(1))).join('')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Converts a string to snake_case.
|
|
42
|
+
* @example snakeCase('userName') // 'user_name'
|
|
43
|
+
*/
|
|
44
|
+
export function snakeCase(s: string): string {
|
|
45
|
+
return splitWords(s).join('_')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Converts a string to PascalCase.
|
|
50
|
+
* @example pascalCase('user team') // 'UserTeam'
|
|
51
|
+
*/
|
|
52
|
+
export function pascalCase(s: string): string {
|
|
53
|
+
return splitWords(s)
|
|
54
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
55
|
+
.join('')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Converts a string to dash-case (kebab-case). Optionally capitalizes each segment.
|
|
60
|
+
* @example dashCase('helloWorld') // 'hello-world'
|
|
61
|
+
* @example dashCase('helloWorld', { capitalize: true }) // 'Hello-World'
|
|
62
|
+
*/
|
|
63
|
+
export function dashCase(s: string, options?: { capitalize?: boolean }): string {
|
|
64
|
+
const words = splitWords(s)
|
|
65
|
+
const segments = options?.capitalize
|
|
66
|
+
? words.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
67
|
+
: words
|
|
68
|
+
return segments.join('-')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts a string to Title Case.
|
|
73
|
+
* @example titleCase('hello world') // 'Hello World'
|
|
74
|
+
*/
|
|
75
|
+
export function titleCase(s: string): string {
|
|
76
|
+
return splitWords(s)
|
|
77
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
78
|
+
.join(' ')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Converts a snake_case/camelCase string to a human-readable form.
|
|
83
|
+
* @example humanize('user_name') // 'User name'
|
|
84
|
+
*/
|
|
85
|
+
export function humanize(s: string): string {
|
|
86
|
+
const words = splitWords(s)
|
|
87
|
+
if (words.length === 0) return ''
|
|
88
|
+
return [words[0]?.charAt(0).toUpperCase() + words[0]?.slice(1), ...words.slice(1)].join(' ')
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Truncation / excerpt
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Truncates a string to maxLength characters.
|
|
97
|
+
* @example truncate('Hello world', 8) // 'Hello wo...'
|
|
98
|
+
*/
|
|
99
|
+
export function truncate(
|
|
100
|
+
text: string,
|
|
101
|
+
maxLength: number,
|
|
102
|
+
options?: { completeWords?: boolean; suffix?: string },
|
|
103
|
+
): string {
|
|
104
|
+
const suffix = options?.suffix !== undefined ? options.suffix : '...'
|
|
105
|
+
if (text.length <= maxLength) return text
|
|
106
|
+
const limit = maxLength - suffix.length
|
|
107
|
+
if (limit <= 0) return suffix.slice(0, maxLength)
|
|
108
|
+
if (options?.completeWords) {
|
|
109
|
+
const truncated = text.slice(0, limit)
|
|
110
|
+
const lastSpace = truncated.lastIndexOf(' ')
|
|
111
|
+
return (lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated) + suffix
|
|
112
|
+
}
|
|
113
|
+
return text.slice(0, limit) + suffix
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Strips HTML tags then truncates. See `truncate` for options.
|
|
118
|
+
* @example excerpt('<p>Hello world</p>', 8) // 'Hello wo...'
|
|
119
|
+
*/
|
|
120
|
+
export function excerpt(
|
|
121
|
+
text: string,
|
|
122
|
+
maxLength: number,
|
|
123
|
+
options?: { completeWords?: boolean; suffix?: string },
|
|
124
|
+
): string {
|
|
125
|
+
const stripped = text.replace(/<[^>]*>/g, '')
|
|
126
|
+
return truncate(stripped, maxLength, options)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// HTML / escaping
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
const HTML_ESCAPE_MAP: Record<string, string> = {
|
|
134
|
+
'&': '&',
|
|
135
|
+
'<': '<',
|
|
136
|
+
'>': '>',
|
|
137
|
+
'"': '"',
|
|
138
|
+
"'": ''',
|
|
139
|
+
'`': '`',
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Escapes HTML special characters. Optionally encodes non-ASCII characters as numeric entities.
|
|
144
|
+
* @example escapeHTML('<b>hi</b>') // '<b>hi</b>'
|
|
145
|
+
*/
|
|
146
|
+
export function escapeHTML(text: string, options?: { encodeSymbols?: boolean }): string {
|
|
147
|
+
let result = text.replace(/[&<>"'`]/g, (ch) => HTML_ESCAPE_MAP[ch] ?? ch)
|
|
148
|
+
if (options?.encodeSymbols) {
|
|
149
|
+
result = result.replace(/[\u0080-\uFFFF]/g, (ch) => {
|
|
150
|
+
const code = ch.codePointAt(0)
|
|
151
|
+
return code !== undefined ? `&#x${code.toString(16).toUpperCase()};` : ch
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
return result
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Encodes only non-ASCII characters as &#xHEX; numeric entities.
|
|
159
|
+
* @example encodeSymbols('héllo') // 'héllo'
|
|
160
|
+
*/
|
|
161
|
+
export function encodeSymbols(text: string): string {
|
|
162
|
+
return text.replace(/[\u0080-\uFFFF]/g, (ch) => {
|
|
163
|
+
const code = ch.codePointAt(0)
|
|
164
|
+
return code !== undefined ? `&#x${code.toString(16).toUpperCase()};` : ch
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// Whitespace / checks
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Returns true if the string is empty or contains only whitespace.
|
|
174
|
+
* @example isEmpty(' ') // true
|
|
175
|
+
*/
|
|
176
|
+
export function isEmpty(value: string): boolean {
|
|
177
|
+
return value.trim().length === 0
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Trims a string and collapses internal whitespace sequences to a single space.
|
|
182
|
+
* @example condenseWhitespace(' hello world ') // 'hello world'
|
|
183
|
+
*/
|
|
184
|
+
export function condenseWhitespace(s: string): string {
|
|
185
|
+
return s.trim().replace(/\s+/g, ' ')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// Slugs
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Converts a string to a URL-friendly slug.
|
|
194
|
+
* @example slug('Hello World!') // 'hello-world'
|
|
195
|
+
*/
|
|
196
|
+
export function slug(
|
|
197
|
+
text: string,
|
|
198
|
+
options?: { replacement?: string; lower?: boolean; strict?: boolean },
|
|
199
|
+
): string {
|
|
200
|
+
const replacement = options?.replacement !== undefined ? options.replacement : '-'
|
|
201
|
+
const lower = options?.lower !== false
|
|
202
|
+
const strict = options?.strict === true
|
|
203
|
+
|
|
204
|
+
let result = lower ? text.toLowerCase() : text
|
|
205
|
+
|
|
206
|
+
if (strict) {
|
|
207
|
+
result = result.replace(/[^a-zA-Z0-9\s]/g, '')
|
|
208
|
+
} else {
|
|
209
|
+
result = result.replace(/[^\w\s-]/g, '')
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
result = result
|
|
213
|
+
.replace(/[\s_]+/g, replacement)
|
|
214
|
+
.replace(new RegExp(`${escapeForRegex(replacement)}+`, 'g'), replacement)
|
|
215
|
+
.replace(new RegExp(`^${escapeForRegex(replacement)}|${escapeForRegex(replacement)}$`, 'g'), '')
|
|
216
|
+
|
|
217
|
+
return result
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function escapeForRegex(s: string): string {
|
|
221
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
// Pluralization
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
|
|
228
|
+
const IRREGULAR_PLURAL: Record<string, string> = {
|
|
229
|
+
person: 'people',
|
|
230
|
+
child: 'children',
|
|
231
|
+
foot: 'feet',
|
|
232
|
+
mouse: 'mice',
|
|
233
|
+
man: 'men',
|
|
234
|
+
woman: 'women',
|
|
235
|
+
tooth: 'teeth',
|
|
236
|
+
goose: 'geese',
|
|
237
|
+
ox: 'oxen',
|
|
238
|
+
leaf: 'leaves',
|
|
239
|
+
half: 'halves',
|
|
240
|
+
knife: 'knives',
|
|
241
|
+
life: 'lives',
|
|
242
|
+
wife: 'wives',
|
|
243
|
+
wolf: 'wolves',
|
|
244
|
+
loaf: 'loaves',
|
|
245
|
+
potato: 'potatoes',
|
|
246
|
+
tomato: 'tomatoes',
|
|
247
|
+
cactus: 'cacti',
|
|
248
|
+
focus: 'foci',
|
|
249
|
+
fungus: 'fungi',
|
|
250
|
+
nucleus: 'nuclei',
|
|
251
|
+
syllabus: 'syllabi',
|
|
252
|
+
analysis: 'analyses',
|
|
253
|
+
diagnosis: 'diagnoses',
|
|
254
|
+
oasis: 'oases',
|
|
255
|
+
thesis: 'theses',
|
|
256
|
+
crisis: 'crises',
|
|
257
|
+
phenomenon: 'phenomena',
|
|
258
|
+
criterion: 'criteria',
|
|
259
|
+
datum: 'data',
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const IRREGULAR_SINGULAR: Record<string, string> = Object.fromEntries(
|
|
263
|
+
Object.entries(IRREGULAR_PLURAL).map(([s, p]) => [p, s]),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
const UNCOUNTABLE = new Set([
|
|
267
|
+
'sheep',
|
|
268
|
+
'fish',
|
|
269
|
+
'deer',
|
|
270
|
+
'series',
|
|
271
|
+
'species',
|
|
272
|
+
'money',
|
|
273
|
+
'rice',
|
|
274
|
+
'information',
|
|
275
|
+
'equipment',
|
|
276
|
+
'aircraft',
|
|
277
|
+
'police',
|
|
278
|
+
])
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Returns the plural form of an English word.
|
|
282
|
+
* @example plural('person') // 'people'; plural('box') // 'boxes'
|
|
283
|
+
*/
|
|
284
|
+
export function plural(word: string): string {
|
|
285
|
+
const lower = word.toLowerCase()
|
|
286
|
+
if (UNCOUNTABLE.has(lower)) return word
|
|
287
|
+
const irregular = IRREGULAR_PLURAL[lower]
|
|
288
|
+
if (irregular) return irregular
|
|
289
|
+
if (/(?:s|x|z|ch|sh)$/i.test(word)) return `${word}es`
|
|
290
|
+
if (/[^aeiou]y$/i.test(word)) return `${word.slice(0, -1)}ies`
|
|
291
|
+
if (/f$/i.test(word)) return `${word.slice(0, -1)}ves`
|
|
292
|
+
if (/fe$/i.test(word)) return `${word.slice(0, -2)}ves`
|
|
293
|
+
return `${word}s`
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Returns the singular form of an English word.
|
|
298
|
+
* @example singular('people') // 'person'; singular('boxes') // 'box'
|
|
299
|
+
*/
|
|
300
|
+
export function singular(word: string): string {
|
|
301
|
+
const lower = word.toLowerCase()
|
|
302
|
+
if (UNCOUNTABLE.has(lower)) return word
|
|
303
|
+
const irregular = IRREGULAR_SINGULAR[lower]
|
|
304
|
+
if (irregular) return irregular
|
|
305
|
+
if (/ves$/i.test(word)) {
|
|
306
|
+
const base = word.slice(0, -3)
|
|
307
|
+
if (/[lw]$/i.test(base)) return `${base}f`
|
|
308
|
+
return `${base}fe`
|
|
309
|
+
}
|
|
310
|
+
if (/ies$/i.test(word)) return `${word.slice(0, -3)}y`
|
|
311
|
+
if (/(?:s|x|z|ch|sh)es$/i.test(word)) return word.slice(0, -2)
|
|
312
|
+
if (/s$/i.test(word) && !/ss$/i.test(word)) return word.slice(0, -1)
|
|
313
|
+
return word
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Returns true if the word appears to be plural.
|
|
318
|
+
* @example isPlural('dogs') // true
|
|
319
|
+
*/
|
|
320
|
+
export function isPlural(word: string): boolean {
|
|
321
|
+
const lower = word.toLowerCase()
|
|
322
|
+
if (UNCOUNTABLE.has(lower)) return true
|
|
323
|
+
return lower !== singular(lower)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Returns true if the word appears to be singular.
|
|
328
|
+
* @example isSingular('dog') // true
|
|
329
|
+
*/
|
|
330
|
+
export function isSingular(word: string): boolean {
|
|
331
|
+
const lower = word.toLowerCase()
|
|
332
|
+
if (UNCOUNTABLE.has(lower)) return true
|
|
333
|
+
return singular(lower) === lower
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
// Random / numeric
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Returns a base64url random string of exactly `length` characters.
|
|
342
|
+
* @example random(16) // e.g. 'Xk3mN9pQ2vR7tZ1w'
|
|
343
|
+
*/
|
|
344
|
+
export function random(length: number): string {
|
|
345
|
+
const bytesNeeded = Math.ceil((length * 3) / 4) + 4
|
|
346
|
+
return randomBytes(bytesNeeded).toString('base64url').slice(0, length)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Alias for `random`. Generates a base64url random string of `size` characters.
|
|
351
|
+
* @example generateRandom(16) // e.g. 'Xk3mN9pQ2vR7tZ1w'
|
|
352
|
+
*/
|
|
353
|
+
export function generateRandom(size: number): string {
|
|
354
|
+
return random(size)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Returns the ordinal representation of a number.
|
|
359
|
+
* @example ordinal(1) // '1st'; ordinal(11) // '11th'; ordinal(22) // '22nd'
|
|
360
|
+
*/
|
|
361
|
+
export function ordinal(n: number): string {
|
|
362
|
+
const abs = Math.abs(n)
|
|
363
|
+
const mod100 = abs % 100
|
|
364
|
+
const mod10 = abs % 10
|
|
365
|
+
if (mod100 >= 11 && mod100 <= 13) return `${n}th`
|
|
366
|
+
if (mod10 === 1) return `${n}st`
|
|
367
|
+
if (mod10 === 2) return `${n}nd`
|
|
368
|
+
if (mod10 === 3) return `${n}rd`
|
|
369
|
+
return `${n}th`
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
// Time / path
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Formats an hrtime tuple to a human-readable string.
|
|
378
|
+
* @example prettyHrTime([0, 1234567]) // '1.235 ms'
|
|
379
|
+
* @example prettyHrTime([2, 500000000]) // '2.500 s'
|
|
380
|
+
*/
|
|
381
|
+
export function prettyHrTime(time: [number, number]): string {
|
|
382
|
+
const [seconds, nanoseconds] = time
|
|
383
|
+
const totalNs = seconds * 1e9 + nanoseconds
|
|
384
|
+
const totalMs = totalNs / 1e6
|
|
385
|
+
const totalS = totalNs / 1e9
|
|
386
|
+
|
|
387
|
+
if (totalNs < 1e6) {
|
|
388
|
+
return `${(totalNs / 1e3).toFixed(3)} μs`
|
|
389
|
+
}
|
|
390
|
+
if (totalMs < 1000) {
|
|
391
|
+
return `${totalMs.toFixed(3)} ms`
|
|
392
|
+
}
|
|
393
|
+
if (totalS < 60) {
|
|
394
|
+
return `${totalS.toFixed(3)} s`
|
|
395
|
+
}
|
|
396
|
+
const mins = Math.floor(totalS / 60)
|
|
397
|
+
const secs = totalS - mins * 60
|
|
398
|
+
return `${mins}m ${secs.toFixed(0)}s`
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Converts Windows backslash paths to Unix forward slashes.
|
|
403
|
+
* @example toUnixSlash('C:\\foo\\bar') // 'C:/foo/bar'
|
|
404
|
+
*/
|
|
405
|
+
export function toUnixSlash(p: string): string {
|
|
406
|
+
return p.replace(/\\/g, '/')
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// ---------------------------------------------------------------------------
|
|
410
|
+
// Templating
|
|
411
|
+
// ---------------------------------------------------------------------------
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Interpolates `{{ key.path }}` placeholders in a template string using `data`.
|
|
415
|
+
* Escape with backslash: `\{{` outputs literal `{{`. Missing keys produce empty string.
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* interpolate('Hello {{ user.name }}!', { user: { name: 'Alice' } }) // 'Hello Alice!'
|
|
419
|
+
*/
|
|
420
|
+
export function interpolate(template: string, data: Record<string, unknown>): string {
|
|
421
|
+
return template.replace(
|
|
422
|
+
/\\(\{\{[\s\S]*?\}\})|(\{\{\s*([\w.]+)\s*\}\})/g,
|
|
423
|
+
(match, escaped: string | undefined, _full: string | undefined, path: string | undefined) => {
|
|
424
|
+
if (escaped !== undefined) return escaped
|
|
425
|
+
if (path === undefined) return match
|
|
426
|
+
const keys = path.split('.')
|
|
427
|
+
let current: unknown = data
|
|
428
|
+
for (const key of keys) {
|
|
429
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
430
|
+
return ''
|
|
431
|
+
}
|
|
432
|
+
current = (current as Record<string, unknown>)[key]
|
|
433
|
+
}
|
|
434
|
+
return current !== null && current !== undefined ? String(current) : ''
|
|
435
|
+
},
|
|
436
|
+
)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// ---------------------------------------------------------------------------
|
|
440
|
+
// Default export
|
|
441
|
+
// ---------------------------------------------------------------------------
|
|
442
|
+
|
|
443
|
+
const string = {
|
|
444
|
+
camelCase,
|
|
445
|
+
snakeCase,
|
|
446
|
+
pascalCase,
|
|
447
|
+
dashCase,
|
|
448
|
+
titleCase,
|
|
449
|
+
humanize,
|
|
450
|
+
truncate,
|
|
451
|
+
excerpt,
|
|
452
|
+
escapeHTML,
|
|
453
|
+
encodeSymbols,
|
|
454
|
+
isEmpty,
|
|
455
|
+
condenseWhitespace,
|
|
456
|
+
slug,
|
|
457
|
+
plural,
|
|
458
|
+
singular,
|
|
459
|
+
isPlural,
|
|
460
|
+
isSingular,
|
|
461
|
+
random,
|
|
462
|
+
generateRandom,
|
|
463
|
+
ordinal,
|
|
464
|
+
prettyHrTime,
|
|
465
|
+
toUnixSlash,
|
|
466
|
+
interpolate,
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export default string
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type helpers — utility types for the Ream framework.
|
|
3
|
+
* Pattern aligned with @adonisjs/core/helpers/types.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ─── Already present (kept for backward compat) ───────────
|
|
7
|
+
|
|
8
|
+
/** Infer route parameters from a route pattern string. */
|
|
9
|
+
export type InferRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}`
|
|
10
|
+
? { [K in Param | keyof InferRouteParams<`/${Rest}`>]: string }
|
|
11
|
+
: T extends `${string}:${infer Param}`
|
|
12
|
+
? { [K in Param]: string }
|
|
13
|
+
: Record<string, never>
|
|
14
|
+
|
|
15
|
+
/** Accept a single value or an array. */
|
|
16
|
+
export type OneOrMore<T> = T | T[]
|
|
17
|
+
|
|
18
|
+
/** Create a nominal/opaque type from a base type. */
|
|
19
|
+
export type Opaque<Base, Tag extends string> = Base & { readonly __tag: Tag }
|
|
20
|
+
|
|
21
|
+
/** Unwrap an opaque type back to its base. */
|
|
22
|
+
export type UnwrapOpaque<T> = T extends Opaque<infer Base, string> ? Base : T
|
|
23
|
+
|
|
24
|
+
/** Accept sync or async values. */
|
|
25
|
+
export type AsyncOrSync<T> = T | Promise<T>
|
|
26
|
+
|
|
27
|
+
/** Constructor type. */
|
|
28
|
+
export type Constructor<T = unknown, Args extends unknown[] = unknown[]> = new (...args: Args) => T
|
|
29
|
+
|
|
30
|
+
/** Abstract constructor type. */
|
|
31
|
+
export type AbstractConstructor<T = unknown> = abstract new (...args: unknown[]) => T
|
|
32
|
+
|
|
33
|
+
/** Extract only function property keys from a type, optionally excluding inherited ones. */
|
|
34
|
+
export type ExtractFunctions<T, Ignore extends keyof T = never> = {
|
|
35
|
+
[K in Exclude<keyof T, Ignore>]: T[K] extends (...args: unknown[]) => unknown ? K : never
|
|
36
|
+
}[Exclude<keyof T, Ignore>]
|
|
37
|
+
|
|
38
|
+
/** Prettify a type intersection for better IDE display. */
|
|
39
|
+
export type Prettify<T> = { [K in keyof T]: T[K] } & {}
|
|
40
|
+
|
|
41
|
+
// ─── AdonisJS-style additions ─────────────────────────────
|
|
42
|
+
|
|
43
|
+
/** Extract keys whose value type may be undefined. */
|
|
44
|
+
export type ExtractUndefined<T> = {
|
|
45
|
+
[K in keyof T]-?: undefined extends T[K] ? K : never
|
|
46
|
+
}[keyof T]
|
|
47
|
+
|
|
48
|
+
/** Extract keys whose value type cannot be undefined. */
|
|
49
|
+
export type ExtractDefined<T> = {
|
|
50
|
+
[K in keyof T]-?: undefined extends T[K] ? never : K
|
|
51
|
+
}[keyof T]
|
|
52
|
+
|
|
53
|
+
/** Lazy module import — `() => import('module')` returning a default export. */
|
|
54
|
+
export type LazyImport<T> = () => Promise<{ default: T }>
|
|
55
|
+
|
|
56
|
+
/** Unwrap the default export from a LazyImport type. */
|
|
57
|
+
export type UnWrapLazyImport<T> = T extends LazyImport<infer U> ? U : T
|
|
58
|
+
|
|
59
|
+
/** Unwrap a Promise type to its resolved value. */
|
|
60
|
+
export type UnwrapPromise<T> = T extends Promise<infer U> ? U : T
|
|
61
|
+
|
|
62
|
+
/** Make specific keys optional. */
|
|
63
|
+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
|
|
64
|
+
|
|
65
|
+
/** Make specific keys required. */
|
|
66
|
+
export type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
|
|
67
|
+
|
|
68
|
+
/** Make specific keys nullable. */
|
|
69
|
+
export type MakeNullable<T, K extends keyof T> = Omit<T, K> & { [P in K]: T[P] | null }
|
|
70
|
+
|
|
71
|
+
/** Recursively make all properties optional. */
|
|
72
|
+
export type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T
|
|
73
|
+
|
|
74
|
+
/** Recursively make all properties required. */
|
|
75
|
+
export type DeepRequired<T> = T extends object ? { [K in keyof T]-?: DeepRequired<T[K]> } : T
|
|
76
|
+
|
|
77
|
+
/** Recursively make all properties readonly. */
|
|
78
|
+
export type DeepReadonly<T> = T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T
|
|
79
|
+
|
|
80
|
+
/** An object with no properties (different from `{}` which accepts anything). */
|
|
81
|
+
export type EmptyObject = Record<string, never>
|
|
82
|
+
|
|
83
|
+
/** Extract keys whose value matches a given type. */
|
|
84
|
+
export type ExtractKeysOfType<T, V> = {
|
|
85
|
+
[K in keyof T]: T[K] extends V ? K : never
|
|
86
|
+
}[keyof T]
|
|
87
|
+
|
|
88
|
+
/** All-of: every member of the union must satisfy. */
|
|
89
|
+
export type AllOf<T extends readonly unknown[]> = T extends readonly [infer Head, ...infer Tail]
|
|
90
|
+
? Head & AllOf<Tail>
|
|
91
|
+
: unknown
|
|
92
|
+
|
|
93
|
+
/** None-of: a value that does not match any of the given types. */
|
|
94
|
+
export type NoneOf<T, Excluded> = T extends Excluded ? never : T
|
|
95
|
+
|
|
96
|
+
/** Type guard signature: `(value: unknown) => value is T`. */
|
|
97
|
+
export type TypeGuard<T> = (value: unknown) => value is T
|
|
98
|
+
|
|
99
|
+
/** Brand a primitive with a tag for nominal typing (alias for Opaque, AdonisJS naming). */
|
|
100
|
+
export type Brand<Base, Tag extends string> = Opaque<Base, Tag>
|