From 58574eec0724e622f0e1d7e3ee4dd7218d44ded9 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 5 Sep 2024 11:08:43 +0200 Subject: [PATCH] feat: Use asynchandler library for handlers --- .componentsignore | 3 +- RELEASE_NOTES.md | 38 +++++ config/app/init/base/init.json | 7 +- config/app/init/default.json | 5 +- config/app/init/initialize-intro.json | 5 +- .../app/init/initialize-prefilled-root.json | 5 +- config/app/init/initialize-root-pod.json | 5 +- config/app/init/initialize-root.json | 5 +- config/app/init/migration/base.json | 5 +- config/app/main/default.json | 8 +- config/app/main/general/templates.json | 7 +- config/app/main/general/util.json | 13 ++ config/http/handler/default.json | 7 +- .../handler/handlers/storage-description.json | 7 +- config/http/handler/simple.json | 7 +- config/http/middleware/default.json | 5 +- .../http/notifications/base/description.json | 7 +- config/http/notifications/base/handler.json | 7 +- config/http/notifications/base/http.json | 9 +- config/http/notifications/base/listener.json | 7 +- config/http/notifications/disabled.json | 9 +- .../http/notifications/legacy-websockets.json | 11 +- .../notifications/new-old-websockets.json | 7 +- .../notifications/streaming-http/http.json | 7 +- .../http/notifications/webhooks/handler.json | 7 +- .../http/notifications/webhooks/routes.json | 7 +- .../notifications/websockets/handler.json | 7 +- .../http/notifications/websockets/http.json | 7 +- .../websockets/subscription.json | 7 +- .../server-factory/configurator/default.json | 7 +- config/identity/access/restricted.json | 5 +- config/identity/email/default.json | 10 +- .../handler/base/provider-factory.json | 5 +- config/identity/handler/disabled.json | 9 +- config/identity/handler/enable/account.json | 7 +- .../handler/enable/client-credentials.json | 7 +- config/identity/handler/enable/pod.json | 7 +- config/identity/handler/enable/webid.json | 7 +- .../handler/routing/account/logout.json | 7 +- .../routing/client-credentials/resource.json | 9 +- .../identity/handler/routing/core/index.json | 7 +- .../identity/handler/routing/core/login.json | 7 +- config/identity/handler/routing/default.json | 9 +- .../identity/handler/routing/oidc/cancel.json | 9 +- .../handler/routing/oidc/consent.json | 9 +- .../handler/routing/oidc/forget-webid.json | 9 +- .../handler/routing/oidc/pick-webid.json | 7 +- .../identity/handler/routing/oidc/prompt.json | 7 +- .../handler/routing/password/create.json | 7 +- .../handler/routing/password/forgot.json | 7 +- .../handler/routing/password/login.json | 7 +- .../handler/routing/password/reset.json | 7 +- .../handler/routing/password/resource.json | 9 +- .../handler/routing/pod/resource.json | 7 +- .../handler/routing/webid/resource.json | 7 +- config/identity/handler/storage/default.json | 5 +- config/identity/handler/storage/password.json | 5 +- config/identity/oidc/disabled.json | 9 +- config/identity/pod/dynamic.json | 5 +- .../pod/pod-generators/templated.json | 5 +- config/ldp/authentication/dpop-bearer.json | 7 +- config/ldp/authorization/acp.json | 5 +- config/ldp/authorization/allow-all.json | 9 +- config/ldp/authorization/readers/acl.json | 7 +- config/ldp/authorization/readers/default.json | 5 +- config/ldp/authorization/webacl.json | 5 +- .../ldp/handler/components/error-handler.json | 7 +- .../handler/components/operation-handler.json | 13 +- .../components/operation-metadata.json | 5 +- .../handler/components/request-parser.json | 9 +- config/ldp/handler/disabled.json | 9 +- config/ldp/metadata-parser/default.json | 5 +- config/ldp/metadata-writer/default.json | 5 +- config/ldp/modes/default.json | 21 ++- config/storage/backend/global-quota-file.json | 5 +- config/storage/backend/pod-quota-file.json | 5 +- .../storage/middleware/stores/patching.json | 17 +- config/util/auxiliary/strategies/acl.json | 5 +- config/util/auxiliary/strategies/acr.json | 5 +- config/util/index/default.json | 9 +- .../representation-conversion/default.json | 9 +- config/util/resource-locker/file.json | 5 +- config/util/resource-locker/redis.json | 5 +- package-lock.json | 152 +++++++++++------- package.json | 1 + src/authentication/CredentialsExtractor.ts | 2 +- .../UnionCredentialsExtractor.ts | 4 +- src/authorization/Authorizer.ts | 2 +- src/authorization/PermissionReader.ts | 2 +- src/authorization/UnionPermissionReader.ts | 4 +- src/authorization/access/AccessChecker.ts | 2 +- .../permissions/ModesExtractor.ts | 2 +- src/http/auxiliary/MetadataGenerator.ts | 2 +- src/http/auxiliary/Validator.ts | 2 +- src/http/input/RequestParser.ts | 2 +- src/http/input/body/BodyParser.ts | 2 +- src/http/input/conditions/ConditionsParser.ts | 2 +- src/http/input/identifier/TargetExtractor.ts | 2 +- src/http/input/metadata/MetadataParser.ts | 2 +- .../input/preferences/PreferenceParser.ts | 2 +- .../preferences/UnionPreferenceParser.ts | 4 +- src/http/ldp/OperationHandler.ts | 2 +- src/http/output/ResponseWriter.ts | 2 +- src/http/output/error/ErrorHandler.ts | 2 +- src/http/output/metadata/MetadataWriter.ts | 2 +- src/identity/configuration/PromptFactory.ts | 2 +- .../interaction/InteractionHandler.ts | 2 +- .../interaction/JsonInteractionHandler.ts | 2 +- .../interaction/password/util/EmailSender.ts | 2 +- .../interaction/pod/util/PodCreator.ts | 2 +- src/identity/ownership/OwnershipValidator.ts | 2 +- src/index.ts | 18 +-- src/init/Initializer.ts | 2 +- src/init/cli/CliExtractor.ts | 2 +- src/init/final/Finalizer.ts | 2 +- src/init/variables/ShorthandResolver.ts | 2 +- .../extractors/ShorthandExtractor.ts | 2 +- .../generate/variables/VariableHandler.ts | 2 +- src/server/HttpHandler.ts | 2 +- src/server/OperationHttpHandler.ts | 2 +- src/server/ServerConfigurator.ts | 2 +- src/server/WebSocketHandler.ts | 2 +- src/server/description/StorageDescriber.ts | 2 +- .../notifications/ListeningActivityHandler.ts | 2 +- .../notifications/NotificationEmitter.ts | 2 +- .../notifications/NotificationHandler.ts | 2 +- src/server/notifications/StateHandler.ts | 2 +- .../StreamingHttp2023Emitter.ts | 2 +- .../StreamingHttpListeningActivityHandler.ts | 2 +- .../WebSocket2023Handler.ts | 2 +- .../generate/NotificationGenerator.ts | 2 +- .../serialize/NotificationSerializer.ts | 2 +- src/server/util/BaseRouterHandler.ts | 4 +- .../conversion/RepresentationConverter.ts | 2 +- src/storage/patch/PatchHandler.ts | 2 +- src/storage/patch/RdfStorePatcher.ts | 2 +- src/storage/patch/RepresentationPatcher.ts | 2 +- src/storage/routing/RouterRule.ts | 2 +- src/util/PromiseUtil.ts | 24 --- src/util/errors/HttpErrorUtil.ts | 23 ++- src/util/handlers/ArrayUnionHandler.ts | 15 -- src/util/handlers/AsyncHandler.ts | 45 ------ src/util/handlers/BooleanHandler.ts | 46 ------ src/util/handlers/CachedHandler.ts | 103 ------------ src/util/handlers/ConditionalHandler.ts | 2 +- src/util/handlers/HandlerUtil.ts | 63 +------- src/util/handlers/MethodFilterHandler.ts | 2 +- src/util/handlers/ParallelHandler.ts | 21 --- src/util/handlers/ProcessHandler.ts | 47 ------ src/util/handlers/SequenceHandler.ts | 32 ---- src/util/handlers/StaticHandler.ts | 20 --- src/util/handlers/StaticThrowHandler.ts | 20 --- src/util/handlers/StatusArrayUnionHandler.ts | 13 ++ src/util/handlers/StatusBooleanHandler.ts | 12 ++ src/util/handlers/StatusHandler.ts | 28 ++++ src/util/handlers/StatusUnionHandler.ts | 23 +++ src/util/handlers/StatusWaterfallHandler.ts | 12 ++ src/util/handlers/UnionHandler.ts | 66 -------- src/util/handlers/UnsupportedAsyncHandler.ts | 22 --- src/util/handlers/WaterfallHandler.ts | 72 --------- src/util/templates/StaticTemplateEngine.ts | 2 +- src/util/templates/TemplateEngine.ts | 2 +- .../server/util/BaseRouterHandler.test.ts | 2 +- test/unit/util/errors/HttpErrorUtil.test.ts | 19 +++ test/unit/util/handlers/AsyncHandler.test.ts | 40 ----- .../unit/util/handlers/BooleanHandler.test.ts | 56 ------- test/unit/util/handlers/CachedHandler.test.ts | 84 ---------- .../util/handlers/ConditionalHandler.test.ts | 2 +- test/unit/util/handlers/HandlerUtil.test.ts | 48 ------ .../util/handlers/MethodFilterHandler.test.ts | 2 +- .../util/handlers/ParallelHandler.test.ts | 100 ------------ .../unit/util/handlers/ProcessHandler.test.ts | 72 --------- .../util/handlers/SequenceHandler.test.ts | 64 -------- test/unit/util/handlers/StaticHandler.test.ts | 18 --- .../util/handlers/StaticThrowHandler.test.ts | 35 ---- ...est.ts => StatusArrayUnionHandler.test.ts} | 14 +- .../handlers/StatusBooleanHandler.test.ts | 26 +++ test/unit/util/handlers/StatusHandler.test.ts | 50 ++++++ .../util/handlers/StatusUnionHandler.test.ts | 43 +++++ .../handlers/StatusWaterfallHandler.test.ts | 26 +++ test/unit/util/handlers/UnionHandler.test.ts | 81 ---------- .../handlers/UnsupportedAsyncHandler.test.ts | 18 --- .../util/handlers/WaterfallHandler.test.ts | 86 ---------- .../templates/StaticTemplateEngine.test.ts | 3 +- test/util/StaticAsyncHandler.ts | 2 +- test/util/Util.ts | 13 ++ 186 files changed, 944 insertions(+), 1590 deletions(-) create mode 100644 config/app/main/general/util.json delete mode 100644 src/util/handlers/ArrayUnionHandler.ts delete mode 100644 src/util/handlers/AsyncHandler.ts delete mode 100644 src/util/handlers/BooleanHandler.ts delete mode 100644 src/util/handlers/CachedHandler.ts delete mode 100644 src/util/handlers/ParallelHandler.ts delete mode 100644 src/util/handlers/ProcessHandler.ts delete mode 100644 src/util/handlers/SequenceHandler.ts delete mode 100644 src/util/handlers/StaticHandler.ts delete mode 100644 src/util/handlers/StaticThrowHandler.ts create mode 100644 src/util/handlers/StatusArrayUnionHandler.ts create mode 100644 src/util/handlers/StatusBooleanHandler.ts create mode 100644 src/util/handlers/StatusHandler.ts create mode 100644 src/util/handlers/StatusUnionHandler.ts create mode 100644 src/util/handlers/StatusWaterfallHandler.ts delete mode 100644 src/util/handlers/UnionHandler.ts delete mode 100644 src/util/handlers/UnsupportedAsyncHandler.ts delete mode 100644 src/util/handlers/WaterfallHandler.ts delete mode 100644 test/unit/util/handlers/AsyncHandler.test.ts delete mode 100644 test/unit/util/handlers/BooleanHandler.test.ts delete mode 100644 test/unit/util/handlers/CachedHandler.test.ts delete mode 100644 test/unit/util/handlers/HandlerUtil.test.ts delete mode 100644 test/unit/util/handlers/ParallelHandler.test.ts delete mode 100644 test/unit/util/handlers/ProcessHandler.test.ts delete mode 100644 test/unit/util/handlers/SequenceHandler.test.ts delete mode 100644 test/unit/util/handlers/StaticHandler.test.ts delete mode 100644 test/unit/util/handlers/StaticThrowHandler.test.ts rename test/unit/util/handlers/{ArrayUnionHandler.test.ts => StatusArrayUnionHandler.test.ts} (60%) create mode 100644 test/unit/util/handlers/StatusBooleanHandler.test.ts create mode 100644 test/unit/util/handlers/StatusHandler.test.ts create mode 100644 test/unit/util/handlers/StatusUnionHandler.test.ts create mode 100644 test/unit/util/handlers/StatusWaterfallHandler.test.ts delete mode 100644 test/unit/util/handlers/UnionHandler.test.ts delete mode 100644 test/unit/util/handlers/UnsupportedAsyncHandler.test.ts delete mode 100644 test/unit/util/handlers/WaterfallHandler.test.ts diff --git a/.componentsignore b/.componentsignore index 8cc732861..a2a5ec54c 100644 --- a/.componentsignore +++ b/.componentsignore @@ -2,6 +2,8 @@ "AccessMap", "Adapter", "AlgJwk", + "AsyncHandlerInput", + "AsyncHandlerOutput", "BaseActivityEmitter", "BaseChannelType", "BaseHttpError", @@ -40,7 +42,6 @@ "TransformOptions", "ValuePreferencesArg", "VariableBindings", - "UnionHandler", "VirtualObject", "WrappedSetMultiMap", "YargsOptions" diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 35fc4bb4f..f74019fbe 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,43 @@ # Community Solid Server release notes +## v8.0.0 + +### New features + +- ... + +### Data migration + +No actions are required to migrate data. + +### Configuration changes + +You might need to make changes to your v7 configuration if you use a custom config. + +The `@context` needs to be updated to +`https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/8.0.0/components/context.jsonld`. + +The following changes pertain to the imports in the default configs: + +- ... + +The following changes are relevant for v7 custom configs that replaced certain features. + +- Due to extracting the core handlers as an external library, + the CSS had to adapt some of them resulting in new class names. + The following renames have happened, meaning that if you used or extended a component of one of the following types, + you will have to update the `@type` in your configuration. + - `ArrayUnionHandler` -> `StatusArrayUnionHandler` + - `BooleanHandler` -> `StatusBooleanHandler` + - `UnionHandler` -> `StatusUnionHandler` + - `WaterfallHandler` -> `StatusWaterfallHandler` + +### Interface changes + +These changes are relevant if you wrote custom modules for the server that depend on existing interfaces. + +- The handler changes discussed above also impact the code if you used one there. + ## v7.0.0 ### New features diff --git a/config/app/init/base/init.json b/config/app/init/base/init.json index acfe076fe..a57a6635b 100644 --- a/config/app/init/base/init.json +++ b/config/app/init/base/init.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/initializers/base-url.json", "css:config/app/init/initializers/logger.json", @@ -26,7 +29,6 @@ "@id": "urn:solid-server:default:PrimaryInitializer", "@type": "ProcessHandler", "executeOnPrimary": true, - "clusterManager": { "@id": "urn:solid-server:default:ClusterManager" }, "source": { "comment": "These initializers will all be executed sequentially when starting the server.", "@id": "urn:solid-server:default:PrimarySequenceInitializer", @@ -47,7 +49,6 @@ "@id": "urn:solid-server:default:WorkerInitializer", "@type": "ProcessHandler", "executeOnPrimary": false, - "clusterManager": { "@id": "urn:solid-server:default:ClusterManager" }, "source": { "comment": "These initializers will all be executed sequentially when starting the server.", "@id": "urn:solid-server:default:WorkerSequenceInitializer", diff --git a/config/app/init/default.json b/config/app/init/default.json index ceec88648..658d0d578 100644 --- a/config/app/init/default.json +++ b/config/app/init/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/base/init.json" ], diff --git a/config/app/init/initialize-intro.json b/config/app/init/initialize-intro.json index 43c027836..77b26948a 100644 --- a/config/app/init/initialize-intro.json +++ b/config/app/init/initialize-intro.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/default.json", "css:config/app/init/initializers/root.json" diff --git a/config/app/init/initialize-prefilled-root.json b/config/app/init/initialize-prefilled-root.json index 365ccf47f..f386f582b 100644 --- a/config/app/init/initialize-prefilled-root.json +++ b/config/app/init/initialize-prefilled-root.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/default.json", "css:config/app/init/initializers/root.json" diff --git a/config/app/init/initialize-root-pod.json b/config/app/init/initialize-root-pod.json index e645bc6ff..d167f49cb 100644 --- a/config/app/init/initialize-root-pod.json +++ b/config/app/init/initialize-root-pod.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/default.json", "css:config/app/init/initializers/root-pod.json" diff --git a/config/app/init/initialize-root.json b/config/app/init/initialize-root.json index 804343053..62ff925bd 100644 --- a/config/app/init/initialize-root.json +++ b/config/app/init/initialize-root.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/default.json", "css:config/app/init/initializers/root.json" diff --git a/config/app/init/migration/base.json b/config/app/init/migration/base.json index 310b782a7..a191afa77 100644 --- a/config/app/init/migration/base.json +++ b/config/app/init/migration/base.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/app/init/migration/v6.json" ], diff --git a/config/app/main/default.json b/config/app/main/default.json index 7f9c13d64..2ea62bea5 100644 --- a/config/app/main/default.json +++ b/config/app/main/default.json @@ -1,7 +1,11 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ - "css:config/app/main/general/templates.json" + "css:config/app/main/general/templates.json", + "css:config/app/main/general/util.json" ], "@graph": [ { diff --git a/config/app/main/general/templates.json b/config/app/main/general/templates.json index 58a198841..ae69e6e1b 100644 --- a/config/app/main/general/templates.json +++ b/config/app/main/general/templates.json @@ -1,10 +1,13 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Template engine that finds the appropriate template engine to use based on the template extension.", "@id": "urn:solid-server:default:TemplateEngine", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Template engine that supports EJS templates.", diff --git a/config/app/main/general/util.json b/config/app/main/general/util.json new file mode 100644 index 000000000..4a968a4ea --- /dev/null +++ b/config/app/main/general/util.json @@ -0,0 +1,13 @@ +{ + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], + "@graph": [ + { + "@id": "urn:solid-server:default:UnsupportedErrorFactory", + "@type": "ClassErrorFactory", + "error": { "@type": "NotImplementedHttpError" } + } + ] +} diff --git a/config/http/handler/default.json b/config/http/handler/default.json index 565bbe5fc..2819857e2 100644 --- a/config/http/handler/default.json +++ b/config/http/handler/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/http/handler/handlers/storage-description.json" ], @@ -12,7 +15,7 @@ { "@id": "urn:solid-server:default:Middleware" }, { "@id": "urn:solid-server:default:BaseHttpHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:StaticAssetHandler" }, { "@id": "urn:solid-server:default:OidcHandler" }, diff --git a/config/http/handler/handlers/storage-description.json b/config/http/handler/handlers/storage-description.json index 01fccaa73..133018ff1 100644 --- a/config/http/handler/handlers/storage-description.json +++ b/config/http/handler/handlers/storage-description.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "The relative path appended to a storage container URL to find its description resource.", @@ -34,7 +37,7 @@ { "comment": "Combines the output of all storage describers.", "@id": "urn:solid-server:default:StorageDescriber", - "@type": "ArrayUnionHandler", + "@type": "StatusArrayUnionHandler", "handlers": [ { "@type": "StaticStorageDescriber", diff --git a/config/http/handler/simple.json b/config/http/handler/simple.json index e65189251..64481a34e 100644 --- a/config/http/handler/simple.json +++ b/config/http/handler/simple.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/http/handler/handlers/storage-description.json" ], @@ -12,7 +15,7 @@ { "@id": "urn:solid-server:default:Middleware" }, { "@id": "urn:solid-server:default:BaseHttpHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:StaticAssetHandler" }, { "@id": "urn:solid-server:default:StorageDescriptionHandler" }, diff --git a/config/http/middleware/default.json b/config/http/middleware/default.json index 0655ba46c..e28df5a81 100644 --- a/config/http/middleware/default.json +++ b/config/http/middleware/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/http/middleware/handlers/constant-headers.json", "css:config/http/middleware/handlers/cors.json" diff --git a/config/http/notifications/base/description.json b/config/http/notifications/base/description.json index 815a59fa1..3281a7c8a 100644 --- a/config/http/notifications/base/description.json +++ b/config/http/notifications/base/description.json @@ -1,9 +1,12 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:StorageDescriber", - "@type": "ArrayUnionHandler", + "@type": "StatusArrayUnionHandler", "handlers": [ { "comment": "New notification subscription types should add a NotificationChannelType here so they can be discovered.", diff --git a/config/http/notifications/base/handler.json b/config/http/notifications/base/handler.json index 7f5de5697..9628b721d 100644 --- a/config/http/notifications/base/handler.json +++ b/config/http/notifications/base/handler.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Generates the Notification objects and caches them based on the topic.", @@ -10,7 +13,7 @@ "@type": "StateNotificationGenerator", "resourceSet": { "@id": "urn:solid-server:default:CachedResourceSet" }, "source": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "DeleteNotificationGenerator" }, { diff --git a/config/http/notifications/base/http.json b/config/http/notifications/base/http.json index d430bf575..f5c43e024 100644 --- a/config/http/notifications/base/http.json +++ b/config/http/notifications/base/http.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:NotificationHttpHandler", @@ -16,7 +19,7 @@ "errorHandler": { "@id": "urn:solid-server:default:ErrorHandler" }, "responseWriter": { "@id": "urn:solid-server:default:ResponseWriter" }, "operationHandler": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:NotificationReadWriteHandler" }, { "@id": "urn:solid-server:default:NotificationDeleteHandler" } @@ -37,7 +40,7 @@ "operationHandler": { "comment": "New notification subscription types should be added here to allow subscriptions.", "@id": "urn:solid-server:default:NotificationTypeHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ ] } } diff --git a/config/http/notifications/base/listener.json b/config/http/notifications/base/listener.json index df020a2ff..a05943b85 100644 --- a/config/http/notifications/base/listener.json +++ b/config/http/notifications/base/listener.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Listens to the activities emitted by the MonitoringStore.", @@ -10,7 +13,7 @@ "handler": { "comment": "New notification types should add a handler here to emit events.", "@id": "urn:solid-server:default:NotificationHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ ] diff --git a/config/http/notifications/disabled.json b/config/http/notifications/disabled.json index 2ec5181c0..2dba6d213 100644 --- a/config/http/notifications/disabled.json +++ b/config/http/notifications/disabled.json @@ -1,10 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Disables notification routing.", "@id": "urn:solid-server:default:NotificationHttpHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/http/notifications/legacy-websockets.json b/config/http/notifications/legacy-websockets.json index 8f2d5c455..564658694 100644 --- a/config/http/notifications/legacy-websockets.json +++ b/config/http/notifications/legacy-websockets.json @@ -1,14 +1,19 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Disables notification routing.", "@id": "urn:solid-server:default:NotificationHttpHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } }, { "@id": "urn:solid-server:default:WebSocketHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Catches the server upgrade events and handles the WebSocket connections.", diff --git a/config/http/notifications/new-old-websockets.json b/config/http/notifications/new-old-websockets.json index dec4dc065..62c71f7f6 100644 --- a/config/http/notifications/new-old-websockets.json +++ b/config/http/notifications/new-old-websockets.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/http/notifications/base/description.json", "css:config/http/notifications/base/handler.json", @@ -13,7 +16,7 @@ "@graph": [ { "@id": "urn:solid-server:default:WebSocketHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Catches the server upgrade events and handles the WebSocket connections.", diff --git a/config/http/notifications/streaming-http/http.json b/config/http/notifications/streaming-http/http.json index e53227ee9..dd20007ee 100644 --- a/config/http/notifications/streaming-http/http.json +++ b/config/http/notifications/streaming-http/http.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:StreamingHTTP2023Route", @@ -43,7 +46,7 @@ { "comment": "Add the router to notification type handler", "@id": "urn:solid-server:default:NotificationTypeHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:StreamingHttp2023Router" } ] diff --git a/config/http/notifications/webhooks/handler.json b/config/http/notifications/webhooks/handler.json index 1b830b694..07edf3579 100644 --- a/config/http/notifications/webhooks/handler.json +++ b/config/http/notifications/webhooks/handler.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the generation and serialization of notifications for WebhookChannel2023.", @@ -25,7 +28,7 @@ { "@id": "urn:solid-server:default:NotificationHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:WebhookNotificationHandler" } ] diff --git a/config/http/notifications/webhooks/routes.json b/config/http/notifications/webhooks/routes.json index d99ae0e50..73c40c934 100644 --- a/config/http/notifications/webhooks/routes.json +++ b/config/http/notifications/webhooks/routes.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:WebhookRoute", @@ -29,7 +32,7 @@ { "@id": "urn:solid-server:default:NotificationTypeHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:WebhookRouter" }, { "@id": "urn:solid-server:default:WebhookWebId" } diff --git a/config/http/notifications/websockets/handler.json b/config/http/notifications/websockets/handler.json index 6c07ba63f..30ef0a59f 100644 --- a/config/http/notifications/websockets/handler.json +++ b/config/http/notifications/websockets/handler.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the generation and serialization of notifications for WebSocketChannel2023.", @@ -23,7 +26,7 @@ { "@id": "urn:solid-server:default:NotificationHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:WebSocket2023NotificationHandler" } ] diff --git a/config/http/notifications/websockets/http.json b/config/http/notifications/websockets/http.json index 8f75707b5..d77e94238 100644 --- a/config/http/notifications/websockets/http.json +++ b/config/http/notifications/websockets/http.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Catches newly opened WebSockets and verifies if they belong to a subscription.", @@ -37,7 +40,7 @@ { "@id": "urn:solid-server:default:WebSocketHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:WebSocket2023Listener" } ] diff --git a/config/http/notifications/websockets/subscription.json b/config/http/notifications/websockets/subscription.json index 508340cf6..d9ed51adc 100644 --- a/config/http/notifications/websockets/subscription.json +++ b/config/http/notifications/websockets/subscription.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the subscriptions targeting a WebSocketChannel2023.", @@ -34,7 +37,7 @@ { "@id": "urn:solid-server:default:NotificationTypeHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:WebSocket2023Router" } ] diff --git a/config/http/server-factory/configurator/default.json b/config/http/server-factory/configurator/default.json index ee7be7379..60828d03e 100644 --- a/config/http/server-factory/configurator/default.json +++ b/config/http/server-factory/configurator/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:ServerConfigurator", @@ -18,7 +21,7 @@ "@type": "WebSocketServerConfigurator", "handler": { "@id": "urn:solid-server:default:WebSocketHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [] } } diff --git a/config/identity/access/restricted.json b/config/identity/access/restricted.json index 1f5f27a87..4e37b369e 100644 --- a/config/identity/access/restricted.json +++ b/config/identity/access/restricted.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/identity/access/initializers/idp.json", "css:config/identity/access/initializers/well-known.json" diff --git a/config/identity/email/default.json b/config/identity/email/default.json index 87b5a71cc..d756234fb 100644 --- a/config/identity/email/default.json +++ b/config/identity/email/default.json @@ -1,11 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "The default configuration does not contain credentials for an email client. In production systems, you likely want to set up your own.", "@id": "urn:solid-server:default:EmailSender", - "@type": "UnsupportedAsyncHandler", - "errorMessage": "No email server is configured." + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/identity/handler/base/provider-factory.json b/config/identity/handler/base/provider-factory.json index da61981e0..dd0425b54 100644 --- a/config/identity/handler/base/provider-factory.json +++ b/config/identity/handler/base/provider-factory.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Sets all the relevant Solid-OIDC parameters.", diff --git a/config/identity/handler/disabled.json b/config/identity/handler/disabled.json index 5f3847e54..7bc695acc 100644 --- a/config/identity/handler/disabled.json +++ b/config/identity/handler/disabled.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/identity/handler/base/adapter-factory.json", "css:config/identity/handler/base/jwks.json", @@ -13,7 +16,9 @@ { "comment": "Disabled the account component.", "@id": "urn:solid-server:default:IdentityProviderHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/identity/handler/enable/account.json b/config/identity/handler/enable/account.json index 22fc5c335..0de51f8d7 100644 --- a/config/identity/handler/enable/account.json +++ b/config/identity/handler/enable/account.json @@ -1,12 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Enable account creation." }, { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountRouter" }] }, diff --git a/config/identity/handler/enable/client-credentials.json b/config/identity/handler/enable/client-credentials.json index b1c2e117c..8b431e9d6 100644 --- a/config/identity/handler/enable/client-credentials.json +++ b/config/identity/handler/enable/client-credentials.json @@ -1,12 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Enable client credentials creation." }, { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountClientCredentialsRouter" }] }, diff --git a/config/identity/handler/enable/pod.json b/config/identity/handler/enable/pod.json index 2c8059e65..321ec3224 100644 --- a/config/identity/handler/enable/pod.json +++ b/config/identity/handler/enable/pod.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Enable pod creation." @@ -7,7 +10,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:AccountPodRouter" } ] diff --git a/config/identity/handler/enable/webid.json b/config/identity/handler/enable/webid.json index c71015d9c..3654af9cb 100644 --- a/config/identity/handler/enable/webid.json +++ b/config/identity/handler/enable/webid.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Enable linking WebIDs to an account." @@ -7,7 +10,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:AccountWebIdRouter" } ] diff --git a/config/identity/handler/routing/account/logout.json b/config/identity/handler/routing/account/logout.json index 19439cd9c..c3b22afc5 100644 --- a/config/identity/handler/routing/account/logout.json +++ b/config/identity/handler/routing/account/logout.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles logging a user out.", @@ -24,7 +27,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountLogoutRouter" }] }, diff --git a/config/identity/handler/routing/client-credentials/resource.json b/config/identity/handler/routing/client-credentials/resource.json index 5831a7a07..c114ee016 100644 --- a/config/identity/handler/routing/client-credentials/resource.json +++ b/config/identity/handler/routing/client-credentials/resource.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the client credentials link details such as deletion.", @@ -12,7 +15,7 @@ }, "source": { "@id": "urn:solid-server:default:ClientCredentialsResourceHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "MethodFilterHandler", @@ -38,7 +41,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountClientCredentialsIdRouter" }] } ] diff --git a/config/identity/handler/routing/core/index.json b/config/identity/handler/routing/core/index.json index 7fb7c5cb6..60ecd6b65 100644 --- a/config/identity/handler/routing/core/index.json +++ b/config/identity/handler/routing/core/index.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Root API entry. Returns an empty body so we can add controls pointing to other interaction routes.", @@ -22,7 +25,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:IndexRouter" }] }, diff --git a/config/identity/handler/routing/core/login.json b/config/identity/handler/routing/core/login.json index 92545ec79..ae96f68e0 100644 --- a/config/identity/handler/routing/core/login.json +++ b/config/identity/handler/routing/core/login.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Returns the links of the HTML pages that can be used to log in with specific methods.", @@ -33,7 +36,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:LoginRouter" }] }, diff --git a/config/identity/handler/routing/default.json b/config/identity/handler/routing/default.json index 930eb5529..d6f8fd640 100644 --- a/config/identity/handler/routing/default.json +++ b/config/identity/handler/routing/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/identity/handler/routing/account/main.json", "css:config/identity/handler/routing/client-credentials/create.json", @@ -17,7 +20,7 @@ "@graph": [ { "@id": "urn:solid-server:default:InteractionHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Returns the relevant HTML pages for the interactions when needed.", @@ -78,7 +81,7 @@ { "comment": "Contains all JsonInteractionHandlers that can potentially handle the input request.", "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [] } ] diff --git a/config/identity/handler/routing/oidc/cancel.json b/config/identity/handler/routing/oidc/cancel.json index ed296f2ec..79fbafa85 100644 --- a/config/identity/handler/routing/oidc/cancel.json +++ b/config/identity/handler/routing/oidc/cancel.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows users to cancel an OIDC interaction, bringing them back to the original client.", @@ -13,7 +16,7 @@ }, "source": { "@id": "urn:solid-server:default:CancelOidcHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "MethodFilterHandler", @@ -26,7 +29,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:OidcCancelRouter" }] }, diff --git a/config/identity/handler/routing/oidc/consent.json b/config/identity/handler/routing/oidc/consent.json index 3dc76e5bc..6ea905451 100644 --- a/config/identity/handler/routing/oidc/consent.json +++ b/config/identity/handler/routing/oidc/consent.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the interaction that occurs when a logged in user wants to authenticate with a new app.", @@ -13,7 +16,7 @@ }, "source": { "@id": "urn:solid-server:default:ConsentHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "MethodFilterHandler", @@ -37,7 +40,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:OidcConsentRouter" }] }, diff --git a/config/identity/handler/routing/oidc/forget-webid.json b/config/identity/handler/routing/oidc/forget-webid.json index 43ade9c9e..c5076123c 100644 --- a/config/identity/handler/routing/oidc/forget-webid.json +++ b/config/identity/handler/routing/oidc/forget-webid.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows the picked WebID to be forgotten in an OIDC interaction so the user can pick again.", @@ -13,7 +16,7 @@ }, "source": { "@id": "urn:solid-server:default:ForgetWebIdHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "MethodFilterHandler", @@ -29,7 +32,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:OidcForgetWebIdRouter" }] }, diff --git a/config/identity/handler/routing/oidc/pick-webid.json b/config/identity/handler/routing/oidc/pick-webid.json index 1bf30912b..6984c65f0 100644 --- a/config/identity/handler/routing/oidc/pick-webid.json +++ b/config/identity/handler/routing/oidc/pick-webid.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles picking a WebID during an OIDC interaction.", @@ -24,7 +27,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:OidcPickWebIdRouter" } ] diff --git a/config/identity/handler/routing/oidc/prompt.json b/config/identity/handler/routing/oidc/prompt.json index 474168054..041797d74 100644 --- a/config/identity/handler/routing/oidc/prompt.json +++ b/config/identity/handler/routing/oidc/prompt.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the interaction that occurs when a logged in user wants to authenticate with a new app.", @@ -33,7 +36,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:OidcPromptRouter" }] }, diff --git a/config/identity/handler/routing/password/create.json b/config/identity/handler/routing/password/create.json index a37fb0e01..d3ee6c2b3 100644 --- a/config/identity/handler/routing/password/create.json +++ b/config/identity/handler/routing/password/create.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows adding the email/password login method to an account", @@ -24,7 +27,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountPasswordRouter" }] }, diff --git a/config/identity/handler/routing/password/forgot.json b/config/identity/handler/routing/password/forgot.json index a55deaca4..8104a8f63 100644 --- a/config/identity/handler/routing/password/forgot.json +++ b/config/identity/handler/routing/password/forgot.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the forgot password interaction.", @@ -31,7 +34,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:ForgotPasswordRouter" }] }, diff --git a/config/identity/handler/routing/password/login.json b/config/identity/handler/routing/password/login.json index b363ea150..10db20427 100644 --- a/config/identity/handler/routing/password/login.json +++ b/config/identity/handler/routing/password/login.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the password login interaction.", @@ -25,7 +28,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:LoginPasswordRouter" }] }, diff --git a/config/identity/handler/routing/password/reset.json b/config/identity/handler/routing/password/reset.json index 7767b0273..5b43b864d 100644 --- a/config/identity/handler/routing/password/reset.json +++ b/config/identity/handler/routing/password/reset.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the reset password interaction.", @@ -24,7 +27,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:ResetPasswordRouter" }] }, diff --git a/config/identity/handler/routing/password/resource.json b/config/identity/handler/routing/password/resource.json index 970beb524..f9b26cbdd 100644 --- a/config/identity/handler/routing/password/resource.json +++ b/config/identity/handler/routing/password/resource.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the password link details such as update and delete.", @@ -12,7 +15,7 @@ }, "source": { "@id": "urn:solid-server:default:PasswordResourceHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "ViewInteractionHandler", @@ -37,7 +40,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountPasswordIdRouter" }] }, diff --git a/config/identity/handler/routing/pod/resource.json b/config/identity/handler/routing/pod/resource.json index 6b734aeaf..37040b389 100644 --- a/config/identity/handler/routing/pod/resource.json +++ b/config/identity/handler/routing/pod/resource.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles updating pod settings.", @@ -37,7 +40,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [{ "@id": "urn:solid-server:default:AccountPodIdRouter" }] }, diff --git a/config/identity/handler/routing/webid/resource.json b/config/identity/handler/routing/webid/resource.json index 56660cd79..8d135788d 100644 --- a/config/identity/handler/routing/webid/resource.json +++ b/config/identity/handler/routing/webid/resource.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles the WebID link details such as deletion.", @@ -24,7 +27,7 @@ { "@id": "urn:solid-server:default:InteractionRouteHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:AccountWebIdLinkRouter" } ] diff --git a/config/identity/handler/storage/default.json b/config/identity/handler/storage/default.json index aa4f6d2be..4e8fa6c3e 100644 --- a/config/identity/handler/storage/default.json +++ b/config/identity/handler/storage/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:AccountStorage", diff --git a/config/identity/handler/storage/password.json b/config/identity/handler/storage/password.json index b1c58ef23..ce6c41332 100644 --- a/config/identity/handler/storage/password.json +++ b/config/identity/handler/storage/password.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:PasswordStore", diff --git a/config/identity/oidc/disabled.json b/config/identity/oidc/disabled.json index 539388873..7220dae1b 100644 --- a/config/identity/oidc/disabled.json +++ b/config/identity/oidc/disabled.json @@ -1,10 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Disabled the OIDC component.", "@id": "urn:solid-server:default:OidcHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/identity/pod/dynamic.json b/config/identity/pod/dynamic.json index 8002c0164..81459bebc 100644 --- a/config/identity/pod/dynamic.json +++ b/config/identity/pod/dynamic.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/identity/pod/pod-generators/templated.json", "css:config/identity/pod/resource-generators/templated.json" diff --git a/config/identity/pod/pod-generators/templated.json b/config/identity/pod/pod-generators/templated.json index e4aef5846..bfb223a97 100644 --- a/config/identity/pod/pod-generators/templated.json +++ b/config/identity/pod/pod-generators/templated.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Generates ResourceStores that correspond to new pods.", diff --git a/config/ldp/authentication/dpop-bearer.json b/config/ldp/authentication/dpop-bearer.json index aaca5a6cd..87c63f6c2 100644 --- a/config/ldp/authentication/dpop-bearer.json +++ b/config/ldp/authentication/dpop-bearer.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Caches the credentials based on the incoming request.", @@ -10,7 +13,7 @@ "@type": "UnionCredentialsExtractor", "extractors": [ { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "DPoPWebIdExtractor", diff --git a/config/ldp/authorization/acp.json b/config/ldp/authorization/acp.json index b2e77de7a..801a1c362 100644 --- a/config/ldp/authorization/acp.json +++ b/config/ldp/authorization/acp.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/authorization/readers/acp.json", "css:config/ldp/authorization/readers/default.json" diff --git a/config/ldp/authorization/allow-all.json b/config/ldp/authorization/allow-all.json index db100e413..7a838bc91 100644 --- a/config/ldp/authorization/allow-all.json +++ b/config/ldp/authorization/allow-all.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": [ @@ -13,7 +16,9 @@ { "comment": "Everything is allowed, so there are no auth-specific resources.", "@id": "urn:solid-server:default:AuthResourceHttpHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/ldp/authorization/readers/acl.json b/config/ldp/authorization/readers/acl.json index 1c90d3fad..d42b6b41e 100644 --- a/config/ldp/authorization/readers/acl.json +++ b/config/ldp/authorization/readers/acl.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/authorization/readers/access-checkers/agent.json", "css:config/ldp/authorization/readers/access-checkers/agent-class.json", @@ -27,7 +30,7 @@ "aclStore": { "@id": "urn:solid-server:default:ResourceStore" }, "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" }, "accessChecker": { - "@type": "BooleanHandler", + "@type": "StatusBooleanHandler", "handlers": [ { "@id": "urn:solid-server:default:AgentAccessChecker" }, { "@id": "urn:solid-server:default:AgentClassAccessChecker" }, diff --git a/config/ldp/authorization/readers/default.json b/config/ldp/authorization/readers/default.json index e2a332ddf..a08be6c9d 100644 --- a/config/ldp/authorization/readers/default.json +++ b/config/ldp/authorization/readers/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/authorization/readers/ownership.json" ], diff --git a/config/ldp/authorization/webacl.json b/config/ldp/authorization/webacl.json index a3d8278a8..41ef1e692 100644 --- a/config/ldp/authorization/webacl.json +++ b/config/ldp/authorization/webacl.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/authorization/acl/wac-allow.json", "css:config/ldp/authorization/readers/acl.json", diff --git a/config/ldp/handler/components/error-handler.json b/config/ldp/handler/components/error-handler.json index 12d41558e..460276a22 100644 --- a/config/ldp/handler/components/error-handler.json +++ b/config/ldp/handler/components/error-handler.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Wraps around the main error handler as a fallback in case something goes wrong.", @@ -12,7 +15,7 @@ "targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" }, "errorHandler": { "@id": "urn:solid-server:default:WaterfallErrorHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Redirects are created internally by throwing a specific error; this handler converts them to the correct response.", diff --git a/config/ldp/handler/components/operation-handler.json b/config/ldp/handler/components/operation-handler.json index 6d602a77c..630fe73ef 100644 --- a/config/ldp/handler/components/operation-handler.json +++ b/config/ldp/handler/components/operation-handler.json @@ -1,9 +1,12 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "@id": "urn:solid-server:default:OperationHandler", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "GetOperationHandler", @@ -34,7 +37,11 @@ }, { "@type": "StaticThrowHandler", - "error": { "@type": "MethodNotAllowedHttpError" } + "onlyHandle": true, + "factory": { + "@type": "ClassErrorFactory", + "error": { "@type": "MethodNotAllowedHttpError" } + } } ] } diff --git a/config/ldp/handler/components/operation-metadata.json b/config/ldp/handler/components/operation-metadata.json index 39d1ec16c..f339d3b44 100644 --- a/config/ldp/handler/components/operation-metadata.json +++ b/config/ldp/handler/components/operation-metadata.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Contains the necessary metadata collectors. Contents depend on authorization scheme.", diff --git a/config/ldp/handler/components/request-parser.json b/config/ldp/handler/components/request-parser.json index c84c4b29f..d952280ae 100644 --- a/config/ldp/handler/components/request-parser.json +++ b/config/ldp/handler/components/request-parser.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Handles everything related to parsing a Request.", @@ -21,7 +24,7 @@ } }, "bodyParser": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:PatchBodyParser" }, { "@type": "RawBodyParser" } @@ -34,7 +37,7 @@ "@type": "MethodFilterHandler", "methods": [ "PATCH" ], "source": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "N3PatchBodyParser" }, { "@type": "SparqlUpdateBodyParser" } diff --git a/config/ldp/handler/disabled.json b/config/ldp/handler/disabled.json index 3f796b439..40407e99e 100644 --- a/config/ldp/handler/disabled.json +++ b/config/ldp/handler/disabled.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/handler/components/authorizer.json", "css:config/ldp/handler/components/error-handler.json", @@ -13,7 +16,9 @@ { "comment": "Disabled the LDP component.", "@id": "urn:solid-server:default:LdpHandler", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/ldp/metadata-parser/default.json b/config/ldp/metadata-parser/default.json index 56ba23931..0e17a1eff 100644 --- a/config/ldp/metadata-parser/default.json +++ b/config/ldp/metadata-parser/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/metadata-parser/parsers/authorization.json", "css:config/ldp/metadata-parser/parsers/content-type.json", diff --git a/config/ldp/metadata-writer/default.json b/config/ldp/metadata-writer/default.json index 558ec874b..a474fc8ba 100644 --- a/config/ldp/metadata-writer/default.json +++ b/config/ldp/metadata-writer/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/metadata-writer/writers/allow-accept.json", "css:config/ldp/metadata-writer/writers/content-type.json", diff --git a/config/ldp/modes/default.json b/config/ldp/modes/default.json index a94e3c131..6d8e3843f 100644 --- a/config/ldp/modes/default.json +++ b/config/ldp/modes/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Caches the requested modes based on the incoming operation.", @@ -16,7 +19,7 @@ { "comment": "Determines required modes based on HTTP methods.", "@id": "urn:solid-server:default:HttpModesExtractor", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "comment": "Extract access modes for PATCH requests based on the request body.", @@ -35,7 +38,11 @@ }, { "@type": "StaticThrowHandler", - "error": { "@type": "MethodNotAllowedHttpError" } + "onlyHandle": true, + "factory": { + "@type": "ClassErrorFactory", + "error": { "@type": "MethodNotAllowedHttpError" } + } } ] }, @@ -47,7 +54,7 @@ "@type": "MethodFilterHandler", "methods": [ "PATCH" ], "source": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "N3PatchModesExtractor", @@ -59,7 +66,11 @@ }, { "@type": "StaticThrowHandler", - "error": { "@type": "UnsupportedMediaTypeHttpError" } + "onlyHandle": true, + "factory": { + "@type": "ClassErrorFactory", + "error": { "@type": "UnsupportedMediaTypeHttpError" } + } } ] } diff --git a/config/storage/backend/global-quota-file.json b/config/storage/backend/global-quota-file.json index c1d1c47e6..bc3c1ac50 100644 --- a/config/storage/backend/global-quota-file.json +++ b/config/storage/backend/global-quota-file.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/metadata-parser/parsers/content-length.json", "css:config/storage/backend/quota/global-quota-file.json", diff --git a/config/storage/backend/pod-quota-file.json b/config/storage/backend/pod-quota-file.json index 797ea1ab6..0995ff0e3 100644 --- a/config/storage/backend/pod-quota-file.json +++ b/config/storage/backend/pod-quota-file.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/ldp/metadata-parser/parsers/content-length.json", "css:config/storage/backend/quota/pod-quota-file.json", diff --git a/config/storage/middleware/stores/patching.json b/config/storage/middleware/stores/patching.json index 79043ff31..e78307c6d 100644 --- a/config/storage/middleware/stores/patching.json +++ b/config/storage/middleware/stores/patching.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows for PATCH operations on stores that don't have native support.", @@ -9,7 +12,7 @@ "@id": "urn:solid-server:default:PatchHandler", "@type": "RepresentationPatchHandler", "patcher": { - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "ConvertingPatcher", @@ -20,7 +23,11 @@ }, { "@type": "StaticThrowHandler", - "error": { "@type": "UnsupportedMediaTypeHttpError" } + "onlyHandle": true, + "factory": { + "@type": "ClassErrorFactory", + "error": { "@type": "UnsupportedMediaTypeHttpError" } + } } ] } @@ -34,7 +41,7 @@ }, { "@id": "urn:solid-server:default:PatchHandler_RDFStore", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:PatchHandler_ImmutableMetadata" }, { "@id": "urn:solid-server:default:PatchHandler_RDF" } @@ -83,7 +90,7 @@ { "comment": "Dedicated handlers that apply specific types of patch documents", "@id": "urn:solid-server:default:PatchHandler_RDF", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@type": "N3Patcher" }, { "@type": "SparqlUpdatePatcher" } diff --git a/config/util/auxiliary/strategies/acl.json b/config/util/auxiliary/strategies/acl.json index a52361a96..da6bcd230 100644 --- a/config/util/auxiliary/strategies/acl.json +++ b/config/util/auxiliary/strategies/acl.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Contains all features of acl auxiliary resources (suffix, etc.).", diff --git a/config/util/auxiliary/strategies/acr.json b/config/util/auxiliary/strategies/acr.json index 3aec296c4..216005180 100644 --- a/config/util/auxiliary/strategies/acr.json +++ b/config/util/auxiliary/strategies/acr.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Contains all features of acr auxiliary resources (suffix, etc.).", diff --git a/config/util/index/default.json b/config/util/index/default.json index 3f927eab7..7416c2df4 100644 --- a/config/util/index/default.json +++ b/config/util/index/default.json @@ -1,10 +1,15 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "This value can be used to set a custom handler for index files. See the example file.", "@id": "urn:solid-server:default:DefaultUiConverter", - "@type": "UnsupportedAsyncHandler" + "@type": "StaticThrowHandler", + "onlyHandle": false, + "factory": { "@id": "urn:solid-server:default:UnsupportedErrorFactory" } } ] } diff --git a/config/util/representation-conversion/default.json b/config/util/representation-conversion/default.json index 99d71b333..fcfbebba8 100644 --- a/config/util/representation-conversion/default.json +++ b/config/util/representation-conversion/default.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "import": [ "css:config/util/representation-conversion/converters/content-type-replacer.json", "css:config/util/representation-conversion/converters/dynamic-json-template.json", @@ -13,7 +16,7 @@ { "comment": "Handles data conversion when required.", "@id": "urn:solid-server:default:RepresentationConverter", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:DynamicJsonToTemplateConverter" }, { @@ -38,7 +41,7 @@ { "comment": "Converts either to a default UI or to a representation.", "@id": "urn:solid-server:default:UiEnabledConverter", - "@type": "WaterfallHandler", + "@type": "StatusWaterfallHandler", "handlers": [ { "@id": "urn:solid-server:default:DefaultUiConverter" }, { "@id": "urn:solid-server:default:RepresentationConverter" } diff --git a/config/util/resource-locker/file.json b/config/util/resource-locker/file.json index ff04de037..da5953993 100644 --- a/config/util/resource-locker/file.json +++ b/config/util/resource-locker/file.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows multiple simultaneous read operations. Locks are stored on filesystem. Locks expire after inactivity. This locker is threadsafe.", diff --git a/config/util/resource-locker/redis.json b/config/util/resource-locker/redis.json index f0d8c6171..af02dff4e 100644 --- a/config/util/resource-locker/redis.json +++ b/config/util/resource-locker/redis.json @@ -1,5 +1,8 @@ { - "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld" + ], "@graph": [ { "comment": "Allows multiple simultaneous read operations. All locks are threadsafe.", diff --git a/package-lock.json b/package-lock.json index 32a016a5c..a2a4c406d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "@types/yargs": "^17.0.28", "arrayify-stream": "^2.0.1", "async-lock": "^1.4.0", + "asynchronous-handlers": "^1.0.2", "bcryptjs": "^2.4.3", "componentsjs": "^6.0.1", "cookie": "^0.5.0", @@ -48,6 +49,7 @@ "escape-string-regexp": "^4.0.0", "fetch-sparql-endpoint": "^5.0.0", "fs-extra": "^11.1.1", + "global-logger-factory": "^1.0.0", "handlebars": "^4.7.8", "ioredis": "^5.3.2", "iso8601-duration": "^2.1.1", @@ -1121,6 +1123,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -1131,9 +1134,9 @@ } }, "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "engines": { "node": ">=0.1.90" } @@ -10664,6 +10667,11 @@ "@types/superagent": "^8.1.0" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", @@ -11643,6 +11651,14 @@ "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.0.tgz", "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==" }, + "node_modules/asynchronous-handlers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/asynchronous-handlers/-/asynchronous-handlers-1.0.2.tgz", + "integrity": "sha512-Jl5zQuDrq5owcX6Y5SD0Q3ZE73lR6hOaUw9Uwz0jglrrNauKYyczOtak/kfJ+u0rfoqbZa6jG4dtYPq5c6w08w==", + "dependencies": { + "global-logger-factory": "^1.0.0" + } + }, "node_modules/asynciterator": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.9.0.tgz", @@ -15439,6 +15455,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/global-logger-factory": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-logger-factory/-/global-logger-factory-1.0.0.tgz", + "integrity": "sha512-hN39r7dWZfdjhEaiM4r+2Fw/M3hjhmSHVVZmecp/IyQWhrCvpawWDk8imeHcsewGfaaGZWXoXjhjF5786E2biQ==", + "dependencies": { + "winston": "^3.14.2", + "winston-transport": "^4.7.1" + } + }, "node_modules/globals": { "version": "15.8.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", @@ -17729,15 +17754,19 @@ "dev": true }, "node_modules/logform": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", - "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", + "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", "dependencies": { - "@colors/colors": "1.5.0", + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" } }, "node_modules/lowercase-keys": { @@ -19821,9 +19850,9 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -21592,45 +21621,37 @@ "dev": true }, "node_modules/winston": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", - "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", + "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.4.0", + "logform": "^2.6.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" + "winston-transport": "^4.7.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.1.tgz", + "integrity": "sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==", "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", + "logform": "^2.6.1", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston/node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "engines": { - "node": ">=0.1.90" + "node": ">= 12.0.0" } }, "node_modules/wordwrap": { @@ -22556,14 +22577,15 @@ "dependencies": { "is-unicode-supported": { "version": "1.3.0", - "bundled": true + "bundled": true, + "extraneous": true } } }, "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" }, "@commitlint/cli": { "version": "19.3.0", @@ -31343,6 +31365,11 @@ "@types/superagent": "^8.1.0" } }, + "@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", @@ -32018,6 +32045,14 @@ "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.0.tgz", "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==" }, + "asynchronous-handlers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/asynchronous-handlers/-/asynchronous-handlers-1.0.2.tgz", + "integrity": "sha512-Jl5zQuDrq5owcX6Y5SD0Q3ZE73lR6hOaUw9Uwz0jglrrNauKYyczOtak/kfJ+u0rfoqbZa6jG4dtYPq5c6w08w==", + "requires": { + "global-logger-factory": "^1.0.0" + } + }, "asynciterator": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.9.0.tgz", @@ -34778,6 +34813,15 @@ } } }, + "global-logger-factory": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-logger-factory/-/global-logger-factory-1.0.0.tgz", + "integrity": "sha512-hN39r7dWZfdjhEaiM4r+2Fw/M3hjhmSHVVZmecp/IyQWhrCvpawWDk8imeHcsewGfaaGZWXoXjhjF5786E2biQ==", + "requires": { + "winston": "^3.14.2", + "winston-transport": "^4.7.1" + } + }, "globals": { "version": "15.8.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", @@ -36527,11 +36571,12 @@ "dev": true }, "logform": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", - "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", + "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", "requires": { - "@colors/colors": "1.5.0", + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", @@ -38166,9 +38211,9 @@ } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -39486,37 +39531,30 @@ "dev": true }, "winston": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", - "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", + "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", "requires": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.4.0", + "logform": "^2.6.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" - }, - "dependencies": { - "@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" - } + "winston-transport": "^4.7.0" } }, "winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.1.tgz", + "integrity": "sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==", "requires": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", + "logform": "^2.6.1", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, diff --git a/package.json b/package.json index 29f4aa418..3a6ab72ec 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "@types/yargs": "^17.0.28", "arrayify-stream": "^2.0.1", "async-lock": "^1.4.0", + "asynchronous-handlers": "^1.0.2", "bcryptjs": "^2.4.3", "componentsjs": "^6.0.1", "cookie": "^0.5.0", diff --git a/src/authentication/CredentialsExtractor.ts b/src/authentication/CredentialsExtractor.ts index 1d7294b2a..877706880 100644 --- a/src/authentication/CredentialsExtractor.ts +++ b/src/authentication/CredentialsExtractor.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../server/HttpRequest'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; import type { Credentials } from './Credentials'; /** diff --git a/src/authentication/UnionCredentialsExtractor.ts b/src/authentication/UnionCredentialsExtractor.ts index 1452929e5..a3a88e239 100644 --- a/src/authentication/UnionCredentialsExtractor.ts +++ b/src/authentication/UnionCredentialsExtractor.ts @@ -1,4 +1,4 @@ -import { UnionHandler } from '../util/handlers/UnionHandler'; +import { StatusUnionHandler } from '../util/handlers/StatusUnionHandler'; import type { Credentials } from './Credentials'; import type { CredentialsExtractor } from './CredentialsExtractor'; @@ -7,7 +7,7 @@ import type { CredentialsExtractor } from './CredentialsExtractor'; * If multiple of these extractors return a value for the same key, * the last result will be used. */ -export class UnionCredentialsExtractor extends UnionHandler { +export class UnionCredentialsExtractor extends StatusUnionHandler { public constructor(extractors: CredentialsExtractor[]) { super(extractors); } diff --git a/src/authorization/Authorizer.ts b/src/authorization/Authorizer.ts index 4c32df1c4..c459622ea 100644 --- a/src/authorization/Authorizer.ts +++ b/src/authorization/Authorizer.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Credentials } from '../authentication/Credentials'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; import type { AccessMap, PermissionMap } from './permissions/Permissions'; export interface AuthorizerInput { diff --git a/src/authorization/PermissionReader.ts b/src/authorization/PermissionReader.ts index 552a211de..73d69f746 100644 --- a/src/authorization/PermissionReader.ts +++ b/src/authorization/PermissionReader.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Credentials } from '../authentication/Credentials'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; import type { AccessMap, PermissionMap } from './permissions/Permissions'; export interface PermissionReaderInput { diff --git a/src/authorization/UnionPermissionReader.ts b/src/authorization/UnionPermissionReader.ts index 583ff2164..fca539bde 100644 --- a/src/authorization/UnionPermissionReader.ts +++ b/src/authorization/UnionPermissionReader.ts @@ -1,4 +1,4 @@ -import { UnionHandler } from '../util/handlers/UnionHandler'; +import { StatusUnionHandler } from '../util/handlers/StatusUnionHandler'; import { IdentifierMap } from '../util/map/IdentifierMap'; import { getDefault } from '../util/map/MapUtil'; import type { PermissionReader } from './PermissionReader'; @@ -8,7 +8,7 @@ import type { PermissionMap, PermissionSet } from './permissions/Permissions'; * Combines the results of multiple PermissionReaders. * Every permission in every credential type is handled according to the rule `false` \> `true` \> `undefined`. */ -export class UnionPermissionReader extends UnionHandler { +export class UnionPermissionReader extends StatusUnionHandler { public constructor(readers: PermissionReader[]) { super(readers); } diff --git a/src/authorization/access/AccessChecker.ts b/src/authorization/access/AccessChecker.ts index 30186b785..4e0af3194 100644 --- a/src/authorization/access/AccessChecker.ts +++ b/src/authorization/access/AccessChecker.ts @@ -1,6 +1,6 @@ import type { Store, Term } from 'n3'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Credentials } from '../../authentication/Credentials'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; /** * Performs an authorization check against the given acl resource. diff --git a/src/authorization/permissions/ModesExtractor.ts b/src/authorization/permissions/ModesExtractor.ts index 1c918b278..a25b703f4 100644 --- a/src/authorization/permissions/ModesExtractor.ts +++ b/src/authorization/permissions/ModesExtractor.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Operation } from '../../http/Operation'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { AccessMap } from './Permissions'; /** diff --git a/src/http/auxiliary/MetadataGenerator.ts b/src/http/auxiliary/MetadataGenerator.ts index 52f63604b..9cc3b8cc2 100644 --- a/src/http/auxiliary/MetadataGenerator.ts +++ b/src/http/auxiliary/MetadataGenerator.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { RepresentationMetadata } from '../representation/RepresentationMetadata'; /** diff --git a/src/http/auxiliary/Validator.ts b/src/http/auxiliary/Validator.ts index 0c61f0fcf..a4174d2bb 100644 --- a/src/http/auxiliary/Validator.ts +++ b/src/http/auxiliary/Validator.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../representation/Representation'; import type { ResourceIdentifier } from '../representation/ResourceIdentifier'; diff --git a/src/http/input/RequestParser.ts b/src/http/input/RequestParser.ts index 06f2d3797..0680923d9 100644 --- a/src/http/input/RequestParser.ts +++ b/src/http/input/RequestParser.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../server/HttpRequest'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { Operation } from '../Operation'; /** diff --git a/src/http/input/body/BodyParser.ts b/src/http/input/body/BodyParser.ts index 3ff3a5626..5173aa1d3 100644 --- a/src/http/input/body/BodyParser.ts +++ b/src/http/input/body/BodyParser.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { Representation } from '../../representation/Representation'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; diff --git a/src/http/input/conditions/ConditionsParser.ts b/src/http/input/conditions/ConditionsParser.ts index ae45f7f99..dc488a098 100644 --- a/src/http/input/conditions/ConditionsParser.ts +++ b/src/http/input/conditions/ConditionsParser.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; import type { Conditions } from '../../../storage/conditions/Conditions'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; /** * Creates a Conditions object based on the input HttpRequest. diff --git a/src/http/input/identifier/TargetExtractor.ts b/src/http/input/identifier/TargetExtractor.ts index 0a630b144..31446a0e4 100644 --- a/src/http/input/identifier/TargetExtractor.ts +++ b/src/http/input/identifier/TargetExtractor.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { ResourceIdentifier } from '../../representation/ResourceIdentifier'; /** diff --git a/src/http/input/metadata/MetadataParser.ts b/src/http/input/metadata/MetadataParser.ts index 563e0fcbd..6a917d73d 100644 --- a/src/http/input/metadata/MetadataParser.ts +++ b/src/http/input/metadata/MetadataParser.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; /** diff --git a/src/http/input/preferences/PreferenceParser.ts b/src/http/input/preferences/PreferenceParser.ts index d2dfd8c67..d4d05305b 100644 --- a/src/http/input/preferences/PreferenceParser.ts +++ b/src/http/input/preferences/PreferenceParser.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { RepresentationPreferences } from '../../representation/RepresentationPreferences'; /** diff --git a/src/http/input/preferences/UnionPreferenceParser.ts b/src/http/input/preferences/UnionPreferenceParser.ts index 5a5684d75..2098ed13c 100644 --- a/src/http/input/preferences/UnionPreferenceParser.ts +++ b/src/http/input/preferences/UnionPreferenceParser.ts @@ -1,5 +1,5 @@ import { InternalServerError } from '../../../util/errors/InternalServerError'; -import { UnionHandler } from '../../../util/handlers/UnionHandler'; +import { StatusUnionHandler } from '../../../util/handlers/StatusUnionHandler'; import type { RepresentationPreferences } from '../../representation/RepresentationPreferences'; import type { PreferenceParser } from './PreferenceParser'; @@ -7,7 +7,7 @@ import type { PreferenceParser } from './PreferenceParser'; * Combines the results of multiple {@link PreferenceParser}s. * Will throw an error if multiple parsers return a range as these can't logically be combined. */ -export class UnionPreferenceParser extends UnionHandler { +export class UnionPreferenceParser extends StatusUnionHandler { public constructor(parsers: PreferenceParser[]) { super(parsers, false, false); } diff --git a/src/http/ldp/OperationHandler.ts b/src/http/ldp/OperationHandler.ts index d3564fdc0..c27f20235 100644 --- a/src/http/ldp/OperationHandler.ts +++ b/src/http/ldp/OperationHandler.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Operation } from '../Operation'; import type { ResponseDescription } from '../output/response/ResponseDescription'; diff --git a/src/http/output/ResponseWriter.ts b/src/http/output/ResponseWriter.ts index 593c0b184..6b1ba9d40 100644 --- a/src/http/output/ResponseWriter.ts +++ b/src/http/output/ResponseWriter.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpResponse } from '../../server/HttpResponse'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { ResponseDescription } from './response/ResponseDescription'; /** diff --git a/src/http/output/error/ErrorHandler.ts b/src/http/output/error/ErrorHandler.ts index 8d6f3b96e..8362ad01e 100644 --- a/src/http/output/error/ErrorHandler.ts +++ b/src/http/output/error/ErrorHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from '../../../server/HttpRequest'; import type { HttpError } from '../../../util/errors/HttpError'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { ResponseDescription } from '../response/ResponseDescription'; export interface ErrorHandlerArgs { diff --git a/src/http/output/metadata/MetadataWriter.ts b/src/http/output/metadata/MetadataWriter.ts index 353ad670e..af70e43ca 100644 --- a/src/http/output/metadata/MetadataWriter.ts +++ b/src/http/output/metadata/MetadataWriter.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpResponse } from '../../../server/HttpResponse'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; export interface MetadataWriterInput { diff --git a/src/identity/configuration/PromptFactory.ts b/src/identity/configuration/PromptFactory.ts index 22257a04f..347b2535c 100644 --- a/src/identity/configuration/PromptFactory.ts +++ b/src/identity/configuration/PromptFactory.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { interactionPolicy } from '../../../templates/types/oidc-provider'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; /** * Used to generate custom {@link interactionPolicy.Prompt}s. diff --git a/src/identity/interaction/InteractionHandler.ts b/src/identity/interaction/InteractionHandler.ts index d1423165d..010875240 100644 --- a/src/identity/interaction/InteractionHandler.ts +++ b/src/identity/interaction/InteractionHandler.ts @@ -1,7 +1,7 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { KoaContextWithOIDC } from '../../../templates/types/oidc-provider'; import type { Operation } from '../../http/Operation'; import type { Representation } from '../../http/representation/Representation'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; // OIDC library does not directly export the Interaction type export type Interaction = NonNullable; diff --git a/src/identity/interaction/JsonInteractionHandler.ts b/src/identity/interaction/JsonInteractionHandler.ts index 7ccc95b9d..68da5719f 100644 --- a/src/identity/interaction/JsonInteractionHandler.ts +++ b/src/identity/interaction/JsonInteractionHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { Json } from '../../util/Json'; import type { Interaction } from './InteractionHandler'; import type { JsonRepresentation } from './InteractionUtil'; diff --git a/src/identity/interaction/password/util/EmailSender.ts b/src/identity/interaction/password/util/EmailSender.ts index ac6198e54..80e20a9cd 100644 --- a/src/identity/interaction/password/util/EmailSender.ts +++ b/src/identity/interaction/password/util/EmailSender.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; export interface EmailArgs { recipient: string; diff --git a/src/identity/interaction/pod/util/PodCreator.ts b/src/identity/interaction/pod/util/PodCreator.ts index b6f4a5889..37f0e94d6 100644 --- a/src/identity/interaction/pod/util/PodCreator.ts +++ b/src/identity/interaction/pod/util/PodCreator.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; export interface PodCreatorInput { /** diff --git a/src/identity/ownership/OwnershipValidator.ts b/src/identity/ownership/OwnershipValidator.ts index 84fcaf0e7..9f0725c29 100644 --- a/src/identity/ownership/OwnershipValidator.ts +++ b/src/identity/ownership/OwnershipValidator.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; /** * A class that validates if a someone owns a WebId. diff --git a/src/index.ts b/src/index.ts index f3024aa2a..c7d83015d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -554,21 +554,13 @@ export * from './util/errors/UnauthorizedHttpError'; export * from './util/errors/UnsupportedMediaTypeHttpError'; // Util/Handlers -export * from './util/handlers/ArrayUnionHandler'; -export * from './util/handlers/AsyncHandler'; -export * from './util/handlers/BooleanHandler'; -export * from './util/handlers/CachedHandler'; export * from './util/handlers/ConditionalHandler'; -export * from './util/handlers/HandlerUtil'; export * from './util/handlers/MethodFilterHandler'; -export * from './util/handlers/ParallelHandler'; -export * from './util/handlers/ProcessHandler'; -export * from './util/handlers/SequenceHandler'; -export * from './util/handlers/StaticHandler'; -export * from './util/handlers/StaticThrowHandler'; -export * from './util/handlers/UnionHandler'; -export * from './util/handlers/UnsupportedAsyncHandler'; -export * from './util/handlers/WaterfallHandler'; +export * from './util/handlers/StatusArrayUnionHandler'; +export * from './util/handlers/StatusBooleanHandler'; +export * from './util/handlers/StatusHandler'; +export * from './util/handlers/StatusUnionHandler'; +export * from './util/handlers/StatusWaterfallHandler'; // Util/Identifiers export * from './util/identifiers/BaseIdentifierStrategy'; diff --git a/src/init/Initializer.ts b/src/init/Initializer.ts index cbdd9d999..810548e10 100644 --- a/src/init/Initializer.ts +++ b/src/init/Initializer.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; /** * Initializer is used to indicate an AsyncHandler that performs initialization logic. diff --git a/src/init/cli/CliExtractor.ts b/src/init/cli/CliExtractor.ts index edbf013fd..9681a3a7f 100644 --- a/src/init/cli/CliExtractor.ts +++ b/src/init/cli/CliExtractor.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { CliArgv, Shorthand } from '../variables/Types'; /** diff --git a/src/init/final/Finalizer.ts b/src/init/final/Finalizer.ts index 97208895b..3f57b4448 100644 --- a/src/init/final/Finalizer.ts +++ b/src/init/final/Finalizer.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; /** * Finalizer is used to indicate an AsyncHandler that performs finalization logic. diff --git a/src/init/variables/ShorthandResolver.ts b/src/init/variables/ShorthandResolver.ts index 63e1d0e3b..70de337cd 100644 --- a/src/init/variables/ShorthandResolver.ts +++ b/src/init/variables/ShorthandResolver.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Shorthand, VariableBindings } from './Types'; /** diff --git a/src/init/variables/extractors/ShorthandExtractor.ts b/src/init/variables/extractors/ShorthandExtractor.ts index c2a28d70a..cbc8e5111 100644 --- a/src/init/variables/extractors/ShorthandExtractor.ts +++ b/src/init/variables/extractors/ShorthandExtractor.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Shorthand } from '../Types'; /** diff --git a/src/pods/generate/variables/VariableHandler.ts b/src/pods/generate/variables/VariableHandler.ts index 73608efc2..ce56e682f 100644 --- a/src/pods/generate/variables/VariableHandler.ts +++ b/src/pods/generate/variables/VariableHandler.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { ResourceIdentifier } from '../../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { PodSettings } from '../../settings/PodSettings'; /** diff --git a/src/server/HttpHandler.ts b/src/server/HttpHandler.ts index a48314ae9..446d4fbdb 100644 --- a/src/server/HttpHandler.ts +++ b/src/server/HttpHandler.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from './HttpRequest'; import type { HttpResponse } from './HttpResponse'; diff --git a/src/server/OperationHttpHandler.ts b/src/server/OperationHttpHandler.ts index 31b4b1ddc..9ad36af4b 100644 --- a/src/server/OperationHttpHandler.ts +++ b/src/server/OperationHttpHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Operation } from '../http/Operation'; import type { ResponseDescription } from '../http/output/response/ResponseDescription'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; import type { HttpHandlerInput } from './HttpHandler'; export interface OperationHttpHandlerInput extends HttpHandlerInput { diff --git a/src/server/ServerConfigurator.ts b/src/server/ServerConfigurator.ts index 60907f9d3..66a7caf26 100644 --- a/src/server/ServerConfigurator.ts +++ b/src/server/ServerConfigurator.ts @@ -1,5 +1,5 @@ import type { Server } from 'node:http'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; /** * Configures a {@link Server} by attaching listeners for specific events. diff --git a/src/server/WebSocketHandler.ts b/src/server/WebSocketHandler.ts index a6f1ceb80..c8e7faa1d 100644 --- a/src/server/WebSocketHandler.ts +++ b/src/server/WebSocketHandler.ts @@ -1,5 +1,5 @@ import type { WebSocket } from 'ws'; -import { AsyncHandler } from '../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { HttpRequest } from './HttpRequest'; export interface WebSocketHandlerInput { diff --git a/src/server/description/StorageDescriber.ts b/src/server/description/StorageDescriber.ts index 842d36342..54174dce7 100644 --- a/src/server/description/StorageDescriber.ts +++ b/src/server/description/StorageDescriber.ts @@ -1,6 +1,6 @@ import type { Quad } from '@rdfjs/types'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; /** * Generates Quads that need to be added to the given storage description resource. diff --git a/src/server/notifications/ListeningActivityHandler.ts b/src/server/notifications/ListeningActivityHandler.ts index 703b5e783..5de9905a9 100644 --- a/src/server/notifications/ListeningActivityHandler.ts +++ b/src/server/notifications/ListeningActivityHandler.ts @@ -1,8 +1,8 @@ import { getLoggerFor } from 'global-logger-factory'; +import { StaticHandler } from 'asynchronous-handlers'; import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { createErrorMessage } from '../../util/errors/ErrorUtil'; -import { StaticHandler } from '../../util/handlers/StaticHandler'; import type { AS, VocabularyTerm } from '../../util/Vocabularies'; import type { ActivityEmitter } from './ActivityEmitter'; import type { NotificationChannelStorage } from './NotificationChannelStorage'; diff --git a/src/server/notifications/NotificationEmitter.ts b/src/server/notifications/NotificationEmitter.ts index b6d4b1d94..ee9d92410 100644 --- a/src/server/notifications/NotificationEmitter.ts +++ b/src/server/notifications/NotificationEmitter.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../../http/representation/Representation'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { NotificationChannel } from './NotificationChannel'; export interface NotificationEmitterInput { diff --git a/src/server/notifications/NotificationHandler.ts b/src/server/notifications/NotificationHandler.ts index 4ddeb64cb..5480d5015 100644 --- a/src/server/notifications/NotificationHandler.ts +++ b/src/server/notifications/NotificationHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { AS, VocabularyTerm } from '../../util/Vocabularies'; import type { NotificationChannel } from './NotificationChannel'; diff --git a/src/server/notifications/StateHandler.ts b/src/server/notifications/StateHandler.ts index ca391ba45..2106cec27 100644 --- a/src/server/notifications/StateHandler.ts +++ b/src/server/notifications/StateHandler.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { NotificationChannel } from './NotificationChannel'; /** diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts index c758dfb32..4bad26c3f 100644 --- a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts @@ -1,6 +1,6 @@ import { getLoggerFor } from 'global-logger-factory'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../../../http/representation/Representation'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import { readableToString } from '../../../util/StreamUtil'; import type { NotificationChannel } from '../NotificationChannel'; import type { StreamingHttpMap } from './StreamingHttpMap'; diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts index 61304a7b1..887636c1f 100644 --- a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts @@ -1,8 +1,8 @@ import { getLoggerFor } from 'global-logger-factory'; +import { StaticHandler } from 'asynchronous-handlers'; import type { RepresentationMetadata } from '../../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../../http/representation/ResourceIdentifier'; import { createErrorMessage } from '../../../util/errors/ErrorUtil'; -import { StaticHandler } from '../../../util/handlers/StaticHandler'; import type { AS, VocabularyTerm } from '../../../util/Vocabularies'; import type { ActivityEmitter } from '../ActivityEmitter'; import type { NotificationHandler } from '../NotificationHandler'; diff --git a/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts index 901930760..2c31c97fb 100644 --- a/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts @@ -1,5 +1,5 @@ import type { WebSocket } from 'ws'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { NotificationChannel } from '../NotificationChannel'; export interface WebSocket2023HandlerInput { diff --git a/src/server/notifications/generate/NotificationGenerator.ts b/src/server/notifications/generate/NotificationGenerator.ts index 19341a9b1..2ae26d2dd 100644 --- a/src/server/notifications/generate/NotificationGenerator.ts +++ b/src/server/notifications/generate/NotificationGenerator.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Notification } from '../Notification'; import type { NotificationHandlerInput } from '../NotificationHandler'; diff --git a/src/server/notifications/serialize/NotificationSerializer.ts b/src/server/notifications/serialize/NotificationSerializer.ts index b637cb7e1..6cf0f6e45 100644 --- a/src/server/notifications/serialize/NotificationSerializer.ts +++ b/src/server/notifications/serialize/NotificationSerializer.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../../../http/representation/Representation'; -import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { Notification } from '../Notification'; import type { NotificationChannel } from '../NotificationChannel'; diff --git a/src/server/util/BaseRouterHandler.ts b/src/server/util/BaseRouterHandler.ts index 8bcf9a927..9370ba03f 100644 --- a/src/server/util/BaseRouterHandler.ts +++ b/src/server/util/BaseRouterHandler.ts @@ -1,8 +1,8 @@ +import type { AsyncHandlerInput, AsyncHandlerOutput } from 'asynchronous-handlers'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { MethodNotAllowedHttpError } from '../../util/errors/MethodNotAllowedHttpError'; import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError'; -import type { AsyncHandlerInput, AsyncHandlerOutput } from '../../util/handlers/AsyncHandler'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import { trimTrailingSlashes } from '../../util/PathUtil'; export interface BaseRouterHandlerArgs> { diff --git a/src/storage/conversion/RepresentationConverter.ts b/src/storage/conversion/RepresentationConverter.ts index e0017547e..7b698baa3 100644 --- a/src/storage/conversion/RepresentationConverter.ts +++ b/src/storage/conversion/RepresentationConverter.ts @@ -1,7 +1,7 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../../http/representation/Representation'; import type { RepresentationPreferences } from '../../http/representation/RepresentationPreferences'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; export interface RepresentationConverterArgs { /** diff --git a/src/storage/patch/PatchHandler.ts b/src/storage/patch/PatchHandler.ts index 8493fc467..a667c793e 100644 --- a/src/storage/patch/PatchHandler.ts +++ b/src/storage/patch/PatchHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Patch } from '../../http/representation/Patch'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { ChangeMap, ResourceStore } from '../ResourceStore'; export type PatchHandlerInput = { diff --git a/src/storage/patch/RdfStorePatcher.ts b/src/storage/patch/RdfStorePatcher.ts index e18d4215f..d1e8d628e 100644 --- a/src/storage/patch/RdfStorePatcher.ts +++ b/src/storage/patch/RdfStorePatcher.ts @@ -1,7 +1,7 @@ import type { Store } from 'n3'; +import { AsyncHandler } from 'asynchronous-handlers'; import type { Patch } from '../../http/representation/Patch'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; export interface RdfStorePatcherInput { /** diff --git a/src/storage/patch/RepresentationPatcher.ts b/src/storage/patch/RepresentationPatcher.ts index 40af46f2d..61b0a1807 100644 --- a/src/storage/patch/RepresentationPatcher.ts +++ b/src/storage/patch/RepresentationPatcher.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Patch } from '../../http/representation/Patch'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; export interface RepresentationPatcherInput { identifier: ResourceIdentifier; diff --git a/src/storage/routing/RouterRule.ts b/src/storage/routing/RouterRule.ts index d5fb70761..1a63de703 100644 --- a/src/storage/routing/RouterRule.ts +++ b/src/storage/routing/RouterRule.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { Representation } from '../../http/representation/Representation'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; -import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import type { ResourceStore } from '../ResourceStore'; /** diff --git a/src/util/PromiseUtil.ts b/src/util/PromiseUtil.ts index e44bd78a5..b63a59e7b 100644 --- a/src/util/PromiseUtil.ts +++ b/src/util/PromiseUtil.ts @@ -1,5 +1,4 @@ import { types } from 'node:util'; -import { createAggregateError } from './errors/HttpErrorUtil'; export type PromiseOrValue = T | Promise; @@ -50,26 +49,3 @@ export async function promiseSome(predicates: Promise[]): Promise resolve(false), noop); }); } - -/** - * Obtains the values of all fulfilled promises. - * If there are rejections (and `ignoreErrors` is false), throws a combined error of all rejected promises. - */ -export async function allFulfilled(promises: Promise [], ignoreErrors = false): Promise { - // Collect values and errors - const values: T[] = []; - const errors: Error[] = []; - for (const result of await Promise.allSettled(promises)) { - if (result.status === 'fulfilled') { - values.push(result.value); - } else if (!ignoreErrors) { - errors.push(result.reason as Error); - } - } - - // Either throw or return - if (errors.length > 0) { - throw createAggregateError(errors); - } - return values; -} diff --git a/src/util/errors/HttpErrorUtil.ts b/src/util/errors/HttpErrorUtil.ts index fc04a66a8..b3a9fef95 100644 --- a/src/util/errors/HttpErrorUtil.ts +++ b/src/util/errors/HttpErrorUtil.ts @@ -2,7 +2,7 @@ import { RepresentationMetadata } from '../../http/representation/Representation import { toPredicateTerm } from '../TermUtil'; import { SOLID_ERROR_TERM } from '../Vocabularies'; import { BadRequestHttpError } from './BadRequestHttpError'; -import { createErrorMessage } from './ErrorUtil'; +import { createErrorMessage, isError } from './ErrorUtil'; import { HttpError } from './HttpError'; import { InternalServerError } from './InternalServerError'; import Dict = NodeJS.Dict; @@ -44,6 +44,24 @@ export function extractErrorTerms(metadata: RepresentationMetadata): Dict - HttpError.isInstance(error) ? error : new InternalServerError(createErrorMessage(error))); + const httpErrors = errors.map(toHttpError); const messages = httpErrors.map((error: Error): string => error.message).filter((msg): boolean => msg.length > 0); // Let message depend on the messages that were present. diff --git a/src/util/handlers/ArrayUnionHandler.ts b/src/util/handlers/ArrayUnionHandler.ts deleted file mode 100644 index b3e4e1170..000000000 --- a/src/util/handlers/ArrayUnionHandler.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { AsyncHandler, AsyncHandlerOutput } from './AsyncHandler'; -import { UnionHandler } from './UnionHandler'; - -/** - * A utility handler that concatenates the results of all its handlers into a single result. - */ -export class ArrayUnionHandler> extends UnionHandler { - public constructor(handlers: T[], requireAll?: boolean, ignoreErrors?: boolean) { - super(handlers, requireAll, ignoreErrors); - } - - protected async combine(results: AsyncHandlerOutput[]): Promise> { - return results.flat() as AsyncHandlerOutput; - } -} diff --git a/src/util/handlers/AsyncHandler.ts b/src/util/handlers/AsyncHandler.ts deleted file mode 100644 index da4ffc6ef..000000000 --- a/src/util/handlers/AsyncHandler.ts +++ /dev/null @@ -1,45 +0,0 @@ -type Awaited = T extends PromiseLike ? U : T; -export type AsyncHandlerInput> = Parameters[0]; -export type AsyncHandlerOutput> = Awaited>; - -/** - * Simple interface for classes that can potentially handle a specific kind of data asynchronously. - */ -export abstract class AsyncHandler { - /** - * Checks whether the input can be handled by this class. - * If it cannot handle the input, rejects with an error explaining why. - * - * @param input - Input that could potentially be handled. - * - * @returns A promise resolving if the input can be handled, rejecting with an Error if not. - */ - // eslint-disable-next-line unused-imports/no-unused-vars - public async canHandle(input: TIn): Promise { - // Support any input by default - } - - /** - * Handles the given input. This may only be called if {@link canHandle} did not reject. - * When unconditionally calling both in sequence, consider {@link handleSafe} instead. - * - * @param input - Input that needs to be handled. - * - * @returns A promise resolving when handling is finished. - */ - public abstract handle(input: TIn): Promise; - - /** - * Helper function that first runs {@link canHandle} followed by {@link handle}. - * Throws the error of {@link canHandle} if the data cannot be handled, - * or returns the result of {@link handle} otherwise. - * - * @param input - Input data that will be handled if it can be handled. - * - * @returns A promise resolving if the input can be handled, rejecting with an Error if not. - */ - public async handleSafe(input: TIn): Promise { - await this.canHandle(input); - return this.handle(input); - } -} diff --git a/src/util/handlers/BooleanHandler.ts b/src/util/handlers/BooleanHandler.ts deleted file mode 100644 index 29d3a9f87..000000000 --- a/src/util/handlers/BooleanHandler.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { getLoggerFor } from 'global-logger-factory'; -import { InternalServerError } from '../errors/InternalServerError'; -import { promiseSome } from '../PromiseUtil'; -import { AsyncHandler } from './AsyncHandler'; -import { filterHandlers } from './HandlerUtil'; - -/** - * A composite handler that returns true if any of its handlers can handle the input and return true. - * Handler errors are interpreted as false results. - */ -export class BooleanHandler extends AsyncHandler { - protected readonly logger = getLoggerFor(this); - - private readonly handlers: AsyncHandler[]; - - /** - * Creates a new BooleanHandler that stores the given handlers. - * - * @param handlers - Handlers over which it will run. - */ - public constructor(handlers: AsyncHandler[]) { - super(); - this.handlers = handlers; - } - - public async canHandle(input: TIn): Promise { - // We use this to generate an error if no handler supports the input - await filterHandlers(this.handlers, input); - } - - public async handleSafe(input: TIn): Promise { - const handlers = await filterHandlers(this.handlers, input); - return promiseSome(handlers.map(async(handler): Promise => handler.handle(input))); - } - - public async handle(input: TIn): Promise { - let handlers: AsyncHandler[]; - try { - handlers = await filterHandlers(this.handlers, input); - } catch (error: unknown) { - this.logger.warn('All handlers failed. This might be the consequence of calling handle before canHandle.'); - throw new InternalServerError('All handlers failed', { cause: error }); - } - return promiseSome(handlers.map(async(handler): Promise => handler.handle(input))); - } -} diff --git a/src/util/handlers/CachedHandler.ts b/src/util/handlers/CachedHandler.ts deleted file mode 100644 index 0f916a7be..000000000 --- a/src/util/handlers/CachedHandler.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { AsyncHandler } from './AsyncHandler'; - -type NestedMap = TOut | WeakMap>; - -/** - * Caches output data from the source handler based on the input object. - * The `fields` parameter can be used to instead use one or more specific entries from the input object as cache key, - * so has as actual required typing `(keyof TIn)[]`. - * - * A {@link WeakMap} is used internally so strict object equality determines cache hits, - * and data will be removed once the key stops existing. - * This also means that the cache key needs to be an object. - * Errors will be thrown in case a primitive is used. - */ -export class CachedHandler, TOut = void> extends AsyncHandler { - private readonly source: AsyncHandler; - private readonly fields?: [keyof TIn, ...(keyof TIn)[]]; - - private readonly cache: WeakMap>; - - public constructor(source: AsyncHandler, fields?: string[]) { - super(); - this.source = source; - if (fields) { - if (fields.length === 0) { - throw new Error('The fields parameter needs to have at least 1 entry if defined.'); - } - // This is the first of many casts in this class. - // All of them are 100% correct though and are a consequence - // of the cache depth depending on the length of `fields` - // and the Node.js array functions not always having strict enough typings. - this.fields = fields as [keyof TIn, ...(keyof TIn)[]]; - } - this.cache = new WeakMap(); - } - - public async canHandle(input: TIn): Promise { - const keys = this.getKeys(input); - const map = this.findDestination(input, keys, this.cache); - - if (map?.has(keys.pop()!)) { - return; - } - - return this.source.canHandle(input); - } - - public async handle(input: TIn): Promise { - const keys = this.getKeys(input); - const map = this.findDestination(input, keys, this.cache, true)!; - - const key = keys.pop()!; - let result = map.get(key); - if (result) { - return result; - } - - result = await this.source.handle(input); - map.set(key, result); - - return result; - } - - /** - * Extracts the values that will be used as keys from the input object. - * In case the `fields` value was undefined, this will return an array containing the input object itself. - */ - protected getKeys(input: TIn): [object, ...object[]] { - if (!this.fields) { - return [ input ]; - } - - return this.fields.map((field): object => input[field] as object) as [object, ...object[]]; - } - - /** - * Returns the `WeakMap` that contains actual objects that were cached, - * so the last `WeakMap` in the chain of maps. - * - * Returns `undefined` if no such map exists because earlier keys were not cached. - * - * Will always return a map if `ensure` is set to true, - * in such a case the intermediate maps will be created and added to the previous map. - */ - protected findDestination(input: TIn, keys: object[], cache: WeakMap>, ensure = false): - WeakMap | undefined { - if (keys.length === 1) { - return cache as WeakMap; - } - - const key = keys[0]; - let nextCache = cache.get(key) as WeakMap> | undefined; - if (!nextCache) { - if (!ensure) { - return; - } - nextCache = new WeakMap>(); - cache.set(key, nextCache); - } - - return this.findDestination(input, keys.slice(1), nextCache, ensure); - } -} diff --git a/src/util/handlers/ConditionalHandler.ts b/src/util/handlers/ConditionalHandler.ts index 559ff3be1..1917b05c0 100644 --- a/src/util/handlers/ConditionalHandler.ts +++ b/src/util/handlers/ConditionalHandler.ts @@ -1,6 +1,6 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import type { KeyValueStorage } from '../../storage/keyvalue/KeyValueStorage'; import { NotImplementedHttpError } from '../errors/NotImplementedHttpError'; -import { AsyncHandler } from './AsyncHandler'; /** * This handler will pass all requests to the wrapped handler, diff --git a/src/util/handlers/HandlerUtil.ts b/src/util/handlers/HandlerUtil.ts index de1f6e528..28d5cc8b2 100644 --- a/src/util/handlers/HandlerUtil.ts +++ b/src/util/handlers/HandlerUtil.ts @@ -1,60 +1,13 @@ -import { createErrorMessage, isError } from '../errors/ErrorUtil'; -import { createAggregateError } from '../errors/HttpErrorUtil'; -import type { AsyncHandler } from './AsyncHandler'; +import { toHttpError } from '../errors/HttpErrorUtil'; /** - * Finds a handler that can handle the given input data. - * Otherwise an error gets thrown. - * - * @param handlers - List of handlers to search in. - * @param input - The input data. - * - * @returns A promise resolving to a handler that supports the data or otherwise rejecting. + * Makes sure that if the given function rejects with an error, + * an {@link HttpError} will be used. */ -export async function findHandler(handlers: AsyncHandler[], input: TIn): -Promise> { - const errors: Error[] = []; - - for (const handler of handlers) { - try { - await handler.canHandle(input); - - return handler; - } catch (error: unknown) { - if (isError(error)) { - errors.push(error); - } else { - errors.push(new Error(createErrorMessage(error))); - } - } +export async function ensureHttpError(fn: () => Promise): Promise { + try { + return await fn(); + } catch (error) { + throw toHttpError(error); } - - throw createAggregateError(errors); -} - -/** - * Filters a list of handlers to only keep those that can handle the input. - * Will error if no matching handlers are found. - * - * @param handlers - Handlers to filter. - * @param input - Input that needs to be supported. - */ -export async function filterHandlers(handlers: AsyncHandler[], input: TIn): -Promise[]> { - const results = await Promise.allSettled(handlers.map(async(handler): Promise> => { - await handler.canHandle(input); - return handler; - })); - const matches = results.filter(({ status }): boolean => status === 'fulfilled') - .map((result): AsyncHandler => - (result as PromiseFulfilledResult>).value); - - if (matches.length > 0) { - return matches; - } - - // Generate error in case no matches were found - const errors = results.map((result): Error => (result as PromiseRejectedResult).reason as Error); - - throw createAggregateError(errors); } diff --git a/src/util/handlers/MethodFilterHandler.ts b/src/util/handlers/MethodFilterHandler.ts index e0c5814c6..c92b6eeab 100644 --- a/src/util/handlers/MethodFilterHandler.ts +++ b/src/util/handlers/MethodFilterHandler.ts @@ -1,5 +1,5 @@ +import { AsyncHandler } from 'asynchronous-handlers'; import { NotImplementedHttpError } from '../errors/NotImplementedHttpError'; -import { AsyncHandler } from './AsyncHandler'; // The formats from which we can detect the method type InType = { method: string } | { request: { method: string }} | { operation: { method: string }}; diff --git a/src/util/handlers/ParallelHandler.ts b/src/util/handlers/ParallelHandler.ts deleted file mode 100644 index bd2a803b4..000000000 --- a/src/util/handlers/ParallelHandler.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AsyncHandler } from './AsyncHandler'; - -/** - * A composite handler that executes handlers in parallel. - */ -export class ParallelHandler extends AsyncHandler { - private readonly handlers: AsyncHandler[]; - - public constructor(handlers: AsyncHandler[]) { - super(); - this.handlers = [ ...handlers ]; - } - - public async canHandle(input: TIn): Promise { - await Promise.all(this.handlers.map(async(handler): Promise => handler.canHandle(input))); - } - - public async handle(input: TIn): Promise { - return Promise.all(this.handlers.map(async(handler): Promise => handler.handle(input))); - } -} diff --git a/src/util/handlers/ProcessHandler.ts b/src/util/handlers/ProcessHandler.ts deleted file mode 100644 index 43dc90e12..000000000 --- a/src/util/handlers/ProcessHandler.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { ClusterManager } from '../../init/cluster/ClusterManager'; -import { NotImplementedHttpError } from '../errors/NotImplementedHttpError'; -import { AsyncHandler } from './AsyncHandler'; - -/** - * A wrapper handler that will only run the wrapped handler if it is executed from: - * * when running multithreaded: either the **primary** or a **worker process** - * * when running singlethreaded: **the only process** (i.e. always) - */ -export class ProcessHandler extends AsyncHandler { - private readonly clusterManager: ClusterManager; - private readonly source: AsyncHandler; - private readonly executeOnPrimary: boolean; - - /** - * Creates a new ProcessHandler - * - * @param source - The wrapped handler - * @param clusterManager - The ClusterManager in use - * @param executeOnPrimary - Whether to execute the source handler when the process is the _primary_ or a _worker_. - */ - public constructor(source: AsyncHandler, clusterManager: ClusterManager, executeOnPrimary: boolean) { - super(); - this.source = source; - this.clusterManager = clusterManager; - this.executeOnPrimary = executeOnPrimary; - } - - public async canHandle(input: TIn): Promise { - if (!this.canExecute()) { - throw new NotImplementedHttpError(`Will not execute on ${this.executeOnPrimary ? 'worker' : 'primary'} process.`); - } - await this.source.canHandle(input); - } - - public async handle(input: TIn): Promise { - return this.source.handle(input); - } - - /** - * Checks if the condition has already been fulfilled. - */ - private canExecute(): boolean { - return this.clusterManager.isSingleThreaded() || - (this.executeOnPrimary ? this.clusterManager.isPrimary() : this.clusterManager.isWorker()); - } -} diff --git a/src/util/handlers/SequenceHandler.ts b/src/util/handlers/SequenceHandler.ts deleted file mode 100644 index f84678cb9..000000000 --- a/src/util/handlers/SequenceHandler.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { AsyncHandler } from './AsyncHandler'; - -/** - * A composite handler that will try to run all supporting handlers sequentially - * and return the value of the last supported handler. - * The `canHandle` check of this handler will always succeed. - */ -export class SequenceHandler extends AsyncHandler { - private readonly handlers: AsyncHandler[]; - - public constructor(handlers: AsyncHandler[]) { - super(); - this.handlers = [ ...handlers ]; - } - - public async handle(input: TIn): Promise { - let result: TOut | undefined; - for (const handler of this.handlers) { - let supported: boolean; - try { - await handler.canHandle(input); - supported = true; - } catch { - supported = false; - } - if (supported) { - result = await handler.handle(input); - } - } - return result; - } -} diff --git a/src/util/handlers/StaticHandler.ts b/src/util/handlers/StaticHandler.ts deleted file mode 100644 index 4edec30c8..000000000 --- a/src/util/handlers/StaticHandler.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { AsyncHandler } from './AsyncHandler'; - -/** - * A handler that always resolves and always returns the stored value. - * Will return undefined if no value is stored. - * - * The generic type extends `any` due to Components.js requirements. - */ -export class StaticHandler extends AsyncHandler { - private readonly value?: T; - - public constructor(value?: T) { - super(); - this.value = value; - } - - public async handle(): Promise { - return this.value!; - } -} diff --git a/src/util/handlers/StaticThrowHandler.ts b/src/util/handlers/StaticThrowHandler.ts deleted file mode 100644 index d33da9129..000000000 --- a/src/util/handlers/StaticThrowHandler.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { HttpError, HttpErrorClass } from '../errors/HttpError'; -import { AsyncHandler } from './AsyncHandler'; - -/** - * Utility handler that can handle all input and always throws an instance of the given error. - */ -export class StaticThrowHandler extends AsyncHandler { - protected readonly error: HttpError; - - public constructor(error: HttpError) { - super(); - this.error = error; - } - - public async handle(): Promise { - // We are creating a new instance of the error instead of rethrowing the error, - // as reusing the same error can cause problem as the metadata is then also reused. - throw new (this.error.constructor as HttpErrorClass)(); - } -} diff --git a/src/util/handlers/StatusArrayUnionHandler.ts b/src/util/handlers/StatusArrayUnionHandler.ts new file mode 100644 index 000000000..b22ea0e97 --- /dev/null +++ b/src/util/handlers/StatusArrayUnionHandler.ts @@ -0,0 +1,13 @@ +import type { AsyncHandler, AsyncHandlerInput, AsyncHandlerOutput } from 'asynchronous-handlers'; +import { ArrayUnionHandler } from 'asynchronous-handlers'; +import { StatusHandler } from './StatusHandler'; + +/** + * A {@link StatusHandler} implementing an {@link ArrayUnionHandler}. + */ +export class StatusArrayUnionHandler> + extends StatusHandler, AsyncHandlerOutput> { + public constructor(handlers: T[], requireAll?: boolean, ignoreErrors?: boolean) { + super(new ArrayUnionHandler(handlers, requireAll, ignoreErrors)); + } +} diff --git a/src/util/handlers/StatusBooleanHandler.ts b/src/util/handlers/StatusBooleanHandler.ts new file mode 100644 index 000000000..ae1e7a911 --- /dev/null +++ b/src/util/handlers/StatusBooleanHandler.ts @@ -0,0 +1,12 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { BooleanHandler } from 'asynchronous-handlers'; +import { StatusHandler } from './StatusHandler'; + +/** + * A {@link StatusHandler} implementing a {@link BooleanHandler}. + */ +export class StatusBooleanHandler extends StatusHandler { + public constructor(handlers: AsyncHandler[]) { + super(new BooleanHandler(handlers)); + } +} diff --git a/src/util/handlers/StatusHandler.ts b/src/util/handlers/StatusHandler.ts new file mode 100644 index 000000000..fcf46d543 --- /dev/null +++ b/src/util/handlers/StatusHandler.ts @@ -0,0 +1,28 @@ +import { AsyncHandler } from 'asynchronous-handlers'; +import { ensureHttpError } from './HandlerUtil'; + +/** + * Wraps around an {@link AsyncHandler} to make sure all errors thrown are an {@link HttpError}. + * In the case of an {@link AggregateError} containing HttpErrors, + * the status code will be determined based on what makes most sense for them. + */ +export class StatusHandler extends AsyncHandler { + protected readonly handler: AsyncHandler; + + public constructor(handler: AsyncHandler) { + super(); + this.handler = handler; + } + + public async canHandle(input: TIn): Promise { + return ensureHttpError(async(): Promise => this.handler.canHandle(input)); + } + + public async handle(input: TIn): Promise { + return ensureHttpError(async(): Promise => this.handler.handle(input)); + } + + public async handleSafe(input: TIn): Promise { + return ensureHttpError(async(): Promise => this.handler.handleSafe(input)); + } +} diff --git a/src/util/handlers/StatusUnionHandler.ts b/src/util/handlers/StatusUnionHandler.ts new file mode 100644 index 000000000..b68103a76 --- /dev/null +++ b/src/util/handlers/StatusUnionHandler.ts @@ -0,0 +1,23 @@ +import type { AsyncHandler, AsyncHandlerInput, AsyncHandlerOutput } from 'asynchronous-handlers'; +import { UnionHandler } from 'asynchronous-handlers'; +import { StatusHandler } from './StatusHandler'; + +/** + * A {@link StatusHandler} implementing a {@link UnionHandler}. + */ +export abstract class StatusUnionHandler> + extends StatusHandler, AsyncHandlerOutput> { + public constructor(handlers: T[], requireAll = false, ignoreErrors = !requireAll) { + // Workaround for the fact that we want the same behaviour as a UnionHandler + let combine: (results: AsyncHandlerOutput[]) => Promise>; + const INTERNAL_CLASS = class extends UnionHandler { + protected async combine(results: AsyncHandlerOutput[]): Promise> { + return combine(results); + } + }; + super(new INTERNAL_CLASS(handlers, requireAll, ignoreErrors)); + combine = this.combine.bind(this); + } + + protected abstract combine(results: AsyncHandlerOutput[]): Promise>; +} diff --git a/src/util/handlers/StatusWaterfallHandler.ts b/src/util/handlers/StatusWaterfallHandler.ts new file mode 100644 index 000000000..d67c5f3c0 --- /dev/null +++ b/src/util/handlers/StatusWaterfallHandler.ts @@ -0,0 +1,12 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { WaterfallHandler } from 'asynchronous-handlers'; +import { StatusHandler } from './StatusHandler'; + +/** + * A {@link StatusHandler} implementing a {@link WaterfallHandler}. + */ +export class StatusWaterfallHandler extends StatusHandler { + public constructor(handlers: AsyncHandler[]) { + super(new WaterfallHandler(handlers)); + } +} diff --git a/src/util/handlers/UnionHandler.ts b/src/util/handlers/UnionHandler.ts deleted file mode 100644 index c508a393f..000000000 --- a/src/util/handlers/UnionHandler.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { allFulfilled } from '../PromiseUtil'; -import type { AsyncHandlerInput, AsyncHandlerOutput } from './AsyncHandler'; -import { AsyncHandler } from './AsyncHandler'; -import { filterHandlers, findHandler } from './HandlerUtil'; - -/** - * Utility handler that allows combining the results of multiple handlers into one. - * Will run the handlers and then call the abstract `combine` function with the results, - * which then generates the handler's output. - */ -export abstract class UnionHandler> extends - AsyncHandler, AsyncHandlerOutput> { - protected readonly handlers: T[]; - private readonly requireAll: boolean; - private readonly ignoreErrors: boolean; - - /** - * Creates a new `UnionHandler`. - * - * When `requireAll` is false or `ignoreErrors` is true, - * the length of the input to `combine` can vary; - * otherwise, it is exactly the number of handlers. - * - * @param handlers - The handlers whose output is to be combined. - * @param requireAll - If true, will fail if any of the handlers do not support the input. - If false, only the handlers that support the input will be called; - * will fail only if none of the handlers can handle the input. - * @param ignoreErrors - If true, ignores handlers that fail by omitting their output; - * if false, fails when any handlers fail. - */ - public constructor(handlers: T[], requireAll = false, ignoreErrors = !requireAll) { - super(); - this.handlers = handlers; - this.requireAll = requireAll; - this.ignoreErrors = ignoreErrors; - } - - public async canHandle(input: AsyncHandlerInput): Promise { - if (this.requireAll) { - await this.allCanHandle(input); - } else { - // This will error if no handler supports the input - await findHandler(this.handlers, input); - } - } - - public async handle(input: AsyncHandlerInput): Promise> { - const handlers = this.requireAll ? this.handlers : (await filterHandlers(this.handlers, input)) as T[]; - const results = handlers.map(async(handler): Promise> => - (handler.handle(input)) as Promise>); - return this.combine(await allFulfilled(results, this.ignoreErrors)); - } - - /** - * Checks if all handlers can handle the input. - * If not, throw an error based on the errors of the failed handlers. - */ - protected async allCanHandle(input: AsyncHandlerInput): Promise { - await allFulfilled(this.handlers.map(async(handler): Promise => handler.canHandle(input))); - } - - /** - * Combines the results of the handlers into a single output. - */ - protected abstract combine(results: AsyncHandlerOutput[]): Promise>; -} diff --git a/src/util/handlers/UnsupportedAsyncHandler.ts b/src/util/handlers/UnsupportedAsyncHandler.ts deleted file mode 100644 index 230f898eb..000000000 --- a/src/util/handlers/UnsupportedAsyncHandler.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { NotImplementedHttpError } from '../errors/NotImplementedHttpError'; -import { AsyncHandler } from './AsyncHandler'; - -/** - * Handler that does not support any input and will always throw an error. - */ -export class UnsupportedAsyncHandler extends AsyncHandler { - private readonly errorMessage?: string; - - public constructor(errorMessage?: string) { - super(); - this.errorMessage = errorMessage; - } - - public async canHandle(): Promise { - throw new NotImplementedHttpError(this.errorMessage); - } - - public async handle(): Promise { - return this.canHandle(); - } -} diff --git a/src/util/handlers/WaterfallHandler.ts b/src/util/handlers/WaterfallHandler.ts deleted file mode 100644 index 2d5271c90..000000000 --- a/src/util/handlers/WaterfallHandler.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { getLoggerFor } from 'global-logger-factory'; -import { InternalServerError } from '../errors/InternalServerError'; -import type { AsyncHandler } from './AsyncHandler'; -import { findHandler } from './HandlerUtil'; - -/** - * A composite handler that tries multiple handlers one by one - * until it finds a handler that supports the input. - * The handlers will be checked in the order they appear in the input array, - * allowing for more fine-grained handlers to check before catch-all handlers. - */ -export class WaterfallHandler implements AsyncHandler { - protected readonly logger = getLoggerFor(this); - - private readonly handlers: AsyncHandler[]; - - /** - * Creates a new WaterfallHandler that stores the given handlers. - * - * @param handlers - Handlers over which it will run. - */ - public constructor(handlers: AsyncHandler[]) { - this.handlers = handlers; - } - - /** - * Checks whether any of the stored handlers can handle the given input. - * - * @param input - The data that would need to be handled. - * - * @returns A promise resolving if at least 1 handler supports to input, or rejecting if none do. - */ - public async canHandle(input: TIn): Promise { - await findHandler(this.handlers, input); - } - - /** - * Finds a handler that supports the given input and then lets it handle the given data. - * - * @param input - The data that needs to be handled. - * - * @returns A promise corresponding to the handle call of a handler that supports the input. - * It rejects if no handlers support the given data. - */ - public async handle(input: TIn): Promise { - let handler: AsyncHandler; - - try { - handler = await findHandler(this.handlers, input); - } catch (error: unknown) { - this.logger.warn('All handlers failed. This might be the consequence of calling handle before canHandle.'); - throw new InternalServerError('All handlers failed', { cause: error }); - } - - return handler.handle(input); - } - - /** - * Identical to {@link AsyncHandler.handleSafe} but optimized for composite - * by only needing 1 canHandle call on members. - * - * @param input - The input data. - * - * @returns A promise corresponding to the handle call of a handler that supports the input. - * It rejects if no handlers support the given data. - */ - public async handleSafe(input: TIn): Promise { - const handler = await findHandler(this.handlers, input); - - return handler.handle(input); - } -} diff --git a/src/util/templates/StaticTemplateEngine.ts b/src/util/templates/StaticTemplateEngine.ts index 3a3bc4913..1309e084c 100644 --- a/src/util/templates/StaticTemplateEngine.ts +++ b/src/util/templates/StaticTemplateEngine.ts @@ -1,4 +1,4 @@ -import type { AsyncHandler } from '../handlers/AsyncHandler'; +import type { AsyncHandler } from 'asynchronous-handlers'; import type { Template, TemplateEngineInput } from './TemplateEngine'; import { TemplateEngine } from './TemplateEngine'; import Dict = NodeJS.Dict; diff --git a/src/util/templates/TemplateEngine.ts b/src/util/templates/TemplateEngine.ts index 4e5100912..a1595b5ba 100644 --- a/src/util/templates/TemplateEngine.ts +++ b/src/util/templates/TemplateEngine.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; import Dict = NodeJS.Dict; export type Template = TemplateFileName | TemplateString | TemplatePath; diff --git a/test/unit/server/util/BaseRouterHandler.test.ts b/test/unit/server/util/BaseRouterHandler.test.ts index 8329ad97c..c2f0c8ed3 100644 --- a/test/unit/server/util/BaseRouterHandler.test.ts +++ b/test/unit/server/util/BaseRouterHandler.test.ts @@ -1,7 +1,7 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier'; import type { BaseRouterHandlerArgs } from '../../../../src/server/util/BaseRouterHandler'; import { BaseRouterHandler } from '../../../../src/server/util/BaseRouterHandler'; -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; class SimpleRouterHandler extends BaseRouterHandler> { public constructor(args: BaseRouterHandlerArgs>) { diff --git a/test/unit/util/errors/HttpErrorUtil.test.ts b/test/unit/util/errors/HttpErrorUtil.test.ts index 66f749135..df7f2786b 100644 --- a/test/unit/util/errors/HttpErrorUtil.test.ts +++ b/test/unit/util/errors/HttpErrorUtil.test.ts @@ -4,7 +4,9 @@ import { createAggregateError, errorTermsToMetadata, extractErrorTerms, + toHttpError, } from '../../../../src/util/errors/HttpErrorUtil'; +import { InternalServerError } from '../../../../src/util/errors/InternalServerError'; import { toPredicateTerm } from '../../../../src/util/TermUtil'; describe('HttpErrorUtil', (): void => { @@ -48,6 +50,23 @@ describe('HttpErrorUtil', (): void => { }); }); + describe('#toHttpError', (): void => { + it('keeps the error if it is an HttpError.', async(): Promise => { + const error = new InternalServerError('internal'); + expect(toHttpError(error)).toBe(error); + }); + + it('converts an error to an InternalServerError.', async(): Promise => { + const error = new Error('error'); + expect(toHttpError(error)).toEqual(new InternalServerError('error')); + }); + + it('converts unknown data to an InternalServerError.', async(): Promise => { + const error = 'error'; + expect(toHttpError(error)).toEqual(new InternalServerError('Unknown error: error')); + }); + }); + describe('#createAggregateError', (): void => { const error401 = new HttpError(401, 'UnauthorizedHttpError'); const error415 = new HttpError(415, 'UnsupportedMediaTypeHttpError'); diff --git a/test/unit/util/handlers/AsyncHandler.test.ts b/test/unit/util/handlers/AsyncHandler.test.ts deleted file mode 100644 index 30fe80a3f..000000000 --- a/test/unit/util/handlers/AsyncHandler.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { StaticAsyncHandler } from '../../../util/StaticAsyncHandler'; - -describe('An AsyncHandler', (): void => { - it('supports any input by default.', async(): Promise => { - class EmptyHandler extends AsyncHandler { - public async handle(): Promise { - return null; - } - } - const handler = new EmptyHandler(); - await expect(handler.canHandle('test')).resolves.toBeUndefined(); - }); - - it('calls canHandle and handle when handleSafe is called.', async(): Promise => { - const handlerTrue: AsyncHandler = new StaticAsyncHandler(true, null); - const canHandleFn = jest.fn(async(input: any): Promise => input); - const handleFn = jest.fn(async(input: any): Promise => input); - - handlerTrue.canHandle = canHandleFn; - handlerTrue.handle = handleFn; - await expect(handlerTrue.handleSafe('test')).resolves.toBe('test'); - expect(canHandleFn).toHaveBeenCalledTimes(1); - expect(handleFn).toHaveBeenCalledTimes(1); - }); - - it('does not call handle when canHandle errors during a handleSafe call.', async(): Promise => { - const handlerFalse: AsyncHandler = new StaticAsyncHandler(false, null); - const canHandleFn = jest.fn(async(): Promise => { - throw new Error('test'); - }); - const handleFn = jest.fn(async(input: any): Promise => input); - - handlerFalse.canHandle = canHandleFn; - handlerFalse.handle = handleFn; - await expect(handlerFalse.handleSafe('test')).rejects.toThrow(Error); - expect(canHandleFn).toHaveBeenCalledTimes(1); - expect(handleFn).toHaveBeenCalledTimes(0); - }); -}); diff --git a/test/unit/util/handlers/BooleanHandler.test.ts b/test/unit/util/handlers/BooleanHandler.test.ts deleted file mode 100644 index f3d46eeff..000000000 --- a/test/unit/util/handlers/BooleanHandler.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { InternalServerError } from '../../../../src/util/errors/InternalServerError'; -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { BooleanHandler } from '../../../../src/util/handlers/BooleanHandler'; -import { StaticAsyncHandler } from '../../../util/StaticAsyncHandler'; - -describe('A BooleanHandler', (): void => { - let handlerFalse: AsyncHandler; - let handlerTrue: AsyncHandler; - let handlerError: AsyncHandler; - let handlerCanNotHandle: AsyncHandler; - - beforeEach(async(): Promise => { - handlerFalse = new StaticAsyncHandler(true, false); - handlerTrue = new StaticAsyncHandler(true, true); - handlerError = new StaticAsyncHandler(true, null) as any; - handlerError.handle = (): never => { - throw new InternalServerError(); - }; - handlerCanNotHandle = new StaticAsyncHandler(false, null); - }); - - it('can handle the input if any of its handlers can.', async(): Promise => { - const handler = new BooleanHandler([ handlerFalse, handlerCanNotHandle ]); - await expect(handler.canHandle(null)).resolves.toBeUndefined(); - }); - - it('errors if none of its handlers supports the input.', async(): Promise => { - const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]); - await expect(handler.canHandle(null)).rejects.toThrow('Not supported, Not supported'); - }); - - it('returns true if any of its handlers returns true.', async(): Promise => { - const handler = new BooleanHandler([ handlerFalse, handlerTrue, handlerCanNotHandle ]); - await expect(handler.handle(null)).resolves.toBe(true); - }); - - it('returns false if none of its handlers returns true.', async(): Promise => { - const handler = new BooleanHandler([ handlerFalse, handlerError, handlerCanNotHandle ]); - await expect(handler.handle(null)).resolves.toBe(false); - }); - - it('throw an internal error when calling handle with unsupported input.', async(): Promise => { - const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]); - await expect(handler.handle(null)).rejects.toThrow(InternalServerError); - }); - - it('returns the same handle results with handleSafe.', async(): Promise => { - const handler = new BooleanHandler([ handlerFalse, handlerTrue, handlerCanNotHandle ]); - await expect(handler.handleSafe(null)).resolves.toBe(true); - }); - - it('throws the canHandle error when calling handleSafe with unsupported input.', async(): Promise => { - const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]); - await expect(handler.handleSafe(null)).rejects.toThrow('Not supported, Not supported'); - }); -}); diff --git a/test/unit/util/handlers/CachedHandler.test.ts b/test/unit/util/handlers/CachedHandler.test.ts deleted file mode 100644 index 391fec320..000000000 --- a/test/unit/util/handlers/CachedHandler.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { - CachedHandler, -} from '../../../../src/util/handlers/CachedHandler'; - -describe('A CachedHandler', (): void => { - const input: any = { field1: { key: 'value' }, field2: { key: 'value' }, field3: { key: 'value2' }}; - const output = 'response'; - let source: jest.Mocked>; - let handler: CachedHandler; - - beforeEach(async(): Promise => { - source = { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue(output), - } as any; - handler = new CachedHandler(source); - }); - - it('can handle input if its source can.', async(): Promise => { - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - expect(source.canHandle).toHaveBeenCalledTimes(1); - source.canHandle.mockRejectedValue(new Error('bad input')); - await expect(handler.canHandle(input)).rejects.toThrow('bad input'); - expect(source.canHandle).toHaveBeenCalledTimes(2); - }); - - it('returns the source result.', async(): Promise => { - await expect(handler.handle(input)).resolves.toBe(output); - expect(source.handle).toHaveBeenCalledTimes(1); - expect(source.handle).toHaveBeenLastCalledWith(input); - }); - - it('caches the result.', async(): Promise => { - await expect(handler.handle(input)).resolves.toBe(output); - await expect(handler.handle(input)).resolves.toBe(output); - expect(source.handle).toHaveBeenCalledTimes(1); - }); - - it('caches on the object itself.', async(): Promise => { - const copy = { ...input }; - await expect(handler.handle(input)).resolves.toBe(output); - await expect(handler.handle(copy)).resolves.toBe(output); - expect(source.handle).toHaveBeenCalledTimes(2); - }); - - it('can handle the input if it has a cached result.', async(): Promise => { - await expect(handler.handle(input)).resolves.toBe(output); - source.canHandle.mockRejectedValue(new Error('bad input')); - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - expect(source.canHandle).toHaveBeenCalledTimes(0); - }); - - it('cannot handle input with multiple keys if the first key is already missing.', async(): Promise => { - handler = new CachedHandler(source, [ 'field1', 'field3' ]); - - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - expect(source.canHandle).toHaveBeenCalledTimes(1); - }); - - it('can use a specific field of the input as key.', async(): Promise => { - handler = new CachedHandler(source, [ 'field1' ]); - - const copy = { ...input }; - await expect(handler.handle(input)).resolves.toBe(output); - await expect(handler.handle(copy)).resolves.toBe(output); - expect(source.handle).toHaveBeenCalledTimes(1); - }); - - it('can use multiple fields of the object as keys.', async(): Promise => { - handler = new CachedHandler(source, [ 'field1', 'field3' ]); - - const copy = { ...input }; - copy.field2 = { other: 'field' }; - await expect(handler.handle(input)).resolves.toBe(output); - await expect(handler.handle(copy)).resolves.toBe(output); - expect(source.handle).toHaveBeenCalledTimes(1); - }); - - it('rejects empty field arrays.', async(): Promise => { - expect((): any => new CachedHandler(source, [])) - .toThrow('The fields parameter needs to have at least 1 entry if defined.'); - }); -}); diff --git a/test/unit/util/handlers/ConditionalHandler.test.ts b/test/unit/util/handlers/ConditionalHandler.test.ts index 8f76ab9d4..d29c23f8c 100644 --- a/test/unit/util/handlers/ConditionalHandler.test.ts +++ b/test/unit/util/handlers/ConditionalHandler.test.ts @@ -1,6 +1,6 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; import type { KeyValueStorage } from '../../../../src/storage/keyvalue/KeyValueStorage'; import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; import { ConditionalHandler } from '../../../../src/util/handlers/ConditionalHandler'; describe('A ConditionalHandler', (): void => { diff --git a/test/unit/util/handlers/HandlerUtil.test.ts b/test/unit/util/handlers/HandlerUtil.test.ts deleted file mode 100644 index 64dfbc589..000000000 --- a/test/unit/util/handlers/HandlerUtil.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { filterHandlers, findHandler } from '../../../../src/util/handlers/HandlerUtil'; -import { StaticAsyncHandler } from '../../../util/StaticAsyncHandler'; - -describe('HandlerUtil', (): void => { - describe('findHandler', (): void => { - let handlerTrue: AsyncHandler; - let handlerFalse: AsyncHandler; - - beforeEach(async(): Promise => { - handlerTrue = new StaticAsyncHandler(true, null); - handlerFalse = new StaticAsyncHandler(false, null); - }); - - it('finds a matching handler.', async(): Promise => { - await expect(findHandler([ handlerFalse, handlerTrue ], null)).resolves.toBe(handlerTrue); - }); - - it('errors if there is no matching handler.', async(): Promise => { - await expect(findHandler([ handlerFalse, handlerFalse ], null)).rejects.toThrow('Not supported, Not supported'); - }); - - it('supports non-native Errors.', async(): Promise => { - jest.spyOn(handlerFalse, 'canHandle').mockRejectedValue('apple'); - await expect(findHandler([ handlerFalse ], null)).rejects.toThrow('Unknown error: apple'); - }); - }); - - describe('filterHandlers', (): void => { - let handlerTrue: AsyncHandler; - let handlerFalse: AsyncHandler; - - beforeEach(async(): Promise => { - handlerTrue = new StaticAsyncHandler(true, null); - handlerFalse = new StaticAsyncHandler(false, null); - }); - - it('finds matching handlers.', async(): Promise => { - await expect(filterHandlers([ handlerTrue, handlerFalse, handlerTrue ], null)) - .resolves.toEqual([ handlerTrue, handlerTrue ]); - }); - - it('errors if there is no matching handler.', async(): Promise => { - await expect(filterHandlers([ handlerFalse, handlerFalse ], null)) - .rejects.toThrow('Not supported, Not supported'); - }); - }); -}); diff --git a/test/unit/util/handlers/MethodFilterHandler.test.ts b/test/unit/util/handlers/MethodFilterHandler.test.ts index 9025d1e38..bdbe0206c 100644 --- a/test/unit/util/handlers/MethodFilterHandler.test.ts +++ b/test/unit/util/handlers/MethodFilterHandler.test.ts @@ -1,7 +1,7 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; import type { Operation } from '../../../../src/http/Operation'; import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation'; import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; import { MethodFilterHandler, } from '../../../../src/util/handlers/MethodFilterHandler'; diff --git a/test/unit/util/handlers/ParallelHandler.test.ts b/test/unit/util/handlers/ParallelHandler.test.ts deleted file mode 100644 index 3d8792ba7..000000000 --- a/test/unit/util/handlers/ParallelHandler.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { ParallelHandler } from '../../../../src/util/handlers/ParallelHandler'; - -describe('A ParallelHandler', (): void => { - const handlers: jest.Mocked>[] = [ - { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue('0'), - }, - { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue('1'), - }, - { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue('2'), - }, - ] as any; - const composite: ParallelHandler = new ParallelHandler(handlers); - - afterEach(jest.clearAllMocks); - - describe('canHandle', (): void => { - it('succeeds if all handlers succeed.', async(): Promise => { - await expect(composite.canHandle('abc')).resolves.toBeUndefined(); - - expect(handlers[0].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[1].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[2].canHandle).toHaveBeenCalledTimes(1); - - expect(handlers[0].canHandle).toHaveBeenCalledWith('abc'); - expect(handlers[1].canHandle).toHaveBeenCalledWith('abc'); - expect(handlers[2].canHandle).toHaveBeenCalledWith('abc'); - }); - - it('fails if one handler fails.', async(): Promise => { - const error = new Error('failure'); - handlers[1].canHandle.mockRejectedValueOnce(error); - await expect(composite.canHandle('abc')).rejects.toThrow(error); - }); - }); - - describe('handle', (): void => { - it('succeeds if all handlers succeed.', async(): Promise => { - await expect(composite.handle('abc')).resolves.toEqual([ '0', '1', '2' ]); - - expect(handlers[0].handle).toHaveBeenCalledTimes(1); - expect(handlers[1].handle).toHaveBeenCalledTimes(1); - expect(handlers[2].handle).toHaveBeenCalledTimes(1); - - expect(handlers[0].handle).toHaveBeenCalledWith('abc'); - expect(handlers[1].handle).toHaveBeenCalledWith('abc'); - expect(handlers[2].handle).toHaveBeenCalledWith('abc'); - }); - - it('fails if one handler fails.', async(): Promise => { - const error = new Error('failure'); - handlers[1].handle.mockRejectedValueOnce(error); - await expect(composite.handle('abc')).rejects.toThrow(error); - }); - }); - - describe('handleSafe', (): void => { - it('succeeds if all handlers succeed.', async(): Promise => { - await expect(composite.handleSafe('abc')).resolves.toEqual([ '0', '1', '2' ]); - - expect(handlers[0].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[1].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[2].canHandle).toHaveBeenCalledTimes(1); - - expect(handlers[0].canHandle).toHaveBeenCalledWith('abc'); - expect(handlers[1].canHandle).toHaveBeenCalledWith('abc'); - expect(handlers[2].canHandle).toHaveBeenCalledWith('abc'); - - expect(handlers[0].handle).toHaveBeenCalledTimes(1); - expect(handlers[1].handle).toHaveBeenCalledTimes(1); - expect(handlers[2].handle).toHaveBeenCalledTimes(1); - - expect(handlers[0].handle).toHaveBeenCalledWith('abc'); - expect(handlers[1].handle).toHaveBeenCalledWith('abc'); - expect(handlers[2].handle).toHaveBeenCalledWith('abc'); - }); - - it('fails if one canHandle fails.', async(): Promise => { - const error = new Error('failure'); - handlers[1].canHandle.mockRejectedValueOnce(error); - await expect(composite.handleSafe('abc')).rejects.toThrow(error); - - expect(handlers[0].handle).toHaveBeenCalledTimes(0); - expect(handlers[1].handle).toHaveBeenCalledTimes(0); - expect(handlers[2].handle).toHaveBeenCalledTimes(0); - }); - - it('fails if one handle fails.', async(): Promise => { - const error = new Error('failure'); - handlers[1].handle.mockRejectedValueOnce(error); - await expect(composite.handleSafe('abc')).rejects.toThrow(error); - }); - }); -}); diff --git a/test/unit/util/handlers/ProcessHandler.test.ts b/test/unit/util/handlers/ProcessHandler.test.ts deleted file mode 100644 index 2d3bd7c82..000000000 --- a/test/unit/util/handlers/ProcessHandler.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import type { AsyncHandler, ClusterManager } from '../../../../src'; -import { NotImplementedHttpError, ProcessHandler } from '../../../../src'; - -function createClusterManager(workers: number, primary: boolean): jest.Mocked { - return { - isSingleThreaded: jest.fn().mockReturnValue(workers === 1), - isWorker: jest.fn().mockReturnValue(!primary), - isPrimary: jest.fn().mockReturnValue(primary), - } as any; -} - -describe('A ProcessHandler', (): void => { - const source: jest.Mocked> = { - canHandle: jest.fn(), - handleSafe: jest.fn().mockResolvedValue('handledSafely'), - handle: jest.fn().mockResolvedValue('handled'), - }; - - describe('allowing only worker processes', (): void => { - it('can create a ProcessHandler.', (): void => { - expect((): ProcessHandler => - new ProcessHandler(source, createClusterManager(1, true), false)).toBeDefined(); - }); - - it('can delegate to its source when run singlethreaded from worker.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(1, false), false); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('can delegate to its source when run singlethreaded from primary.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(1, true), false); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('can delegate to its source when run multithreaded from worker.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(2, false), false); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('errors when run multithreaded from primary.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(2, true), false); - await expect(ph.handleSafe('test')).rejects.toThrow(NotImplementedHttpError); - }); - }); - - describe('allowing only the primary process', (): void => { - it('can create a ProcessHandler.', (): void => { - expect((): ProcessHandler => - new ProcessHandler(source, createClusterManager(1, true), true)).toBeDefined(); - }); - - it('can delegate to its source when run singlethreaded from worker.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(1, false), true); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('can delegate to its source when run singlethreaded from primary.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(1, true), true); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('can delegate to its source when run multithreaded from primary.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(2, true), true); - await expect(ph.handleSafe('test')).resolves.toBe('handled'); - }); - - it('errors when run multithreaded from worker.', async(): Promise => { - const ph = new ProcessHandler(source, createClusterManager(2, false), true); - await expect(ph.handleSafe('test')).rejects.toThrow(NotImplementedHttpError); - }); - }); -}); diff --git a/test/unit/util/handlers/SequenceHandler.test.ts b/test/unit/util/handlers/SequenceHandler.test.ts deleted file mode 100644 index b13f4983c..000000000 --- a/test/unit/util/handlers/SequenceHandler.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { SequenceHandler } from '../../../../src/util/handlers/SequenceHandler'; - -describe('A SequenceHandler', (): void => { - const handlers: jest.Mocked>[] = [ - { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue('0'), - } as any, - { - canHandle: jest.fn().mockRejectedValue(new Error('not supported')), - handle: jest.fn().mockRejectedValue(new Error('should not be called')), - } as any, - { - canHandle: jest.fn(), - handle: jest.fn().mockResolvedValue('2'), - } as any, - ]; - let composite: SequenceHandler; - - beforeEach(async(): Promise => { - composite = new SequenceHandler(handlers); - }); - - it('can handle all input.', async(): Promise => { - await expect(composite.canHandle('test')).resolves.toBeUndefined(); - }); - - it('runs all supported handlers.', async(): Promise => { - await composite.handleSafe('test'); - - expect(handlers[0].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[0].canHandle).toHaveBeenLastCalledWith('test'); - expect(handlers[0].handle).toHaveBeenCalledTimes(1); - expect(handlers[0].handle).toHaveBeenLastCalledWith('test'); - - expect(handlers[1].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[1].canHandle).toHaveBeenLastCalledWith('test'); - expect(handlers[1].handle).toHaveBeenCalledTimes(0); - - expect(handlers[2].canHandle).toHaveBeenCalledTimes(1); - expect(handlers[2].canHandle).toHaveBeenLastCalledWith('test'); - expect(handlers[2].handle).toHaveBeenCalledTimes(1); - expect(handlers[2].handle).toHaveBeenLastCalledWith('test'); - }); - - it('returns the result of the last supported handler.', async(): Promise => { - await expect(composite.handleSafe('test')).resolves.toBe('2'); - - handlers[2].canHandle.mockRejectedValueOnce(new Error('not supported')); - await expect(composite.handleSafe('test')).resolves.toBe('0'); - }); - - it('returns undefined if no handler is supported.', async(): Promise => { - handlers[0].canHandle.mockRejectedValueOnce(new Error('not supported')); - handlers[2].canHandle.mockRejectedValueOnce(new Error('not supported')); - await expect(composite.handleSafe('test')).resolves.toBeUndefined(); - }); - - it('errors if a handler errors.', async(): Promise => { - handlers[2].handle.mockRejectedValueOnce(new Error('failure')); - await expect(composite.handleSafe('test')).rejects.toThrow('failure'); - }); -}); diff --git a/test/unit/util/handlers/StaticHandler.test.ts b/test/unit/util/handlers/StaticHandler.test.ts deleted file mode 100644 index c55139238..000000000 --- a/test/unit/util/handlers/StaticHandler.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { StaticHandler } from '../../../../src/util/handlers/StaticHandler'; - -describe('A StaticHandler', (): void => { - it('can handle everything.', async(): Promise => { - const handler = new StaticHandler(); - await expect(handler.canHandle(null)).resolves.toBeUndefined(); - }); - - it('returns the stored value.', async(): Promise => { - const handler = new StaticHandler('apple'); - await expect(handler.handle()).resolves.toBe('apple'); - }); - - it('returns undefined if there is no stored value.', async(): Promise => { - const handler = new StaticHandler(); - await expect(handler.handle()).resolves.toBeUndefined(); - }); -}); diff --git a/test/unit/util/handlers/StaticThrowHandler.test.ts b/test/unit/util/handlers/StaticThrowHandler.test.ts deleted file mode 100644 index 803ca26a7..000000000 --- a/test/unit/util/handlers/StaticThrowHandler.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; -import { StaticThrowHandler } from '../../../../src/util/handlers/StaticThrowHandler'; -import { SOLID_ERROR } from '../../../../src/util/Vocabularies'; - -describe('A StaticThrowHandler', (): void => { - const error = new BadRequestHttpError(); - const handler = new StaticThrowHandler(error); - - it('can handle all requests.', async(): Promise => { - await expect(handler.canHandle({})).resolves.toBeUndefined(); - }); - - it('always throws an instance of the given error.', async(): Promise => { - await expect(handler.handle()).rejects.toThrow(error); - }); - - it('creates a new instance every time.', async(): Promise => { - /* eslint-disable jest/no-conditional-expect */ - try { - await handler.handle(); - } catch (error: unknown) { - expect(BadRequestHttpError.isInstance(error)).toBe(true); - // Change the metadata - (error as BadRequestHttpError).metadata.add(SOLID_ERROR.terms.target, 'http://example.com/foo'); - } - try { - await handler.handle(); - } catch (error: unknown) { - expect(BadRequestHttpError.isInstance(error)).toBe(true); - // Metadata should not have the change - expect((error as BadRequestHttpError).metadata.has(SOLID_ERROR.terms.target)).toBe(false); - } - /* eslint-enable jest/no-conditional-expect */ - }); -}); diff --git a/test/unit/util/handlers/ArrayUnionHandler.test.ts b/test/unit/util/handlers/StatusArrayUnionHandler.test.ts similarity index 60% rename from test/unit/util/handlers/ArrayUnionHandler.test.ts rename to test/unit/util/handlers/StatusArrayUnionHandler.test.ts index 1f89f4ef3..2f4587793 100644 --- a/test/unit/util/handlers/ArrayUnionHandler.test.ts +++ b/test/unit/util/handlers/StatusArrayUnionHandler.test.ts @@ -1,23 +1,23 @@ -import { ArrayUnionHandler } from '../../../../src/util/handlers/ArrayUnionHandler'; -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; +import type { AsyncHandler } from 'asynchronous-handlers'; +import { StatusArrayUnionHandler } from '../../../../src/util/handlers/StatusArrayUnionHandler'; -describe('An ArrayUnionHandler', (): void => { +describe('A StatusArrayUnionHandler', (): void => { let handlers: jest.Mocked>[]; - let handler: ArrayUnionHandler>; + let handler: StatusArrayUnionHandler>; beforeEach(async(): Promise => { handlers = [ { canHandle: jest.fn(), handle: jest.fn().mockResolvedValue([ 1, 2 ]), - } as any, + } satisfies Partial> as any, { canHandle: jest.fn(), handle: jest.fn().mockResolvedValue([ 3, 4 ]), - } as any, + } satisfies Partial> as any, ]; - handler = new ArrayUnionHandler(handlers); + handler = new StatusArrayUnionHandler(handlers); }); it('merges the array results.', async(): Promise => { diff --git a/test/unit/util/handlers/StatusBooleanHandler.test.ts b/test/unit/util/handlers/StatusBooleanHandler.test.ts new file mode 100644 index 000000000..4184571a4 --- /dev/null +++ b/test/unit/util/handlers/StatusBooleanHandler.test.ts @@ -0,0 +1,26 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { StatusBooleanHandler } from '../../../../src/util/handlers/StatusBooleanHandler'; + +describe('A StatusBooleanHandler', (): void => { + let handlers: jest.Mocked>[]; + let handler: StatusBooleanHandler; + + beforeEach(async(): Promise => { + handlers = [ + { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue(false), + } satisfies Partial> as any, + { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue(true), + } satisfies Partial> as any, + ]; + + handler = new StatusBooleanHandler(handlers); + }); + + it('returns true if one of the handlers returns true.', async(): Promise => { + await expect(handler.handleSafe('input')).resolves.toBe(true); + }); +}); diff --git a/test/unit/util/handlers/StatusHandler.test.ts b/test/unit/util/handlers/StatusHandler.test.ts new file mode 100644 index 000000000..f58629159 --- /dev/null +++ b/test/unit/util/handlers/StatusHandler.test.ts @@ -0,0 +1,50 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; +import { ForbiddenHttpError } from '../../../../src/util/errors/ForbiddenHttpError'; +import { InternalServerError } from '../../../../src/util/errors/InternalServerError'; +import { MethodNotAllowedHttpError } from '../../../../src/util/errors/MethodNotAllowedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; +import { StatusHandler } from '../../../../src/util/handlers/StatusHandler'; +import { getError } from '../../../util/Util'; + +describe('A StatusHandler', (): void => { + it('converts non-HttpErrors to an HttpError.', async(): Promise => { + const handler: AsyncHandler = { + canHandle: jest.fn().mockRejectedValue(new Error('canHandle')), + handle: jest.fn().mockRejectedValue(new Error('handle')), + handleSafe: jest.fn().mockRejectedValue(new Error('handleSafe')), + }; + const statusHandler = new StatusHandler(handler); + + const canHandleError = await getError(async(): Promise => statusHandler.canHandle('input')); + expect(InternalServerError.isInstance(canHandleError)).toBe(true); + expect(canHandleError.message).toBe('canHandle'); + + const handleError = await getError(async(): Promise => statusHandler.handle('input')); + expect(InternalServerError.isInstance(handleError)).toBe(true); + expect(handleError.message).toBe('handle'); + + const handleSafeError = await getError(async(): Promise => statusHandler.handleSafe('input')); + expect(InternalServerError.isInstance(handleSafeError)).toBe(true); + expect(handleSafeError.message).toBe('handleSafe'); + }); + + it('converts AggregateErrors to HttpErrors.', async(): Promise => { + const handler: AsyncHandler = { + canHandle: jest.fn().mockRejectedValue(new MethodNotAllowedHttpError()), + handle: jest.fn().mockRejectedValue(new AggregateError([ + new MethodNotAllowedHttpError(), + new ForbiddenHttpError(), + ], 'error')), + handleSafe: jest.fn().mockRejectedValue(new AggregateError([ + new MethodNotAllowedHttpError(), + new NotImplementedHttpError(), + ], 'error')), + }; + const statusHandler = new StatusHandler(handler); + + await expect(statusHandler.canHandle('input')).rejects.toThrow(MethodNotAllowedHttpError); + await expect(statusHandler.handle('input')).rejects.toThrow(BadRequestHttpError); + await expect(statusHandler.handleSafe('input')).rejects.toThrow(InternalServerError); + }); +}); diff --git a/test/unit/util/handlers/StatusUnionHandler.test.ts b/test/unit/util/handlers/StatusUnionHandler.test.ts new file mode 100644 index 000000000..77fb740ea --- /dev/null +++ b/test/unit/util/handlers/StatusUnionHandler.test.ts @@ -0,0 +1,43 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { StatusUnionHandler } from '../../../../src/util/handlers/StatusUnionHandler'; + +class SimpleUnionHandler extends StatusUnionHandler> { + protected async combine(results: string[]): Promise { + return results.join(''); + } +} + +describe('A StatusUnionHandler', (): void => { + const input = { data: 'text' }; + let handlers: jest.Mocked>[]; + let handler: SimpleUnionHandler; + + beforeEach(async(): Promise => { + handlers = [ + { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue('a'), + } satisfies Partial> as any, + { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue('b'), + } satisfies Partial> as any, + ]; + + handler = new SimpleUnionHandler(handlers, true); + }); + + it('calls the combine function when calling canHandle.', async(): Promise => { + await expect(handler.canHandle(input)).resolves.toBeUndefined(); + + expect(handlers[0].canHandle).toHaveBeenLastCalledWith(input); + expect(handlers[1].canHandle).toHaveBeenLastCalledWith(input); + }); + + it('calls the combine function on handle calls.', async(): Promise => { + await expect(handler.handle(input)).resolves.toBe('ab'); + + expect(handlers[0].handle).toHaveBeenLastCalledWith(input); + expect(handlers[1].handle).toHaveBeenLastCalledWith(input); + }); +}); diff --git a/test/unit/util/handlers/StatusWaterfallHandler.test.ts b/test/unit/util/handlers/StatusWaterfallHandler.test.ts new file mode 100644 index 000000000..a60314b28 --- /dev/null +++ b/test/unit/util/handlers/StatusWaterfallHandler.test.ts @@ -0,0 +1,26 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; +import { StatusWaterfallHandler } from '../../../../src/util/handlers/StatusWaterfallHandler'; + +describe('A StatusBooleanHandler', (): void => { + let handlers: jest.Mocked>[]; + let handler: StatusWaterfallHandler; + + beforeEach(async(): Promise => { + handlers = [ + { + canHandle: jest.fn().mockRejectedValue(new Error('no handle')), + handle: jest.fn().mockResolvedValue(false), + } satisfies Partial> as any, + { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue(true), + } satisfies Partial> as any, + ]; + + handler = new StatusWaterfallHandler(handlers); + }); + + it('returns true if one of the handlers returns true.', async(): Promise => { + await expect(handler.handleSafe('input')).resolves.toBe(true); + }); +}); diff --git a/test/unit/util/handlers/UnionHandler.test.ts b/test/unit/util/handlers/UnionHandler.test.ts deleted file mode 100644 index fc409e3d6..000000000 --- a/test/unit/util/handlers/UnionHandler.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { UnionHandler } from '../../../../src/util/handlers/UnionHandler'; - -class SimpleUnionHandler extends UnionHandler> { - protected async combine(results: string[]): Promise { - return results.join(''); - } -} - -describe('A UnionHandler', (): void => { - const input = { data: 'text' }; - let handlers: jest.Mocked>[]; - let handler: SimpleUnionHandler; - - beforeEach(async(): Promise => { - handlers = [ - { canHandle: jest.fn(), handle: jest.fn().mockResolvedValue('a') } as any, - { canHandle: jest.fn(), handle: jest.fn().mockResolvedValue('b') } as any, - ]; - - handler = new SimpleUnionHandler(handlers); - }); - - it('can handle a request if at least one extractor can handle it.', async(): Promise => { - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - - handlers[0].canHandle.mockRejectedValue(new Error('bad request')); - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - - handlers[1].canHandle.mockRejectedValue(new Error('bad request')); - await expect(handler.canHandle(input)).rejects.toThrow('bad request'); - - await expect(handler.handleSafe(input)).rejects.toThrow('bad request'); - }); - - it('requires all handlers to support the input if requireAll is true.', async(): Promise => { - handler = new SimpleUnionHandler(handlers, true); - await expect(handler.canHandle(input)).resolves.toBeUndefined(); - - handlers[0].canHandle.mockRejectedValue(new Error('bad request')); - await expect(handler.canHandle(input)).rejects.toThrow('bad request'); - - await expect(handler.handleSafe(input)).rejects.toThrow('bad request'); - }); - - it('calls all handlers that support the input.', async(): Promise => { - handlers[0].canHandle.mockRejectedValue(new Error('bad request')); - await expect(handler.handle(input)).resolves.toBe('b'); - await expect(handler.handleSafe(input)).resolves.toBe('b'); - }); - - it('calls all handlers if requireAll is true.', async(): Promise => { - handler = new SimpleUnionHandler(handlers, true); - await expect(handler.handleSafe(input)).resolves.toBe('ab'); - - // `handle` call does not need to check `canHandle` values anymore - handlers[0].canHandle.mockRejectedValue(new Error('bad request')); - await expect(handler.handle(input)).resolves.toBe('ab'); - }); - - it('requires all handlers to succeed if requireAll is true.', async(): Promise => { - handler = new SimpleUnionHandler(handlers, true); - - handlers[0].handle.mockRejectedValue(new Error('bad request')); - await expect(handler.handleSafe(input)).rejects.toThrow('bad request'); - }); - - it('does not require all handlers to succeed if ignoreErrors is true.', async(): Promise => { - handler = new SimpleUnionHandler(handlers, true, true); - - handlers[0].handle.mockRejectedValueOnce(new Error('bad request')); - await expect(handler.handleSafe(input)).resolves.toBe('b'); - - handlers[1].handle.mockRejectedValueOnce(new Error('bad request')); - await expect(handler.handleSafe(input)).resolves.toBe('a'); - - handlers[0].handle.mockRejectedValueOnce(new Error('bad request')); - handlers[1].handle.mockRejectedValueOnce(new Error('bad request')); - await expect(handler.handleSafe(input)).resolves.toBe(''); - }); -}); diff --git a/test/unit/util/handlers/UnsupportedAsyncHandler.test.ts b/test/unit/util/handlers/UnsupportedAsyncHandler.test.ts deleted file mode 100644 index ae46cd2c5..000000000 --- a/test/unit/util/handlers/UnsupportedAsyncHandler.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; -import { UnsupportedAsyncHandler } from '../../../../src/util/handlers/UnsupportedAsyncHandler'; - -describe('An UnsupportedAsyncHandler', (): void => { - it('throws a default error when no message is set.', async(): Promise => { - const handler = new UnsupportedAsyncHandler(); - await expect(handler.canHandle()).rejects.toThrow(NotImplementedHttpError); - await expect(handler.handle()).rejects.toThrow(NotImplementedHttpError); - await expect(handler.handleSafe(null)).rejects.toThrow(NotImplementedHttpError); - }); - - it('throws the specified error when a message is set.', async(): Promise => { - const handler = new UnsupportedAsyncHandler('custom error'); - await expect(handler.canHandle()).rejects.toThrow('custom error'); - await expect(handler.handle()).rejects.toThrow('custom error'); - await expect(handler.handleSafe(null)).rejects.toThrow('custom error'); - }); -}); diff --git a/test/unit/util/handlers/WaterfallHandler.test.ts b/test/unit/util/handlers/WaterfallHandler.test.ts deleted file mode 100644 index dbde7d497..000000000 --- a/test/unit/util/handlers/WaterfallHandler.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; -import { WaterfallHandler } from '../../../../src/util/handlers/WaterfallHandler'; -import { StaticAsyncHandler } from '../../../util/StaticAsyncHandler'; - -describe('A WaterfallHandler', (): void => { - describe('with no handlers', (): void => { - it('can never handle data.', async(): Promise => { - const handler = new WaterfallHandler([]); - - await expect(handler.canHandle(null)).rejects.toThrow(Error); - }); - - it('errors if its handle function is called.', async(): Promise => { - const handler = new WaterfallHandler([]); - - await expect(handler.handle(null)).rejects.toThrow(Error); - }); - }); - - describe('with multiple handlers', (): void => { - let handlerTrue: AsyncHandler; - let handlerFalse: AsyncHandler; - let canHandleFn: jest.Mock, [any]>; - let handleFn: jest.Mock, [any]>; - - beforeEach(async(): Promise => { - handlerTrue = new StaticAsyncHandler(true, null); - handlerFalse = new StaticAsyncHandler(false, null); - - canHandleFn = jest.fn(async(input: any): Promise => input); - handleFn = jest.fn(async(input: any): Promise => input); - handlerTrue.canHandle = canHandleFn; - handlerTrue.handle = handleFn; - }); - - it('can handle data if a handler supports it.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerTrue ]); - - await expect(handler.canHandle(null)).resolves.toBeUndefined(); - }); - - it('can not handle data if no handler supports it.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]); - - await expect(handler.canHandle(null)).rejects.toThrow('Not supported, Not supported'); - }); - - it('throws unknown errors if no Error objects are thrown.', async(): Promise => { - handlerFalse.canHandle = async(): Promise => { - // eslint-disable-next-line ts/no-throw-literal - throw 'apple'; - }; - const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]); - - await expect(handler.canHandle(null)).rejects.toThrow('Unknown error: apple, Unknown error: apple'); - }); - - it('handles data if a handler supports it.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerTrue ]); - - await expect(handler.handle('test')).resolves.toBe('test'); - expect(canHandleFn).toHaveBeenCalledTimes(1); - expect(handleFn).toHaveBeenCalledTimes(1); - }); - - it('errors if the handle function is called but no handler supports the data.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]); - - await expect(handler.handle('test')).rejects.toThrow('All handlers failed'); - }); - - it('only calls the canHandle function once of its handlers when handleSafe is called.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerTrue ]); - - await expect(handler.handleSafe('test')).resolves.toBe('test'); - expect(canHandleFn).toHaveBeenCalledTimes(1); - expect(handleFn).toHaveBeenCalledTimes(1); - }); - - it('throws the canHandle error when calling handleSafe if the data is not supported.', async(): Promise => { - const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]); - - await expect(handler.handleSafe(null)).rejects.toThrow('Not supported, Not supported'); - }); - }); -}); diff --git a/test/unit/util/templates/StaticTemplateEngine.test.ts b/test/unit/util/templates/StaticTemplateEngine.test.ts index f9db6a1dc..a716955bc 100644 --- a/test/unit/util/templates/StaticTemplateEngine.test.ts +++ b/test/unit/util/templates/StaticTemplateEngine.test.ts @@ -1,5 +1,6 @@ +import type { AsyncHandler } from 'asynchronous-handlers'; import { NotFoundHttpError, StaticTemplateEngine } from '../../../../src'; -import type { AsyncHandler, TemplateEngineInput } from '../../../../src'; +import type { TemplateEngineInput } from '../../../../src'; import Dict = NodeJS.Dict; describe('A StaticTemplateEngine', (): void => { diff --git a/test/util/StaticAsyncHandler.ts b/test/util/StaticAsyncHandler.ts index c482285d5..883fa8faa 100644 --- a/test/util/StaticAsyncHandler.ts +++ b/test/util/StaticAsyncHandler.ts @@ -1,4 +1,4 @@ -import { AsyncHandler } from '../../src/util/handlers/AsyncHandler'; +import { AsyncHandler } from 'asynchronous-handlers'; export class StaticAsyncHandler extends AsyncHandler { private readonly canHandleStatic: boolean; diff --git a/test/util/Util.ts b/test/util/Util.ts index d23899eab..efa625dd8 100644 --- a/test/util/Util.ts +++ b/test/util/Util.ts @@ -105,6 +105,19 @@ export function compareMaps(map1: Map, map2: Map any): Promise { + try { + await fn(); + } catch (err: unknown) { + return err as Error; + } + throw new Error('Function did not throw'); +} + /** * Mocks (some) functions of the fs system library. * It is important that you call `jest.mock('node:fs');` in your test file before calling this!!!