diff --git a/include/ccf/js/registry.h b/include/ccf/js/registry.h index 38c4fc5067d1..282504c8d4c0 100644 --- a/include/ccf/js/registry.h +++ b/include/ccf/js/registry.h @@ -141,6 +141,8 @@ namespace ccf::js ccf::endpoints::EndpointDefinitionPtr e, ccf::endpoints::CommandEndpointContext& endpoint_ctx, const ccf::TxID& tx_id) override; + + void build_api(nlohmann::json& document, kv::ReadOnlyTx& tx) override; ///@} }; } diff --git a/src/js/registry.cpp b/src/js/registry.cpp index ac89b9c119b6..42f81adb7b2a 100644 --- a/src/js/registry.cpp +++ b/src/js/registry.cpp @@ -800,4 +800,42 @@ namespace ccf::js ccf::endpoints::EndpointRegistry::execute_endpoint_locally_committed( e, endpoint_ctx, tx_id); } + + // Since we do our own dispatch (overriding find_endpoint), make sure we + // describe those operations in the auto-generated OpenAPI + void DynamicJSEndpointRegistry::build_api( + nlohmann::json& document, kv::ReadOnlyTx& tx) + { + ccf::UserEndpointRegistry::build_api(document, tx); + + auto endpoints = tx.ro(metadata_map); + + endpoints->foreach([&document](const auto& key, const auto& properties) { + const auto http_verb = key.verb.get_http_method(); + if (!http_verb.has_value()) + { + return true; + } + + if (!properties.openapi_hidden) + { + auto& path_op = ds::openapi::path_operation( + ds::openapi::path( + document, + fmt::format( + "/{}{}", + ccf::get_actor_prefix(ccf::ActorsType::users), + key.uri_path)), + http_verb.value(), + false); + if (!properties.openapi.empty()) + { + path_op.insert( + properties.openapi.cbegin(), properties.openapi.cend()); + } + } + + return true; + }); + } }