Files
zeekayandHanzo Dev 384cc08eba cpp is a row, and the version floor it left over was a fact about a document
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]>
2026-08-14 20:37:43 -07:00

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}}