Compare commits

...

52 Commits

Author SHA1 Message Date
William Cheng
eb9cbdab50 minor fix 2025-07-29 12:14:29 +08:00
William Cheng
3ff367b764 fix workflow 2025-07-29 12:09:01 +08:00
William Cheng
4ebdcc0662 add r petstore github workflow 2025-07-29 12:05:19 +08:00
William Cheng
1a178ae804 add @dsteeley to Rust technical committee (#21651) 2025-07-29 11:42:46 +08:00
William Cheng
2f70572219 update samples 2025-07-28 20:24:46 +08:00
P.H. Knot
86052aa989 fix: Use correct constructor for ApiException in PSR-18 PHP library (#21631)
* fix: Use correct constructor for ApiException

* chore: Generate samples

* fix: Missing $

* fix: Remove extraneous line
2025-07-28 20:19:59 +08:00
Mattias Sehlstedt
7c4ada33c4 [Java] [SpringClient] Introduce setting for sealed oneOf interfaces for Spring clients (#21586)
* Add setting for generating the oneOf interfaces as sealed interfaces

* Generate samples

* Add internal java17 additionalProperty setting

* Move samples to highlight that they do not use the petstore

* Align documentation

* Update samples

* Align documentation

* Update mustache files and samples to change gradle settings to java17
2025-07-28 20:03:54 +08:00
William Cheng
3453c7ba10 Test PHP clients in Github workflow (#21643)
* test php clients in github workflow

* trigger build failure

* update workflow

* Revert "trigger build failure"

This reverts commit 572a69f6bc.

* update tests

* update tests

* update test

* fix tests

* fix async test

* update tests
2025-07-28 18:33:52 +08:00
Christopher Gual
a60d3d4f81 [Bug][java-spring] Use Flux only for multipart-form-data file parameters with multiple file uploads (#21561)
* Use Flux only for multipart-form-data file parameters with multiple files

* Update samples

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
2025-07-28 18:28:53 +08:00
Simon
d69714f197 [php] Fix file uploads by backporting #21458 (#21632)
* [php] Backport #21458 to php client

Fixes #21485

Credits to @jozefbriss

* [php] Fix deprecation warning when running integration tests

OpenAPI\Client\FakeHttpClient::setResponse(): Implicitly marking parameter $response as nullable is deprecated, the explicit nullable type must be used instead

---------

Co-authored-by: simonhammes <simonhammes@users.noreply.github.com>
2025-07-28 16:58:03 +08:00
hirish
7d3913f1dd Add verbose, keepalive, keepidle, keepintvl to c-libcurl (#21613)
* Add keepalive to c-libcurl

* Fix manual tests on client/petstore/c

* Update Readme of c/libcurl

* better curlConfig handling on c-libcurl
2025-07-28 16:43:34 +08:00
Iurii Ignatko
f5da0ea4a1 Remove [this-escape] warnings in generated ApiClient classes (#21620) 2025-07-28 16:43:14 +08:00
Tobias Guttenberger
1c2ef3356d Bugfix for remote specs with params (#21634)
* [Bugfix][Maven-Plugin] Bugfix for remote input specs with parameters

If the inputSpec was a web address that contained parameters, code generation would fail, because the filepath would contain illegal characters, since the code inside the if-block would be skipped. A side effect of this was, that in the log and in the filename in linux the parameters would be leaked, which could potentially sensitive information like Gitlab Access Tokens

* [Test][Gradle Plugin] Update GenerateTaskDslTest.kt

Extended the Test for testing remote inputSpecs with urlParams, a case that caused problems in the maven plugin.
2025-07-28 16:40:20 +08:00
Mattias Sehlstedt
edbacaa3c7 Add suggestion to PR template to encourage contributors to use a GitHub link their PR to issue (#21624) 2025-07-28 16:02:05 +08:00
klahap
f3944b152d Add treatWarningsAsErrors option to ValidateTask in gradle plugin (#21626) 2025-07-28 16:01:31 +08:00
Stefan Wurzinger
0e97e19bbc kotlin-spring: fix exception thrown in enum.forValue (#21622)
* kotlin-spring: fix exception thrown in enum.forValue

* update samples
2025-07-28 16:01:03 +08:00
Christopher Gual
ee5a12a29d [test][typescript-fetch] Add / improve unit tests for current typescript-fetch oneOf logic #21057 #21464 (#21638)
* Add unit tests for current oneOf logic #21057 #21464

* Remove comment from issue_21259.yaml

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
2025-07-28 09:28:07 +02:00
devhl-labs
64e9b372c0 [csharp] Handle nested maps recursively (#21636)
* handle nested maps recurssively

* improve git diff readability
2025-07-28 11:28:27 +08:00
devhl-labs
dfc66e34aa [csharp][generichost] Verify net9 samples up to date (#21637)
* verify net9 samples up to date

* verify net9 samples up to date

* remove erroneous files

* use different logic to delete directories
2025-07-28 10:56:24 +08:00
Ilya Nemtsev
ef22749345 [Java][native] Add ability to add header to specific calls (#21495)
* add bearer capability

* avoid using shared state

* revert needless change

* Revert authentication changes from unused root Java/api.mustache template

* applied change to correct lib type

* updated test files

* made security method more generic for flexibility

* regenerated samples

* further cleanup

* code style

* regenerated samples

* made header assignment more explicit, per each method

* fixed extra comma

* fixed commas, regenerated samples

* moved header population to utility method

* moved static class inside main class

* regenerated samples

* added comments, fixed indentation

* regenerated samples

---------

Co-authored-by: Ilya Nemtsev <ilyanemtsev@192.168.1.34>
2025-07-27 11:18:39 +08:00
DavidGrath
f1a093537d [typescript-fetch] oneOf models now consider primitives when converting. Issue #21259 (#21464)
* [typescript-fetch] number, string, and Date now considered in oneOf models. Issue #21259

* Generated samples
2025-07-24 08:05:06 +02:00
Linh Tran Tuan
777b7eeea0 [Rust-Axum] Basic Authorization - Basic Analytic - XSS Sanitize (#21578)
* Update

* Update

* Update

* Update

* Update

* Update
2025-07-22 17:43:46 +08:00
William Cheng
0b0d534d0d use cpp oatapp test spec (#21601) 2025-07-21 18:23:47 +08:00
Christopher Gual
bfb69388aa [Bug][kotlin-spring] add a Spring type converter for enum values #21564 (#21579)
* [kotlin-spring] add a Spring type converter for enum values #21564

* [kotlin-spring] simplify unit test for inner enum converter

* update samples

* code review feedback; move containsEnums to ModelUtils

* code review feedback; provide comment for generated EnumConverterConfiguration.kt

* update samples

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
2025-07-21 18:22:32 +08:00
Christopher Gual
31089c0e49 [Java-Spring] add comment to EnumConverterConfiguration mustache file (#21598)
* [java-spring] provide a clarifying comment for the generated EnumConverterConfiguration class

* update samples

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
2025-07-21 18:21:44 +08:00
Kraust
20ed1ee3cc Fixes to cpp-oatpp-server generator. (#21595) 2025-07-21 18:08:44 +08:00
Mikko Maunu
90001d4fac Conditional import of AtomicInteger added to delegate template. fix #21566 (#21597) 2025-07-21 17:27:33 +08:00
William Cheng
b7fb3b2107 update go version, oauth2 dep (#21594) 2025-07-19 22:10:53 +08:00
James Shaw
7ca3fc3115 Fix response model generation with ParseOptions.resolveResponses=true (#21568)
* set resolveResponses=true

needed by swagger-parser>=2.1.23, see https://github.com/swagger-api/swagger-parser/pull/2127

* update samples

---------

Co-authored-by: James Shaw <james.shaw@masabi.com>
2025-07-19 21:37:11 +08:00
Ilia
f632ab7977 [dart-dio] Fix compile error in enum properties with "default" values (#20495) (#21355)
* [dart-dio] Fix compile error in enum properties with "default" values(#20495)

* Add a test schema with enum properties
2025-07-17 13:11:39 +08:00
William Cheng
0f305a5958 update reactor netty to newer version (#21574) 2025-07-17 13:09:03 +08:00
Rym Bouabid
4372659a0b Add 'isFormStyle', 'isSpaceDelimited', and 'isPipeDelimited' flags to CodegenParameter (#21240) 2025-07-17 01:53:21 +08:00
Mikko Maunu
d82ca75cc3 Type check of array element only when array is not empty. fix #21276 (#21571) 2025-07-17 01:30:31 +08:00
Mikko Maunu
faf6924f63 Regular comment instead of document comment before package declaration. fix #21496 (#21572) 2025-07-17 01:29:18 +08:00
andreas-umbricht
ad53684e11 Fixed primitive type check for array of array (#21500) 2025-07-16 16:20:31 +08:00
JacobOJ
63c56f00b7 [java][Microprofile] add config options to disable usage of ApiExceptionMapper (#20762)
* [java][Microprofile] add config options to disable usage of ApiExceptionMapper

* Update modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java

Co-authored-by: martin-mfg <2026226+martin-mfg@users.noreply.github.com>

---------

Co-authored-by: martin-mfg <2026226+martin-mfg@users.noreply.github.com>
2025-07-16 16:14:23 +08:00
Pascal Bachor
c4a7c14c8f python: Reinstate lazy imports (#21486)
* python: reinstate lazy imports

* python: Update samples

---------

Co-authored-by: Pascal Bachor <bachorp@users.noreply.github.com>
2025-07-16 15:53:38 +08:00
William Cheng
ee77b7f4f0 update copyright, minor code formatting change (#21569) 2025-07-16 15:48:39 +08:00
Diego Casella
7f2ee8520e Generators "scala-sttp" and "scala-sttp4" produce valid code when using APIKeyQuery, APIKeyHeader and APIKeyCookie #13474 (#21551)
* fix: using APIKeyQuery and APIKeyHeader generates invalid code (#13474)

* fix: include test

* fix: also fix auth generation for sttp4

* fix: maintain prev whitespaces & update generated APIs
2025-07-16 15:41:01 +08:00
Kraust
8862b960f8 Add cpp-oatpp-server generator (alpha) (#21547)
* Oat++ Server Generator (C++)

* Fixed for support for newest OpenAPI version.

* ALPHA not STABLE.

* Fixed for support for newest OpenAPI version.

* Added github workflow & changed to OA3 Petstore.

* Good catch on adding the Workflow.

* Might help to update the samples.

* Set C++ Standard the CMake way.

* Would be easier if there was a .pc file.

* oatpp.lib.

* Add ws2.

* This probably doesn't work, need to take a time out.
2025-07-16 15:32:28 +08:00
jase
64ab13a790 feat(typescript-angular): add Angular 20 support (#21563)
* feat(typescript-angular): add Angular 20 support

* chore: remove unused .openapi-generator-ignore file
2025-07-15 11:44:12 +02:00
Jonas Reichert
f9098d5a89 [swift] [urlsession] Fixes crash for uploads with content-type "image/" (#21544)
* Fix image upload for content-type image

* update samples

* add test case in spec and update samples

* update bitrise stack so we get xcpretty 0.4.1

* Revert "add test case in spec and update samples"

This reverts commit 92202dd850.
2025-07-15 16:25:34 +08:00
daniel
ca8c6d2f5d Add Null-check and return if null (#21556) 2025-07-15 16:06:00 +08:00
David Gamero
0995e5935c [typescript] COPY: Add optional erasable syntax configuration to Typescript generator. (#21560)
* Add optional erasable syntax configuration.

* Changes from generation clean-up.

---------

Co-authored-by: Brendan Burns <5751682+brendandburns@users.noreply.github.com>
2025-07-15 09:25:09 +02:00
Nico Kraetschmer
473343ff94 [Typescript Fetch] Fix missing closing bracket (#21549) 2025-07-14 15:41:50 +02:00
William Cheng
d63459c051 update common langs dep to newer version (#21552) 2025-07-14 17:11:11 +08:00
donilg
7a6be5a3e6 [scala][http4s] fix codegen for using reserved words in openapi (#21518) 2025-07-12 22:18:55 +08:00
Adrian Hjertstedt
65cb95bef0 Revert "[typescript-fetch] to fix incorrect parsing with additional properties (#20923)" (#21542)
This reverts commit 0becb3feb7.

Co-authored-by: Adrian Hjertstedt <ahjertstedt@ldms.com>
2025-07-10 18:41:29 +02:00
Florian Brombauer
78691cb11c Followup fix for importFileExtension config for typescript-axios (#21541) 2025-07-10 17:16:23 +02:00
Christopher Gual
81e135e038 [req] Allow models and apis list properties to span multi-lines and i… (#21536)
* [req] Allow models and apis list properties to span multi-lines and include white space (#19628)

* Add comment for DefaultGenerator.getPropertyAsSet

* Fix some variable names in DefaultGeneratorTest.testGenerateMultiLinePropertiesIssue19628

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
2025-07-10 16:41:05 +08:00
Mattias Sehlstedt
c6b51ff6fc DefaultCodegenTest use same test engine for all tests (#21532)
* Changes so that the tests use one test engine (junit) rather than switching between two (junit and testng)

* Update outdated samples

* Correct remaining missed assertEquals clauses (expected - actual misplaced)
2025-07-10 16:40:47 +08:00
Lukáš Vasek
117be2ca4c 1385 Generate constants for path in spring boot @RequestMapping (#19782) 2025-07-09 16:26:52 +08:00
1831 changed files with 79196 additions and 5562 deletions

View File

@@ -18,4 +18,5 @@
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`.
IMPORTANT: Do **NOT** purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (upcoming `7.x.0` minor release - breaking changes with fallbacks), `8.0.x` (breaking changes without fallbacks)
- [ ] If your PR solves a reported issue, reference it using [GitHub's linking syntax](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) (e.g., having `"fixes #123"` present in the PR description)
- [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request.

View File

@@ -142,37 +142,19 @@ jobs:
path: modules/openapi-generator-cli/target
- name: Delete samples that are entirely generated
run: |
rm -rf samples/client/petstore/csharp/generichost/latest/HelloWorld
rm -rf samples/client/petstore/csharp/generichost/latest/Tags
rm -rf samples/client/petstore/csharp/generichost/latest/OneOfList
rm -rf samples/client/petstore/csharp/generichost/net8/AllOf
rm -rf samples/client/petstore/csharp/generichost/net8/AnyOf
rm -rf samples/client/petstore/csharp/generichost/net8/AnyOfNoCompare
rm -rf samples/client/petstore/csharp/generichost/net8/FormModels
rm -rf samples/client/petstore/csharp/generichost/net8/NullReferenceTypes
rm -rf samples/client/petstore/csharp/generichost/net8/OneOf
rm -rf samples/client/petstore/csharp/generichost/net8/Petstore
rm -rf samples/client/petstore/csharp/generichost/net8/SourceGeneration
rm -rf samples/client/petstore/csharp/generichost/net8/UseDateTimeForDate
rm -rf samples/client/petstore/csharp/generichost/standard2.0/Petstore
rm -rf samples/client/petstore/csharp/generichost/net4.8/AllOf
rm -rf samples/client/petstore/csharp/generichost/net4.8/AnyOf
rm -rf samples/client/petstore/csharp/generichost/net4.8/AnyOfNoCompare
rm -rf samples/client/petstore/csharp/generichost/net4.8/FormModels
rm -rf samples/client/petstore/csharp/generichost/net4.8/OneOf
rm -rf samples/client/petstore/csharp/generichost/net4.8/Petstore
rm -rf samples/client/petstore/csharp/generichost/net4.8/UseDateTimeForDate
rm -rf samples/client/petstore/csharp/generichost/net4.7/AllOf
rm -rf samples/client/petstore/csharp/generichost/net4.7/AnyOf
rm -rf samples/client/petstore/csharp/generichost/net4.7/AnyOfNoCompare
rm -rf samples/client/petstore/csharp/generichost/net4.7/FormModels
rm -rf samples/client/petstore/csharp/generichost/net4.7/OneOf
rm -rf samples/client/petstore/csharp/generichost/net4.7/Petstore
rm -rf samples/client/petstore/csharp/generichost/net4.7/UseDateTimeForDate
# List all directories in generichost, filter out Manual directories, and remove the rest
cd samples/client/petstore/csharp/generichost
for version_dir in */ ; do
if [ -d "$version_dir" ]; then
cd "$version_dir"
for dir in */ ; do
if [ -d "$dir" ] && [[ ! "$dir" =~ Manual ]]; then
rm -rf "$dir"
fi
done
cd ..
fi
done
- name: Generate samples
run: |
bash bin/generate-samples.sh

View File

@@ -0,0 +1,30 @@
name: Samples cpp oat++ server
on:
push:
branches:
- "samples/server/petstore/cpp-oatpp/**"
pull_request:
paths:
- "samples/server/petstore/cpp-oatpp/**"
env:
GRADLE_VERSION: 6.9
jobs:
build:
name: Build cpp qt client
strategy:
matrix:
sample:
- samples/server/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

View File

@@ -6,6 +6,7 @@ on:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/restclient-*/**
- samples/client/others/java/webclient-sealedInterface/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
- samples/client/others/java/restclient-enum-in-multipart/**
pull_request:
@@ -13,6 +14,7 @@ on:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/restclient-*/**
- samples/client/others/java/webclient-sealedInterface/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
- samples/client/others/java/restclient-enum-in-multipart/**
jobs:
@@ -31,6 +33,7 @@ jobs:
- samples/client/petstore/java/restclient-swagger2
- samples/client/petstore/java/restclient-useSingleRequestParameter
- samples/client/petstore/java/restclient-useSingleRequestParameter-static
- samples/client/others/java/webclient-sealedInterface
- samples/client/petstore/java/webclient-useSingleRequestParameter
- samples/client/others/java/restclient-enum-in-multipart
steps:

View File

@@ -0,0 +1,45 @@
name: Samples PHP clients
on:
push:
paths:
- samples/client/petstore/php/OpenAPIClient-php/**
pull_request:
paths:
- samples/client/petstore/php/OpenAPIClient-php/**
jobs:
build:
name: Build PHP projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
sample:
# clients
- samples/client/petstore/php/OpenAPIClient-php/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v4
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
tools: php-cs-fixer, phpunit
- name: composer install
working-directory: ${{ matrix.sample }}
run: composer install
- name: phpunit
working-directory: ${{ matrix.sample }}
run: vendor/bin/phpunit tests

View File

@@ -0,0 +1,43 @@
name: Samples R Petstore
on:
push:
paths:
- 'samples/client/petstore/R/**'
pull_request:
paths:
- 'samples/client/petstore/R/**'
jobs:
build:
name: Build R
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- 'samples/client/petstore/R/'
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
with:
r-version: 3.6.1
- uses: r-lib/actions/setup-r-dependencies@v2
with:
cache-version: 2
- name: Install curl
run: sudo apt-get install -y r-cran-curl
- name: build and test
working-directory: ${{ matrix.sample }}
run: |
# export _R_CHECK_FORCE_SUGGESTS_=false
/bin/bash build_and_test.bash
shell: bash

View File

@@ -92,7 +92,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| | Languages/Frameworks |
| -------------------------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.1, .NET Core 3.1, .NET 5.0. Libraries: RestSharp, GenericHost, HttpClient), **C++** (Arduino, cpp-restsdk, Qt5, Tizen, Unreal Engine 4), **Clojure**, **Crystal**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Apache HttpClient 4.x, Apache HttpClient 5.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client, Spring 6 RestClient, MicroProfile Rest Client, Helidon), **Jetbrains HTTP Client**, **Julia**, **k6**, **Kotlin**, **Lua**, **N4JS**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types, Apollo GraphQL DataStore), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (hyper, reqwest, rust-server), **Scala** (akka, http4s, scalaz, sttp, swagger-async-httpclient, pekko), **Swift** (2.x, 3.x, 4.x, 5.x, 6.x), **Typescript** (AngularJS, Angular (9.x - 19.x), Aurelia, Axios, Fetch, Inversify, jQuery, Nestjs, Node, redux-query, Rxjs), **XoJo**, **Zapier** |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, Azure Functions), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant, Yesod), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/), [Apache Camel](https://camel.apache.org/), [Helidon](https://helidon.io/)), **Julia**, **Kotlin** (Spring Boot, [Ktor](https://github.com/ktorio/ktor), [Vert.x](https://vertx.io/)), **PHP** ([Flight](https://docs.flightphp.com/), Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** ([rust-server](https://openapi-generator.tech/docs/generators/rust-server/)), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), [Cask](https://github.com/com-lihaoyi/cask), Scalatra) |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, Azure Functions), **C++** (Oat++, Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant, Yesod), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/), [Apache Camel](https://camel.apache.org/), [Helidon](https://helidon.io/)), **Julia**, **Kotlin** (Spring Boot, [Ktor](https://github.com/ktorio/ktor), [Vert.x](https://vertx.io/)), **PHP** ([Flight](https://docs.flightphp.com/), Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** ([rust-server](https://openapi-generator.tech/docs/generators/rust-server/)), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), [Cask](https://github.com/com-lihaoyi/cask), Scalatra) |
| **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML** |
| **Configuration files** | [**Apache2**](https://httpd.apache.org/) |
| **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Postman Collection**, **Protocol Buffer**, **WSDL** |
@@ -1128,6 +1128,7 @@ Here is a list of template creators:
* C# Azure functions: @Abrhm7786
* C# NancyFX: @mstefaniuk
* C++ (Qt5 QHttpEngine): @etherealjoy
* C++ Oat++: @Kraust
* C++ Pistache: @sebymiano
* C++ Restbed: @stkrwork
* Erlang Server: @galaxie @nelsonvides
@@ -1269,7 +1270,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Python | @cbornet (2017/09) @tomplus (2018/10) @krjakbrjak (2023/02) @fa0311 (2023/10) @multani (2023/10) |
| R | @Ramanth (2019/07) @saigiridhar21 (2019/07) |
| Ruby | @cliffano (2017/07) @zlx (2017/09) @autopp (2019/02) |
| Rust | @frol (2017/07) @farcaller (2017/08) @richardwhiuk (2019/07) @paladinzh (2020/05) @jacob-pro (2022/10) |
| Rust | @frol (2017/07) @farcaller (2017/08) @richardwhiuk (2019/07) @paladinzh (2020/05) @jacob-pro (2022/10) @@dsteeley (2025/07) |
| Scala | @clasnake (2017/07), @shijinkui (2018/01), @ramzimaalej (2018/03), @chameleon82 (2020/03), @Bouillie (2020/04) @fish86 (2023/06) |
| Swift | @jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) @4brunu (2019/11) @dydus0x14 (2023/06) |
| TypeScript | @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02) @davidgamero (2022/03) @mkusaka (2022/04) @joscha (2024/10) |

View File

@@ -0,0 +1,6 @@
generatorName: cpp-oatpp-server
outputDir: samples/server/petstore/cpp-oatpp
inputSpec: modules/openapi-generator/src/test/resources/3_0/cpp-oatpp-server/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/cpp-oatpp-server
additionalProperties:
addExternalLibs: "true"

View File

@@ -0,0 +1,10 @@
generatorName: java
outputDir: samples/client/others/java/webclient-sealedInterface
library: webclient
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneof_polymorphism_and_inheritance.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: sealed-interface-webclient
hideGenerationTimestamp: "true"
useOneOfInterfaces: true
useSealedOneOfInterfaces: true

View File

@@ -0,0 +1,14 @@
generatorName: rust-axum
outputDir: samples/server/petstore/rust-axum/output/apikey-authorization
inputSpec: modules/openapi-generator/src/test/resources/3_0/jetbrains/CheckoutBasicBearerCookieQueryHeaderBasicBearer.yaml
templateDir: modules/openapi-generator/src/main/resources/rust-axum
generateAliasAsModel: true
additionalProperties:
hideGenerationTimestamp: "true"
packageName: apikey-authorization
basicAuthorization: true
basicAnalytic: true
ownedRequest: true
globalProperties:
skipFormModel: false
enablePostProcessFile: true

View File

@@ -0,0 +1,8 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v20/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 20.0.0
npmName: sample-angular-20-0-0
supportsES6: true

View File

@@ -48,4 +48,4 @@ workflows:
meta:
bitrise.io:
stack: osx-xcode-16.0.x
stack: osx-xcode-16.3.x

View File

@@ -87,6 +87,7 @@ The following generators are available:
* [ada-server](generators/ada-server.md)
* [aspnet-fastendpoints](generators/aspnet-fastendpoints.md)
* [aspnetcore](generators/aspnetcore.md)
* [cpp-oatpp-server](generators/cpp-oatpp-server.md)
* [cpp-pistache-server](generators/cpp-pistache-server.md)
* [cpp-qt-qhttpengine-server](generators/cpp-qt-qhttpengine-server.md)
* [cpp-restbed-server](generators/cpp-restbed-server.md)

View File

@@ -65,6 +65,7 @@ The following generators are available:
## SERVER generators
* [ada-server](ada-server.md)
* [aspnetcore](aspnetcore.md)
* [cpp-oatpp-server](cpp-oatpp-server.md)
* [cpp-pistache-server](cpp-pistache-server.md)
* [cpp-qt5-qhttpengine-server](cpp-qt5-qhttpengine-server.md)
* [cpp-restbed-server](cpp-restbed-server.md)

View File

@@ -0,0 +1,262 @@
---
title: Documentation for the cpp-oatpp-server Generator
---
## METADATA
| Property | Value | Notes |
| -------- | ----- | ----- |
| generator name | cpp-oatpp-server | pass this to the generate command after -g |
| generator stability | STABLE | |
| generator type | SERVER | |
| generator language | C++ | |
| generator default templating engine | mustache | |
| helpTxt | Generates a C++ API server (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 -&gt; Value)| |true|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>oatpp::Any</li>
<li>oatpp::Boolean</li>
<li>oatpp::Fields</li>
<li>oatpp::Float64</li>
<li>oatpp::Int32</li>
<li>oatpp::Int64</li>
<li>oatpp::Object</li>
<li>oatpp::String</li>
<li>oatpp::UnorderedSet</li>
<li>oatpp::Vector</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>NULL</li>
<li>alignas</li>
<li>alignof</li>
<li>and</li>
<li>and_eq</li>
<li>asm</li>
<li>auto</li>
<li>bitand</li>
<li>bitor</li>
<li>bool</li>
<li>break</li>
<li>case</li>
<li>catch</li>
<li>char</li>
<li>char16_t</li>
<li>char32_t</li>
<li>class</li>
<li>compl</li>
<li>concept</li>
<li>const</li>
<li>const_cast</li>
<li>constexpr</li>
<li>continue</li>
<li>decltype</li>
<li>default</li>
<li>delete</li>
<li>do</li>
<li>double</li>
<li>dynamic_cast</li>
<li>else</li>
<li>enum</li>
<li>explicit</li>
<li>export</li>
<li>extern</li>
<li>false</li>
<li>float</li>
<li>for</li>
<li>friend</li>
<li>goto</li>
<li>if</li>
<li>inline</li>
<li>int</li>
<li>linux</li>
<li>long</li>
<li>mutable</li>
<li>namespace</li>
<li>new</li>
<li>noexcept</li>
<li>not</li>
<li>not_eq</li>
<li>nullptr</li>
<li>operator</li>
<li>or</li>
<li>or_eq</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>register</li>
<li>reinterpret_cast</li>
<li>requires</li>
<li>return</li>
<li>short</li>
<li>signed</li>
<li>sizeof</li>
<li>static</li>
<li>static_assert</li>
<li>static_cast</li>
<li>struct</li>
<li>switch</li>
<li>template</li>
<li>this</li>
<li>thread_local</li>
<li>throw</li>
<li>true</li>
<li>try</li>
<li>typedef</li>
<li>typeid</li>
<li>typename</li>
<li>union</li>
<li>unsigned</li>
<li>using</li>
<li>virtual</li>
<li>void</li>
<li>volatile</li>
<li>wchar_t</li>
<li>while</li>
<li>xor</li>
<li>xor_eq</li>
</ul>
## 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

View File

@@ -66,7 +66,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|licenseName|The name of the license| |Unlicense|
|licenseUrl|The URL of the license| |http://unlicense.org|
|microprofileFramework|Framework for microprofile. Possible values &quot;kumuluzee&quot;| |null|
|microprofileGlobalExceptionMapper|Should ApiExceptionMapper be annotated with @Provider making it a global exception mapper| |true|
|microprofileMutiny|Whether to use async types for microprofile (currently only Smallrye Mutiny is supported).| |null|
|microprofileRegisterExceptionMapper|Should generated API Clients be annotated with @RegisterProvider(ApiExceptionMapper.class).| |true|
|microprofileRestClientVersion|Version of MicroProfile Rest Client API.| |null|
|modelPackage|package for generated models| |org.openapitools.client.model|
|openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true|
@@ -101,6 +103,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
|useSingleRequestParameter|Setting this property to &quot;true&quot; will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to &quot;static&quot; does the same as &quot;true&quot;, but also makes the generated arguments class static with single parameter instantiation.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|

View File

@@ -66,7 +66,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|licenseName|The name of the license| |Unlicense|
|licenseUrl|The URL of the license| |http://unlicense.org|
|microprofileFramework|Framework for microprofile. Possible values &quot;kumuluzee&quot;| |null|
|microprofileGlobalExceptionMapper|Should ApiExceptionMapper be annotated with @Provider making it a global exception mapper| |true|
|microprofileMutiny|Whether to use async types for microprofile (currently only Smallrye Mutiny is supported).| |null|
|microprofileRegisterExceptionMapper|Should generated API Clients be annotated with @RegisterProvider(ApiExceptionMapper.class).| |true|
|microprofileRestClientVersion|Version of MicroProfile Rest Client API.| |null|
|modelPackage|package for generated models| |org.openapitools.client.model|
|openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true|
@@ -101,6 +103,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
|useSingleRequestParameter|Setting this property to &quot;true&quot; will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to &quot;static&quot; does the same as &quot;true&quot;, but also makes the generated arguments class static with single parameter instantiation.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|

View File

@@ -11,7 +11,7 @@ title: Documentation for the typescript-angular Generator
| generator type | CLIENT | |
| generator language | Typescript | |
| generator default templating engine | mustache | |
| helpTxt | Generates a TypeScript Angular (9.x - 19.x) client library. | |
| helpTxt | Generates a TypeScript Angular (9.x - 20.x) client library. | |
## 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.
@@ -34,7 +34,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name. Only change it if you provide your own run-time code for (de-)serialization of models| |original|
|modelSuffix|The suffix of the generated model.| |null|
|ngPackagrVersion|The version of ng-packagr compatible with Angular (see ngVersion option).| |null|
|ngVersion|The version of Angular. (At least 9.0.0)| |19.0.0|
|ngVersion|The version of Angular. (At least 9.0.0)| |20.0.0|
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0|

View File

@@ -42,6 +42,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportsES6|Generate code that conforms to ES6.| |false|
|useErasableSyntax|Use erasable syntax for the generated code. This is a temporary feature and will be removed in the future.| |false|
|useInversify|Enable this to generate decorators and service identifiers for the InversifyJS inversion of control container. If you set 'deno' as 'platform', the generator will process this value as 'disable'.| |false|
|useObjectParameters|Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.| |false|
|useRxJS|Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.| |false|

View File

@@ -85,6 +85,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
inputSpec.set(validate.inputSpec)
recommend.set(validate.recommend)
treatWarningsAsErrors.set(validate.treatWarningsAsErrors)
}
register("openApiGenerate", GenerateTask::class.java).configure {

View File

@@ -34,4 +34,9 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
* Whether to offer recommendations related to the validated specification document.
*/
val recommend = project.objects.property<Boolean>().convention(true)
/**
* Whether to treat warnings as errors and fail the task.
*/
val treatWarningsAsErrors = project.objects.property<Boolean>().convention(false)
}

View File

@@ -60,6 +60,10 @@ open class ValidateTask : DefaultTask() {
@Input
val recommend = project.objects.property<Boolean>().convention(true)
@Optional
@Input
val treatWarningsAsErrors = project.objects.property<Boolean>().convention(false)
@get:Internal
@set:Option(option = "input", description = "The input specification.")
var input: String? = null
@@ -73,6 +77,7 @@ open class ValidateTask : DefaultTask() {
val spec = inputSpec.get()
val recommendations = recommend.get()
val failOnWarnings = treatWarningsAsErrors.get()
logger.quiet("Validating spec $spec")
@@ -117,10 +122,16 @@ open class ValidateTask : DefaultTask() {
}
throw GradleException("Validation failed.")
} else {
out.withStyle(StyledTextOutput.Style.Success)
logger.debug("No error validations from swagger-parser or internal validations.")
out.println("Spec is valid.")
}
if (failOnWarnings && validationResult.warnings.isNotEmpty()) {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\nWarnings found in the spec and 'treatWarningsAsErrors' is enabled.\nFailing validation.\n")
throw GradleException("Validation failed due to warnings (treatWarningsAsErrors = true).")
}
out.withStyle(StyledTextOutput.Style.Success)
logger.debug("No error validations from swagger-parser or internal validations.")
out.println("Spec is valid.")
}
}

View File

@@ -34,6 +34,7 @@ class GenerateTaskDslTest : TestBase() {
@Test
fun `openApiGenerate should create an expected file structure from URL config`() {
val specUrl = "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/b6b8c0db872fb4a418ae496e89c7e656e14be165/modules/openapi-generator-gradle-plugin/src/test/resources/specs/petstore-v3.0.yaml"
val urlParams ="?meaningless=params&amp;so=it&amp;results=in&amp;illegal=filenames&amp;on=windows"
// Arrange
val buildContents = """
plugins {
@@ -41,7 +42,7 @@ class GenerateTaskDslTest : TestBase() {
}
openApiGenerate {
generatorName = "kotlin"
remoteInputSpec = "$specUrl"
remoteInputSpec = "$specUrl$urlParams"
outputDir = file("build/kotlin").absolutePath
apiPackage = "org.openapitools.example.api"
invokerPackage = "org.openapitools.example.invoker"

View File

@@ -308,6 +308,48 @@ class ValidateTaskDslTest : TestBase() {
)
}
@Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should fail with treatWarningsAsErrors on valid spec with warnings`(gradleVersion: String?) {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-recommend.yaml")
)
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| treatWarningsAsErrors = true
| }
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(
result.output.contains("Spec has issues or recommendations."),
"Unexpected/no message presented to the user for a valid spec."
)
assertTrue(
result.output.contains("Failing validation."),
"Expected validation to fail due to warnings, but no failure message was found."
)
assertEquals(
FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should succeed without recommendations on valid spec`(gradleVersion: String?) {
// Arrange

View File

@@ -1066,7 +1066,7 @@ public class CodeGenMojo extends AbstractMojo {
String name = inputSpecFile.getName();
URL url = inputSpecRemoteUrl();
if (inputSpecFile.exists() && url != null) {
if (url != null) {
String[] segments = url.getPath().split("/");
name = Files.getNameWithoutExtension(segments[segments.length - 1]);
}

View File

@@ -68,6 +68,10 @@ public class CodeGenMojoTest extends BaseTestCase {
testCommonConfiguration("jar");
}
public void testCommonConfigurationWithRemoteInputSpec() throws Exception {
testCommonConfiguration("remote");
}
@SuppressWarnings("unchecked")
private void testCommonConfiguration(String profile) throws Exception {
CodeGenMojo mojo = loadMojo(newTempFolder(), "src/test/resources/default", profile);

View File

@@ -55,6 +55,12 @@
</dependency>
</dependencies>
</profile>
<profile>
<id>remote</id>
<properties>
<inputSpec>https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml?meaningless=params&amp;so=it&amp;results=in&amp;illegal=filenames&amp;on=windows</inputSpec>
</properties>
</profile>
</profiles>
<build>
<finalName>common-maven</finalName>

View File

@@ -31,7 +31,8 @@ import java.util.*;
public class CodegenParameter implements IJsonSchemaValidationProperties {
public boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
isCookieParam, isBodyParam, isContainer,
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, isDeepObject, isMatrix, isAllowEmptyValue;
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, isDeepObject, isMatrix, isAllowEmptyValue,
isFormStyle, isSpaceDelimited, isPipeDelimited;
public String baseName, paramName, dataType, datatypeWithEnum, dataFormat, contentType,
collectionFormat, description, unescapedDescription, baseType, defaultValue, enumDefaultValue, enumName, style;
@@ -268,6 +269,9 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
output.isExplode = this.isExplode;
output.style = this.style;
output.isDeepObject = this.isDeepObject;
output.isFormStyle = this.isFormStyle;
output.isSpaceDelimited = this.isSpaceDelimited;
output.isPipeDelimited = this.isPipeDelimited;
output.isMatrix = this.isMatrix;
output.isAllowEmptyValue = this.isAllowEmptyValue;
output.contentType = this.contentType;
@@ -282,6 +286,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description,
unescapedDescription, baseType, containerType, containerTypeMapped, defaultValue,
enumDefaultValue, enumName, style, isDeepObject, isMatrix, isAllowEmptyValue, example, examples,
isFormStyle, isSpaceDelimited, isPipeDelimited,
jsonSchema, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isDecimal,
isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isPassword,
isFreeFormObject, isAnyType, isArray, isMap, isOptional, isFile, isEnum, isEnumRef, _enum, allowableValues,
@@ -375,6 +380,9 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
Objects.equals(enumName, that.enumName) &&
Objects.equals(style, that.style) &&
Objects.equals(isDeepObject, that.isDeepObject) &&
Objects.equals(isFormStyle, that.isFormStyle) &&
Objects.equals(isSpaceDelimited, that.isSpaceDelimited) &&
Objects.equals(isPipeDelimited, that.isPipeDelimited) &&
Objects.equals(isMatrix, that.isMatrix) &&
Objects.equals(isAllowEmptyValue, that.isAllowEmptyValue) &&
Objects.equals(example, that.example) &&
@@ -440,6 +448,9 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
sb.append(", enumName='").append(enumName).append('\'');
sb.append(", style='").append(style).append('\'');
sb.append(", deepObject='").append(isDeepObject).append('\'');
sb.append(", isFormStyle='").append(isFormStyle).append('\'');
sb.append(", isSpaceDelimited='").append(isSpaceDelimited).append('\'');
sb.append(", isPipeDelimited='").append(isPipeDelimited).append('\'');
sb.append(", isMatrix='").append(isMatrix).append('\'');
sb.append(", allowEmptyValue='").append(isAllowEmptyValue).append('\'');
sb.append(", example='").append(example).append('\'');

View File

@@ -2135,6 +2135,9 @@ public class DefaultCodegen implements CodegenConfig {
}
codegenParameter.style = style.toString();
codegenParameter.isFormStyle = Encoding.StyleEnum.FORM == style;
codegenParameter.isSpaceDelimited = Encoding.StyleEnum.SPACE_DELIMITED == style;
codegenParameter.isPipeDelimited = Encoding.StyleEnum.PIPE_DELIMITED == style;
codegenParameter.isDeepObject = Encoding.StyleEnum.DEEP_OBJECT == style;
if (codegenParameter.isContainer) {
@@ -5398,6 +5401,9 @@ public class DefaultCodegen implements CodegenConfig {
if (parameter.getStyle() != null) {
codegenParameter.style = parameter.getStyle().toString();
codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle();
codegenParameter.isFormStyle = Parameter.StyleEnum.FORM == parameter.getStyle();
codegenParameter.isSpaceDelimited = Parameter.StyleEnum.SPACEDELIMITED == parameter.getStyle();
codegenParameter.isPipeDelimited = Parameter.StyleEnum.PIPEDELIMITED == parameter.getStyle();
codegenParameter.isMatrix = Parameter.StyleEnum.MATRIX == parameter.getStyle();
}

View File

@@ -626,6 +626,22 @@ public class DefaultGenerator implements Generator {
}
}
/**
* this method splits the specified property by commas, trims any results for spaces and
* newlines, and returns them as a Set of Strings. the method will return an empty
* set if the specified property has not been set or is an empty string.
*/
private Set<String> getPropertyAsSet(String propertyName) {
String propertyRaw = GlobalSettings.getProperty(propertyName);
if (propertyRaw == null || propertyRaw.isEmpty()) {
return Collections.emptySet();
}
return Arrays.stream(propertyRaw.split(","))
.map(String::trim)
.collect(Collectors.toSet());
}
private Set<String> modelKeys() {
final Map<String, Schema> schemas = ModelUtils.getSchemas(this.openAPI);
if (schemas == null) {
@@ -633,12 +649,7 @@ public class DefaultGenerator implements Generator {
return Collections.emptySet();
}
String modelNames = GlobalSettings.getProperty("models");
Set<String> modelsToGenerate = null;
if (modelNames != null && !modelNames.isEmpty()) {
modelsToGenerate = new HashSet<>(Arrays.asList(modelNames.split(",")));
}
Set<String> modelsToGenerate = getPropertyAsSet(CodegenConstants.MODELS);
Set<String> modelKeys = schemas.keySet();
if (modelsToGenerate != null && !modelsToGenerate.isEmpty()) {
Set<String> updatedKeys = new HashSet<>();
@@ -661,11 +672,7 @@ public class DefaultGenerator implements Generator {
return;
}
Map<String, List<CodegenOperation>> paths = processPaths(this.openAPI.getPaths());
Set<String> apisToGenerate = null;
String apiNames = GlobalSettings.getProperty(CodegenConstants.APIS);
if (apiNames != null && !apiNames.isEmpty()) {
apisToGenerate = new HashSet<>(Arrays.asList(apiNames.split(",")));
}
Set<String> apisToGenerate = getPropertyAsSet(CodegenConstants.APIS);
if (apisToGenerate != null && !apisToGenerate.isEmpty()) {
Map<String, List<CodegenOperation>> updatedPaths = new TreeMap<>();
for (String m : paths.keySet()) {
@@ -827,11 +834,7 @@ public class DefaultGenerator implements Generator {
return;
}
Map<String, List<CodegenOperation>> webhooks = processWebhooks(this.openAPI.getWebhooks());
Set<String> webhooksToGenerate = null;
String webhookNames = GlobalSettings.getProperty(CodegenConstants.WEBHOOKS);
if (webhookNames != null && !webhookNames.isEmpty()) {
webhooksToGenerate = new HashSet<>(Arrays.asList(webhookNames.split(",")));
}
Set<String> webhooksToGenerate = getPropertyAsSet(CodegenConstants.WEBHOOKS);
if (webhooksToGenerate != null && !webhooksToGenerate.isEmpty()) {
Map<String, List<CodegenOperation>> Webhooks = new TreeMap<>();
for (String m : webhooks.keySet()) {
@@ -1064,12 +1067,7 @@ public class DefaultGenerator implements Generator {
return;
}
Set<String> supportingFilesToGenerate = null;
String supportingFiles = GlobalSettings.getProperty(CodegenConstants.SUPPORTING_FILES);
if (supportingFiles != null && !supportingFiles.isEmpty()) {
supportingFilesToGenerate = new HashSet<>(Arrays.asList(supportingFiles.split(",")));
}
Set<String> supportingFilesToGenerate = getPropertyAsSet(CodegenConstants.SUPPORTING_FILES);
for (SupportingFile support : config.supportingFiles()) {
try {
String outputFolder = config.outputFolder();

View File

@@ -683,6 +683,7 @@ public class CodegenConfigurator {
final List<AuthorizationValue> authorizationValues = AuthParser.parse(this.auth);
ParseOptions options = new ParseOptions();
options.setResolve(true);
options.setResolveResponses(true);
SwaggerParseResult result = new OpenAPIParser().readLocation(inputSpec, authorizationValues, options);
// TODO: Move custom validations to a separate type as part of a "Workflow"

View File

@@ -751,6 +751,37 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
protected void patchPropertyIsInherited(CodegenModel model, CodegenProperty property) {
}
private void patchNestedMaps(CodegenProperty property) {
// Process nested types before making any replacements to ensure we have the correct inner type
if (property.items != null) {
patchNestedMaps(property.items);
}
String[] nestedTypes = {"List", "Collection", "ICollection", "Dictionary"};
if (property.datatypeWithEnum != null) {
String originalType = property.datatypeWithEnum;
for (String nestedType : nestedTypes) {
// fix incorrect data types for maps of maps
if (property.items != null) {
if (property.datatypeWithEnum.contains(", " + nestedType + ">")) {
property.datatypeWithEnum = property.datatypeWithEnum.replace(", " + nestedType + ">", ", " + property.items.datatypeWithEnum + ">");
}
if (property.datatypeWithEnum.contains("<" + nestedType + ">")) {
property.datatypeWithEnum = property.datatypeWithEnum.replace("<" + nestedType + ">", "<" + property.items.datatypeWithEnum + ">");
}
}
}
// Only update dataType if we actually made changes
if (!originalType.equals(property.datatypeWithEnum)) {
property.dataType = property.datatypeWithEnum;
}
}
}
protected void patchProperty(Map<String, CodegenModel> enumRefs, CodegenModel model, CodegenProperty property) {
if (enumRefs.containsKey(property.dataType)) {
// Handle any enum properties referred to by $ref.
@@ -770,20 +801,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
property.name = patchPropertyName(model, property.name, null);
String[] nestedTypes = {"List", "Collection", "ICollection", "Dictionary"};
Arrays.stream(nestedTypes).forEach(nestedType -> {
// fix incorrect data types for maps of maps
if (property.datatypeWithEnum.contains(", " + nestedType + ">") && property.items != null) {
property.datatypeWithEnum = property.datatypeWithEnum.replace(", " + nestedType + ">", ", " + property.items.datatypeWithEnum + ">");
property.dataType = property.datatypeWithEnum;
}
if (property.datatypeWithEnum.contains("<" + nestedType + ">") && property.items != null) {
property.datatypeWithEnum = property.datatypeWithEnum.replace("<" + nestedType + ">", "<" + property.items.datatypeWithEnum + ">");
property.dataType = property.datatypeWithEnum;
}
});
patchNestedMaps(property);
// HOTFIX: https://github.com/OpenAPITools/openapi-generator/issues/14944
if (property.datatypeWithEnum.equals("decimal")) {

View File

@@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.OpenAPI;
@@ -50,6 +51,7 @@ import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.ReplaceAllLambda;
import org.openapitools.codegen.utils.CamelizeOption;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;

View File

@@ -0,0 +1,502 @@
/*
* 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 CppOatppServerCodegen extends AbstractCppCodegen {
private final Logger LOGGER = LoggerFactory.getLogger(CppOatppServerCodegen.class);
protected String implFolder = "impl";
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.SERVER;
}
@Override
public String getName() {
return "cpp-oatpp-server";
}
@Override
public String getHelp() {
return "Generates a C++ API server (based on Oat++)";
}
public CppOatppServerCodegen() {
super();
// TODO: cpp-oatpp-server 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.server.api";
modelPackage = "org.openapitools.server.model";
apiTemplateFiles.put("api-header.mustache", ".hpp");
apiTemplateFiles.put("api-impl-header.mustache", ".hpp");
apiTemplateFiles.put("api-impl-source.mustache", ".cpp");
modelTemplateFiles.put("model-header.mustache", ".hpp");
embeddedTemplateDir = templateDir = "cpp-oatpp-server";
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-server.mustache", "", modelNamePrefix + "main-api-server.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<String> 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<Server> 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<ModelMap> 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<CodegenOperation> 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<Map<String, String>> 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<String> 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) {
String result = super.apiFilename(templateName, tag);
if (templateName.endsWith("impl-header.mustache")) {
result = implFilenameFromApiFilename(result, ".hpp");
} else if (templateName.endsWith("impl-source.mustache")) {
result = implFilenameFromApiFilename(result, ".cpp");
}
return result;
}
/**
* implFilenameFromApiFilename - Inserts the string "Controller" in front of the
* suffix and replace "api" with "impl" directory prefix.
*
* @param filename Filename of the api-file to be modified
* @param suffix Suffix of the file (usually ".cpp" or ".hpp")
* @return a filename string of impl file.
*/
private String implFilenameFromApiFilename(String filename, String suffix) {
String result = filename.substring(0, filename.length() - suffix.length()) + "Controller" + suffix;
result = result.replace(apiFileFolder(), implFileFolder());
return result;
}
@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) + "<oatpp::Object<" + getTypeDeclaration(inner) + ">>";
}
if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "<std::string, " + getTypeDeclaration(inner) + ">";
} 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<std::string, " + inner + ">()";
} 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);
}
private String implFileFolder() {
return (outputFolder + "/" + implFolder).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;
}
}

View File

@@ -70,6 +70,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String CASE_INSENSITIVE_RESPONSE_HEADERS = "caseInsensitiveResponseHeaders";
public static final String MICROPROFILE_FRAMEWORK = "microprofileFramework";
public static final String MICROPROFILE_MUTINY = "microprofileMutiny";
public static final String MICROPROFILE_GLOBAL_EXCEPTION_MAPPER = "microprofileGlobalExceptionMapper";
public static final String MICROPROFILE_REGISTER_EXCEPTION_MAPPER = "microprofileRegisterExceptionMapper";
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
public static final String DYNAMIC_OPERATIONS = "dynamicOperations";
public static final String SUPPORT_STREAMING = "supportStreaming";
@@ -102,6 +104,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String USE_ENUM_CASE_INSENSITIVE = "useEnumCaseInsensitive";
public static final String FAIL_ON_UNKNOWN_PROPERTIES = "failOnUnknownProperties";
public static final String SUPPORT_VERTX_FUTURE = "supportVertxFuture";
public static final String USE_SEALED_ONE_OF_INTERFACES = "useSealedOneOfInterfaces";
// Internal configurations
public static final String SINGLE_REQUEST_PARAMETER = "singleRequestParameter";
public static final String STATIC_REQUEST = "staticRequest";
public static final String JAVA_17 = "java17";
public static final String SERIALIZATION_LIBRARY_GSON = "gson";
public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
@@ -120,6 +128,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Setter protected String microprofileFramework = MICROPROFILE_DEFAULT;
@Setter protected String microprofileRestClientVersion = MICROPROFILE_REST_CLIENT_DEFAULT_VERSION;
@Setter protected boolean microprofileMutiny = false;
@Setter protected boolean microProfileGlobalExceptionMapper = true;
@Setter protected boolean microProfileRegisterExceptionMapper = true;
@Setter protected String configKey = null;
@Setter(AccessLevel.PRIVATE) protected boolean configKeyFromClassName = false;
@@ -138,6 +148,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Setter protected String errorObjectType;
@Getter @Setter protected boolean failOnUnknownProperties = false;
@Setter protected boolean supportVertxFuture = false;
@Setter protected boolean useSealedOneOfInterfaces = false;
protected String authFolder;
/**
* Serialization library.
@@ -229,6 +240,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(CASE_INSENSITIVE_RESPONSE_HEADERS, "Make API response's headers case-insensitive. Available on " + OKHTTP_GSON + ", " + JERSEY2 + " libraries"));
cliOptions.add(CliOption.newString(MICROPROFILE_FRAMEWORK, "Framework for microprofile. Possible values \"kumuluzee\""));
cliOptions.add(CliOption.newString(MICROPROFILE_MUTINY, "Whether to use async types for microprofile (currently only Smallrye Mutiny is supported)."));
cliOptions.add(CliOption.newString(MICROPROFILE_REGISTER_EXCEPTION_MAPPER, "Should generated API Clients be annotated with @RegisterProvider(ApiExceptionMapper.class).").defaultValue("true"));
cliOptions.add(CliOption.newString(MICROPROFILE_GLOBAL_EXCEPTION_MAPPER, "Should ApiExceptionMapper be annotated with @Provider making it a global exception mapper").defaultValue("true"));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk. Available on resttemplate, webclient, restclient, libraries"));
cliOptions.add(CliOption.newBoolean(DYNAMIC_OPERATIONS, "Generate operations dynamically at runtime from an OAS", this.dynamicOperations));
cliOptions.add(CliOption.newBoolean(SUPPORT_STREAMING, "Support streaming endpoint (beta)", this.supportStreaming));
@@ -246,6 +259,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_ENUM_CASE_INSENSITIVE, "Use `equalsIgnoreCase` when String for enum comparison", useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", this.failOnUnknownProperties));
cliOptions.add(CliOption.newBoolean(SUPPORT_VERTX_FUTURE, "Also generate api methods that return a vertx Future instead of taking a callback. Only `vertx` supports this option. Requires vertx 4 or greater.", this.supportVertxFuture));
cliOptions.add(CliOption.newBoolean(USE_SEALED_ONE_OF_INTERFACES, "Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.", this.useSealedOneOfInterfaces));
supportedLibraries.put(JERSEY2, "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.17.1");
supportedLibraries.put(JERSEY3, "HTTP client: Jersey client 3.1.1. JSON processing: Jackson 2.17.1");
@@ -361,8 +375,13 @@ public class JavaClientCodegen extends AbstractJavaCodegen
convertPropertyToBooleanAndWriteBack(USE_RX_JAVA2, this::setUseRxJava2);
}
convertPropertyToStringAndWriteBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, this::setUseSingleRequestParameter);
writePropertyBack("singleRequestParameter", getSingleRequestParameter());
writePropertyBack("staticRequest", getStaticRequest());
convertPropertyToBooleanAndWriteBack(USE_SEALED_ONE_OF_INTERFACES, this::setUseSealedOneOfInterfaces);
writePropertyBack(SINGLE_REQUEST_PARAMETER, getSingleRequestParameter());
writePropertyBack(STATIC_REQUEST, getStaticRequest());
if (libWebClient && (useSealedOneOfInterfaces || useJakartaEe)) {
writePropertyBack(JAVA_17, true);
}
if (!useRxJava && !useRxJava2 && !useRxJava3) {
additionalProperties.put(DO_NOT_USE_RX, true);
@@ -380,6 +399,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
convertPropertyToStringAndWriteBack(MICROPROFILE_FRAMEWORK, this::setMicroprofileFramework);
convertPropertyToBooleanAndWriteBack(MICROPROFILE_GLOBAL_EXCEPTION_MAPPER, this::setMicroProfileGlobalExceptionMapper);
convertPropertyToBooleanAndWriteBack(MICROPROFILE_REGISTER_EXCEPTION_MAPPER, this::setMicroProfileRegisterExceptionMapper);
additionalProperties.put(MICROPROFILE_REGISTER_EXCEPTION_MAPPER, microProfileRegisterExceptionMapper);
additionalProperties.put(MICROPROFILE_GLOBAL_EXCEPTION_MAPPER, microProfileGlobalExceptionMapper);
convertPropertyToBooleanAndWriteBack(MICROPROFILE_MUTINY, this::setMicroprofileMutiny);
convertPropertyToStringAndWriteBack(MICROPROFILE_REST_CLIENT_VERSION, value -> microprofileRestClientVersion = value);

View File

@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Lambda;
import com.samskivert.mustache.Template;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import lombok.Getter;
@@ -33,6 +34,7 @@ import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -768,6 +770,11 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
if (SPRING_BOOT.equals(library) && ModelUtils.containsEnums(this.openAPI)) {
supportingFiles.add(new SupportingFile("converter.mustache",
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "EnumConverterConfiguration.kt"));
}
if (!additionalProperties.containsKey(TITLE)) {
// The purpose of the title is for:
// - README documentation

View File

@@ -1105,14 +1105,17 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
addtionalPropertiesName = schema.getTitle();
} else {
Schema additionalProperties = ModelUtils.getAdditionalProperties(schema);
if (additionalProperties.getTitle() != null) {
if(additionalProperties == null) {
return;
} else if (additionalProperties.getTitle() != null) {
addtionalPropertiesName = additionalProperties.getTitle();
} else if (additionalProperties.get$ref() != null) {
String ref = ModelUtils.getSimpleRef(additionalProperties.get$ref());
addtionalPropertiesName = toVarName(toModelName(ref));
}
}
properties.put(addtionalPropertiesName, schema);
properties.put(addtionalPropertiesName, schema);
}
}
}

View File

@@ -61,6 +61,9 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
private Boolean allowBlockingValidator = false;
private Boolean allowBlockingResponseSerialize = false;
private String externCrateName;
private Boolean basicAuthorization = false;
private Boolean basicAnalytic = false;
private Boolean ownedRequest = false;
// Types
private static final String uuidType = "uuid::Uuid";
@@ -286,7 +289,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
LOGGER.info("Warning: Environment variable 'RUST_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (!Boolean.TRUE.equals(ModelUtils.isGenerateAliasAsModel())) {
if (!ModelUtils.isGenerateAliasAsModel()) {
LOGGER.warn("generateAliasAsModel is set to false, which means array/map will be generated as model instead and the resulting code may have issues. Please enable `generateAliasAsModel` to address the issue.");
}
@@ -316,6 +319,24 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} else {
additionalProperties.put("allowBlockingResponseSerialize", allowBlockingResponseSerialize);
}
if (additionalProperties.containsKey("basicAuthorization")) {
basicAuthorization = convertPropertyToBooleanAndWriteBack("basicAuthorization");
} else {
additionalProperties.put("basicAuthorization", basicAuthorization);
}
if (additionalProperties.containsKey("basicAnalytic")) {
basicAnalytic = convertPropertyToBooleanAndWriteBack("basicAnalytic");
} else {
additionalProperties.put("basicAnalytic", basicAnalytic);
}
if (additionalProperties.containsKey("ownedRequest")) {
ownedRequest = convertPropertyToBooleanAndWriteBack("ownedRequest");
} else {
additionalProperties.put("ownedRequest", ownedRequest);
}
}
private void setPackageName(String packageName) {
@@ -722,6 +743,21 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
operations.put("havingAuthMethod", true);
operations.getOperation().forEach(op -> op.vendorExtensions.put("havingAuthMethod", true));
this.havingAuthMethods = true;
if (basicAuthorization) {
operations.put("basicAuthorization", true);
operations.getOperation().forEach(op -> op.vendorExtensions.put("basicAuthorization", true));
}
}
if (basicAnalytic) {
operations.put("basicAnalytic", true);
operations.getOperation().forEach(op -> op.vendorExtensions.put("basicAnalytic", true));
}
if (ownedRequest) {
operations.put("ownedRequest", true);
operations.getOperation().forEach(op -> op.vendorExtensions.put("ownedRequest", true));
}
return operationsMap;
@@ -982,6 +1018,22 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
property.dataType = objectType;
property.isNullable = false;
}
if (property.dataType.startsWith(vecType + "<String")) {
property.vendorExtensions.put("is-vec-string", true);
} else if (property.dataType.startsWith(vecType + "<models::")) {
property.vendorExtensions.put("is-vec-nested", true);
} else if (property.dataType.startsWith(mapType + "<String, String")) {
property.vendorExtensions.put("is-map-string", true);
} else if (property.dataType.startsWith(mapType + "<String, models::")) {
property.vendorExtensions.put("is-map-nested", true);
} else if (property.dataType.startsWith(mapType + "<String")) {
property.vendorExtensions.put("is-map", true);
} else if (property.dataType.startsWith("models::")) {
property.vendorExtensions.put("is-nested", true);
} else if (stringType.equals(property.dataType)) {
property.vendorExtensions.put("is-string", true);
}
}
@Override

View File

@@ -16,10 +16,14 @@
package org.openapitools.codegen.languages;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Escapers;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.*;
import org.openapitools.codegen.templating.mustache.EscapeKeywordLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -140,7 +144,7 @@ public class ScalaHttp4sServerCodegen extends DefaultCodegen implements CodegenC
additionalProperties.put("infoEmail", "team@openapitools.org");
additionalProperties.put("licenseInfo", "Apache 2.0");
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put("fnEscapeBacktick", new EscapeBacktickLambda());
languageSpecificPrimitives = new HashSet<>(
Arrays.asList(
@@ -557,7 +561,12 @@ public class ScalaHttp4sServerCodegen extends DefaultCodegen implements CodegenC
@Override
public String escapeReservedWord(String name) {
return "_" + name;
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
// Reserved words will be further escaped at the mustache compiler level.
// Scala escaping done here (via `, without compiler escaping) would otherwise be HTML encoded.
return "`" + name + "`";
}
@Override
@@ -807,12 +816,12 @@ public class ScalaHttp4sServerCodegen extends DefaultCodegen implements CodegenC
if (_vendorExtensions.size() == 1) { // only `x-type`
if ("String".equals(cp.getDataType())) {
return cp.paramName;
return escapeReservedWordUnapply(cp.baseName);
} else {
return cp.dataType + "Varr(" + cp.paramName + ")";
return cp.dataType + "Varr(" + escapeReservedWordUnapply(cp.baseName) + ")";
}
} else {
return cp.baseName + "Varr(" + cp.paramName + ")";
return cp.baseName + "Varr(" + escapeReservedWordUnapply(cp.baseName) + ")";
}
}
@@ -844,11 +853,34 @@ public class ScalaHttp4sServerCodegen extends DefaultCodegen implements CodegenC
}
vendorExtensions.putAll(refineProp(cp, imports));
return cp.baseName + "QueryParam(" + cp.paramName + ")";
return cp.baseName + "QueryParam(" + escapeReservedWordUnapply(cp.baseName) + ")";
}
@Override
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.SCALA;
}
@Override
protected ImmutableMap.Builder<String, Mustache.Lambda> addMustacheLambdas() {
return super.addMustacheLambdas()
.put("escapeReservedWordUnapply", new EscapeKeywordLambda(this::escapeReservedWordUnapply));
}
private String escapeReservedWordUnapply(String value) {
// The unapply method doesnt allow you to work with reserved variables via backticks;
// in such cases you should use the variable via a placeholder instead.
return isReservedWord(value) ? "_" + value : value;
}
private static class EscapeBacktickLambda extends AbstractScalaCodegen.CustomLambda {
@Override
public String formatFragment(String fragment) {
if (fragment.startsWith("`") && fragment.endsWith("`")) {
String unescaped = fragment.substring(1, fragment.length() - 1);
return "`" + Escapers.HTML.escape(unescaped) + "`";
}
return Escapers.HTML.escape(fragment);
}
}
}

View File

@@ -18,7 +18,6 @@
package org.openapitools.codegen.languages;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
@@ -40,6 +39,7 @@ import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.SplitStringLambda;
import org.openapitools.codegen.templating.mustache.SpringHttpStatusLambda;
import org.openapitools.codegen.templating.mustache.TrimWhitespaceLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
@@ -648,20 +648,6 @@ public class SpringCodegen extends AbstractJavaCodegen
supportsAdditionalPropertiesWithComposedSchema = true;
}
private boolean containsEnums() {
if (openAPI == null) {
return false;
}
Components components = this.openAPI.getComponents();
if (components == null || components.getSchemas() == null) {
return false;
}
return components.getSchemas().values().stream()
.anyMatch(it -> it.getEnum() != null && !it.getEnum().isEmpty());
}
private boolean supportLibraryUseTags() {
return SPRING_BOOT.equals(library) || SPRING_CLOUD_LIBRARY.equals(library);
}
@@ -696,7 +682,7 @@ public class SpringCodegen extends AbstractJavaCodegen
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
if (SPRING_BOOT.equals(library) && containsEnums()) {
if (SPRING_BOOT.equals(library) && ModelUtils.containsEnums(this.openAPI)) {
supportingFiles.add(new SupportingFile("converter.mustache",
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "EnumConverterConfiguration.java"));
}

View File

@@ -84,7 +84,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
public static final String NGPACKAGR_VERSION = "ngPackagrVersion";
public static final String ZONEJS_VERSION = "zonejsVersion";
protected String ngVersion = "19.0.0";
protected String ngVersion = "20.0.0";
@Getter @Setter
protected String npmRepository = null;
@Setter(AccessLevel.PRIVATE) private boolean useSingleRequestParameter = false;
@@ -170,7 +170,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override
public String getHelp() {
return "Generates a TypeScript Angular (9.x - 19.x) client library.";
return "Generates a TypeScript Angular (9.x - 20.x) client library.";
}
@Override

View File

@@ -78,6 +78,9 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
private static final String USE_OBJECT_PARAMS_SWITCH = "useObjectParameters";
private static final String USE_OBJECT_PARAMS_DESC = "Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.";
public static final String USE_ERASABLE_SYNTAX = "useErasableSyntax";
public static final String USE_ERASABLE_SYNTAX_DESC = "Use erasable syntax for the generated code. This is a temporary feature and will be removed in the future.";
private final Map<String, String> frameworkToHttpLibMap;
// NPM Options
@@ -122,6 +125,7 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_INVERSIFY_SWITCH, TypeScriptClientCodegen.USE_INVERSIFY_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_ERASABLE_SYNTAX, TypeScriptClientCodegen.USE_ERASABLE_SYNTAX_DESC).defaultValue("false"));
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
for (String option : TypeScriptClientCodegen.FRAMEWORKS) {

View File

@@ -799,6 +799,11 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
.filter(Objects::nonNull)
.collect(Collectors.toCollection(TreeSet::new));
cm.oneOfPrimitives = oneOfsList.stream()
.filter(CodegenProperty::getIsPrimitiveType)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(HashSet::new));
if (!cm.oneOf.isEmpty()) {
// For oneOfs only import $refs within the oneOf
cm.imports = cm.imports.stream()
@@ -1484,6 +1489,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
public Set<String> oneOfModels = new TreeSet<>();
@Getter @Setter
public Set<String> oneOfArrays = new TreeSet<>();
@Getter @Setter
public Set<CodegenProperty> oneOfPrimitives = new HashSet<>();
public boolean isEntity; // Is a model containing an "id" property marked as isUniqueId
public String returnPassthrough;

View File

@@ -2435,6 +2435,19 @@ public class ModelUtils {
schema.getContentSchema() != null);
}
/**
* Returns true if the OpenAPI specification contains any schemas which are enums.
* @param openAPI OpenAPI specification
* @return true if the OpenAPI specification contains any schemas which are enums.
*/
public static boolean containsEnums(OpenAPI openAPI) {
Map<String, Schema> schemaMap = getSchemas(openAPI);
if (schemaMap.isEmpty()) {
return false;
}
return schemaMap.values().stream().anyMatch(ModelUtils::isEnumSchema);
}
@FunctionalInterface
private interface OpenAPISchemaVisitor {

View File

@@ -15,16 +15,16 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}
## Installation
You'll need the `curl 7.58.0` package in order to build the API. To have code formatted nicely, you also need to have uncrustify version 0.67 or later.
You'll need the `curl 7.61.1` package in order to build the API. To have code formatted nicely, you also need to have uncrustify version 0.67 or later.
# Prerequisites
## Install the `curl 7.58.0` package with the following command on Linux.
## Install the `curl 7.61.1` package with the following command on Linux.
```bash
sudo apt remove curl
wget http://curl.haxx.se/download/curl-7.58.0.tar.gz
tar -xvf curl-7.58.0.tar.gz
cd curl-7.58.0/
wget http://curl.haxx.se/download/curl-7.61.1.tar.gz
tar -xvf curl-7.61.1.tar.gz
cd curl-7.61.1/
./configure
make
sudo make install

View File

@@ -10,6 +10,7 @@ apiClient_t *apiClient_create() {
apiClient_t *apiClient = malloc(sizeof(apiClient_t));
apiClient->basePath = strdup("{{{basePath}}}");
apiClient->sslConfig = NULL;
apiClient->curlConfig = NULL;
apiClient->dataReceived = NULL;
apiClient->dataReceivedLen = 0;
apiClient->data_callback_func = NULL;
@@ -60,6 +61,12 @@ apiClient_t *apiClient_create_with_base_path(const char *basePath
apiClient->sslConfig = NULL;
}
apiClient->curlConfig = malloc(sizeof(curlConfig_t));
apiClient->curlConfig->verbose = 0;
apiClient->curlConfig->keepalive = 0;
apiClient->curlConfig->keepidle = 120;
apiClient->curlConfig->keepintvl = 60;
apiClient->dataReceived = NULL;
apiClient->dataReceivedLen = 0;
apiClient->data_callback_func = NULL;
@@ -142,6 +149,12 @@ void apiClient_free(apiClient_t *apiClient) {
{{/isApiKey}}
{{/authMethods}}
{{/hasAuthMethods}}
if(apiClient->curlConfig) {
free(apiClient->curlConfig);
apiClient->curlConfig = NULL;
}
free(apiClient);
}
@@ -498,7 +511,6 @@ void apiClient_invoke(apiClient_t *apiClient,
CURLOPT_WRITEDATA,
apiClient);
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_VERBOSE, 0); // to get curl debug msg 0: to disable, 1L:to enable
{{#hasAuthMethods}}
{{#authMethods}}
@@ -543,6 +555,15 @@ void apiClient_invoke(apiClient_t *apiClient,
postData(handle, bodyParameters, bodyParametersLength);
}
if(apiClient->curlConfig != NULL) {
if(apiClient->curlConfig->keepalive == 1) {
curl_easy_setopt(handle, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(handle, CURLOPT_TCP_KEEPIDLE, apiClient->curlConfig->keepidle);
curl_easy_setopt(handle, CURLOPT_TCP_KEEPINTVL, apiClient->curlConfig->keepintvl);
}
curl_easy_setopt(handle, CURLOPT_VERBOSE, apiClient->curlConfig->verbose);
}
res = curl_easy_perform(handle);
curl_slist_free_all(headers);

View File

@@ -19,9 +19,19 @@ typedef struct sslConfig_t {
/* 1 -- skip ssl verify for server certificate */
} sslConfig_t;
typedef struct curlConfig_t {
long verbose; /* 0 -- disable verbose (default) */
/* 1 -- enable verbose */
int keepalive; /* 0 -- disable keepalive (default) */
/* 1 -- enable keepalive */
long keepidle; /* keep-alive idle time: default to 120 seconds */
long keepintvl; /* interval time between keep-alive probes: default to 60 seconds */
} curlConfig_t;
typedef struct apiClient_t {
char *basePath;
sslConfig_t *sslConfig;
curlConfig_t *curlConfig;
void *dataReceived;
long dataReceivedLen;
void (*data_callback_func)(void **, long *);

View File

@@ -535,7 +535,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param value The value of the parameter.
* @return A list of {@code Pair} objects.
*/
public List<Pair> parameterToPairs(String collectionFormat, String name, Collection value) {
public List<Pair> parameterToPairs(String collectionFormat, String name, Collection<?> value) {
List<Pair> params = new ArrayList<Pair>();
// preconditions

View File

@@ -6,6 +6,7 @@ import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.Module.SetupContext;
{{>generatedAnnotation}}
@@ -14,9 +15,15 @@ public class RFC3339JavaTimeModule extends SimpleModule {
public RFC3339JavaTimeModule() {
super("RFC3339JavaTimeModule");
addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
}
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
}
}

View File

@@ -24,7 +24,9 @@ import {{rootJavaEEPackage}}.validation.constraints.*;
import {{rootJavaEEPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#microprofileRegisterExceptionMapper}}
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
{{/microprofileRegisterExceptionMapper}}
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
{{#appName}}
@@ -41,7 +43,9 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
{{^microprofileServer}}
@RegisterRestClient{{#configKey}}(configKey="{{configKey}}"){{/configKey}}{{#configKeyFromClassName}}{{#operations}}(configKey="{{configKey}}"){{/operations}}{{/configKeyFromClassName}}
{{/microprofileServer}}
{{#microprofileRegisterExceptionMapper}}
@RegisterProvider(ApiExceptionMapper.class)
{{/microprofileRegisterExceptionMapper}}
@Path("{{#useAnnotatedBasePath}}{{contextPath}}{{/useAnnotatedBasePath}}{{commonPath}}")
public interface {{classname}} {
{{#operations}}

View File

@@ -3,10 +3,14 @@ package {{apiPackage}};
import {{rootJavaEEPackage}}.ws.rs.core.MultivaluedMap;
import {{rootJavaEEPackage}}.ws.rs.core.Response;
{{#microprofileGlobalExceptionMapper}}
import {{rootJavaEEPackage}}.ws.rs.ext.Provider;
{{/microprofileGlobalExceptionMapper}}
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
{{#microprofileGlobalExceptionMapper}}
@Provider
{{/microprofileGlobalExceptionMapper}}
public class ApiExceptionMapper
implements ResponseExceptionMapper<ApiException> {

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -158,7 +158,7 @@ public class ApiClient {
public ApiClient() {
this.builder = createDefaultHttpClientBuilder();
this.mapper = createDefaultObjectMapper();
updateBaseUri(getDefaultBaseUri());
updateBaseUri("{{{basePath}}}");
interceptor = null;
readTimeout = null;
connectTimeout = null;
@@ -176,7 +176,7 @@ public class ApiClient {
public ApiClient(HttpClient.Builder builder, ObjectMapper mapper, String baseUri) {
this.builder = builder;
this.mapper = mapper;
updateBaseUri(baseUri != null ? baseUri : getDefaultBaseUri());
updateBaseUri(baseUri != null ? baseUri : "{{{basePath}}}");
interceptor = null;
readTimeout = null;
connectTimeout = null;
@@ -201,8 +201,8 @@ public class ApiClient {
return mapper;
}
protected String getDefaultBaseUri() {
return "{{{basePath}}}";
protected final String getDefaultBaseUri() {
return basePath;
}
public static HttpClient.Builder createDefaultHttpClientBuilder() {

View File

@@ -57,6 +57,26 @@ import java.util.concurrent.CompletableFuture;
{{#operations}}
public class {{classname}} {
/**
* Utility class for extending HttpRequest.Builder functionality.
*/
private static class HttpRequestBuilderExtensions {
/**
* Adds additional headers to the provided HttpRequest.Builder. Useful for adding method/endpoint specific headers.
*
* @param builder the HttpRequest.Builder to which headers will be added
* @param headers a map of header names and values to add; may be null
* @return the same HttpRequest.Builder instance with the additional headers set
*/
static HttpRequest.Builder withAdditionalHeaders(HttpRequest.Builder builder, Map<String, String> headers) {
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
builder.header(entry.getKey(), entry.getValue());
}
}
return builder;
}
}
private final HttpClient memberVarHttpClient;
private final ObjectMapper memberVarObjectMapper;
private final String memberVarBaseUri;
@@ -78,6 +98,7 @@ public class {{classname}} {
memberVarResponseInterceptor = apiClient.getResponseInterceptor();
memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor();
}
{{#asyncNative}}
private ApiException getApiException(String operationId, HttpResponse<String> response) {
@@ -177,11 +198,40 @@ public class {{classname}} {
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture<Void>{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest) throws ApiException {
{{#returnType}}return {{/returnType}}{{^returnType}}{{#asyncNative}}return {{/asyncNative}}{{/returnType}}{{operationId}}(apiRequest, null);
}
/**
* {{summary}}
* {{notes}}
* @param apiRequest {@link API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request}
* @param headers Optional headers to include in the request
{{#returnType}}
* @return {{#asyncNative}}CompletableFuture&lt;{{/asyncNative}}{{returnType}}{{#asyncNative}}&gt;{{/asyncNative}}
{{/returnType}}
{{^returnType}}
{{#asyncNative}}
* @return CompletableFuture&lt;Void&gt;
{{/asyncNative}}
{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture<Void>{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest, Map<String, String> headers) throws ApiException {
{{#allParams}}
{{>nullable_var_annotations}}{{! prevent indent}}
{{{dataType}}} {{paramName}} = apiRequest.{{paramName}}();
{{/allParams}}
{{#returnType}}return {{/returnType}}{{^returnType}}{{#asyncNative}}return {{/asyncNative}}{{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{#returnType}}return {{/returnType}}{{^returnType}}{{#asyncNative}}return {{/asyncNative}}{{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
}
/**
@@ -202,10 +252,32 @@ public class {{classname}} {
@Deprecated
{{/isDeprecated}}
public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest) throws ApiException {
return {{operationId}}WithHttpInfo(apiRequest, null);
}
/**
* {{summary}}
* {{notes}}
* @param apiRequest {@link API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request}
* @param headers Optional headers to include in the request
* @return {{#asyncNative}}CompletableFuture&lt;{{/asyncNative}}ApiResponse&lt;{{returnType}}{{^returnType}}Void{{/returnType}}&gt;{{#asyncNative}}&gt;{{/asyncNative}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest, Map<String, String> headers) throws ApiException {
{{#allParams}}
{{{dataType}}} {{paramName}} = apiRequest.{{paramName}}();
{{/allParams}}
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
}
{{/hasParams}}
@@ -237,15 +309,46 @@ public class {{classname}} {
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture<Void>{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws ApiException {
{{#returnType}}return {{/returnType}}{{^returnType}}{{#asyncNative}}return {{/asyncNative}}{{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}null);
}
/**
* {{summary}}
* {{notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}{{/isContainer}}){{/required}}
{{/allParams}}
* @param headers Optional headers to include in the request
{{#returnType}}
* @return {{#asyncNative}}CompletableFuture&lt;{{/asyncNative}}{{returnType}}{{#asyncNative}}&gt;{{/asyncNative}}
{{/returnType}}
{{^returnType}}
{{#asyncNative}}
* @return CompletableFuture&lt;Void&gt;
{{/asyncNative}}
{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture<Void>{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Map<String, String> headers) throws ApiException {
{{^asyncNative}}
{{#returnType}}ApiResponse<{{{.}}}> localVarResponse = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{#returnType}}ApiResponse<{{{.}}}> localVarResponse = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
{{#returnType}}
return localVarResponse.getData();
{{/returnType}}
{{/asyncNative}}
{{#asyncNative}}
try {
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
return memberVarHttpClient.sendAsync(
localVarRequestBuilder.build(),
HttpResponse.BodyHandlers.ofString()).thenComposeAsync(localVarResponse -> {
@@ -293,8 +396,32 @@ public class {{classname}} {
@Deprecated
{{/isDeprecated}}
public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws ApiException {
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}null);
}
/**
* {{summary}}
* {{notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}{{/isContainer}}){{/required}}
{{/allParams}}
* @param headers Optional headers to include in the request
* @return {{#asyncNative}}CompletableFuture&lt;{{/asyncNative}}ApiResponse&lt;{{returnType}}{{^returnType}}Void{{/returnType}}&gt;{{#asyncNative}}&gt;{{/asyncNative}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Map<String, String> headers) throws ApiException {
{{^asyncNative}}
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
try {
HttpResponse<InputStream> localVarResponse = memberVarHttpClient.send(
localVarRequestBuilder.build(),
@@ -386,7 +513,7 @@ public class {{classname}} {
{{/asyncNative}}
{{#asyncNative}}
try {
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
HttpRequest.Builder localVarRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers);
return memberVarHttpClient.sendAsync(
localVarRequestBuilder.build(),
HttpResponse.BodyHandlers.ofString()).thenComposeAsync(localVarResponse -> {
@@ -423,7 +550,7 @@ public class {{classname}} {
{{/asyncNative}}
}
private HttpRequest.Builder {{operationId}}RequestBuilder({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws ApiException {
private HttpRequest.Builder {{operationId}}RequestBuilder({{#allParams}}{{>nullable_var_annotations}} {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Map<String, String> headers) throws ApiException {
{{#allParams}}
{{#required}}
// verify the required parameter '{{paramName}}' is set
@@ -628,6 +755,8 @@ public class {{classname}} {
if (memberVarReadTimeout != null) {
localVarRequestBuilder.timeout(memberVarReadTimeout);
}
// Add custom headers if provided
localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers);
if (memberVarInterceptor != null) {
memberVarInterceptor.accept(localVarRequestBuilder);
}

View File

@@ -909,7 +909,7 @@ public class ApiClient {
* @param value The value of the parameter.
* @return A list of {@code Pair} objects.
*/
public List<Pair> parameterToPairs(String collectionFormat, String name, Collection value) {
public List<Pair> parameterToPairs(String collectionFormat, String name, Collection<?> value) {
List<Pair> params = new ArrayList<Pair>();
// preconditions

View File

@@ -81,7 +81,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
{{^isPrimitiveType}}
{{#isArray}}
List<?> list = (List<?>) value.getActualInstance();
if (list.get(0) instanceof {{{items.dataType}}}) {
if (!list.isEmpty() && list.get(0) instanceof {{{items.dataType}}}) {
JsonArray array = adapter{{#sanitizeDataType}}{{{dataType}}}{{/sanitizeDataType}}.toJsonTree(({{{dataType}}})value.getActualInstance()).getAsJsonArray();
elementAdapter.write(out, array);
return;
@@ -252,7 +252,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
if (instance instanceof {{#isArray}}List<?>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
{{#isArray}}
List<?> list = (List<?>) instance;
if (list.get(0) instanceof {{{items.dataType}}}) {
if (!list.isEmpty() && list.get(0) instanceof {{{items.dataType}}}) {
super.setActualInstance(instance);
return;
}

View File

@@ -140,7 +140,7 @@ dependencies {
{{#hasOAuthMethods}}
implementation group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.2'
{{/hasOAuthMethods}}
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.18.0'
{{#joda}}
implementation 'joda-time:joda-time:2.9.9'
{{/joda}}

View File

@@ -13,7 +13,7 @@ lazy val root = (project in file(".")).
"com.squareup.okhttp3" % "okhttp" % "4.12.0",
"com.squareup.okhttp3" % "logging-interceptor" % "4.12.0",
"com.google.code.gson" % "gson" % "2.9.1",
"org.apache.commons" % "commons-lang3" % "3.17.0",
"org.apache.commons" % "commons-lang3" % "3.18.0",
"jakarta.ws.rs" % "jakarta.ws.rs-api" % "2.1.6",
{{#openApiNullable}}
"org.openapitools" % "jackson-databind-nullable" % "0.2.6",

View File

@@ -94,7 +94,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
{{^isPrimitiveType}}
{{#isArray}}
List<?> list = (List<?>) value.getActualInstance();
if (list.get(0) instanceof {{{items.dataType}}}) {
if (!list.isEmpty() && list.get(0) instanceof {{{items.dataType}}}) {
JsonArray array = adapter{{#sanitizeDataType}}{{{dataType}}}{{/sanitizeDataType}}.toJsonTree(({{{dataType}}})value.getActualInstance()).getAsJsonArray();
elementAdapter.write(out, array);
return;
@@ -330,7 +330,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
if (instance instanceof {{#isArray}}List<?>{{/isArray}}{{#isMap}}Map<?, ?>{{/isMap}}{{^isMap}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isMap}}) {
{{#isArray}}
List<?> list = (List<?>) instance;
if (list.get(0) instanceof {{{items.dataType}}}) {
if (!list.isEmpty() && list.get(0) instanceof {{{items.dataType}}}) {
super.setActualInstance(instance);
return;
}

View File

@@ -414,7 +414,7 @@
{{/swagger2AnnotationLibrary}}
<okhttp-version>4.12.0</okhttp-version>
<gson-version>2.10.1</gson-version>
<commons-lang3-version>3.17.0</commons-lang3-version>
<commons-lang3-version>3.18.0</commons-lang3-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.6</jackson-databind-nullable-version>
{{/openApiNullable}}

View File

@@ -29,7 +29,7 @@
{{#vendorExtensions.x-class-extra-annotation}}
{{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}
public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{
public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{{>permits}}{
{{#serializableModel}}
private static final long serialVersionUID = 1L;

View File

@@ -32,14 +32,14 @@ if(hasProperty('target') && target == 'android') {
}
compileOptions {
{{#useJakartaEe}}
{{#java17}}
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
{{/useJakartaEe}}
{{^useJakartaEe}}
{{/java17}}
{{^java17}}
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
{{/useJakartaEe}}
{{/java17}}
}
// Rename the aar correctly
@@ -84,14 +84,14 @@ if(hasProperty('target') && target == 'android') {
apply plugin: 'java'
apply plugin: 'maven-publish'
{{#useJakartaEe}}
{{#java17}}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
{{/useJakartaEe}}
{{^useJakartaEe}}
{{/java17}}
{{^java17}}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
{{/useJakartaEe}}
{{/java17}}
publishing {
publications {
@@ -135,14 +135,14 @@ ext {
jakarta_annotation_version = "2.1.1"
beanvalidation_version = "3.0.2"
reactor_version = "3.5.12"
reactor_netty_version = "1.1.13"
reactor_netty_version = "1.2.8"
{{/useJakartaEe}}
{{^useJakartaEe}}
spring_boot_version = "2.7.17"
jakarta_annotation_version = "1.3.5"
beanvalidation_version = "2.0.2"
reactor_version = "3.4.34"
reactor_netty_version = "1.0.39"
reactor_netty_version = "1.2.8"
{{/useJakartaEe}}
jackson_version = "2.17.1"
jackson_databind_version = "2.17.1"

View File

@@ -29,7 +29,7 @@
{{#vendorExtensions.x-class-extra-annotation}}
{{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}
public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{
public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{{>permits}}{
{{#serializableModel}}
private static final long serialVersionUID = 1L;

View File

@@ -45,14 +45,14 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
{{#useJakartaEe}}
{{#java17}}
<source>17</source>
<target>17</target>
{{/useJakartaEe}}
{{^useJakartaEe}}
{{/java17}}
{{^java17}}
<source>1.8</source>
<target>1.8</target>
{{/useJakartaEe}}
{{/java17}}
</configuration>
</plugin>
<plugin>
@@ -176,13 +176,13 @@
<spring-boot-version>3.0.12</spring-boot-version>
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<reactor-version>3.5.12</reactor-version>
<reactor-netty-version>1.1.13</reactor-netty-version>
<reactor-netty-version>1.2.8</reactor-netty-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<spring-boot-version>2.7.17</spring-boot-version>
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<reactor-version>3.4.34</reactor-version>
<reactor-netty-version>1.0.39</reactor-netty-version>
<reactor-netty-version>1.2.8</reactor-netty-version>
{{/useJakartaEe}}
<junit-version>5.10.2</junit-version>
{{#joda}}

View File

@@ -1,5 +1,5 @@
{{>additionalOneOfTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
public {{>sealed}}interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}}{{>permits}}{
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}

View File

@@ -0,0 +1 @@
{{#useSealedOneOfInterfaces}}{{#vendorExtensions.x-is-one-of-interface}}{{#permits}}{{#-first}}permits {{/-first}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}} {{/-last}}{{/permits}}{{/vendorExtensions.x-is-one-of-interface}}{{/useSealedOneOfInterfaces}}

View File

@@ -0,0 +1 @@
{{#useSealedOneOfInterfaces}}{{#vendorExtensions.x-is-one-of-interface}}{{#permits.0}}sealed {{/permits.0}}{{/vendorExtensions.x-is-one-of-interface}}{{^permits.0}}{{#vendorExtensions.x-implements}}final {{/vendorExtensions.x-implements}}{{/permits.0}}{{/useSealedOneOfInterfaces}}

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.
@@ -129,6 +129,7 @@ public interface {{classname}} {
{{/jdk8-default-interface}}
{{#operation}}
public static final String PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} = "{{{path}}}";
/**
* {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}}
{{#notes}}
@@ -246,7 +247,7 @@ public interface {{classname}} {
{{/implicitHeadersParams.0}}
@RequestMapping(
method = RequestMethod.{{httpMethod}},
value = "{{{path}}}"{{#singleContentTypes}}{{#hasProduces}},
value = {{classname}}.PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}{{#singleContentTypes}}{{#hasProduces}},
produces = { {{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}} }{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}},
@@ -274,7 +275,7 @@ public interface {{classname}} {
}
// Override this method
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}{{#isArray}}List<MultipartFile>{{/isArray}}{{^isArray}}MultipartFile{{/isArray}}{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} {
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}MultipartFile{{#isArray}}>{{/isArray}}{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} {
{{/delegate-method}}
{{^isDelegate}}
{{>methodBody}}{{! prevent indent}}

View File

@@ -27,6 +27,9 @@ import java.util.Optional;
{{#async}}
import java.util.concurrent.CompletableFuture;
{{/async}}
{{#returnSuccessCode}}
import java.util.concurrent.atomic.AtomicInteger;
{{/returnSuccessCode}}
import {{javaxPackage}}.annotation.Generated;
{{#operations}}
@@ -68,7 +71,7 @@ public interface {{classname}}Delegate {
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}{{#isFormParam}}MultipartFile{{/isFormParam}}{{^isFormParam}}{{>optionalDataType}}{{/isFormParam}}{{/reactive}}{{#isArray}}>{{/isArray}}{{/isFile}} {{paramName}}{{^-last}},
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}{{#isFormParam}}MultipartFile{{/isFormParam}}{{^isFormParam}}{{>optionalDataType}}{{/isFormParam}}{{#isArray}}>{{/isArray}}{{/reactive}}{{/isFile}} {{paramName}}{{^-last}},
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
{{/hasParams}}ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} {
{{>methodBody}}{{! prevent indent}}

View File

@@ -12,6 +12,13 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
/**
* This class provides Spring Converter beans for the enum models in the OpenAPI specification.
*
* By default, Spring only converts primitive types to enums using Enum::valueOf, which can prevent
* correct conversion if the OpenAPI specification is using an `enumPropertyNaming` other than
* `original` or the specification has an integer enum.
*/
@Configuration(value = "{{configPackage}}.enumConverterConfiguration")
public class EnumConverterConfiguration {

View File

@@ -1 +1 @@
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}{{#isArray}}@RequestPart{{/isArray}}{{^isArray}}{{#reactive}}@RequestPart{{/reactive}}{{^reactive}}@RequestParam{{/reactive}}{{/isArray}}{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{^required}}{{#useOptional}}Optional<{{/useOptional}}{{/required}}{{{dataType}}}{{^required}}{{#useOptional}}>{{/useOptional}}{{/required}} {{paramName}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}} {{paramName}}{{/isFile}}{{/isFormParam}}
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}{{#isArray}}@RequestPart{{/isArray}}{{^isArray}}{{#reactive}}@RequestPart{{/reactive}}{{^reactive}}@RequestParam{{/reactive}}{{/isArray}}{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{^required}}{{#useOptional}}Optional<{{/useOptional}}{{/required}}{{{dataType}}}{{^required}}{{#useOptional}}>{{/useOptional}}{{/required}} {{paramName}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}MultipartFile{{#isArray}}>{{/isArray}}{{/reactive}} {{paramName}}{{/isFile}}{{/isFormParam}}

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -14,6 +14,7 @@ org.openapitools.codegen.languages.ClojureClientCodegen
org.openapitools.codegen.languages.ConfluenceWikiCodegen
org.openapitools.codegen.languages.CppQtClientCodegen
org.openapitools.codegen.languages.CppQtQHttpEngineServerCodegen
org.openapitools.codegen.languages.CppOatppServerCodegen
org.openapitools.codegen.languages.CppPistacheServerCodegen
org.openapitools.codegen.languages.CppRestbedServerCodegen
org.openapitools.codegen.languages.CppRestbedServerDeprecatedCodegen

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -0,0 +1,46 @@
# REST API Server for {{appName}}
## Overview
This API Server 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 server generator creates three folders:
- `api`: This folder contains the handlers for each method specified in the OpenAPI definition. Every handler extracts
the path and body parameters (if any) from the requests and tries to parse and possibly validate them.
Once this step is completed, the main API class calls the corresponding abstract method that should be implemented
by the developer (a basic implementation is provided under the `impl` folder)
- `impl`: As written above, the implementation folder contains, for each API, the corresponding implementation class,
which extends the main API class and implements the abstract methods.
Every method receives the path and body parameters as constant reference variables and a reference to the response
object, that should be filled with the right response and sent at the end of the method with the command:
response.send(returnCode, responseBody, [mimeType])
- `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 start the server.
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 server please follow the steps below:
```bash
mkdir build
cd build
cmake ..
make
```
Once compiled run the server:
```bash
cd build
./api-server
```
## Libraries required
- [Oat++](https://oatpp.io/)
## Namespaces
{{{apiPackage}}}
{{{modelPackage}}}

View File

@@ -0,0 +1,58 @@
{{>licenseInfo}}
{{#operations}}/*
* {{classname}}.h
*
* {{description}}
*/
#ifndef {{classname}}_H_
#define {{classname}}_H_
{{{defaultInclude}}}
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/macro/component.hpp"
#include "oatpp/core/Types.hpp"
{{#imports}}{{{import}}}
{{/imports}}
#include OATPP_CODEGEN_BEGIN(ApiController) ///< Begin ApiController codegen section
namespace {{apiNamespace}}
{
class {{classname}} : public oatpp::web::server::api::ApiController {
public:
{{classname}}(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper) /* Inject object mapper */)
: oatpp::web::server::api::ApiController(objectMapper)
{}
{{#operation}}
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <param name="request">HTTP Request</param>
{{#allParams}}
{{#isPathParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isPathParam}}{{#isQueryParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isQueryParam}}{{#isBodyParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isBodyParam}}{{#isHeaderParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isHeaderParam}}
{{/allParams}}
virtual std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> {{operationIdSnakeCase}}(const std::shared_ptr<IncomingRequest> &request{{#allParams}}{{#isPathParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isPathParam}}{{#isQueryParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isQueryParam}}{{#isBodyParam}}, const {{#isModel}}oatpp::Object<{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}>{{/isModel}}{{^isModel}}{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}{{/isModel}} &{{paramName}}{{/isBodyParam}}{{#isHeaderParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isHeaderParam}}{{/allParams}}) = 0;
ENDPOINT("{{httpMethod}}", "{{{vendorExtensions.x-codegen-oatpp-path}}}", {{operationIdSnakeCase}}_handler, REQUEST(std::shared_ptr<IncomingRequest>, request){{#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}}) {
return {{operationIdSnakeCase}}(request{{#allParams}}{{#isPathParam}}, {{paramName}}{{/isPathParam}}{{#isQueryParam}}, {{paramName}}{{/isQueryParam}}{{#isBodyParam}}, {{paramName}}{{/isBodyParam}}{{#isHeaderParam}}, {{paramName}}{{/isHeaderParam}}{{/allParams}});
}
{{/operation}}
};
#include OATPP_CODEGEN_END(ApiController) ///< End ApiController codegen section
} // namespace {{apiNamespace}}
#endif /* {{classname}}_H_ */
{{/operations}}

View File

@@ -0,0 +1,45 @@
{{>licenseInfo}}
{{#operations}}/*
* {{classname}}Controller.hpp
*
* {{description}}
*/
#ifndef {{classnameSnakeUpperCase}}_IMPL_H_
#define {{classnameSnakeUpperCase}}_IMPL_H_
{{{defaultInclude}}}
#include <{{classname}}.hpp>
#include "oatpp/core/Types.hpp"
{{#imports}}{{{import}}}
{{/imports}}
namespace {{apiNamespace}}
{
class {{declspec}} {{classname}}Controller : public {{classname}} {
public:
{{#operation}}
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <param name="request">HTTP Request</param>
{{#allParams}}
{{#isPathParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isPathParam}}{{#isQueryParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isQueryParam}}{{#isBodyParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isBodyParam}}{{#isHeaderParam}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/isHeaderParam}}
{{/allParams}}
virtual std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> {{operationIdSnakeCase}}(const std::shared_ptr<IncomingRequest> &request{{#allParams}}{{#isPathParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isPathParam}}{{#isQueryParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isQueryParam}}{{#isBodyParam}}, const {{#isModel}}oatpp::Object<{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}>{{/isModel}}{{^isModel}}{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}{{/isModel}} &{{paramName}}{{/isBodyParam}}{{#isHeaderParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isHeaderParam}}{{/allParams}});
{{/operation}}
};
} // namespace {{apiNamespace}}
{{/operations}}
#endif

View File

@@ -0,0 +1,27 @@
{{>licenseInfo}}
{{#operations}}
#include "{{classname}}Controller.hpp"
{{#apiNamespaceDeclarations}}
namespace {{this}} {
{{/apiNamespaceDeclarations}}
{{#operation}}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> {{classname}}Controller::{{operationIdSnakeCase}}(const std::shared_ptr<IncomingRequest> &request{{#allParams}}{{#isPathParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isPathParam}}{{#isQueryParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isQueryParam}}{{#isBodyParam}}, const {{#isModel}}oatpp::Object<{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}>{{/isModel}}{{^isModel}}{{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}}{{/isModel}} &{{paramName}}{{/isBodyParam}}{{#isHeaderParam}}, const {{#isModel}}{{modelNamespace}}::{{/isModel}}{{{dataType}}} &{{paramName}}{{/isHeaderParam}}{{/allParams}}) {
(void)request;
{{#allParams}}
{{#isPathParam}}(void){{paramName}};{{/isPathParam}}
{{#isQueryParam}}(void){{paramName}};{{/isQueryParam}}
{{#isBodyParam}}(void){{paramName}};{{/isBodyParam}}
{{#isHeaderParam}}(void){{paramName}};{{/isHeaderParam}}
{{/allParams}}
return createResponse(Status::CODE_501, "TODO: Implement API Handler");
}
{{/operation}}
{{#apiNamespaceDeclarations}}
}
{{/apiNamespaceDeclarations}}
{{/operations}}

View File

@@ -0,0 +1,38 @@
cmake_minimum_required (VERSION 3.2)
project(api-server)
{{#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}}

View File

@@ -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.
*/

View File

@@ -0,0 +1,95 @@
{{>licenseInfo}}
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "oatpp/network/Server.hpp"
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/parser/json/Utils.hpp"
{{#apiInfo}}{{#apis}}{{#operations}}
#include "{{classname}}Controller.hpp"{{/operations}}{{/apis}}{{/apiInfo}}
/**
* Class which creates and holds Application components and registers components in oatpp::base::Environment
* Order of components initialization is from top to bottom
*/
class AppComponent {
public:
/**
* Create ConnectionProvider component which listens on the port
*/
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
return oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", {{serverPort}}{{^serverPort}}8080{{/serverPort}}, oatpp::network::Address::IP_4});
}());
/**
* Create Router component
*/
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
return oatpp::web::server::HttpRouter::createShared();
}());
/**
* Create ConnectionHandler component which uses Router component to route requests
*/
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
return oatpp::web::server::HttpConnectionHandler::createShared(router);
}());
/**
* Create ObjectMapper component to serialize/deserialize DTOs in Contoller's API
*/
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
return oatpp::parser::json::mapping::ObjectMapper::createShared();
}());
};
static int _main_app(void) {
/* Register Components in scope of run() method */
AppComponent components;
/* Get router component */
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
{{#apiInfo}}{{#apis}}{{#operations}}
/* Create {{classname}}Controller and add all of its endpoints to router */
auto {{classname}}Controller = std::make_shared<{{apiNamespace}}::{{classname}}Controller>();
router->addController({{classname}}Controller);
{{/operations}}{{/apis}}{{/apiInfo}}
/* Get connection handler component */
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
/* Get connection provider component */
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
/* Create server which takes provided TCP connections and passes them to HTTP connection handler */
oatpp::network::Server server(connectionProvider, connectionHandler);
/* Print info about server port */
OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").getData());
/* Run server */
server.run();
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;
}

View File

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

View File

@@ -32,7 +32,7 @@
@BuiltValueHook(initializeBuilder: true)
static void _defaults({{{classname}}}Builder b) => b{{#vendorExtensions.x-parent-discriminator}}..{{propertyName}}=b.discriminatorValue{{/vendorExtensions.x-parent-discriminator}}{{#vendorExtensions.x-self-and-ancestor-only-props}}{{#defaultValue}}
..{{{name}}} = {{#isEnum}}{{^isContainer}}const {{{enumName}}}._({{/isContainer}}{{/isEnum}}{{{defaultValue}}}{{#isEnum}}{{^isContainer}}){{/isContainer}}{{/isEnum}}{{/defaultValue}}{{/vendorExtensions.x-self-and-ancestor-only-props}};
..{{{name}}} = {{#isEnum}}{{^isContainer}}{{{defaultValue}}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{defaultValue}}}{{/isEnum}}{{/defaultValue}}{{/vendorExtensions.x-self-and-ancestor-only-props}};
{{/vendorExtensions.x-is-parent}} @BuiltValueSerializer(custom: true)
static Serializer<{{classname}}> get serializer => _${{classname}}Serializer();

View File

@@ -1,10 +1,11 @@
module {{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}
go 1.18
go 1.23
require (
{{#hasOAuthMethods}}
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558
github.com/stretchr/testify v1.10.0
golang.org/x/oauth2 v0.27.0
{{/hasOAuthMethods}}
{{#withAWSV4Signature}}
github.com/aws/aws-sdk-go v1.34.14

View File

@@ -5,8 +5,8 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
{{#hasOAuthMethods}}
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
{{/hasOAuthMethods}}
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -16,4 +16,4 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
{{#importValidator}}
gopkg.in/validator.v2 v2.0.1 h1:xF0KWyGWXm/LM2G1TrEjqOu4pa6coO9AlWSf3msVfDY=
gopkg.in/validator.v2 v2.0.1/go.mod h1:lIUZBlB3Im4s/eYp39Ry/wkR02yOPhZ9IwIRBjuPuG8=
{{/importValidator}}
{{/importValidator}}

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -1,4 +1,4 @@
/**
/*
* {{{appName}}}
* {{{appDescription}}}
*

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -1,4 +1,4 @@
/**
/*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.

View File

@@ -110,7 +110,7 @@ import java.io.IOException
if (value.actualInstance is {{#isArray}}List<*>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
{{#isArray}}
val list = value.actualInstance as List<Any>
if (list.get(0) is {{{items.dataType}}}) {
if (!list.isEmpty() && list.get(0) is {{{items.dataType}}}) {
val array = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}.toJsonTree(value.actualInstance as {{{dataType}}}?).getAsJsonArray()
elementAdapter.write(out, array)
return

Some files were not shown because too many files have changed in this diff Show More