diff --git a/.github/workflows/samples-cpp-oatpp-client.yaml b/.github/workflows/samples-cpp-oatpp-client.yaml new file mode 100644 index 00000000000..4d133eb891e --- /dev/null +++ b/.github/workflows/samples-cpp-oatpp-client.yaml @@ -0,0 +1,30 @@ +name: Samples cpp oat++ client + +on: + push: + branches: + - "samples/client/petstore/cpp-oatpp/**" + pull_request: + paths: + - "samples/client/petstore/cpp-oatpp/**" + +env: + GRADLE_VERSION: 6.9 + +jobs: + build: + name: Build cpp oat++ client + strategy: + matrix: + sample: + - samples/client/petstore/cpp-oatpp + os: + - ubuntu-latest + - macOS-latest + - windows-latest + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Build + working-directory: ${{ matrix.sample }} + run: cmake -B build && cmake --build build --verbose diff --git a/.github/workflows/samples-cpp-oatpp-server.yaml b/.github/workflows/samples-cpp-oatpp-server.yaml index 12ad210e587..37ff5c81d66 100644 --- a/.github/workflows/samples-cpp-oatpp-server.yaml +++ b/.github/workflows/samples-cpp-oatpp-server.yaml @@ -13,7 +13,7 @@ env: jobs: build: - name: Build cpp qt client + name: Build cpp oat++ server strategy: matrix: sample: diff --git a/.gitignore b/.gitignore index a2e29abe05b..5c6df879f35 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,12 @@ samples/client/petstore/cpp-restsdk/client/cmake_install.cmake samples/client/petstore/cpp-restsdk/client/CppRestPetstoreClientConfig.cmake samples/client/petstore/cpp-restsdk/client/CMakeCache.txt +# cpp-oatpp +samples/client/petstore/cpp-oatpp/build +samples/client/petstore/cpp-oatpp/external +samples/server/petstore/cpp-oatpp/build +samples/server/petstore/cpp-oatpp/external + #Java/Android **/.gradle samples/client/petstore/java/hello.txt diff --git a/README.md b/README.md index e7af152c433..c4c0e95a042 100644 --- a/README.md +++ b/README.md @@ -1025,6 +1025,7 @@ Here is a list of template creators: * Apex: @asnelling * Bash: @bkryza * C: @PowerOfCreation @zhemant [:heart:](https://www.patreon.com/zhemant) + * C++ Oat++: @Kraust * C++ REST: @Danielku15 * C++ Tiny: @AndersSpringborg @kaareHH @michelealbano @mkakbas * C++ UE4: @Kahncode diff --git a/bin/configs/cpp-oatpp-client.yaml b/bin/configs/cpp-oatpp-client.yaml new file mode 100644 index 00000000000..eb8d3804a4e --- /dev/null +++ b/bin/configs/cpp-oatpp-client.yaml @@ -0,0 +1,6 @@ +generatorName: cpp-oatpp-client +outputDir: samples/client/petstore/cpp-oatpp +inputSpec: modules/openapi-generator/src/test/resources/3_0/cpp-oatpp-client/petstore.yaml +templateDir: modules/openapi-generator/src/main/resources/cpp-oatpp-client +additionalProperties: + addExternalLibs: "true" diff --git a/docs/generators.md b/docs/generators.md index 009bb56b4bc..ca295d97c5a 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -12,6 +12,7 @@ The following generators are available: * [bash](generators/bash.md) * [c](generators/c.md) * [clojure](generators/clojure.md) +* [cpp-oatpp-client](generators/cpp-oatpp-client.md) * [cpp-qt-client](generators/cpp-qt-client.md) * [cpp-restsdk](generators/cpp-restsdk.md) * [cpp-tiny (beta)](generators/cpp-tiny.md) diff --git a/docs/generators/cpp-oatpp-client.md b/docs/generators/cpp-oatpp-client.md new file mode 100644 index 00000000000..343f01645ea --- /dev/null +++ b/docs/generators/cpp-oatpp-client.md @@ -0,0 +1,262 @@ +--- +title: Documentation for the cpp-oatpp-client Generator +--- + +## METADATA + +| Property | Value | Notes | +| -------- | ----- | ----- | +| generator name | cpp-oatpp-client | pass this to the generate command after -g | +| generator stability | STABLE | | +| generator type | CLIENT | | +| generator language | C++ | | +| generator default templating engine | mustache | | +| helpTxt | Generates a C++ API client (based on Oat++) | | + +## CONFIG OPTIONS +These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details. + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|addExternalLibs|Add the Possibility to fetch and compile external Libraries needed by this Framework.| |true| +|reservedWordPrefix|Prefix to prepend to reserved words in order to avoid conflicts| |r_| +|variableNameFirstCharacterUppercase|Make first character of variable name uppercase (eg. value -> Value)| |true| + +## IMPORT MAPPING + +| Type/Alias | Imports | +| ---------- | ------- | + + +## INSTANTIATION TYPES + +| Type/Alias | Instantiated By | +| ---------- | --------------- | + + +## LANGUAGE PRIMITIVES + + + +## RESERVED WORDS + + + +## FEATURE SET + + +### Client Modification Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasePath|✗|ToolingExtension +|Authorizations|✗|ToolingExtension +|UserAgent|✗|ToolingExtension +|MockServer|✗|ToolingExtension + +### Data Type Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Custom|✗|OAS2,OAS3 +|Int32|✓|OAS2,OAS3 +|Int64|✓|OAS2,OAS3 +|Float|✓|OAS2,OAS3 +|Double|✓|OAS2,OAS3 +|Decimal|✓|ToolingExtension +|String|✓|OAS2,OAS3 +|Byte|✓|OAS2,OAS3 +|Binary|✓|OAS2,OAS3 +|Boolean|✓|OAS2,OAS3 +|Date|✓|OAS2,OAS3 +|DateTime|✓|OAS2,OAS3 +|Password|✓|OAS2,OAS3 +|File|✓|OAS2 +|Uuid|✗| +|Array|✓|OAS2,OAS3 +|Null|✗|OAS3 +|AnyType|✗|OAS2,OAS3 +|Object|✓|OAS2,OAS3 +|Maps|✓|ToolingExtension +|CollectionFormat|✓|OAS2 +|CollectionFormatMulti|✓|OAS2 +|Enum|✓|OAS2,OAS3 +|ArrayOfEnum|✓|ToolingExtension +|ArrayOfModel|✓|ToolingExtension +|ArrayOfCollectionOfPrimitives|✓|ToolingExtension +|ArrayOfCollectionOfModel|✓|ToolingExtension +|ArrayOfCollectionOfEnum|✓|ToolingExtension +|MapOfEnum|✓|ToolingExtension +|MapOfModel|✓|ToolingExtension +|MapOfCollectionOfPrimitives|✓|ToolingExtension +|MapOfCollectionOfModel|✓|ToolingExtension +|MapOfCollectionOfEnum|✓|ToolingExtension + +### Documentation Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Readme|✓|ToolingExtension +|Model|✓|ToolingExtension +|Api|✓|ToolingExtension + +### Global Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Host|✓|OAS2,OAS3 +|BasePath|✓|OAS2,OAS3 +|Info|✓|OAS2,OAS3 +|Schemes|✗|OAS2,OAS3 +|PartialSchemes|✓|OAS2,OAS3 +|Consumes|✓|OAS2 +|Produces|✓|OAS2 +|ExternalDocumentation|✓|OAS2,OAS3 +|Examples|✓|OAS2,OAS3 +|XMLStructureDefinitions|✗|OAS2,OAS3 +|MultiServer|✗|OAS3 +|ParameterizedServer|✗|OAS3 +|ParameterStyling|✗|OAS3 +|Callbacks|✗|OAS3 +|LinkObjects|✗|OAS3 + +### Parameter Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Path|✓|OAS2,OAS3 +|Query|✓|OAS2,OAS3 +|Header|✓|OAS2,OAS3 +|Body|✓|OAS2 +|FormUnencoded|✓|OAS2 +|FormMultipart|✓|OAS2 +|Cookie|✗|OAS3 + +### Schema Support Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Simple|✓|OAS2,OAS3 +|Composite|✓|OAS2,OAS3 +|Polymorphism|✗|OAS2,OAS3 +|Union|✗|OAS3 +|allOf|✗|OAS2,OAS3 +|anyOf|✗|OAS3 +|oneOf|✗|OAS3 +|not|✗|OAS3 + +### Security Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasicAuth|✗|OAS2,OAS3 +|ApiKey|✗|OAS2,OAS3 +|OpenIDConnect|✗|OAS3 +|BearerToken|✗|OAS3 +|OAuth2_Implicit|✗|OAS2,OAS3 +|OAuth2_Password|✗|OAS2,OAS3 +|OAuth2_ClientCredentials|✗|OAS2,OAS3 +|OAuth2_AuthorizationCode|✗|OAS2,OAS3 +|SignatureAuth|✗|OAS3 +|AWSV4Signature|✗|ToolingExtension + +### Wire Format Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|JSON|✓|OAS2,OAS3 +|XML|✓|OAS2,OAS3 +|PROTOBUF|✗|ToolingExtension +|Custom|✗|OAS2,OAS3 diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppOatppClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppOatppClientCodegen.java new file mode 100644 index 00000000000..eec28ac05de --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppOatppClientCodegen.java @@ -0,0 +1,474 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.languages; + +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.servers.Server; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.OperationMap; +import org.openapitools.codegen.model.OperationsMap; +import org.openapitools.codegen.utils.ModelUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.*; +import java.util.function.Predicate; + +import static org.openapitools.codegen.utils.StringUtils.underscore; + +public class CppOatppClientCodegen extends AbstractCppCodegen { + private final Logger LOGGER = LoggerFactory.getLogger(CppOatppClientCodegen.class); + + protected boolean isAddExternalLibs = true; + public static final String OPTIONAL_EXTERNAL_LIB = "addExternalLibs"; + public static final String OPTIONAL_EXTERNAL_LIB_DESC = "Add the Possibility to fetch and compile external Libraries needed by this Framework."; + protected final String PREFIX = ""; + + @Override + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + @Override + public String getName() { + return "cpp-oatpp-client"; + } + + @Override + public String getHelp() { + return "Generates a C++ API client (based on Oat++)"; + } + + public CppOatppClientCodegen() { + super(); + + // TODO: cpp-oatpp-client maintainer review + modifyFeatureSet(features -> features + .includeDocumentationFeatures(DocumentationFeature.Readme) + .securityFeatures(EnumSet.noneOf(SecurityFeature.class)) + .excludeGlobalFeatures( + GlobalFeature.XMLStructureDefinitions, + GlobalFeature.Callbacks, + GlobalFeature.LinkObjects, + GlobalFeature.ParameterStyling, + GlobalFeature.MultiServer) + .excludeSchemaSupportFeatures( + SchemaSupportFeature.Polymorphism) + .excludeParameterFeatures( + ParameterFeature.Cookie)); + + if (StringUtils.isEmpty(modelNamePrefix)) { + modelNamePrefix = PREFIX; + } + + apiPackage = "org.openapitools.client.api"; + modelPackage = "org.openapitools.client.model"; + + apiTemplateFiles.put("api-header.mustache", ".hpp"); + + modelTemplateFiles.put("model-header.mustache", ".hpp"); + + embeddedTemplateDir = templateDir = "cpp-oatpp-client"; + + cliOptions.clear(); + addSwitch(OPTIONAL_EXTERNAL_LIB, OPTIONAL_EXTERNAL_LIB_DESC, this.isAddExternalLibs); + addOption(RESERVED_WORD_PREFIX_OPTION, RESERVED_WORD_PREFIX_DESC, this.reservedWordPrefix); + addOption(VARIABLE_NAME_FIRST_CHARACTER_UPPERCASE_OPTION, + VARIABLE_NAME_FIRST_CHARACTER_UPPERCASE_DESC, + Boolean.toString(this.variableNameFirstCharacterUppercase)); + + setupSupportingFiles(); + + languageSpecificPrimitives = new HashSet<>( + Arrays.asList( + "oatpp::String", + "oatpp::Boolean", + "oatpp::Int32", + "oatpp::Int64", + "oatpp::Vector", + "oatpp::Fields", + "oatpp::UnorderedSet", + "oatpp::Object", + "oatpp::Float64", + "oatpp::Any" + )); + + typeMapping = new HashMap<>(); + typeMapping.put("date", "oatpp::String"); + typeMapping.put("DateTime", "oatpp::String"); + typeMapping.put("string", "oatpp::String"); + typeMapping.put("integer", "oatpp::Int32"); + typeMapping.put("long", "oatpp::Int64"); + typeMapping.put("boolean", "oatpp::Boolean"); + typeMapping.put("array", "oatpp::Vector"); + typeMapping.put("map", "oatpp::Fields"); + typeMapping.put("set", "oatpp::UnorderedSet"); + typeMapping.put("file", "oatpp::String"); + typeMapping.put("object", "oatpp::Object"); + typeMapping.put("binary", "oatpp::String"); + typeMapping.put("number", "oatpp::Float64"); + typeMapping.put("UUID", "oatpp::String"); + typeMapping.put("URI", "oatpp::String"); + typeMapping.put("ByteArray", "oatpp::String"); + typeMapping.put("AnyType", "oatpp::Any"); + + super.importMapping = new HashMap<>(); + } + + private void setupSupportingFiles() { + supportingFiles.clear(); + supportingFiles + .add(new SupportingFile("main-api-client.mustache", "", modelNamePrefix + "main-api-client.cpp")); + supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + } + + @Override + public void processOpts() { + super.processOpts(); + if (additionalProperties.containsKey("modelNamePrefix")) { + additionalProperties().put("prefix", modelNamePrefix); + setupSupportingFiles(); + } + if (additionalProperties.containsKey(RESERVED_WORD_PREFIX_OPTION)) { + reservedWordPrefix = (String) additionalProperties.get(RESERVED_WORD_PREFIX_OPTION); + } + + additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\.")); + additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::")); + additionalProperties.put("apiNamespaceDeclarations", apiPackage.split("\\.")); + additionalProperties.put("apiNamespace", apiPackage.replaceAll("\\.", "::")); + additionalProperties.put(RESERVED_WORD_PREFIX_OPTION, reservedWordPrefix); + + if (additionalProperties.containsKey(OPTIONAL_EXTERNAL_LIB)) { + setAddExternalLibs(convertPropertyToBooleanAndWriteBack(OPTIONAL_EXTERNAL_LIB)); + } else { + additionalProperties.put(OPTIONAL_EXTERNAL_LIB, isAddExternalLibs); + } + } + + @Override + public String toModelImport(String name) { + if (importMapping.containsKey(name)) { + return importMapping.get(name); + } else { + return "#include \"" + name + ".hpp\""; + } + } + + @Override + public CodegenModel fromModel(String name, Schema model) { + CodegenModel codegenModel = super.fromModel(name, model); + + Set oldImports = codegenModel.imports; + codegenModel.imports = new HashSet<>(); + for (String imp : oldImports) { + String newImp = toModelImport(imp); + if (!newImp.isEmpty()) { + codegenModel.imports.add(newImp); + } + } + + if (!codegenModel.isEnum + && codegenModel.anyOf.size() > 1 + && codegenModel.anyOf.contains("std::string") + && !codegenModel.anyOf.contains("AnyType") + && codegenModel.interfaces.size() == 1) { + codegenModel.vendorExtensions.put("x-is-string-enum-container", true); + } + return codegenModel; + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List servers) { + CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); + + if (operation.getResponses() != null && !operation.getResponses().isEmpty()) { + ApiResponse apiResponse = findMethodResponse(operation.getResponses()); + + if (apiResponse != null) { + Schema response = ModelUtils.getSchemaFromResponse(openAPI, apiResponse); + if (response != null) { + CodegenProperty cm = fromProperty("response", response, false); + op.vendorExtensions.put("x-codegen-response", cm); + if ("HttpContent".equals(cm.dataType)) { + op.vendorExtensions.put("x-codegen-response-ishttpcontent", true); + } + } + } + } + + String pathForOatpp = path.replaceAll("\\{(.*?)}", "{$1}"); + op.vendorExtensions.put("x-codegen-oatpp-path", pathForOatpp); + + return op; + } + + @Override + public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { + OperationMap operations = objs.getOperations(); + String classname = operations.getClassname(); + operations.put("classnameSnakeUpperCase", underscore(classname).toUpperCase(Locale.ROOT)); + operations.put("classnameSnakeLowerCase", underscore(classname).toLowerCase(Locale.ROOT)); + List operationList = operations.getOperation(); + for (CodegenOperation op : operationList) { + postProcessSingleOperation(operations, op); + } + + return objs; + } + + private void postProcessSingleOperation(OperationMap operations, CodegenOperation op) { + if (op.vendorExtensions == null) { + op.vendorExtensions = new HashMap<>(); + } + + if (op.bodyParam != null) { + if (op.bodyParam.vendorExtensions == null) { + op.bodyParam.vendorExtensions = new HashMap<>(); + } + + boolean isStringOrDate = op.bodyParam.isString || op.bodyParam.isDate; + op.bodyParam.vendorExtensions.put("x-codegen-oatpp-is-string-or-date", isStringOrDate); + } + + boolean consumeJson = false; + if (op.consumes != null) { + Predicate> isMediaTypeJson = consume -> (consume.get("mediaType") != null + && consume.get("mediaType").equals("application/json")); + consumeJson = op.consumes.stream().anyMatch(isMediaTypeJson); + } + op.vendorExtensions.put("x-codegen-oatpp-consumes-json", consumeJson); + + // Check if any one of the operations needs a model, then at API file level, at + // least one model has to be included. + Predicate importNotInImportMapping = hdr -> !importMapping.containsKey(hdr); + if (op.imports.stream().anyMatch(importNotInImportMapping)) { + operations.put("hasModelImport", true); + } + } + + /** + * postProcessSingleParam - Modifies a single parameter, adjusting generated + * data types for Header and Query parameters. + * + * @param param CodegenParameter to be modified. + */ + private static void postProcessSingleParam(CodegenParameter param) { + if (param.isQueryParam) { + param.dataType = "std::optional<" + param.dataType + ">"; + if (!param.isPrimitiveType) { + param.baseType = "std::optional<" + param.baseType + ">"; + } + } + } + + @Override + public String toModelFilename(String name) { + return toModelName(name); + } + + @Override + public String apiFilename(String templateName, String tag) { + return super.apiFilename(templateName, tag); + } + + @Override + public String toApiFilename(String name) { + return toApiName(name); + } + + /** + * Optional - type declaration. This is a String which is used by the + * templates to instantiate your types. There is typically special handling + * for different property types + * + * @return a string value used as the `dataType` field for model templates, + * `returnType` for api templates + */ + @Override + public String getTypeDeclaration(Schema p) { + String openAPIType = getSchemaType(p); + + if (ModelUtils.isArraySchema(p)) { + ArraySchema ap = (ArraySchema) p; + Schema inner = ap.getItems(); + if (languageSpecificPrimitives.contains(getSchemaType(inner))) { + return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">"; + } + return getSchemaType(p) + ">"; + } + if (ModelUtils.isMapSchema(p)) { + Schema inner = ModelUtils.getAdditionalProperties(p); + return getSchemaType(p) + ""; + } else if (ModelUtils.isByteArraySchema(p)) { + return "std::string"; + } + if (ModelUtils.isStringSchema(p) + || ModelUtils.isDateSchema(p) + || ModelUtils.isDateTimeSchema(p) || ModelUtils.isFileSchema(p) + || languageSpecificPrimitives.contains(openAPIType)) { + return toModelName(openAPIType); + } + + String namespace = (String) additionalProperties.get("modelNamespace"); + return namespace + "::" + openAPIType; + } + + @Override + public String toDefaultValue(Schema p) { + if (ModelUtils.isStringSchema(p)) { + if (p.getDefault() != null) { + return "\"" + p.getDefault().toString() + "\""; + } else { + return "\"\""; + } + } else if (ModelUtils.isBooleanSchema(p)) { + if (p.getDefault() != null) { + return p.getDefault().toString(); + } else { + return "false"; + } + } else if (ModelUtils.isDateSchema(p)) { + if (p.getDefault() != null) { + return "\"" + p.getDefault().toString() + "\""; + } else { + return "\"\""; + } + } else if (ModelUtils.isDateTimeSchema(p)) { + if (p.getDefault() != null) { + return "\"" + p.getDefault().toString() + "\""; + } else { + return "\"\""; + } + } else if (ModelUtils.isNumberSchema(p)) { + if (ModelUtils.isFloatSchema(p)) { // float + if (p.getDefault() != null) { + // We have to ensure that our default value has a decimal point, + // because in C++ the 'f' suffix is not valid on integer literals + // i.e. 374.0f is a valid float but 374 isn't. + String defaultStr = p.getDefault().toString(); + if (defaultStr.indexOf('.') < 0) { + return defaultStr + ".0f"; + } else { + return defaultStr + "f"; + } + } else { + return "0.0f"; + } + } else { // double + if (p.getDefault() != null) { + return p.getDefault().toString(); + } else { + return "0.0"; + } + } + } else if (ModelUtils.isIntegerSchema(p)) { + if (ModelUtils.isLongSchema(p)) { // long + if (p.getDefault() != null) { + return p.getDefault().toString() + "L"; + } else { + return "0L"; + } + } else { // integer + if (p.getDefault() != null) { + return p.getDefault().toString(); + } else { + return "0"; + } + } + } else if (ModelUtils.isByteArraySchema(p)) { + if (p.getDefault() != null) { + return "\"" + p.getDefault().toString() + "\""; + } else { + return "\"\""; + } + } else if (ModelUtils.isMapSchema(p)) { + String inner = getSchemaType(ModelUtils.getAdditionalProperties(p)); + return "std::map()"; + } else if (ModelUtils.isArraySchema(p)) { + ArraySchema ap = (ArraySchema) p; + String inner = getSchemaType(ap.getItems()); + if (!languageSpecificPrimitives.contains(inner)) { + inner = "std::shared_ptr<" + inner + ">"; + } + return "std::vector<" + inner + ">()"; + } else if (!StringUtils.isEmpty(p.get$ref())) { + return "std::make_shared<" + toModelName(ModelUtils.getSimpleRef(p.get$ref())) + ">()"; + } + + return "nullptr"; + } + + /** + * Location to write model files. You can use the modelPackage() as defined + * when the class is instantiated + */ + @Override + public String modelFileFolder() { + return (outputFolder + "/model").replace("/", File.separator); + } + + /** + * Location to write api files. You can use the apiPackage() as defined when + * the class is instantiated + */ + @Override + public String apiFileFolder() { + return (outputFolder + "/api").replace("/", File.separator); + } + + /** + * Optional - OpenAPI type conversion. This is used to map OpenAPI types in + * a `Schema` into either language specific types via `typeMapping` or + * into complex models if there is not a mapping. + * + * @return a string value of the type or complex model for this property + */ + @Override + public String getSchemaType(Schema p) { + String openAPIType = super.getSchemaType(p); + String type = null; + if (typeMapping.containsKey(openAPIType)) { + type = typeMapping.get(openAPIType); + } else { + type = openAPIType; + } + return toModelName(type); + } + + @Override + public String getTypeDeclaration(String str) { + return toModelName(str); + } + + /** + * Specify whether external libraries will be added during the generation + * + * @param value the value to be set + */ + public void setAddExternalLibs(boolean value) { + isAddExternalLibs = value; + } +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 1d48c0c0d66..fe481e526af 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -12,6 +12,7 @@ org.openapitools.codegen.languages.CrystalClientCodegen org.openapitools.codegen.languages.CLibcurlClientCodegen org.openapitools.codegen.languages.ClojureClientCodegen org.openapitools.codegen.languages.ConfluenceWikiCodegen +org.openapitools.codegen.languages.CppOatppClientCodegen org.openapitools.codegen.languages.CppQtClientCodegen org.openapitools.codegen.languages.CppQtQHttpEngineServerCodegen org.openapitools.codegen.languages.CppOatppServerCodegen diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/README.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/README.mustache new file mode 100644 index 00000000000..801776da4f0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/README.mustache @@ -0,0 +1,39 @@ +# REST API Client for {{appName}} + +## Overview +This API Client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +It uses the [Oat++](https://github.com/oatpp/oatpp) Framework. + +## Files organization +The Oat++ C++ REST client generator creates two folders: +- `api`: This folder contains the handlers for each method specified in the OpenAPI definition. Every handler extracts +the path and parameters (if any) from the request issue them against the server. +- `model`: This folder contains the corresponding class for every object schema found in the OpenAPI specification. + +The main folder contains also a file with a main that can be used to issue REST requests through the client. +Of course, is you should customize this file based on your needs + +## Installation +First of all, you need to download and install the libraries listed [here](#libraries-required). + +Once the libraries are installed, in order to compile and run the client please follow the steps below: +```bash +mkdir build +cd build +cmake .. +make +``` + +Once compiled run the client: + +```bash +cd build +./api-client +``` + +## Libraries required +- [Oat++](https://oatpp.io/) + +## Namespaces +{{{apiPackage}}} +{{{modelPackage}}} diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/api-header.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/api-header.mustache new file mode 100644 index 00000000000..a9fde1523b4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/api-header.mustache @@ -0,0 +1,50 @@ +{{>licenseInfo}} +{{#operations}}/* + * {{classname}}.h + * + * {{description}} + */ + +#ifndef {{classname}}_H_ +#define {{classname}}_H_ + +{{{defaultInclude}}} + +#include "oatpp/web/client/ApiClient.hpp" +#include "oatpp/web/protocol/http/outgoing/MultipartBody.hpp" +#include "oatpp/core/macro/codegen.hpp" + +{{#imports}}{{{import}}} +{{/imports}} + +#include OATPP_CODEGEN_BEGIN(ApiClient) ///< Begin code-gen section + +namespace {{apiNamespace}} +{ + +class {{classname}} : public oatpp::web::client::ApiClient { +public: + + API_CLIENT_INIT({{classname}}) + + {{#operation}} + /// + /// {{summary}} + /// + /// + /// {{notes}} + /// + {{#allParams}} + {{#isPathParam}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}{{/isPathParam}}{{#isQueryParam}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}{{/isQueryParam}}{{#isBodyParam}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}{{/isBodyParam}}{{#isHeaderParam}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}{{/isHeaderParam}}{{#isFormParam}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}{{/isFormParam}} + {{/allParams}} + API_CALL("{{httpMethod}}", "{{{vendorExtensions.x-codegen-oatpp-path}}}", {{operationIdSnakeCase}}{{#allParams}}{{#isPathParam}}, PATH({{#isModel}}{{modelNamespace}}::{{/isModel}}{{&dataType}}, {{paramName}}){{/isPathParam}}{{#isQueryParam}}, QUERY({{#isModel}}{{modelNamespace}}::{{/isModel}}{{&dataType}}, {{paramName}}){{/isQueryParam}}{{#isBodyParam}}, BODY_DTO({{#isModel}}oatpp::Object<{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}>{{/isModel}}{{^isModel}}{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}{{/isModel}}, {{paramName}}){{/isBodyParam}}{{#isHeaderParam}}, HEADER({{{dataType}}}, {{paramName}}, "{{paramName}}"){{/isHeaderParam}}{{/allParams}}{{#hasFormParams}}, BODY(std::shared_ptr, formData){{/hasFormParams}}) + {{/operation}} +}; + +#include OATPP_CODEGEN_END(ApiClient) ///< End code-gen section + +} // namespace {{apiNamespace}} + +#endif /* {{classname}}_H_ */ + +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/cmake.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/cmake.mustache new file mode 100644 index 00000000000..5346e8e9470 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/cmake.mustache @@ -0,0 +1,38 @@ +cmake_minimum_required (VERSION 3.2) + +project(api-client) + +{{#addExternalLibs}} +include(ExternalProject) + +set(EXTERNAL_INSTALL_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/external) + +ExternalProject_Add(OATPP + GIT_REPOSITORY https://github.com/oatpp/oatpp.git + BUILD_IN_SOURCE true + GIT_TAG 1.3.1 + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} +) + +include_directories(${EXTERNAL_INSTALL_LOCATION}/include/oatpp-1.3.0/oatpp) +{{/addExternalLibs}} + +include_directories(model) +include_directories(api) +include_directories(impl) + +file(GLOB SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) + +add_executable(${PROJECT_NAME} ${SRCS}) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) + +{{#addExternalLibs}}add_dependencies(${PROJECT_NAME} OATPP) +if(WIN32) +target_link_libraries(${PROJECT_NAME} ${EXTERNAL_INSTALL_LOCATION}/lib/oatpp-1.3.0/oatpp.lib) +target_link_libraries(${PROJECT_NAME} ws2_32) +else() +target_link_libraries(${PROJECT_NAME} ${EXTERNAL_INSTALL_LOCATION}/lib/oatpp-1.3.0/liboatpp.a) +endif(WIN32){{/addExternalLibs}} diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/licenseInfo.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/licenseInfo.mustache new file mode 100644 index 00000000000..8d5259173a1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/licenseInfo.mustache @@ -0,0 +1,11 @@ +/** +* {{{appName}}} +* {{{appDescription}}} +* +* {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}} +* {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}} +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/main-api-client.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/main-api-client.mustache new file mode 100644 index 00000000000..a6504fed825 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/main-api-client.mustache @@ -0,0 +1,38 @@ +{{>licenseInfo}} + +#include "oatpp/web/client/HttpRequestExecutor.hpp" +#include "oatpp/parser/json/mapping/ObjectMapper.hpp" +#include "oatpp/network/tcp/client/ConnectionProvider.hpp" + +{{#apiInfo}}{{#apis}}{{#operations}} +#include "{{classname}}.hpp"{{/operations}}{{/apis}}{{/apiInfo}} + +static int _main_app(void) { + /* create connection provider */ + auto connectionProvider = oatpp::network::tcp::client::ConnectionProvider::createShared({"localhost", {{serverPort}}{{^serverPort}}8080{{/serverPort}}, oatpp::network::Address::IP_4}); + + /* create HTTP request executor */ + auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(connectionProvider); + + /* create JSON object mapper */ + auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared(); + +{{#apiInfo}}{{#apis}}{{#operations}} + /* create API client */ + auto {{classname}}Client = {{apiNamespace}}::{{classname}}::createShared(requestExecutor, objectMapper); +{{/operations}}{{/apis}}{{/apiInfo}} + + return 0; +} + +int main(int argc, char **argv) { + /* Init oatpp Environment */ + oatpp::base::Environment::init(); + + int ret = _main_app(); + + /* Destroy oatpp Environment */ + oatpp::base::Environment::destroy(); + + return ret; +} diff --git a/modules/openapi-generator/src/main/resources/cpp-oatpp-client/model-header.mustache b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/model-header.mustache new file mode 100644 index 00000000000..322867688f3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/cpp-oatpp-client/model-header.mustache @@ -0,0 +1,61 @@ +{{>licenseInfo}} +{{#models}}{{#model}}/* + * {{classname}}.h + * + * {{description}} + */ + +#ifndef {{classname}}_H_ +#define {{classname}}_H_ + +{{{defaultInclude}}} +{{#imports}}{{{this}}} +{{/imports}} +{{^isEnum}} +#include "oatpp/core/macro/codegen.hpp" +{{/isEnum}} +#include "oatpp/core/Types.hpp" + +namespace {{modelNamespace}} +{ + +{{^isEnum}} +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class {{classname}} : public oatpp::DTO { + + DTO_INIT({{classname}}, DTO /* Extends */) + + {{#vars}} + DTO_FIELD({{#isModel}}oatpp::Object<{{{dataType}}}>{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}, {{baseName}}); + {{^required}} + DTO_FIELD(oatpp::Boolean, {{baseName}}IsSet);{{/required}} + {{/vars}} + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) +{{/isEnum}} + +{{#isEnum}} +typedef {{dataType}} {{classname}}; +class {{classname}}Values { +public: +{{#allowableValues}} +{{#enumVars}} + static {{classname}} {{value}}(void) { return "{{value}}"; } +{{/enumVars}} +{{/allowableValues}} +}; +{{/isEnum}} + +} // namespace {{modelNamespace}} + +#endif /* {{classname}}_H_ */ +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/test/resources/3_0/cpp-oatpp-client/petstore.yaml b/modules/openapi-generator/src/test/resources/3_0/cpp-oatpp-client/petstore.yaml new file mode 100644 index 00000000000..a8f9809a124 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/cpp-oatpp-client/petstore.yaml @@ -0,0 +1,741 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - pet + summary: Update an existing pet + description: '' + operationId: updatePet + externalDocs: + url: "http://petstore.swagger.io/v2/doc/updatePet" + description: "API documentation for the updatePet operation" + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + style: form + explode: false + deprecated: true + schema: + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: >- + Multiple tags can be provided with comma separated strings. Use tag1, + tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: true + style: form + explode: false + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'read:pets' + deprecated: true + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + name: + description: Updated name of the pet + type: string + status: + description: Updated status of the pet + type: string + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + additionalMetadata: + description: Additional data to pass to server + type: string + file: + description: file to upload + type: string + format: binary + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: '' + operationId: placeOrder + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid Order + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + description: order placed for purchasing the pet + required: true + '/store/order/{orderId}': + get: + tags: + - store + summary: Find purchase order by ID + description: >- + For valid response try integer IDs with value <= 5 or > 10. Other values + will generate exceptions + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of pet that needs to be fetched + required: true + schema: + type: integer + format: int64 + minimum: 1 + maximum: 5 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: >- + For valid response try integer IDs with value < 1000. Anything above + 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Created user object + required: true + /user/createWithArray: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithArrayInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithListInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: true + schema: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + - name: password + in: query + description: The password for login in clear text + required: true + schema: + type: string + responses: + '200': + description: successful operation + headers: + Set-Cookie: + description: >- + Cookie authentication key for use with the `api_key` + apiKey authentication. + schema: + type: string + example: AUTH_KEY=abcde12345; Path=/; HttpOnly + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + responses: + default: + description: successful operation + security: + - api_key: [] + '/user/{username}': + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + parameters: + - name: username + in: path + description: The name that needs to be fetched. Use user1 for testing. + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Updated user + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid user supplied + '404': + description: User not found + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Updated user object + required: true + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found + security: + - api_key: [] +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + UserArray: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + description: List of user object + required: true + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Order: + title: Pet Order + description: An order for a pets from the pet store + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + ApiResponse: + title: An uploaded response + description: Describes the result of uploading an image resource + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string diff --git a/samples/client/petstore/cpp-oatpp/.openapi-generator-ignore b/samples/client/petstore/cpp-oatpp/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/cpp-oatpp/.openapi-generator/FILES b/samples/client/petstore/cpp-oatpp/.openapi-generator/FILES new file mode 100644 index 00000000000..9053625c3ff --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/.openapi-generator/FILES @@ -0,0 +1,12 @@ +CMakeLists.txt +README.md +api/PetApi.hpp +api/StoreApi.hpp +api/UserApi.hpp +main-api-client.cpp +model/ApiResponse.hpp +model/Category.hpp +model/Order.hpp +model/Pet.hpp +model/Tag.hpp +model/User.hpp diff --git a/samples/client/petstore/cpp-oatpp/.openapi-generator/VERSION b/samples/client/petstore/cpp-oatpp/.openapi-generator/VERSION new file mode 100644 index 00000000000..fc74d6ceba8 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/client/petstore/cpp-oatpp/CMakeLists.txt b/samples/client/petstore/cpp-oatpp/CMakeLists.txt new file mode 100644 index 00000000000..b4f622b85d2 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required (VERSION 3.2) + +project(api-client) + +include(ExternalProject) + +set(EXTERNAL_INSTALL_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/external) + +ExternalProject_Add(OATPP + GIT_REPOSITORY https://github.com/oatpp/oatpp.git + BUILD_IN_SOURCE true + GIT_TAG 1.3.1 + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} +) + +include_directories(${EXTERNAL_INSTALL_LOCATION}/include/oatpp-1.3.0/oatpp) + +include_directories(model) +include_directories(api) +include_directories(impl) + +file(GLOB SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) + +add_executable(${PROJECT_NAME} ${SRCS}) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) + +add_dependencies(${PROJECT_NAME} OATPP) +if(WIN32) +target_link_libraries(${PROJECT_NAME} ${EXTERNAL_INSTALL_LOCATION}/lib/oatpp-1.3.0/oatpp.lib) +target_link_libraries(${PROJECT_NAME} ws2_32) +else() +target_link_libraries(${PROJECT_NAME} ${EXTERNAL_INSTALL_LOCATION}/lib/oatpp-1.3.0/liboatpp.a) +endif(WIN32) diff --git a/samples/client/petstore/cpp-oatpp/README.md b/samples/client/petstore/cpp-oatpp/README.md new file mode 100644 index 00000000000..f59a250fa9a --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/README.md @@ -0,0 +1,39 @@ +# REST API Client for OpenAPI Petstore + +## Overview +This API Client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +It uses the [Oat++](https://github.com/oatpp/oatpp) Framework. + +## Files organization +The Oat++ C++ REST client generator creates two folders: +- `api`: This folder contains the handlers for each method specified in the OpenAPI definition. Every handler extracts +the path and parameters (if any) from the request issue them against the server. +- `model`: This folder contains the corresponding class for every object schema found in the OpenAPI specification. + +The main folder contains also a file with a main that can be used to issue REST requests through the client. +Of course, is you should customize this file based on your needs + +## Installation +First of all, you need to download and install the libraries listed [here](#libraries-required). + +Once the libraries are installed, in order to compile and run the client please follow the steps below: +```bash +mkdir build +cd build +cmake .. +make +``` + +Once compiled run the client: + +```bash +cd build +./api-client +``` + +## Libraries required +- [Oat++](https://oatpp.io/) + +## Namespaces +org.openapitools.client.api +org.openapitools.client.model diff --git a/samples/client/petstore/cpp-oatpp/api/PetApi.hpp b/samples/client/petstore/cpp-oatpp/api/PetApi.hpp new file mode 100644 index 00000000000..159d3e12af2 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/api/PetApi.hpp @@ -0,0 +1,116 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * PetApi.h + * + * + */ + +#ifndef PetApi_H_ +#define PetApi_H_ + + + +#include "oatpp/web/client/ApiClient.hpp" +#include "oatpp/web/protocol/http/outgoing/MultipartBody.hpp" +#include "oatpp/core/macro/codegen.hpp" + +#include "ApiResponse.hpp" +#include "Pet.hpp" + +#include OATPP_CODEGEN_BEGIN(ApiClient) ///< Begin code-gen section + +namespace org::openapitools::client::api +{ + +class PetApi : public oatpp::web::client::ApiClient { +public: + + API_CLIENT_INIT(PetApi) + + /// + /// Add a new pet to the store + /// + /// + /// + /// + /// Pet object that needs to be added to the store + API_CALL("POST", "/pet", add_pet, BODY_DTO(oatpp::Object, pet)) + /// + /// Deletes a pet + /// + /// + /// + /// + /// Pet id to delete + /// (optional, default to "") + API_CALL("DELETE", "/pet/{petId}", delete_pet, PATH(oatpp::Int64, petId), HEADER(oatpp::String, apiKey, "apiKey")) + /// + /// Finds Pets by status + /// + /// + /// Multiple status values can be provided with comma separated strings + /// + /// Status values that need to be considered for filter + API_CALL("GET", "/pet/findByStatus", find_pets_by_status, QUERY(oatpp::Vector, status)) + /// + /// Finds Pets by tags + /// + /// + /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + /// + /// Tags to filter by + API_CALL("GET", "/pet/findByTags", find_pets_by_tags, QUERY(oatpp::Vector, tags)) + /// + /// Find pet by ID + /// + /// + /// Returns a single pet + /// + /// ID of pet to return + API_CALL("GET", "/pet/{petId}", get_pet_by_id, PATH(oatpp::Int64, petId)) + /// + /// Update an existing pet + /// + /// + /// + /// + /// Pet object that needs to be added to the store + API_CALL("PUT", "/pet", update_pet, BODY_DTO(oatpp::Object, pet)) + /// + /// Updates a pet in the store with form data + /// + /// + /// + /// + /// ID of pet that needs to be updated + /// Updated name of the pet (optional, default to "") + /// Updated status of the pet (optional, default to "") + API_CALL("POST", "/pet/{petId}", update_pet_with_form, PATH(oatpp::Int64, petId), BODY(std::shared_ptr, formData)) + /// + /// uploads an image + /// + /// + /// + /// + /// ID of pet to update + /// Additional data to pass to server (optional, default to "") + /// file to upload (optional, default to "") + API_CALL("POST", "/pet/{petId}/uploadImage", upload_file, PATH(oatpp::Int64, petId), BODY(std::shared_ptr, formData)) +}; + +#include OATPP_CODEGEN_END(ApiClient) ///< End code-gen section + +} // namespace org::openapitools::client::api + +#endif /* PetApi_H_ */ + diff --git a/samples/client/petstore/cpp-oatpp/api/StoreApi.hpp b/samples/client/petstore/cpp-oatpp/api/StoreApi.hpp new file mode 100644 index 00000000000..f48ec25ab0a --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/api/StoreApi.hpp @@ -0,0 +1,77 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * StoreApi.h + * + * + */ + +#ifndef StoreApi_H_ +#define StoreApi_H_ + + + +#include "oatpp/web/client/ApiClient.hpp" +#include "oatpp/web/protocol/http/outgoing/MultipartBody.hpp" +#include "oatpp/core/macro/codegen.hpp" + +#include "Order.hpp" + +#include OATPP_CODEGEN_BEGIN(ApiClient) ///< Begin code-gen section + +namespace org::openapitools::client::api +{ + +class StoreApi : public oatpp::web::client::ApiClient { +public: + + API_CLIENT_INIT(StoreApi) + + /// + /// Delete purchase order by ID + /// + /// + /// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + /// + /// ID of the order that needs to be deleted + API_CALL("DELETE", "/store/order/{orderId}", delete_order, PATH(oatpp::String, orderId)) + /// + /// Returns pet inventories by status + /// + /// + /// Returns a map of status codes to quantities + /// + API_CALL("GET", "/store/inventory", get_inventory) + /// + /// Find purchase order by ID + /// + /// + /// For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + /// + /// ID of pet that needs to be fetched + API_CALL("GET", "/store/order/{orderId}", get_order_by_id, PATH(oatpp::Int64, orderId)) + /// + /// Place an order for a pet + /// + /// + /// + /// + /// order placed for purchasing the pet + API_CALL("POST", "/store/order", place_order, BODY_DTO(oatpp::Object, order)) +}; + +#include OATPP_CODEGEN_END(ApiClient) ///< End code-gen section + +} // namespace org::openapitools::client::api + +#endif /* StoreApi_H_ */ + diff --git a/samples/client/petstore/cpp-oatpp/api/UserApi.hpp b/samples/client/petstore/cpp-oatpp/api/UserApi.hpp new file mode 100644 index 00000000000..0a469f46d07 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/api/UserApi.hpp @@ -0,0 +1,111 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * UserApi.h + * + * + */ + +#ifndef UserApi_H_ +#define UserApi_H_ + + + +#include "oatpp/web/client/ApiClient.hpp" +#include "oatpp/web/protocol/http/outgoing/MultipartBody.hpp" +#include "oatpp/core/macro/codegen.hpp" + +#include "User.hpp" + +#include OATPP_CODEGEN_BEGIN(ApiClient) ///< Begin code-gen section + +namespace org::openapitools::client::api +{ + +class UserApi : public oatpp::web::client::ApiClient { +public: + + API_CLIENT_INIT(UserApi) + + /// + /// Create user + /// + /// + /// This can only be done by the logged in user. + /// + /// Created user object + API_CALL("POST", "/user", create_user, BODY_DTO(oatpp::Object, user)) + /// + /// Creates list of users with given input array + /// + /// + /// + /// + /// List of user object + API_CALL("POST", "/user/createWithArray", create_users_with_array_input, BODY_DTO(oatpp::Vector>, user)) + /// + /// Creates list of users with given input array + /// + /// + /// + /// + /// List of user object + API_CALL("POST", "/user/createWithList", create_users_with_list_input, BODY_DTO(oatpp::Vector>, user)) + /// + /// Delete user + /// + /// + /// This can only be done by the logged in user. + /// + /// The name that needs to be deleted + API_CALL("DELETE", "/user/{username}", delete_user, PATH(oatpp::String, username)) + /// + /// Get user by user name + /// + /// + /// + /// + /// The name that needs to be fetched. Use user1 for testing. + API_CALL("GET", "/user/{username}", get_user_by_name, PATH(oatpp::String, username)) + /// + /// Logs user into the system + /// + /// + /// + /// + /// The user name for login + /// The password for login in clear text + API_CALL("GET", "/user/login", login_user, QUERY(oatpp::String, username), QUERY(oatpp::String, password)) + /// + /// Logs out current logged in user session + /// + /// + /// + /// + API_CALL("GET", "/user/logout", logout_user) + /// + /// Updated user + /// + /// + /// This can only be done by the logged in user. + /// + /// name that need to be deleted + /// Updated user object + API_CALL("PUT", "/user/{username}", update_user, PATH(oatpp::String, username), BODY_DTO(oatpp::Object, user)) +}; + +#include OATPP_CODEGEN_END(ApiClient) ///< End code-gen section + +} // namespace org::openapitools::client::api + +#endif /* UserApi_H_ */ + diff --git a/samples/client/petstore/cpp-oatpp/main-api-client.cpp b/samples/client/petstore/cpp-oatpp/main-api-client.cpp new file mode 100644 index 00000000000..d49b5ada062 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/main-api-client.cpp @@ -0,0 +1,56 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + +#include "oatpp/web/client/HttpRequestExecutor.hpp" +#include "oatpp/parser/json/mapping/ObjectMapper.hpp" +#include "oatpp/network/tcp/client/ConnectionProvider.hpp" + + +#include "PetApi.hpp" +#include "StoreApi.hpp" +#include "UserApi.hpp" + +static int _main_app(void) { + /* create connection provider */ + auto connectionProvider = oatpp::network::tcp::client::ConnectionProvider::createShared({"localhost", 8080, oatpp::network::Address::IP_4}); + + /* create HTTP request executor */ + auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(connectionProvider); + + /* create JSON object mapper */ + auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared(); + + + /* create API client */ + auto PetApiClient = org::openapitools::client::api::PetApi::createShared(requestExecutor, objectMapper); + + /* create API client */ + auto StoreApiClient = org::openapitools::client::api::StoreApi::createShared(requestExecutor, objectMapper); + + /* create API client */ + auto UserApiClient = org::openapitools::client::api::UserApi::createShared(requestExecutor, objectMapper); + + + return 0; +} + +int main(int argc, char **argv) { + /* Init oatpp Environment */ + oatpp::base::Environment::init(); + + int ret = _main_app(); + + /* Destroy oatpp Environment */ + oatpp::base::Environment::destroy(); + + return ret; +} diff --git a/samples/client/petstore/cpp-oatpp/model/ApiResponse.hpp b/samples/client/petstore/cpp-oatpp/model/ApiResponse.hpp new file mode 100644 index 00000000000..284c8eae3ca --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/ApiResponse.hpp @@ -0,0 +1,53 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * ApiResponse.h + * + * Describes the result of uploading an image resource + */ + +#ifndef ApiResponse_H_ +#define ApiResponse_H_ + + +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class ApiResponse : public oatpp::DTO { + + DTO_INIT(ApiResponse, DTO /* Extends */) + + DTO_FIELD(oatpp::Int32, code); + DTO_FIELD(oatpp::Boolean, codeIsSet); + DTO_FIELD(oatpp::String, type); + DTO_FIELD(oatpp::Boolean, typeIsSet); + DTO_FIELD(oatpp::String, message); + DTO_FIELD(oatpp::Boolean, messageIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* ApiResponse_H_ */ diff --git a/samples/client/petstore/cpp-oatpp/model/Category.hpp b/samples/client/petstore/cpp-oatpp/model/Category.hpp new file mode 100644 index 00000000000..6ab21e5221c --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/Category.hpp @@ -0,0 +1,51 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Category.h + * + * A category for a pet + */ + +#ifndef Category_H_ +#define Category_H_ + + +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class Category : public oatpp::DTO { + + DTO_INIT(Category, DTO /* Extends */) + + DTO_FIELD(oatpp::Int64, id); + DTO_FIELD(oatpp::Boolean, idIsSet); + DTO_FIELD(oatpp::String, name); + DTO_FIELD(oatpp::Boolean, nameIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* Category_H_ */ diff --git a/samples/client/petstore/cpp-oatpp/model/Order.hpp b/samples/client/petstore/cpp-oatpp/model/Order.hpp new file mode 100644 index 00000000000..27e133bc945 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/Order.hpp @@ -0,0 +1,59 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Order.h + * + * An order for a pets from the pet store + */ + +#ifndef Order_H_ +#define Order_H_ + + +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class Order : public oatpp::DTO { + + DTO_INIT(Order, DTO /* Extends */) + + DTO_FIELD(oatpp::Int64, id); + DTO_FIELD(oatpp::Boolean, idIsSet); + DTO_FIELD(oatpp::Int64, petId); + DTO_FIELD(oatpp::Boolean, petIdIsSet); + DTO_FIELD(oatpp::Int32, quantity); + DTO_FIELD(oatpp::Boolean, quantityIsSet); + DTO_FIELD(oatpp::String, shipDate); + DTO_FIELD(oatpp::Boolean, shipDateIsSet); + DTO_FIELD(oatpp::String, status); + DTO_FIELD(oatpp::Boolean, statusIsSet); + DTO_FIELD(oatpp::Boolean, complete); + DTO_FIELD(oatpp::Boolean, completeIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* Order_H_ */ diff --git a/samples/client/petstore/cpp-oatpp/model/Pet.hpp b/samples/client/petstore/cpp-oatpp/model/Pet.hpp new file mode 100644 index 00000000000..9d483308a47 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/Pet.hpp @@ -0,0 +1,61 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Pet.h + * + * A pet for sale in the pet store + */ + +#ifndef Pet_H_ +#define Pet_H_ + + +#include "Category.hpp" +#include "Tag.hpp" +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class Pet : public oatpp::DTO { + + DTO_INIT(Pet, DTO /* Extends */) + + DTO_FIELD(oatpp::Int64, id); + DTO_FIELD(oatpp::Boolean, idIsSet); + DTO_FIELD(oatpp::Object, category); + DTO_FIELD(oatpp::Boolean, categoryIsSet); + DTO_FIELD(oatpp::String, name); + + DTO_FIELD(oatpp::Vector, photoUrls); + + DTO_FIELD(oatpp::Vector>, tags); + DTO_FIELD(oatpp::Boolean, tagsIsSet); + DTO_FIELD(oatpp::String, status); + DTO_FIELD(oatpp::Boolean, statusIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* Pet_H_ */ diff --git a/samples/client/petstore/cpp-oatpp/model/Tag.hpp b/samples/client/petstore/cpp-oatpp/model/Tag.hpp new file mode 100644 index 00000000000..befd6854d51 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/Tag.hpp @@ -0,0 +1,51 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Tag.h + * + * A tag for a pet + */ + +#ifndef Tag_H_ +#define Tag_H_ + + +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class Tag : public oatpp::DTO { + + DTO_INIT(Tag, DTO /* Extends */) + + DTO_FIELD(oatpp::Int64, id); + DTO_FIELD(oatpp::Boolean, idIsSet); + DTO_FIELD(oatpp::String, name); + DTO_FIELD(oatpp::Boolean, nameIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* Tag_H_ */ diff --git a/samples/client/petstore/cpp-oatpp/model/User.hpp b/samples/client/petstore/cpp-oatpp/model/User.hpp new file mode 100644 index 00000000000..b60150cf0b4 --- /dev/null +++ b/samples/client/petstore/cpp-oatpp/model/User.hpp @@ -0,0 +1,63 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * User.h + * + * A User who is purchasing from the pet store + */ + +#ifndef User_H_ +#define User_H_ + + +#include "oatpp/core/macro/codegen.hpp" +#include "oatpp/core/Types.hpp" + +namespace org::openapitools::client::model +{ + +/* Begin DTO code-generation */ +#include OATPP_CODEGEN_BEGIN(DTO) + +/** + * Message Data-Transfer-Object + */ +class User : public oatpp::DTO { + + DTO_INIT(User, DTO /* Extends */) + + DTO_FIELD(oatpp::Int64, id); + DTO_FIELD(oatpp::Boolean, idIsSet); + DTO_FIELD(oatpp::String, username); + DTO_FIELD(oatpp::Boolean, usernameIsSet); + DTO_FIELD(oatpp::String, firstName); + DTO_FIELD(oatpp::Boolean, firstNameIsSet); + DTO_FIELD(oatpp::String, lastName); + DTO_FIELD(oatpp::Boolean, lastNameIsSet); + DTO_FIELD(oatpp::String, email); + DTO_FIELD(oatpp::Boolean, emailIsSet); + DTO_FIELD(oatpp::String, password); + DTO_FIELD(oatpp::Boolean, passwordIsSet); + DTO_FIELD(oatpp::String, phone); + DTO_FIELD(oatpp::Boolean, phoneIsSet); + DTO_FIELD(oatpp::Int32, userStatus); + DTO_FIELD(oatpp::Boolean, userStatusIsSet); + +}; + +/* End DTO code-generation */ +#include OATPP_CODEGEN_END(DTO) + + +} // namespace org::openapitools::client::model + +#endif /* User_H_ */ diff --git a/website/i18n/en.json b/website/i18n/en.json index 9f06b9b90e6..f032b40060b 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -87,6 +87,10 @@ "title": "Config Options for clojure", "sidebar_label": "clojure" }, + "generators/cpp-oatpp-client": { + "title": "Config Options for cpp-oatpp-client", + "sidebar_label": "cpp-oatpp-client" + }, "generators/cpp-oatpp-server": { "title": "Config Options for cpp-oatpp-server", "sidebar_label": "cpp-oatpp-server"