C++ was the last language owning its own invocation, and it gave two reasons. `templates:` retired the first one for rust already; this retires the second, which needs saying precisely because it was true when it was written. The floor said generator 7.24.0 against the 7.14.0 pinned here, because on 7.14.0 ten translation units would not compile through two defects in the generator's type resolution that no template reaches — mustache interpolates the strings resolution produces, it cannot recompute a type. Both defects were real. Both lived in SCHEMAS THE DOCUMENT NO LONGER CARRIES: vector_NamedVectors / vector_DenseVector under additionalProperties (9 TUs), and an integer-backed enum declared over utility::string_t and defined over int32_t, framework_Document.docstatus (1 TU). Neither schema exists at the ref this fleet reads, so neither defect is reachable and the floor expired with its cause. Re-measured rather than argued: at cloud@49389cf9, ignoring blank lines and the generator string each file's header carries, exactly one of 5327 files differs between 7.14.0 and 7.24.0 — a doc comment on ConsoleSettings::getOidcConfig. On 7.14.0 the library builds with 0 errors (2663 sources, 192 API classes, 2462 models, 2502 operations) and the six example flows build with 0 errors, on aarch64 Ubuntu 24.04 with g++ 13.3. So the row needs no version of its own and this does not raise the pin. The four cpp-restsdk overrides move here as templates/cpp-restsdk/, next to the flags they go with. They are load-bearing and measured: generating without them fails with 8 errors, all in ModelBase.h. One flag, and it is the one six other rows already carry. o11y.GettableAgentCheckIn publishes integration_config beside integrationConfig and removed_at beside removedAt so older agents keep working; C++ camel-cases a property into its accessor, so each pair declared one method twice. Renaming the accessor keeps both wire keys — measured, all four are present in the emitted model, each under the document's own name. `take` is include/ and src/. The generator's CMakeLists.txt, Config.cmake.in, git_push.sh and README.md sit at the output root under neither, so they are never copied and need no `drop` entry — the repo keeps its own build contract. Verified against the tree the departed script produced: `generate.py cpp --check` reports clean, byte for byte, 5327 files. Co-authored-by: Hanzo Dev <[email protected]>
382 lines
17 KiB
Plaintext
382 lines
17 KiB
Plaintext
{{! openapi-generator 7.24.0 cpp-rest-sdk-client/api-source.mustache, overridden.
|
|
Forked from the stock template at that exact version, so a bump
|
|
re-derives these rather than merging them. Every changed hunk carries
|
|
a comment saying which generator defect it fixes; the measurement is
|
|
in LLM.md. Nothing here says anything about the Hanzo API. }}
|
|
{{>licenseInfo}}
|
|
{{#operations}}
|
|
|
|
#include "{{packageName}}/api/{{classname}}.h"
|
|
#include "{{packageName}}/IHttpBody.h"
|
|
#include "{{packageName}}/JsonBody.h"
|
|
#include "{{packageName}}/MultipartFormData.h"
|
|
|
|
#include <boost/algorithm/string/replace.hpp>
|
|
|
|
#include <unordered_set>
|
|
|
|
{{#apiNamespaceDeclarations}}
|
|
namespace {{this}} {
|
|
{{/apiNamespaceDeclarations}}
|
|
|
|
using namespace {{modelNamespace}};
|
|
|
|
{{classname}}::{{classname}}( std::shared_ptr<const ApiClient> apiClient )
|
|
: m_ApiClient(apiClient)
|
|
{
|
|
}
|
|
|
|
{{classname}}::~{{classname}}()
|
|
{
|
|
}
|
|
|
|
{{#operation}}
|
|
pplx::task<{{{returnType}}}{{^returnType}}void{{/returnType}}> {{classname}}::{{operationId}}({{#allParams}}{{^required}}boost::optional<{{/required}}{{{dataType}}}{{^required}}>{{/required}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) const
|
|
{
|
|
{{#allParams}}{{#required}}{{^isPrimitiveType}}{{^isContainer}}
|
|
// verify the required parameter '{{paramName}}' is set
|
|
if ({{paramName}} == nullptr)
|
|
{
|
|
throw ApiException(400, utility::conversions::to_string_t("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}"));
|
|
}
|
|
{{/isContainer}}{{/isPrimitiveType}}{{/required}}{{/allParams}}
|
|
|
|
std::shared_ptr<const ApiConfiguration> localVarApiConfiguration( m_ApiClient->getConfiguration() );
|
|
utility::string_t localVarPath = utility::conversions::to_string_t("{{{path}}}");
|
|
{{#pathParams}}
|
|
boost::replace_all(localVarPath, utility::conversions::to_string_t("{") + utility::conversions::to_string_t("{{baseName}}") + utility::conversions::to_string_t("}"), web::uri::encode_uri(ApiClient::parameterToString({{{paramName}}})));
|
|
{{/pathParams}}
|
|
|
|
std::map<utility::string_t, utility::string_t> localVarQueryParams;
|
|
std::map<utility::string_t, utility::string_t> localVarHeaderParams( localVarApiConfiguration->getDefaultHeaders() );
|
|
std::map<utility::string_t, utility::string_t> localVarFormParams;
|
|
std::map<utility::string_t, std::shared_ptr<HttpContent>> localVarFileParams;
|
|
|
|
std::unordered_set<utility::string_t> localVarResponseHttpContentTypes;
|
|
{{#produces}}
|
|
localVarResponseHttpContentTypes.insert( utility::conversions::to_string_t("{{{mediaType}}}") );
|
|
{{/produces}}
|
|
|
|
utility::string_t localVarResponseHttpContentType;
|
|
|
|
// use JSON if possible
|
|
if ( localVarResponseHttpContentTypes.size() == 0 )
|
|
{
|
|
{{#vendorExtensions.x-codegen-response.isString}}
|
|
localVarResponseHttpContentType = utility::conversions::to_string_t("text/plain");
|
|
{{/vendorExtensions.x-codegen-response.isString}}
|
|
{{^vendorExtensions.x-codegen-response.isString}}
|
|
localVarResponseHttpContentType = utility::conversions::to_string_t("application/json");
|
|
{{/vendorExtensions.x-codegen-response.isString}}
|
|
}
|
|
// JSON
|
|
else if ( localVarResponseHttpContentTypes.find(utility::conversions::to_string_t("application/json")) != localVarResponseHttpContentTypes.end() )
|
|
{
|
|
localVarResponseHttpContentType = utility::conversions::to_string_t("application/json");
|
|
}
|
|
// multipart formdata
|
|
else if( localVarResponseHttpContentTypes.find(utility::conversions::to_string_t("multipart/form-data")) != localVarResponseHttpContentTypes.end() )
|
|
{
|
|
localVarResponseHttpContentType = utility::conversions::to_string_t("multipart/form-data");
|
|
}
|
|
{{#vendorExtensions.x-codegen-response.isString}}
|
|
// plain text
|
|
else if( localVarResponseHttpContentTypes.find(utility::conversions::to_string_t("text/plain")) != localVarResponseHttpContentTypes.end() )
|
|
{
|
|
localVarResponseHttpContentType = utility::conversions::to_string_t("text/plain");
|
|
}
|
|
{{/vendorExtensions.x-codegen-response.isString}}
|
|
{{#vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
else
|
|
{
|
|
//It's going to be binary, so just use the first one.
|
|
localVarResponseHttpContentType = *localVarResponseHttpContentTypes.begin();
|
|
}
|
|
{{/vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
{{^vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
else
|
|
{
|
|
throw ApiException(400, utility::conversions::to_string_t("{{classname}}->{{operationId}} does not produce any supported media type"));
|
|
}
|
|
{{/vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
|
|
localVarHeaderParams[utility::conversions::to_string_t("Accept")] = localVarResponseHttpContentType;
|
|
|
|
std::unordered_set<utility::string_t> localVarConsumeHttpContentTypes;
|
|
{{#consumes}}
|
|
localVarConsumeHttpContentTypes.insert( utility::conversions::to_string_t("{{{mediaType}}}") );
|
|
{{/consumes}}
|
|
|
|
{{#allParams}}
|
|
{{^isBodyParam}}
|
|
{{^isPathParam}}
|
|
{{#required}}
|
|
{{^isPrimitiveType}}
|
|
{{^isContainer}}
|
|
if ({{paramName}} != nullptr)
|
|
{{/isContainer}}
|
|
{{/isPrimitiveType}}
|
|
{{/required}}
|
|
{{^required}}
|
|
{{^isPrimitiveType}}
|
|
{{^isContainer}}
|
|
if ({{paramName}} && *{{paramName}} != nullptr)
|
|
{{/isContainer}}
|
|
{{/isPrimitiveType}}
|
|
{{#isPrimitiveType}}
|
|
{{#isFile}}
|
|
if ({{paramName}} && *{{paramName}} != nullptr)
|
|
{{/isFile}}
|
|
{{^isFile}}
|
|
if ({{paramName}})
|
|
{{/isFile}}
|
|
{{/isPrimitiveType}}
|
|
{{#isContainer}}
|
|
if ({{paramName}})
|
|
{{/isContainer}}
|
|
{{/required}}
|
|
{
|
|
{{#isQueryParam}}
|
|
localVarQueryParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToString({{^required}}*{{/required}}{{paramName}});
|
|
{{/isQueryParam}}
|
|
{{#isHeaderParam}}
|
|
localVarHeaderParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToString({{^required}}*{{/required}}{{paramName}});
|
|
{{/isHeaderParam}}
|
|
{{#isFormParam}}
|
|
{{#isFile}}
|
|
localVarFileParams[ utility::conversions::to_string_t("{{baseName}}") ] = {{^required}}*{{/required}}{{paramName}};
|
|
{{/isFile}}
|
|
{{^isFile}}
|
|
localVarFormParams[ utility::conversions::to_string_t("{{baseName}}") ] = ApiClient::parameterToString({{^required}}*{{/required}}{{paramName}});
|
|
{{/isFile}}
|
|
{{/isFormParam}}
|
|
}
|
|
{{/isPathParam}}
|
|
{{/isBodyParam}}
|
|
{{/allParams}}
|
|
|
|
std::shared_ptr<IHttpBody> localVarHttpBody;
|
|
utility::string_t localVarRequestHttpContentType;
|
|
|
|
// use JSON if possible
|
|
if ( localVarConsumeHttpContentTypes.size() == 0 || localVarConsumeHttpContentTypes.find(utility::conversions::to_string_t("application/json")) != localVarConsumeHttpContentTypes.end() )
|
|
{
|
|
localVarRequestHttpContentType = utility::conversions::to_string_t("application/json");
|
|
{{#bodyParam}}
|
|
web::json::value localVarJson;
|
|
|
|
{{#isPrimitiveType}}
|
|
localVarJson = ModelBase::toJson({{paramName}}{{^required}}.get(){{/required}});
|
|
{{/isPrimitiveType}}
|
|
{{^isPrimitiveType}}
|
|
{{#isArray}}
|
|
{
|
|
std::vector<web::json::value> localVarJsonArray;
|
|
for( auto& localVarItem : {{paramName}}{{^required}}.get(){{/required}} )
|
|
{
|
|
{{#items.isPrimitiveType}}localVarJsonArray.push_back(ModelBase::toJson(localVarItem));
|
|
{{/items.isPrimitiveType}}{{^items.isPrimitiveType}}{{#items.isString}}localVarJsonArray.push_back(ModelBase::toJson(localVarItem));
|
|
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}localVarJsonArray.push_back(ModelBase::toJson(localVarItem));
|
|
{{! Same resolution gap on the way out: the item may be a model
|
|
held BY VALUE, which has no operator-> . ModelBase overloads
|
|
both kinds. }}
|
|
{{/items.isDateTime}}{{^items.isDateTime}}localVarJsonArray.push_back(ModelBase::toJson(localVarItem));
|
|
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
|
|
}
|
|
localVarJson = web::json::value::array(localVarJsonArray);
|
|
}
|
|
{{/isArray}}
|
|
{{^isArray}}{{#required}}localVarJson = ModelBase::toJson({{paramName}});
|
|
{{/required}}{{^required}}if ({{paramName}})
|
|
localVarJson = ModelBase::toJson(*{{paramName}});{{/required}}
|
|
{{/isArray}}
|
|
{{/isPrimitiveType}}
|
|
|
|
localVarHttpBody = std::shared_ptr<IHttpBody>( new JsonBody( localVarJson ) );
|
|
{{/bodyParam}}
|
|
}
|
|
// multipart formdata
|
|
else if( localVarConsumeHttpContentTypes.find(utility::conversions::to_string_t("multipart/form-data")) != localVarConsumeHttpContentTypes.end() )
|
|
{
|
|
localVarRequestHttpContentType = utility::conversions::to_string_t("multipart/form-data");
|
|
{{#bodyParam}}
|
|
std::shared_ptr<MultipartFormData> localVarMultipart(new MultipartFormData);
|
|
{{#isPrimitiveType}}
|
|
localVarMultipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), {{paramName}}{{^required}}.get(){{/required}}));
|
|
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isArray}}
|
|
{
|
|
std::vector<web::json::value> localVarJsonArray;
|
|
for( auto& localVarItem : {{paramName}}{{^required}}.get(){{/required}} )
|
|
{
|
|
localVarJsonArray.push_back(ModelBase::toJson(localVarItem));
|
|
}
|
|
localVarMultipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), localVarJsonArray, utility::conversions::to_string_t("application/json")));
|
|
}{{/isArray}}{{#isMap}}
|
|
{
|
|
std::map<utility::string_t, web::json::value> localVarJsonMap;
|
|
for( auto& localVarItem : {{paramName}}{{^required}}.get(){{/required}} )
|
|
{
|
|
web::json::value jval;
|
|
localVarJsonMap.insert( std::pair<utility::string_t, web::json::value>(localVarItem.first, ModelBase::toJson(localVarItem.second) ));
|
|
}
|
|
localVarMultipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), localVarJsonMap, utility::conversions::to_string_t("application/json")));
|
|
}{{/isMap}}
|
|
{{^isArray}}{{^isMap}}{{#isString}}localVarMultipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), {{paramName}}));
|
|
{{/isString}}{{^isString}}if({{^required}}{{paramName}} && (*{{paramName}}){{/required}}{{#required}}{{paramName}}{{/required}}.get())
|
|
{
|
|
{{^required}}(*{{/required}}{{paramName}}{{^required}}){{/required}}->toMultipart(localVarMultipart, utility::conversions::to_string_t("{{paramName}}"));
|
|
}
|
|
{{/isString}}
|
|
{{/isMap}}{{/isArray}}{{/isPrimitiveType}}
|
|
|
|
localVarHttpBody = localVarMultipart;
|
|
localVarRequestHttpContentType += utility::conversions::to_string_t("; boundary=") + localVarMultipart->getBoundary();
|
|
{{/bodyParam}}
|
|
}
|
|
else if (localVarConsumeHttpContentTypes.find(utility::conversions::to_string_t("application/x-www-form-urlencoded")) != localVarConsumeHttpContentTypes.end())
|
|
{
|
|
localVarRequestHttpContentType = utility::conversions::to_string_t("application/x-www-form-urlencoded");
|
|
}
|
|
else
|
|
{
|
|
throw ApiException(415, utility::conversions::to_string_t("{{classname}}->{{operationId}} does not consume any supported media type"));
|
|
}
|
|
|
|
{{#authMethods}}
|
|
// authentication ({{name}}) required
|
|
{{#isApiKey}}
|
|
{{#isKeyInHeader}}
|
|
{
|
|
utility::string_t localVarApiKey = localVarApiConfiguration->getApiKey(utility::conversions::to_string_t("{{name}}"));
|
|
if ( localVarApiKey.size() > 0 )
|
|
{
|
|
localVarHeaderParams[utility::conversions::to_string_t("{{keyParamName}}")] = localVarApiKey;
|
|
}
|
|
}
|
|
{{/isKeyInHeader}}
|
|
{{#isKeyInQuery}}
|
|
{
|
|
utility::string_t localVarApiKey = localVarApiConfiguration->getApiKey(utility::conversions::to_string_t("{{name}}"));
|
|
if ( localVarApiKey.size() > 0 )
|
|
{
|
|
localVarQueryParams[utility::conversions::to_string_t("{{keyParamName}}")] = localVarApiKey;
|
|
}
|
|
}
|
|
{{/isKeyInQuery}}
|
|
{{/isApiKey}}
|
|
{{#isBasicBasic}}
|
|
// Basic authentication is added automatically as part of the http_client_config
|
|
{{/isBasicBasic}}
|
|
{{#isOAuth}}
|
|
// oauth2 authentication is added automatically as part of the http_client_config
|
|
{{/isOAuth}}
|
|
{{/authMethods}}
|
|
|
|
return m_ApiClient->callApi(localVarPath, utility::conversions::to_string_t("{{httpMethod}}"), localVarQueryParams, localVarHttpBody, localVarHeaderParams, localVarFormParams, localVarFileParams, localVarRequestHttpContentType)
|
|
.then([=, this](web::http::http_response localVarResponse)
|
|
{
|
|
if (m_ApiClient->getResponseHandler())
|
|
{
|
|
m_ApiClient->getResponseHandler()(localVarResponse.status_code(), localVarResponse.headers());
|
|
}
|
|
|
|
// 1xx - informational : OK
|
|
// 2xx - successful : OK
|
|
// 3xx - redirection : OK
|
|
// 4xx - client error : not OK
|
|
// 5xx - client error : not OK
|
|
if (localVarResponse.status_code() >= 400)
|
|
{
|
|
throw ApiException(localVarResponse.status_code()
|
|
, utility::conversions::to_string_t("error calling {{operationId}}: ") + localVarResponse.reason_phrase()
|
|
, std::make_shared<std::stringstream>(localVarResponse.extract_utf8string(true).get()));
|
|
}
|
|
|
|
// check response content type
|
|
if(localVarResponse.headers().has(utility::conversions::to_string_t("Content-Type")))
|
|
{
|
|
utility::string_t localVarContentType = localVarResponse.headers()[utility::conversions::to_string_t("Content-Type")];
|
|
if( localVarContentType.find(localVarResponseHttpContentType) == std::string::npos )
|
|
{
|
|
throw ApiException(500
|
|
, utility::conversions::to_string_t("error calling {{operationId}}: unexpected response type: ") + localVarContentType
|
|
, std::make_shared<std::stringstream>(localVarResponse.extract_utf8string(true).get()));
|
|
}
|
|
}
|
|
|
|
{{#vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
return localVarResponse.extract_vector();
|
|
})
|
|
.then([=, this](std::vector<unsigned char> localVarResponse)
|
|
{
|
|
{{{returnType}}} localVarResult = std::make_shared<HttpContent>();
|
|
std::shared_ptr<std::stringstream> stream = std::make_shared<std::stringstream>(std::string(localVarResponse.begin(), localVarResponse.end()));
|
|
localVarResult->setData(stream);
|
|
return localVarResult;
|
|
{{/vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
{{^vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
return localVarResponse.extract_string();
|
|
})
|
|
.then([=, this](utility::string_t localVarResponse)
|
|
{
|
|
{{^returnType}}
|
|
return void();
|
|
{{/returnType}}
|
|
{{#returnType}}
|
|
{{#returnContainer}}
|
|
{{{returnType}}} localVarResult;
|
|
{{/returnContainer}}
|
|
{{^returnContainer}}
|
|
{{{returnType}}} localVarResult({{{defaultResponse}}});
|
|
{{/returnContainer}}
|
|
|
|
if(localVarResponseHttpContentType == utility::conversions::to_string_t("application/json"))
|
|
{
|
|
web::json::value localVarJson = web::json::value::parse(localVarResponse);
|
|
{{! The container and its element type are resolved separately, so an
|
|
array of free-form objects declares std::vector<Object> and is
|
|
filled with push_back(std::shared_ptr<Object>). Reading the
|
|
element type off the container itself is correct for every item
|
|
kind, and ModelBase routes both. }}
|
|
{{#isArray}}
|
|
for( auto& localVarItem : localVarJson.as_array() )
|
|
{
|
|
{{{returnType}}}::value_type localVarItemObj;
|
|
ModelBase::fromJson(localVarItem, localVarItemObj);
|
|
localVarResult.push_back(localVarItemObj);
|
|
}{{/isArray}}{{#isMap}}
|
|
for( auto& localVarItem : localVarJson.as_object() )
|
|
{
|
|
{{{returnType}}}::mapped_type localVarItemObj;
|
|
ModelBase::fromJson(localVarItem.second, localVarItemObj);
|
|
localVarResult[localVarItem.first] = localVarItemObj;
|
|
}{{/isMap}}{{^isArray}}{{^isMap}}
|
|
ModelBase::fromJson(localVarJson, localVarResult);{{/isMap}}{{/isArray}}
|
|
}{{#vendorExtensions.x-codegen-response.isString}}
|
|
else if(localVarResponseHttpContentType == utility::conversions::to_string_t("text/plain"))
|
|
{
|
|
localVarResult = localVarResponse;
|
|
}{{/vendorExtensions.x-codegen-response.isString}}
|
|
// else if(localVarResponseHttpContentType == utility::conversions::to_string_t("multipart/form-data"))
|
|
// {
|
|
// TODO multipart response parsing
|
|
// }
|
|
else
|
|
{
|
|
throw ApiException(500
|
|
, utility::conversions::to_string_t("error calling {{operationId}}: unsupported response type"));
|
|
}
|
|
|
|
return localVarResult;
|
|
{{/returnType}}
|
|
{{/vendorExtensions.x-codegen-response-ishttpcontent}}
|
|
});
|
|
}
|
|
{{/operation}}
|
|
|
|
{{#apiNamespaceDeclarations}}
|
|
}
|
|
{{/apiNamespaceDeclarations}}
|
|
|
|
{{/operations}}
|