Compare commits

...

46 Commits

Author SHA1 Message Date
Tino Fuhrmann
4f788e7ae7 Extract enum type fix to abstract client codegen 2023-04-29 08:44:23 +02:00
Tino Fuhrmann
6f1d1c0084 Remove space from "type" 2023-04-20 20:41:19 +02:00
Tino Fuhrmann
9546218bb8 Regenerated samples 2023-04-20 17:37:42 +02:00
Tino Fuhrmann
cd79f5eff9 Remove printlns 2023-04-20 17:36:10 +02:00
Tino Fuhrmann
7527911393 Fix invalid discrimnator value and enum type 2023-04-20 17:32:57 +02:00
William Cheng
7a41231721 minor bug fix to openapi normalizer (#15225) 2023-04-15 22:00:03 +08:00
William Cheng
9ad695d52c better npe in processUseAllOfRefAsParent (openapi normalizer) (#15224) 2023-04-15 15:54:54 +08:00
William Cheng
c5a8fafc3d remove deprecated warning (#15223) 2023-04-15 15:24:14 +08:00
William Cheng
5832731c0e [java] Update undertow to newer version (#15222)
* update undertow to newer version

* fix
2023-04-15 14:56:48 +08:00
Tom Sanidas
6a67551ea5 Issue 3175 - using @objcMembers to expose all props and funcs to ObjC code when objcCompatible is requested. (#15188) 2023-04-14 09:31:59 +01:00
John Dimeo
90b78fe97e Jersey2/3 - Probe content type for multipart upload parts (#14965)
* Probe content type for multipart form uploads since many servers require each part to correctly identify its type.

* Update samples

* Add explanatory comment

* Update samples with comment
2023-04-14 12:15:13 +08:00
Robin Karlsson
b247ad75e1 [java] Add public static version field (#15108) 2023-04-14 01:06:54 +08:00
Barnaby Court
53d9d30834 For microprofile java - use {{rootJavaEEPackage}} instead of {{javaxPackage}} (#15179) 2023-04-14 00:59:33 +08:00
André Andersson
241d649164 Fix list of type not including correct import (#15171) 2023-04-14 00:14:28 +08:00
Andrii Serkes
60e6d2d57f fix Jsonb issue for Helidon SE Client generator (#15146)
Signed-off-by: aserkes <andrii.serkes@oracle.com>
2023-04-13 23:28:12 +08:00
Robbert van Waveren
8a426b2f4a allow to specify the useOneOfInterfaces option for java (#15042) 2023-04-12 15:21:34 +03:00
William Cheng
e852ceceef add lwj5 to go tech comm (#15199) 2023-04-12 16:26:46 +08:00
Beppe Catanese
0fff9642bf Add blog Mustache templates with OpenAPI generator (#15198) 2023-04-12 16:12:38 +08:00
Steven Goris
0b41ee1c78 Issue #15095: Improve gradle task documentation (#15193)
Co-authored-by: Steven <steven.goris@nike.com>
2023-04-12 11:38:09 +08:00
William Cheng
ff48f80379 udpate vertx to newer version 3.5.2 (#15197) 2023-04-12 11:32:11 +08:00
Robert Schweizer
448cbfd018 [python-nextgen] Limit allowed pydantic version range (#15189)
Align the lower limits between pyproject.toml and setup.py.

Set a common upper limit of <2, because version 2 brings breaking
changes.
2023-04-12 11:08:28 +08:00
William Cheng
f8cb5fde97 Add tests for aspnetcore 6.0 useSwashBuckle option (#15176)
* add test for aspnetcore 6.0 useSwashBuckle option

* update samples

* update petstore with more tests

* add options

* update samples

* remove unused files
2023-04-11 17:43:39 +08:00
Ween Jiann
81cafdc196 [go] Fix: reservedWordsMappings not checked for reserved word (#15083)
* Fix: reservedWordsMappings not checked for reserved word

* Fix coding issue
2023-04-11 15:39:53 +08:00
Ween Jiann
8ce990d3d7 [go-server] Add ability to handle parameters of number type (#15079)
* Add ability to handle parameters of number type

* Generate samples

* Add handling for number without format

* Regenerate samples

* Fix indentation
2023-04-11 15:38:58 +08:00
Beppe Catanese
2b796d5c61 [Go] Format error message only when Kind is Struct (#15154)
* Check if Kind is Struct

* Commit regenerated files

* Tabs indentation instead of 4-space

* Commit regenerated files
2023-04-11 14:39:08 +08:00
leonluc-dev
a17bb59097 Added useSwashBuckle condition (#15157)
Added useSwashBuckle condition to Swashbuckle attributes in models
2023-04-10 18:21:32 +08:00
martin-mfg
e9e0f50ab6 Update customization.md (#15172)
Clarify which OpenAPI Generator version exactly introduced [Set skipFormModel to true by default](https://github.com/OpenAPITools/openapi-generator/pull/8125).
2023-04-10 17:16:19 +08:00
Amrith Nayak
5d490d742a Add Flipkart as a company using OpenAPI Generator (#15175)
* Adding Flipkart as a openapi generator user

* chore: added flipkart company logo static asset

* fix: fixed typo in users
2023-04-10 17:14:25 +08:00
devhl-labs
1e2f16ed69 [csharp-netcore] Explicitly implement IValidatableObject (#15160)
* explicit interface implementation

* minor spacing change
2023-04-10 11:20:48 +08:00
Takeshi Masaki
5e3bb7e33e [Ruby] fix RSpec documentation URL (#15164) 2023-04-10 10:44:28 +08:00
Tushar
a4f5a74d5b fix(python-nextgen): dependency incompatiblity (#15167)
Downgrade tox and flake8. Alternateively, we can increase minimum python version to 3.8.1
2023-04-10 10:31:53 +08:00
Tushar
4a83c9181f fix(python-nextgen): Use spec format for authors in pyproject (#15170) 2023-04-10 10:31:37 +08:00
Ween Jiann
a5bc7f107d [typescript] Make TypeScriptClientCodegen extend AbstractTypeScriptClientCodegen (#15096)
* Make TypeScriptClientCodegen extend AbstractTypeScriptClientCodegen

* Regenerate samples

* Update docs

* Clean up

* Remove updated toEnumName

* Fix: SUPPORTS_ES6

* Fix: `setSupportsES6` should not be set directly in unit tests

* Set modelPropertyNaming to camelCase
2023-04-09 20:43:58 +02:00
Martin Delille
f40433d28f qt ctest (#14968)
* [cpp-qt-client] Fix warning about deprecated count() method

* [cpp-qt-client] Ignore build directory

* [cpp-qt-client] Use ctest

* Fix CMakeLists.txt for cpp-qt-client
2023-04-07 16:24:11 +08:00
William Cheng
b2be16746c fix link, add links to posts (#15153) 2023-04-07 16:14:24 +08:00
William Cheng
e8e62ccadb simplify enum of string & string to enum of string (#15149) 2023-04-07 15:54:42 +08:00
William Cheng
bda2e4a167 fix NPE in simplifyOneOfAnyOf (#15142) 2023-04-07 09:34:20 +08:00
William Cheng
bd7bc9aa79 [python-nextgen] Add bytearray, none_type as primitive type (#15130)
* add bytearray, none type as primitive type

* update samples

* update doc
2023-04-07 09:34:04 +08:00
William Cheng
ba2c42e34b add override to java native pojo (#15125) 2023-04-06 15:00:14 +08:00
William Cheng
07227d4650 add support for union of strictfloat and strictint (#15124) 2023-04-06 11:51:12 +08:00
Tommaso Barbugli
b409ceb3a0 respect api visibility for oneof enum (#15122) 2023-04-04 09:45:27 +01:00
devhl-labs
3b11187200 made escaped regex be not literal strings (#15107) 2023-04-04 15:15:14 +08:00
William Cheng
3d7c173eb2 update ue4 c++ client 2023-04-01 19:11:37 +08:00
Samuel Kahn
033b946856 [cpp-ue4] Series of fixes for cpp-ue4 (#15068)
* [cpp-ue4] Removed warning related to wrong casing of HTTP module

* [cpp-ue4] Fixed compilation error when using file parameters in json body generation

* [cpp-ue4] Do not write the form param json body generation unless there actually are form params

* [cpp-ue4] Added support for enum values in path params
2023-04-01 19:01:45 +08:00
William Cheng
938c72cec0 trigger build 2023-04-01 19:00:14 +08:00
William Cheng
5d1e18306a Prepare 6.6.0-SNAPSHOT (#15100)
* set 6.6.0 snapshot version

* update samples

* update readme
2023-04-01 18:48:01 +08:00
2351 changed files with 12182 additions and 3477 deletions

View File

@@ -23,12 +23,16 @@ jobs:
- ubuntu-latest
- macOS-latest
- windows-latest
include:
- os: windows-latest
tools: 'tools_openssl_x64'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: jurplel/install-qt-action@v3
with:
version: ${{ matrix.qt-version }}
tools: ${{ matrix.tools }}
- name: Build
working-directory: "samples/client/petstore/cpp-qt"
run: ./build-and-test.bash
run: cmake . && cmake --build .

View File

@@ -7,12 +7,14 @@ on:
- 'samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
- 'samples/server/petstore/aspnetcore-6.0-useSwashBuckle/**'
pull_request:
paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
- 'samples/server/petstore/aspnetcore-6.0-useSwashBuckle/**'
jobs:
build:
name: Build .Net projects
@@ -30,6 +32,7 @@ jobs:
- samples/server/petstore/aspnetcore-6.0
- samples/server/petstore/aspnetcore-6.0-pocoModels
- samples/server/petstore/aspnetcore-6.0-project4Models
- samples/server/petstore/aspnetcore-6.0-useSwashBuckle
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.0.3

View File

@@ -15,14 +15,14 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.4.0`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.6.0`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
[7.0.x](https://github.com/OpenAPITools/openapi-generator/tree/7.0.x) (`7.0.x`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/7.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=7.0.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/7.0.x?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
@@ -120,9 +120,9 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | Feb/Mar 2023 | Major release with breaking changes (no fallback) |
| 6.4.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.4.0-SNAPSHOT/) | 05.12.2022 | Minor release with breaking changes (with fallback) |
| [6.3.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.3.0) (latest stable release) | 01.02.2023 | Minor release with breaking changes (with fallback) |
| 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | May/Jun 2023 | Major release with breaking changes (no fallback) |
| 6.6.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.5.0-SNAPSHOT/) | 28.04.2023 | Minor release with breaking changes (with fallback) |
| [6.5.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.5.0) (latest stable release) | 01.04.2023 | Minor release with breaking changes (with fallback) |
| [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) |
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
@@ -182,16 +182,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -430,7 +430,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 6.3.0
openapi-generator-cli version-manager set 6.5.0
```
Or install it as dev-dependency:
@@ -454,7 +454,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
<!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar)
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar)
<!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
@@ -893,6 +893,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2022-04-06 - [Effective Software Development using OpenAPI Generator](https://apexlabs.ai/post/openapi-generator) by Ajil Oommen (Senior Flutter Developer)
- 2022-05-13 - [A Path From an API To Client Libraries](https://www.youtube.com/watch?v=XC8oVn_efTw) by [Filip Srnec](https://www.devoxx.co.uk/talk/?id=11211) at Infobip
- 2022-06-01 - [API First, using OpenAPI and Spring Boot](https://medium.com/xgeeks/api-first-using-openapi-and-spring-boot-2602c04bb0d3) by [Micael Estrázulas Vianna](https://estrazulas.medium.com/)
- 2022-06-12 - [Mustache templates with OpenAPI specs](https://medium.com/geekculture/mustache-templates-with-openapi-specs-f24711c67dec) by [Beppe Catanese](https://github.com/gcatanese)
- 2022-07-01 - [Generate API contract using OpenAPI Generator Maven plugin](https://huongdanjava.com/generate-api-contract-using-openapi-generator-maven-plugin.html) by [Khanh Nguyen](https://huongdanjava.com/)
- 2022-07-22 - [使用OpenAPI Generator Maven plugin开发api优先的java客户端和服务端代码](https://blog.roccoshi.top/2022/java/openapi-generator%E7%9A%84%E4%BD%BF%E7%94%A8/) by [Lincest](https://github.com/Lincest)
- 2022-08-01 - [Tutorial: Etsy Open API v3 (ruby)](https://blog.tjoyal.dev/etsy-open-api-v3/) by [Thierry Joyal](https://github.com/tjoyal)
@@ -904,6 +905,10 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2022-12-13 - [API-First with Spring WebFlux and OpenAPI Generator](https://boottechnologies-ci.medium.com/api-first-with-spring-webflux-and-openapi-generator-38b7804c4ed4) by [Eric Anicet](https://boottechnologies-ci.medium.com/)
- 2023-01-06 - [Major Improvements with Helidon and OpenAPI](https://medium.com/helidon/major-improvements-with-helidon-and-openapi-f76a0951508e) by [Tim Quinn](https://medium.com/@tquinno600)
- 2023-02-02 - [Replacing Postman with the Jetbrains HTTP Client](https://lengrand.fr/replacing-postman-in-seconds-with-the-jetbrains-http-client/) by [julien Lengrand-Lambert](https://github.com/jlengrand)
- 2023-03-15 - [OpenAPI Generatorに適したOpenAPIの書き方](https://techblog.zozo.com/entry/how-to-write-openapi-for-openapi-generator) by [ZOZO Tech Blog](https://techblog.zozo.com/)
- 2023-03-19 - [EXOGEM: Extending OpenAPI Generator for Monitoring of RESTful APIs](https://link.springer.com/chapter/10.1007/978-3-031-26507-5_10) by Daniel Friis Holtebo, Jannik Lucas Sommer, Magnus Mølgaard Lund, Alessandro Tibo, Junior Dongo & Michele Albano at "ICSOC 2022: Service-Oriented Computing ICSOC 2022 Workshops"
- 2023-03-28 - [API-First Design with OpenAPI Generator](https://www.linkedin.com/pulse/api-first-design-openapi-generator-jonathan-manera/) by [Jonathan Manera](https://www.linkedin.com/in/manerajona/)
- 2023-03-28 - [ハンズオンで学ぶサーバーサイド KotlinSpring Boot&Arrow&OpenAPI Generatorv1.0.1](https://zenn.dev/msksgm/books/implementing-server-side-kotlin-development) by [msk](https://zenn.dev/msksgm)
## [6 - About Us](#table-of-contents)
@@ -1031,6 +1036,7 @@ Here is a list of template creators:
* Erlang Server: @galaxie
* F# (Giraffe) Server: @nmfisher
* Go Server: @guohuang
* Go Server (refactored in 7.0.0): @lwj5
* Go (Echo) Server: @ph4r5h4d
* Go (Gin) Server: @kemokemo
* GraphQL Express Server: @renepardon
@@ -1135,7 +1141,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Elm | @eriktim (2018/09) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| F# | @nmfisher (2019/05) |
| Go | @antihax (2017/11) @grokify (2018/07) @kemokemo (2018/09) @jirikuncar (2021/01) @ph4r5h4d (2021/04) |
| Go | @antihax (2017/11) @grokify (2018/07) @kemokemo (2018/09) @jirikuncar (2021/01) @ph4r5h4d (2021/04) @lwj5 (2023/04) |
| GraphQL | @renepardon (2018/12) |
| Groovy | |
| Haskell | |
@@ -1245,3 +1251,4 @@ See the License for the specific language governing permissions and
limitations under the License.
---

View File

@@ -0,0 +1,11 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-6.0-useSwashBuckle
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'
aspnetCoreVersion: "6.0"
userSecretsGuid: 'cb87e868-8646-48ef-9bb6-344b537d0d37'
useSwashBuckle: false
buildTarget: library
isLibrary: true

View File

@@ -5,4 +5,4 @@ templateDir: modules/openapi-generator/src/main/resources/python-nextgen
library: asyncio
additionalProperties:
packageName: petstore_api
floatStrictType: false
mapNumberTo: float

View File

@@ -6,3 +6,4 @@ additionalProperties:
packageName: petstore_api
useOneOfDiscriminatorLookup: "true"
disallowAdditionalPropertiesIfNotPresent: false
mapNumberTo: StrictFloat

View File

@@ -216,7 +216,7 @@ These options default to true and don't limit the generation of the feature opti
When using selective generation, _only_ the templates needed for the specific generation will be used.
To skip models defined as the form parameters in "requestBody", please use `skipFormModel` (default to `true`) (this option is introduced at v3.2.2 and `true` by default starting from v5.x).
To skip models defined as the form parameters in "requestBody", please use `skipFormModel` (default to `true`) (this option is introduced at v3.2.2 and `true` by default starting from v5.0.0).
```sh
--global-property skipFormModel=true

View File

@@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/groovy|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -96,6 +96,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|

View File

@@ -62,6 +62,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useAbstractClass|Whether to generate abstract classes for REST API instead of interfaces.| |false|
|useBeanValidation|Use Bean Validation| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -67,6 +67,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -85,6 +85,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|Client service name| |null|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
|visitable|Generate visitor for subtypes with a discriminator| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -84,6 +84,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useAuth|Whether to import authorization and to annotate controller methods accordingly| |true|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
|visitable|Generate visitor for subtypes with a discriminator| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |null|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|zipkinUri|Zipkin URI| |null|

View File

@@ -75,6 +75,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useInterfaces|Makes the controllerImp implements an interface to facilitate automatic completion when updating from version x to y of your spec| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSwaggerUI|Add a route to /api which show your documentation in swagger-ui. Will also import needed dependencies| |true|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|wrapCalls|Add a wrapper to each controller function to handle things like metrics, response modification, etc..| |true|

View File

@@ -67,6 +67,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -67,6 +67,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -69,6 +69,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|vertxSwaggerRouterVersion|Specify the version of the swagger router library| |null|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -87,6 +87,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useGzipFeature|Send gzip-encoded requests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|
|useReflectionEqualsHashCode|Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact.| |false|
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey, jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|

View File

@@ -78,6 +78,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useGzipFeatureForTests|Use Gzip Feature for tests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -90,6 +90,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useLoggingFeature|Use Logging Feature| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|useMultipartFeature|Use Multipart Feature| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSpringAnnotationConfig|Use Spring Annotation Config| |false|
|useSwaggerFeature|Use Swagger Feature| |false|
|useSwaggerUI|Use Swagger UI| |false|

View File

@@ -85,6 +85,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useLoggingFeature|Use Logging Feature| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|useMultipartFeature|Use Multipart Feature| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSpringAnnotationConfig|Use Spring Annotation Config| |false|
|useSwaggerFeature|Use Swagger Feature| |false|
|useSwaggerUI|Use Swagger UI| |false|

View File

@@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSwaggerFeature|Use dynamic Swagger generator| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -78,6 +78,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -22,10 +22,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|dateFormat|date format for query parameters| |%Y-%m-%d|
|datetimeFormat|datetime format for query parameters| |%Y-%m-%dT%H:%M:%S%z|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|floatStrictType|Use strict type for float, i.e. StrictFloat or confloat(strict=true, ...)| |true|
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3| |urllib3|
|mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]|
|packageName|python package name (convention: snake_case).| |openapi_client|
|packageUrl|python package URL.| |null|
|packageVersion|python package version.| |1.0.0|
@@ -50,6 +50,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>Dict</li>
<li>List</li>
<li>bool</li>
<li>bytearray</li>
<li>bytes</li>
<li>date</li>
<li>datetime</li>
@@ -58,6 +59,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>float</li>
<li>int</li>
<li>list</li>
<li>none_type</li>
<li>object</li>
<li>str</li>
</ul>

View File

@@ -89,6 +89,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|

View File

@@ -21,6 +21,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumNameSuffix|Suffix that will be appended to all enum names.| |Enum|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |PascalCase|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)| |Buffer|
|framework|Specify the framework which should be used in the client code.|<dl><dt>**fetch-api**</dt><dd>fetch-api</dd><dt>**jquery**</dt><dd>jquery</dd></dl>|fetch-api|
@@ -30,6 +32,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|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|
|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false|
|paramNaming|Naming convention for parameters: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|platform|Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.|<dl><dt>**browser**</dt><dd>browser</dd><dt>**node**</dt><dd>node</dd><dt>**deno**</dt><dd>deno</dd></dl>|browser|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
@@ -67,11 +71,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>Long</li>
<li>Map</li>
<li>Object</li>
<li>ReadonlyArray</li>
<li>Set</li>
<li>String</li>
<li>any</li>
<li>boolean</li>
<li>number</li>
<li>object</li>
<li>string</li>
</ul>
@@ -156,7 +162,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath||ToolingExtension
|BasePath||ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
@@ -201,7 +207,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme||ToolingExtension
|Readme||ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
@@ -221,7 +227,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks||OAS3
|Callbacks||OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
@@ -250,14 +256,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth||OAS2,OAS3
|ApiKey||OAS2,OAS3
|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
|BearerToken||OAS3
|OAuth2_Implicit||OAS2,OAS3
|OAuth2_Password||OAS2,OAS3
|OAuth2_ClientCredentials||OAS2,OAS3
|OAuth2_AuthorizationCode||OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |

View File

@@ -91,19 +91,19 @@ This gives access to the following tasks:
| ---- | ----------- |
| openApiGenerate | Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents. |
| openApiGenerators | Lists generators available via Open API Generators. |
| openApiMeta | Generates a new generator to be consumed via Open API Generator. |
| openApiMeta | Generates a new generator to be consumed via Open API Generator. |
| openApiValidate | Validates an Open API 2.0 or 3.x specification document. |
> The plugin implements the above tasks as project extensions of the same name. If youd like to declare these tasks as dependencies to other tasks (using `dependsOn`), youll need a task reference. e.g.:
> ```groovy
> compileJava.dependsOn tasks.openApiGenerate
> compileJava.dependsOn tasks.named("openApiGenerate")
> ```
For full details of all options, see the [plugin README](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-gradle-plugin).
### Example
An example task for generating a kotlin client:
An example openApiGenerate task configuration for generating a kotlin client:
```groovy
openApiGenerate {
@@ -113,8 +113,10 @@ openApiGenerate {
apiPackage = "org.openapi.example.api"
invokerPackage = "org.openapi.example.invoker"
modelPackage = "org.openapi.example.model"
configOptions = [
configOptions.putAll([
dateLibrary: "java8"
]
])
}
```
*If you want to create separate tasks (for example when you have more than one api spec and require different parameters for each), this is how to do so in Gradle 7+: `tasks.register('taskName', org.openapitools.generator.gradle.plugin.tasks.GenerateTask) { ... }`.*

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -6,7 +6,7 @@
<artifactId>openapi-generator-project</artifactId>
<groupId>org.openapitools</groupId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=6.5.0
openApiGeneratorVersion=6.6.0-SNAPSHOT
# /RELEASE_VERSION
# BEGIN placeholders

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -1,3 +1,3 @@
# RELEASE_VERSION
openApiGeneratorVersion=6.5.0
openApiGeneratorVersion=6.6.0-SNAPSHOT
# /RELEASE_VERSION

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -15,7 +15,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -19,7 +19,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<dependencies>
<dependency>

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -20,7 +20,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -5,7 +5,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>6.5.0</version>
<version>6.6.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -421,7 +421,8 @@ public class OpenAPINormalizer {
}
for (Map.Entry<String, Schema> propertiesEntry : properties.entrySet()) {
Schema property = propertiesEntry.getValue();
normalizeSchema(property, visitedSchemas);
Schema newProperty = normalizeSchema(property, visitedSchemas);
propertiesEntry.setValue(newProperty);
}
}
@@ -514,6 +515,10 @@ public class OpenAPINormalizer {
return;
}
if (schema.getAllOf() == null) {
return;
}
for (Object item : schema.getAllOf()) {
if (!(item instanceof Schema)) {
throw new RuntimeException("Error! allOf schema is not of the type Schema: " + item);
@@ -598,7 +603,7 @@ public class OpenAPINormalizer {
/**
* If the schema is anyOf and the sub-schemas are either string or enum of string,
* then simplify it to just string as many generators do not yet support anyOf.
* then simplify it to just enum of string as many generators do not yet support anyOf.
*
* @param schema Schema
* @return Schema
@@ -624,12 +629,12 @@ public class OpenAPINormalizer {
s0 = ModelUtils.getReferencedSchema(openAPI, s0);
s1 = ModelUtils.getReferencedSchema(openAPI, s1);
// find the string schema (not enum)
// find the string schema (enum)
if (s0 instanceof StringSchema && s1 instanceof StringSchema) {
if (((StringSchema) s0).getEnum() != null) { // s0 is enum, s1 is string
result = (StringSchema) s1;
} else if (((StringSchema) s1).getEnum() != null) { // s1 is enum, s0 is string
result = (StringSchema) s0;
} else if (((StringSchema) s1).getEnum() != null) { // s1 is enum, s0 is string
result = (StringSchema) s1;
} else { // both are string
result = schema;
}
@@ -665,7 +670,9 @@ public class OpenAPINormalizer {
if (schema.getOneOf() != null && !schema.getOneOf().isEmpty()) {
for (int i = 0; i < schema.getOneOf().size(); i++) {
// convert null sub-schema to `nullable: true`
if (schema.getOneOf().get(i) == null || ((Schema) schema.getOneOf().get(i)).getType() == null) {
if (schema.getOneOf().get(i) == null ||
(((Schema) schema.getOneOf().get(i)).getType() == null &&
((Schema) schema.getOneOf().get(i)).get$ref() == null)) {
schema.getOneOf().remove(i);
schema.setNullable(true);
continue;
@@ -709,7 +716,9 @@ public class OpenAPINormalizer {
if (schema.getAnyOf() != null && !schema.getAnyOf().isEmpty()) {
for (int i = 0; i < schema.getAnyOf().size(); i++) {
// convert null sub-schema to `nullable: true`
if (schema.getAnyOf().get(i) == null || ((Schema) schema.getAnyOf().get(i)).getType() == null) {
if (schema.getAnyOf().get(i) == null ||
(((Schema) schema.getAnyOf().get(i)).getType() == null &&
((Schema) schema.getAnyOf().get(i)).get$ref() == null)) {
schema.getAnyOf().remove(i);
schema.setNullable(true);
continue;
@@ -728,7 +737,7 @@ public class OpenAPINormalizer {
// if only one element left, simplify to just the element (schema)
if (schema.getAnyOf().size() == 1) {
if (schema.getNullable()) { // retain nullable setting
if (Boolean.TRUE.equals(schema.getNullable())) { // retain nullable setting
((Schema) schema.getAnyOf().get(0)).setNullable(true);
}
return (Schema) schema.getAnyOf().get(0);

View File

@@ -145,8 +145,6 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
"float32", "float64")
);
importMapping = new HashMap<>();
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Go package name (convention: lowercase).")
.defaultValue("openapi"));
@@ -225,7 +223,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
protected boolean isReservedWord(String word) {
return word != null && reservedWords.contains(word);
return word != null && (reservedWords.contains(word) || reservedWordsMappings().containsKey(word));
}
@Override
@@ -407,7 +405,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String ref = p.get$ref();
String type = null;
String type;
if (ref != null && !ref.isEmpty()) {
type = toModelName(openAPIType);

View File

@@ -88,6 +88,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public static final String CONTAINER_DEFAULT_TO_NULL = "containerDefaultToNull";
public static final String CAMEL_CASE_DOLLAR_SIGN = "camelCaseDollarSign";
public static final String USE_ONE_OF_INTERFACES = "useOneOfInterfaces";
public static final String DEFAULT_TEST_FOLDER = "${project.build.directory}/generated-test-sources/openapi";
@@ -256,6 +257,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
cliOptions.add(CliOption.newBoolean(DISCRIMINATOR_CASE_SENSITIVE, "Whether the discriminator value lookup should be case-sensitive or not. This option only works for Java API client", discriminatorCaseSensitive));
cliOptions.add(CliOption.newBoolean(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC, this.isHideGenerationTimestamp()));
cliOptions.add(CliOption.newBoolean(WITH_XML, "whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)"));
cliOptions.add(CliOption.newBoolean(USE_ONE_OF_INTERFACES, "whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface"));
CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use").defaultValue(this.getDateLibrary());
Map<String, String> dateOptions = new HashMap<>();
@@ -574,6 +576,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.setCamelCaseDollarSign(Boolean.parseBoolean(additionalProperties.get(CAMEL_CASE_DOLLAR_SIGN).toString()));
}
if (additionalProperties.containsKey(USE_ONE_OF_INTERFACES)) {
this.setUseOneOfInterfaces(Boolean.parseBoolean(additionalProperties.get(USE_ONE_OF_INTERFACES).toString()));
}
if (!StringUtils.isEmpty(parentGroupId) && !StringUtils.isEmpty(parentArtifactId) && !StringUtils.isEmpty(parentVersion)) {
additionalProperties.put("parentOverridden", true);
}

View File

@@ -25,10 +25,10 @@ import io.swagger.v3.oas.models.parameters.Parameter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.openapitools.codegen.*;
import org.openapitools.codegen.CodegenConstants.ENUM_PROPERTY_NAMING_TYPE;
import org.openapitools.codegen.CodegenConstants.MODEL_PROPERTY_NAMING_TYPE;
import org.openapitools.codegen.CodegenConstants.PARAM_NAMING_TYPE;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
@@ -46,7 +46,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.*;
import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.form;
import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.simple;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -392,10 +393,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
setParamNaming((String) additionalProperties.get(CodegenConstants.PARAM_NAMING));
}
if (additionalProperties.containsKey(CodegenConstants.SUPPORTS_ES6)) {
setSupportsES6(Boolean.valueOf(additionalProperties.get(CodegenConstants.SUPPORTS_ES6).toString()));
additionalProperties.put("supportsES6", getSupportsES6());
}
setSupportsES6(convertPropertyToBooleanAndWriteBack(CodegenConstants.SUPPORTS_ES6));
if (additionalProperties.containsKey(NULL_SAFE_ADDITIONAL_PROPS)) {
setNullSafeAdditionalProps(Boolean.valueOf(additionalProperties.get(NULL_SAFE_ADDITIONAL_PROPS).toString()));
@@ -612,6 +610,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
} else if (ModelUtils.isBinarySchema(p)) {
return "ArrayBuffer";
}
return super.getTypeDeclaration(p);
}
@@ -839,7 +838,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
if ("number".equals(datatype) || "boolean".equals(datatype)) {
return value;
} else {
return "\'" + escapeText(value) + "\'";
return "'" + escapeText(value) + "'";
}
}
@@ -887,7 +886,8 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
public String toEnumName(CodegenProperty property) {
String enumName = property.name;
enumName = addSuffix(enumName, enumSuffix);
return toTypescriptTypeName(enumName, "_");
String tsName = toTypescriptTypeName(enumName, "_");
return tsName;
}
protected void setEnumPropertyNaming(String naming) {
@@ -964,6 +964,40 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
return objs;
}
/**
* Update datatypeWithEnum for array container
*
* @param property Codegen property
*/
protected void updateDataTypeWithEnumForArray(CodegenProperty property) {
CodegenProperty baseItem = property.items;
while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap)
|| Boolean.TRUE.equals(baseItem.isArray))) {
baseItem = baseItem.items;
}
if (baseItem != null) {
/*
* Note: There are cases where we have datatypeWithEnum == Array<{ [key: string]: string}
* In these cases, we then have Array <{ [key: EnumName]: EnumName}> - which is invalid typescript
* To protect agains this we first replace [key: string] with a special/reserved placeholder (i.e. *[key]* )
*/
property.datatypeWithEnum = property.datatypeWithEnum.replace("[key: string]", "*PLACEHOLDER*")
.replace(baseItem.baseType, toEnumName(baseItem))
.replace("*PLACEHOLDER*", "[key: string]");
// naming the enum with respect to the language enum naming convention
// e.g. remove [], {} from array/map of enum
property.enumName = toEnumName(property);
// set default value for variable with inner enum
if (property.defaultValue != null) {
property.defaultValue = property.defaultValue.replace(baseItem.baseType, toEnumName(baseItem));
}
updateCodegenPropertyEnum(property);
}
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> result = super.postProcessAllModels(objs);

View File

@@ -375,18 +375,26 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
});
});
final boolean includeTime =
anyOperationResponse(ops, response -> response.isDate || response.isDateTime) ||
anyOperationParam(ops, param -> param.isDate || param.isDateTime);
final boolean includeUuid =
anyOperationResponse(ops, response -> response.isUuid) ||
anyOperationParam(ops, param -> param.isUuid);
final boolean includeTime = anyOperationResponse(ops, response -> response.isDate || response.isDateTime) ||
anyOperationParam(ops, param -> (param.isDate || param.isDateTime) || itemsIncludesType(param.items, p -> p.isDate || p.isDateTime));
final boolean includeUuid = anyOperationResponse(ops, response -> response.isUuid) ||
anyOperationParam(ops, param -> param.isUuid || itemsIncludesType(param.items, p -> p.isUuid));
operations.put("includeTime", includeTime);
operations.put("includeUuid", includeUuid);
return operations;
}
private static boolean itemsIncludesType(CodegenProperty p, Predicate<CodegenProperty> condition) {
if (p == null)
return false;
if (p.items != null)
return itemsIncludesType(p.items, condition);
return condition.test(p);
}
static class ParameterSorter implements Comparator<CodegenParameter> {
public int compare(final CodegenParameter p1, final CodegenParameter p2) {
return index(p1) - index(p2);

View File

@@ -47,18 +47,18 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
public static final String PACKAGE_URL = "packageUrl";
public static final String DEFAULT_LIBRARY = "urllib3";
public static final String RECURSION_LIMIT = "recursionLimit";
public static final String FLOAT_STRICT_TYPE = "floatStrictType";
public static final String DATETIME_FORMAT = "datetimeFormat";
public static final String DATE_FORMAT = "dateFormat";
public static final String MAP_NUMBER_TO = "mapNumberTo";
protected String packageUrl;
protected String apiDocPath = "docs" + File.separator;
protected String modelDocPath = "docs" + File.separator;
protected boolean hasModelsToImport = Boolean.FALSE;
protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
protected boolean floatStrictType = true;
protected String datetimeFormat = "%Y-%m-%dT%H:%M:%S.%f%z";
protected String dateFormat = "%Y-%m-%d";
protected String mapNumberTo = "Union[StrictFloat, StrictInt]";
protected Map<Character, String> regexModifiers;
@@ -120,6 +120,8 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
languageSpecificPrimitives.remove("file");
languageSpecificPrimitives.add("decimal.Decimal");
languageSpecificPrimitives.add("bytearray");
languageSpecificPrimitives.add("none_type");
supportsInheritance = true;
modelPackage = "models";
@@ -177,8 +179,8 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
cliOptions.add(new CliOption(CodegenConstants.SOURCECODEONLY_GENERATION, CodegenConstants.SOURCECODEONLY_GENERATION_DESC)
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(RECURSION_LIMIT, "Set the recursion limit. If not set, use the system default value."));
cliOptions.add(new CliOption(FLOAT_STRICT_TYPE, "Use strict type for float, i.e. StrictFloat or confloat(strict=true, ...)")
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(MAP_NUMBER_TO, "Map number to Union[StrictFloat, StrictInt], StrictStr or float.")
.defaultValue("Union[StrictFloat, StrictInt]"));
cliOptions.add(new CliOption(DATETIME_FORMAT, "datetime format for query parameters")
.defaultValue("%Y-%m-%dT%H:%M:%S%z"));
cliOptions.add(new CliOption(DATE_FORMAT, "date format for query parameters")
@@ -281,8 +283,8 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
additionalProperties.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, useOneOfDiscriminatorLookup);
}
if (additionalProperties.containsKey(FLOAT_STRICT_TYPE)) {
setFloatStrictType(convertPropertyToBooleanAndWriteBack(FLOAT_STRICT_TYPE));
if (additionalProperties.containsKey(MAP_NUMBER_TO)) {
setMapNumberTo(String.valueOf(additionalProperties.get(MAP_NUMBER_TO)));
}
if (additionalProperties.containsKey(DATETIME_FORMAT)) {
@@ -478,34 +480,59 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
} else if (cp.isNumber || cp.isFloat || cp.isDouble) {
if (cp.hasValidation) {
List<String> fieldCustomization = new ArrayList<>();
List<String> intFieldCustomization = new ArrayList<>();
// e.g. confloat(ge=10, le=100, strict=True)
if (cp.getMaximum() != null) {
if (cp.getExclusiveMaximum()) {
fieldCustomization.add("gt=" + cp.getMaximum());
fieldCustomization.add("lt=" + cp.getMaximum());
intFieldCustomization.add("lt=" + Math.ceil(Double.valueOf(cp.getMaximum()))); // e.g. < 7.59 becomes < 8
} else {
fieldCustomization.add("ge=" + cp.getMaximum());
fieldCustomization.add("le=" + cp.getMaximum());
intFieldCustomization.add("le=" + Math.floor(Double.valueOf(cp.getMaximum()))); // e.g. <= 7.59 becomes <= 7
}
}
if (cp.getMinimum() != null) {
if (cp.getExclusiveMinimum()) {
fieldCustomization.add("lt=" + cp.getMinimum());
fieldCustomization.add("gt=" + cp.getMinimum());
intFieldCustomization.add("gt=" + Math.floor(Double.valueOf(cp.getMinimum()))); // e.g. > 7.59 becomes > 7
} else {
fieldCustomization.add("le=" + cp.getMinimum());
fieldCustomization.add("ge=" + cp.getMinimum());
intFieldCustomization.add("ge=" + Math.ceil(Double.valueOf(cp.getMinimum()))); // e.g. >= 7.59 becomes >= 8
}
}
if (cp.getMultipleOf() != null) {
fieldCustomization.add("multiple_of=" + cp.getMultipleOf());
}
if (floatStrictType) {
if ("Union[StrictFloat, StrictInt]".equals(mapNumberTo)) {
fieldCustomization.add("strict=True");
intFieldCustomization.add("strict=True");
pydanticImports.add("confloat");
pydanticImports.add("conint");
typingImports.add("Union");
return String.format(Locale.ROOT, "Union[%s(%s), %s(%s)]", "confloat",
StringUtils.join(fieldCustomization, ", "),
"conint",
StringUtils.join(intFieldCustomization, ", ")
);
} else if ("StrictFloat".equals(mapNumberTo)) {
fieldCustomization.add("strict=True");
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
} else { // float
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
}
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
} else {
if (floatStrictType) {
if ("Union[StrictFloat, StrictInt]".equals(mapNumberTo)) {
typingImports.add("Union");
pydanticImports.add("StrictFloat");
pydanticImports.add("StrictInt");
return "Union[StrictFloat, StrictInt]";
} else if ("StrictFloat".equals(mapNumberTo)) {
pydanticImports.add("StrictFloat");
return "StrictFloat";
} else {
@@ -723,34 +750,59 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
} else if (cp.isNumber || cp.isFloat || cp.isDouble) {
if (cp.hasValidation) {
List<String> fieldCustomization = new ArrayList<>();
List<String> intFieldCustomization = new ArrayList<>();
// e.g. confloat(ge=10, le=100, strict=True)
if (cp.getMaximum() != null) {
if (cp.getExclusiveMaximum()) {
fieldCustomization.add("lt=" + cp.getMaximum());
intFieldCustomization.add("lt=" + (int) Math.ceil(Double.valueOf(cp.getMaximum()))); // e.g. < 7.59 => < 8
} else {
fieldCustomization.add("le=" + cp.getMaximum());
intFieldCustomization.add("le=" + (int) Math.floor(Double.valueOf(cp.getMaximum()))); // e.g. <= 7.59 => <= 7
}
}
if (cp.getMinimum() != null) {
if (cp.getExclusiveMinimum()) {
fieldCustomization.add("gt=" + cp.getMinimum());
intFieldCustomization.add("gt=" + (int) Math.floor(Double.valueOf(cp.getMinimum()))); // e.g. > 7.59 => > 7
} else {
fieldCustomization.add("ge=" + cp.getMinimum());
intFieldCustomization.add("ge=" + (int) Math.ceil(Double.valueOf(cp.getMinimum()))); // e.g. >= 7.59 => >= 8
}
}
if (cp.getMultipleOf() != null) {
fieldCustomization.add("multiple_of=" + cp.getMultipleOf());
}
if (floatStrictType) {
if ("Union[StrictFloat, StrictInt]".equals(mapNumberTo)) {
fieldCustomization.add("strict=True");
intFieldCustomization.add("strict=True");
pydanticImports.add("confloat");
pydanticImports.add("conint");
typingImports.add("Union");
return String.format(Locale.ROOT, "Union[%s(%s), %s(%s)]", "confloat",
StringUtils.join(fieldCustomization, ", "),
"conint",
StringUtils.join(intFieldCustomization, ", ")
);
} else if ("StrictFloat".equals(mapNumberTo)) {
fieldCustomization.add("strict=True");
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
} else { // float
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
}
pydanticImports.add("confloat");
return String.format(Locale.ROOT, "%s(%s)", "confloat",
StringUtils.join(fieldCustomization, ", "));
} else {
if (floatStrictType) {
if ("Union[StrictFloat, StrictInt]".equals(mapNumberTo)) {
typingImports.add("Union");
pydanticImports.add("StrictFloat");
pydanticImports.add("StrictInt");
return "Union[StrictFloat, StrictInt]";
} else if ("StrictFloat".equals(mapNumberTo)) {
pydanticImports.add("StrictFloat");
return "StrictFloat";
} else {
@@ -1334,8 +1386,8 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
}
}
vendorExtensions.put("x-regex", regex.replace("\"","\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"","\\\""));
vendorExtensions.put("x-regex", regex.replace("\"", "\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\""));
vendorExtensions.put("x-modifiers", modifiers);
}
}
@@ -1529,8 +1581,14 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
return "var_" + name;
}
public void setFloatStrictType(boolean floatStrictType) {
this.floatStrictType = floatStrictType;
public void setMapNumberTo(String mapNumberTo) {
if ("Union[StrictFloat, StrictInt]".equals(mapNumberTo)
|| "StrictFloat".equals(mapNumberTo)
|| "float".equals(mapNumberTo)) {
this.mapNumberTo = mapNumberTo;
} else {
throw new IllegalArgumentException("mapNumberTo value must be Union[StrictFloat, StrictInt], StrictStr or float");
}
}
public void setDatetimeFormat(String datetimeFormat) {

View File

@@ -17,17 +17,12 @@
package org.openapitools.codegen.languages;
import com.github.curiousoddman.rgxgen.RgxGen;
import com.google.common.collect.Sets;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
@@ -40,42 +35,30 @@ import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.curiousoddman.rgxgen.RgxGen;
import com.github.curiousoddman.rgxgen.config.RgxGenOption;
import com.github.curiousoddman.rgxgen.config.RgxGenProperties;
import java.io.File;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.OnceLogger.once;
public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(TypeScriptClientCodegen.class);
private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value";
private static final String UNDEFINED_VALUE = "undefined";
private static final String FRAMEWORK_SWITCH = "framework";
private static final String FRAMEWORK_SWITCH_DESC = "Specify the framework which should be used in the client code.";
private static final String[] FRAMEWORKS = { "fetch-api", "jquery" };
private static final String[] FRAMEWORKS = {"fetch-api", "jquery"};
private static final String PLATFORM_SWITCH = "platform";
private static final String PLATFORM_SWITCH_DESC = "Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.";
private static final String[] PLATFORMS = { "browser", "node", "deno" };
private static final String[] PLATFORMS = {"browser", "node", "deno"};
private static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension";
private static final String IMPORT_FILE_EXTENSION_SWITCH_DESC = "File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.";
private static final String FILE_CONTENT_DATA_TYPE= "fileContentDataType";
private static final String FILE_CONTENT_DATA_TYPE = "fileContentDataType";
private static final String FILE_CONTENT_DATA_TYPE_DESC = "Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)";
private static final String USE_RXJS_SWITCH = "useRxJS";
private static final String USE_RXJS_SWITCH_DESC = "Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.";
@@ -85,27 +68,17 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
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.";
private final Map<String, String> frameworkToHttpLibMap;
// NPM Options
private static final String SNAPSHOT = "snapshot";
@SuppressWarnings("squid:S5164")
protected static final ThreadLocal<SimpleDateFormat> SNAPSHOT_SUFFIX_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT));
private static final String NPM_REPOSITORY = "npmRepository";
private static final String NPM_NAME = "npmName";
private static final String NPM_VERSION = "npmVersion";
// NPM Option Values
protected String npmRepository = null;
protected String snapshot = null;
protected String npmName = null;
protected String npmVersion = "1.0.0";
protected String modelPropertyNaming = "camelCase";
protected HashSet<String> languageGenericTypes;
private DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
private DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
private final DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
private final DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
public TypeScriptClientCodegen() {
super();
@@ -114,88 +87,23 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
this.frameworkToHttpLibMap.put("fetch-api", "isomorphic-fetch");
this.frameworkToHttpLibMap.put("jquery", "jquery");
this.generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build();
outputFolder = "generated-code" + File.separator + "typescript";
embeddedTemplateDir = templateDir = "typescript";
supportsInheritance = true;
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(Arrays.asList(
// local variable names used in API methods (endpoints)
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
"requestOptions", "from",
"from",
// Typescript reserved words
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "constructor", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
"constructor"));
languageSpecificPrimitives = new HashSet<>(Arrays.asList(
"string",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object",
"Array",
"Date",
"number",
"any",
"File",
"Error",
"Map",
"Set"
));
languageGenericTypes = new HashSet<>(Arrays.asList(
"Array"
));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("map", "any");
typeMapping.put("Set", "Set");
typeMapping.put("set", "Set");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "Date");
typeMapping.put("binary", "any");
typeMapping.put("File", "any");
typeMapping.put("file", "any");
typeMapping.put("ByteArray", "string");
typeMapping.put("UUID", "string");
typeMapping.put("Error", "Error");
typeMapping.put("AnyType", "any");
cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." +
" Required to generate a full package"));
cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. If not provided, using the version from the OpenAPI specification file.").defaultValue(this.getNpmVersion()));
cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json"));
cliOptions.add(CliOption.newBoolean(SNAPSHOT,
"When setting this property to true, the version will be suffixed with -SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.get().toPattern(),
false));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
cliOptions.add(new CliOption(CodegenConstants.SUPPORTS_ES6, CodegenConstants.SUPPORTS_ES6_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE, TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE_DESC).defaultValue("Buffer"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
@@ -203,20 +111,23 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
for (String option : TypeScriptClientCodegen.FRAMEWORKS) {
frameworkOption.addEnum(option, option);
}
frameworkOption.defaultValue(FRAMEWORKS[0]);
cliOptions.add(frameworkOption);
CliOption platformOption = new CliOption(TypeScriptClientCodegen.PLATFORM_SWITCH, TypeScriptClientCodegen.PLATFORM_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.PLATFORMS) {
for (String option : TypeScriptClientCodegen.PLATFORMS) {
platformOption.addEnum(option, option);
}
platformOption.defaultValue(PLATFORMS[0]);
cliOptions.add(platformOption);
// Set property naming to camelCase
supportModelPropertyNaming(CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.camelCase);
// Git
supportingFiles.add(new SupportingFile(".gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
@@ -274,42 +185,12 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
this.npmVersion = npmVersion;
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
if (additionalProperties.containsKey(NPM_NAME)) {
// If no npmVersion is provided in additional properties, version from API specification is used.
// If none of them is provided then fallbacks to default version
if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
} else if (openAPI.getInfo() != null && openAPI.getInfo().getVersion() != null) {
this.setNpmVersion(openAPI.getInfo().getVersion());
}
if (additionalProperties.containsKey(SNAPSHOT) && Boolean.parseBoolean(additionalProperties.get(SNAPSHOT).toString())) {
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
} else {
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
}
}
additionalProperties.put(NPM_VERSION, npmVersion);
}
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
final Object propFramework = additionalProperties.get(FRAMEWORK_SWITCH);
Map<String, Boolean> frameworks = new HashMap<>();
for (String framework: FRAMEWORKS) {
for (String framework : FRAMEWORKS) {
frameworks.put(framework, framework.equals(propFramework));
}
objs.put("framework", propFramework);
@@ -331,7 +212,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
OperationMap operationsMap = operations.getOperations();
List<CodegenOperation> operationList = operationsMap.getOperation();
for (CodegenOperation operation: operationList) {
for (CodegenOperation operation : operationList) {
List<CodegenResponse> responses = operation.responses;
operation.returnType = this.getReturnType(responses);
}
@@ -340,12 +221,13 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
/**
* Returns the correct return type based on all 2xx HTTP responses defined for an operation.
*
* @param responses all CodegenResponses defined for one operation
* @return TypeScript return type
*/
private String getReturnType(List<CodegenResponse> responses) {
Set<String> returnTypes = new HashSet<>();
for (CodegenResponse response: responses) {
for (CodegenResponse response : responses) {
if (response.is2xx) {
if (response.dataType != null) {
returnTypes.add(response.dataType);
@@ -362,18 +244,21 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return String.join(" | ", returnTypes);
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
// sanitize name
name = sanitizeName(name);
if ("_".equals(name)) {
name = "_u";
}
// if it's all upper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
return super.toParamName(name);
}
@Override
@@ -390,22 +275,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return name;
}
name = getNameUsingModelPropertyNaming(name);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toModelName(final String name) {
String fullModelName = name;
fullModelName = addPrefix(fullModelName, modelNamePrefix);
fullModelName = addSuffix(fullModelName, modelNameSuffix);
return toTypescriptTypeName(fullModelName, "Model");
return super.toVarName(name);
}
@Override
@@ -414,283 +284,12 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return "../" + modelPackage() + "/" + toModelName(name);
}
protected String addPrefix(String name, String prefix) {
if (!StringUtils.isEmpty(prefix)) {
name = prefix + "_" + name;
}
return name;
}
protected String addSuffix(String name, String suffix) {
if (!StringUtils.isEmpty(suffix)) {
name = name + "_" + suffix;
}
return name;
}
protected String toTypescriptTypeName(final String name, String safePrefix) {
ArrayList<String> exceptions = new ArrayList<>(Arrays.asList("\\|", " "));
String sanName = sanitizeName(name, "(?![| ])\\W", exceptions);
sanName = camelize(sanName);
// model name cannot use reserved keyword, e.g. return
// this is unlikely to happen, because we have just camelized the name, while reserved words are usually all lowercase
if (isReservedWord(sanName)) {
String modelName = safePrefix + sanName;
LOGGER.warn("{} (reserved word) cannot be used as model name. Renamed to {}", sanName, modelName);
return modelName;
}
// model name starts with number
if (sanName.matches("^\\d.*")) {
String modelName = safePrefix + sanName; // e.g. 200Response => Model200Response
LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", sanName,
modelName);
return modelName;
}
if (languageSpecificPrimitives.contains(sanName)) {
String modelName = safePrefix + sanName;
LOGGER.warn("{} (model name matches existing language type) cannot be used as a model name. Renamed to {}",
sanName, modelName);
return modelName;
}
return sanName;
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
protected String getParameterDataType(Parameter parameter, Schema p) {
// handle enums of various data types
Schema inner;
if (ModelUtils.isArraySchema(p)) {
ArraySchema mp1 = (ArraySchema) p;
inner = mp1.getItems();
return this.getSchemaType(p) + "<" + this.getParameterDataType(parameter, inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = (Schema) p.getAdditionalProperties();
return "{ [key: string]: " + this.getParameterDataType(parameter, inner) + "; }";
} else if (ModelUtils.isStringSchema(p)) {
// Handle string enums
if (p.getEnum() != null) {
return enumValuesToEnumTypeUnion(p.getEnum(), "string");
}
} else if (ModelUtils.isIntegerSchema(p)) {
// Handle integer enums
if (p.getEnum() != null) {
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
}
} else if (ModelUtils.isNumberSchema(p)) {
// Handle double enums
if (p.getEnum() != null) {
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
}
}
return this.getTypeDeclaration(p);
}
/**
* Converts a list of strings to a literal union for representing enum values as a type.
* Example output: 'available' | 'pending' | 'sold'
*
* @param values list of allowed enum values
* @param dataType either "string" or "number"
* @return a literal union for representing enum values as a type
*/
protected String enumValuesToEnumTypeUnion(List<String> values, String dataType) {
StringBuilder b = new StringBuilder();
boolean isFirst = true;
for (String value : values) {
if (!isFirst) {
b.append(" | ");
}
b.append(toEnumValue(value, dataType));
isFirst = false;
}
return b.toString();
}
/**
* Converts a list of numbers to a literal union for representing enum values as a type.
* Example output: 3 | 9 | 55
*
* @param values a list of numbers
* @return a literal union for representing enum values as a type
*/
protected String numericEnumValuesToEnumTypeUnion(List<Number> values) {
List<String> stringValues = new ArrayList<>();
for (Number value : values) {
stringValues.add(value.toString());
}
return enumValuesToEnumTypeUnion(stringValues, "number");
}
@Override
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isDateSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isDateTimeSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
return "'" + (String) p.getDefault() + "'";
}
return UNDEFINED_VALUE;
} else {
return UNDEFINED_VALUE;
}
}
@Override
protected boolean isReservedWord(String word) {
// NOTE: This differs from super's implementation in that TypeScript does _not_ want case insensitive matching.
return reservedWords.contains(word);
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String type = null;
if (ModelUtils.isComposedSchema(p)) {
return openAPIType;
} else if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = openAPIType;
return toModelName(type);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
// append _ at the beginning, e.g. _return
if (isReservedWord(operationId)) {
return escapeReservedWord(camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER));
}
return camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);
}
public void setModelPropertyNaming(String naming) {
if ("original".equals(naming) || "camelCase".equals(naming) ||
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
this.modelPropertyNaming = naming;
} else {
throw new IllegalArgumentException("Invalid model property naming '" +
naming + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}
public String getModelPropertyNaming() {
return this.modelPropertyNaming;
}
public String getNameUsingModelPropertyNaming(String name) {
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
case original:
return name;
case camelCase:
return camelize(name, LOWERCASE_FIRST_LETTER);
case PascalCase:
return camelize(name);
case snake_case:
return underscore(name);
default:
throw new IllegalArgumentException("Invalid model property naming '" +
name + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}
@Override
public String toEnumValue(String value, String datatype) {
if ("number".equals(datatype)) {
return value;
} else {
return "\'" + escapeText(value) + "\'";
}
}
@Override
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "_" + value;
}
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return camelize(getSymbolName(name));
}
// number
if ("number".equals(datatype)) {
String varName = "NUMBER_" + name;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String enumName = sanitizeName(name);
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
// camelize the enum variable name
// ref: https://basarat.gitbooks.io/typescript/content/docs/enums.html
enumName = camelize(enumName);
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
@Override
public String toEnumName(CodegenProperty property) {
String enumName = toModelName(property.name) + "Enum";
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
return "'" + escapeText(value) + "'";
}
}
@@ -704,13 +303,15 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) {
if (Boolean.TRUE.equals(var.isEnum)) {
String replaceName = var.isInnerEnum ? "Inner" + super.enumSuffix : var.enumName;
var.datatypeWithEnum = var.datatypeWithEnum.replace(replaceName, var.enumName);
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + var.enumName);
}
}
if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum
var.datatypeWithEnum = var.datatypeWithEnum
.replace(var.enumName, cm.classname + var.enumName);
}
}
@@ -738,53 +339,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return tsImports;
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> result = super.postProcessAllModels(objs);
for (ModelsMap entry : result.values()) {
for (ModelMap mo : entry.getModels()) {
CodegenModel cm = mo.getModel();
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
this.setDiscriminatorValue(child, cm.discriminator.getPropertyName(), this.getDiscriminatorValue(child));
}
}
}
}
return result;
}
private void setDiscriminatorValue(CodegenModel model, String baseName, String value) {
for (CodegenProperty prop : model.allVars) {
if (prop.baseName.equals(baseName)) {
prop.discriminatorValue = value;
}
}
if (model.children != null) {
final boolean newDiscriminator = model.discriminator != null;
for (CodegenModel child : model.children) {
this.setDiscriminatorValue(child, baseName, newDiscriminator ? value : this.getDiscriminatorValue(child));
}
}
}
private String getDiscriminatorValue(CodegenModel model) {
return model.vendorExtensions.containsKey(X_DISCRIMINATOR_TYPE) ?
(String) model.vendorExtensions.get(X_DISCRIMINATOR_TYPE) : model.classname;
}
@Override
public String escapeQuotationMark(String input) {
// remove ', " to avoid code injection
return input.replace("\"", "").replace("'", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String getName() {
return "typescript";
@@ -795,17 +349,10 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return "Generates a TypeScript client library using Fetch API (beta).";
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
convertPropertyToBooleanAndWriteBack(CodegenConstants.SUPPORTS_ES6);
// change package names
apiPackage = this.apiPackage + ".apis";
testPackage = this.testPackage + ".tests";
@@ -815,8 +362,8 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
String httpLibName = this.getHttpLibForFramework(additionalProperties.get(FRAMEWORK_SWITCH).toString());
supportingFiles.add(new SupportingFile(
"http" + File.separator + httpLibName + ".mustache",
"http", httpLibName + ".ts"
"http" + File.separator + httpLibName + ".mustache",
"http", httpLibName + ".ts"
));
Object propPlatform = additionalProperties.get(PLATFORM_SWITCH);
@@ -826,7 +373,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
}
Map<String, Boolean> platforms = new HashMap<>();
for (String platform: PLATFORMS) {
for (String platform : PLATFORMS) {
platforms.put(platform, platform.equals(propPlatform));
}
additionalProperties.put("platforms", platforms);
@@ -861,14 +408,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
}
// NPM Settings
if (additionalProperties.containsKey(NPM_NAME)) {
setNpmName(additionalProperties.get(NPM_NAME).toString());
}
if (additionalProperties.containsKey(NPM_VERSION)) {
setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
}
if (additionalProperties.containsKey(NPM_REPOSITORY)) {
setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}
@@ -885,8 +424,8 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
if (ModelUtils.isArraySchema(p)) {
inner = ((ArraySchema) p).getItems();
return this.getSchemaType(p) + "<" + this.getTypeDeclaration(unaliasSchema(inner)) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = getSchemaAdditionalProperties(p);
} else if (ModelUtils.isMapSchema(p)) { // it is an object schema
inner = getSchemaAdditionalProperties(p); // additional properties?
String postfix = "";
if (Boolean.TRUE.equals(inner.getNullable())) {
postfix = " | null";
@@ -1396,9 +935,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return example;
}
/***
*
* Set the codegenParameter example value
* We have a custom version of this function so we can invoke toExampleValue
*
@@ -1489,64 +1026,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
return cp;
}
@Override
public String toAnyOfName(List<String> names, ComposedSchema composedSchema) {
List<String> types = getTypesFromSchemas(composedSchema.getAnyOf());
return String.join(" | ", types);
}
@Override
public String toOneOfName(List<String> names, ComposedSchema composedSchema) {
List<String> types = getTypesFromSchemas(composedSchema.getOneOf());
return String.join(" | ", types);
}
@Override
public String toAllOfName(List<String> names, ComposedSchema composedSchema) {
List<String> types = getTypesFromSchemas(composedSchema.getAllOf());
return String.join(" & ", types);
}
/**
* Extracts the list of type names from a list of schemas.
* Excludes `AnyType` if there are other valid types extracted.
*
* @param schemas list of schemas
* @return list of types
*/
protected List<String> getTypesFromSchemas(List<Schema> schemas) {
List<Schema> filteredSchemas = schemas.size() > 1
? schemas.stream().filter(schema -> !"AnyType".equals(super.getSchemaType(schema))).collect(Collectors.toList())
: schemas;
return filteredSchemas.stream().map(schema -> {
String schemaType = getSchemaType(schema);
if (ModelUtils.isArraySchema(schema)) {
ArraySchema ap = (ArraySchema) schema;
Schema inner = ap.getItems();
schemaType = schemaType + "<" + getSchemaType(inner) + ">";
}
return schemaType;
}).distinct().collect(Collectors.toList());
}
@Override
protected void addImport(CodegenModel m, String type) {
if (type == null) {
return;
}
String[] parts = splitComposedType(type);
for (String s : parts) {
if (needToImport(s)) {
m.imports.add(s);
}
}
}
@Override
protected void addImport(Set<String> importsToBeAddedTo, String type) {
if (type == null) {
@@ -1567,9 +1046,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
* @return list of types
*/
protected String[] splitComposedType(String type) {
return type.replace(" ","").split("[|&<>]");
return type.replace(" ", "").split("[|&<>]");
}
@Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.TYPESCRIPT; }
}

View File

@@ -1362,14 +1362,6 @@ public class ModelUtils {
}
}
if (refedWithoutDiscriminator.size() == 1 && hasAmbiguousParents) {
// allOf with a single $ref (no discriminator)
// TODO to be removed in 5.x or 6.x release
LOGGER.info("[deprecated] inheritance without use of 'discriminator.propertyName' has been deprecated" +
" in the 5.x release. Composed schema name: {}. Title: {}",
composedSchema.getName(), composedSchema.getTitle());
}
return null;
}

View File

@@ -4,6 +4,8 @@ package {{invokerPackage}};
{{>generatedAnnotation}}
public class Configuration {
public static final String VERSION = "{{{artifactVersion}}}";
private static ApiClient defaultApiClient = new ApiClient();
/**

View File

@@ -990,7 +990,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
File file = (File) param.getValue();
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
.fileName(file.getName()).size(file.length()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));

View File

@@ -990,7 +990,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
File file = (File) param.getValue();
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
.fileName(file.getName()).size(file.length()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));

View File

@@ -20,8 +20,8 @@ import io.smallrye.mutiny.Uni;
{{/microprofileMutiny}}
{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
import {{rootJavaEEPackage}}.validation.constraints.*;
import {{rootJavaEEPackage}}.validation.Valid;
{{/useBeanValidation}}
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;

View File

@@ -267,6 +267,23 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{/vars}}
{{>libraries/native/additional_properties}}
{{#parent}}
{{#allVars}}
{{#isOverridden}}
@Override
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
{{#vendorExtensions.x-is-jackson-optional-nullable}}
this.{{setter}}(JsonNullable.<{{{datatypeWithEnum}}}>of({{name}}));
{{/vendorExtensions.x-is-jackson-optional-nullable}}
{{^vendorExtensions.x-is-jackson-optional-nullable}}
this.{{setter}}({{name}});
{{/vendorExtensions.x-is-jackson-optional-nullable}}
return this;
}
{{/isOverridden}}
{{/allVars}}
{{/parent}}
/**
* Return true if this {{name}} object is equal to o.
*/

View File

@@ -6,6 +6,7 @@ import io.vertx.core.json.JsonObject;
import java.util.Objects;
public class Configuration {
public static final String VERSION = "{{{artifactVersion}}}";
private static ApiClient defaultApiClient = null;

View File

@@ -32,7 +32,7 @@ ext {
swagger_annotations_version = "1.5.21"
jackson_version = "2.13.4"
jackson_databind_version = "2.13.4.2"
vertx_version = "3.4.2"
vertx_version = "3.5.2"
junit_version = "4.13.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.6"

View File

@@ -292,7 +292,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<vertx-version>3.4.2</vertx-version>
<vertx-version>3.5.2</vertx-version>
<swagger-annotations-version>1.6.6</swagger-annotations-version>
<jackson-version>2.13.4</jackson-version>
<jackson-databind>2.13.4.2</jackson-databind>

View File

@@ -11,7 +11,9 @@ using Newtonsoft.Json;
{{#model}}
{{#discriminator}}
using JsonSubTypes;
{{#useSwashbuckle}}
using Swashbuckle.AspNetCore.Annotations;
{{/useSwashbuckle}}
{{/discriminator}}
{{/model}}
{{/models}}
@@ -27,10 +29,14 @@ namespace {{modelPackage}}
[DataContract]
{{#discriminator}}
[JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")]
{{#useSwashbuckle}}
[SwaggerDiscriminator("{{{discriminatorName}}}")]
{{/useSwashbuckle}}
{{#mappedModels}}
[JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{^vendorExtensions.x-discriminator-value}}{{{mappingName}}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{.}}}{{/vendorExtensions.x-discriminator-value}}")]
{{#useSwashbuckle}}
[SwaggerSubType(typeof({{{modelName}}}), DiscriminatorValue = "{{^vendorExtensions.x-discriminator-value}}{{{mappingName}}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{.}}}{{/vendorExtensions.x-discriminator-value}}")]
{{/useSwashbuckle}}
{{/mappedModels}}
{{/discriminator}}
public {{#modelClassModifier}}{{.}} {{/modelClassModifier}}class {{classname}} {{#parent}}: {{{.}}}{{^pocoModels}}, {{/pocoModels}}{{/parent}}{{^pocoModels}}{{^parent}}: {{/parent}}IEquatable<{{classname}}>{{/pocoModels}}

View File

@@ -2,39 +2,53 @@ cmake_minimum_required(VERSION 3.2)
project({{{packageName}}})
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network Gui)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network Gui)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
file(GLOB_RECURSE HEADER_FILES "*.h")
file(GLOB_RECURSE SOURCE_FILES "*.cpp")
add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
target_compile_options(${PROJECT_NAME}
PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wno-unused-variable>
)
add_library(${PROJECT_NAME}
{{#models}}
{{#model}}
{{classname}}.h
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{classname}}.h
{{/operations}}
{{/apis}}
{{/apiInfo}}
{{prefix}}Helpers.h
{{prefix}}HttpRequest.h
{{prefix}}Object.h
{{prefix}}Enum.h
{{prefix}}HttpFileElement.h
{{prefix}}ServerConfiguration.h
{{prefix}}ServerVariable.h
{{prefix}}Oauth.h
{{#models}}
{{#model}}
{{classname}}.cpp
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{classname}}.cpp
{{/operations}}
{{/apis}}
{{/apiInfo}}
{{prefix}}Helpers.cpp
{{prefix}}HttpRequest.cpp
{{prefix}}HttpFileElement.cpp
{{prefix}}Oauth.cpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
@@ -48,11 +62,6 @@ target_link_libraries(${PROJECT_NAME}
${ZLIB_LIBRARIES}{{/contentCompression}}
)
if(NOT APPLE)
find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ssl crypto)
endif()
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"

View File

@@ -225,7 +225,7 @@ bool fromStringValue(const QString &inStr, QByteArray &value) {
} else {
value.clear();
value.append(inStr.toUtf8());
return value.count() > 0;
return value.size() > 0;
}
}

View File

@@ -11,7 +11,7 @@ public class {{unrealModuleName}} : ModuleRules
new string[]
{
"Core",
"Http",
"HTTP",
"Json",
}
);

View File

@@ -172,11 +172,16 @@ void {{classname}}::{{operationIdCamelCase}}Request::SetupHttpRequest(const FHtt
HttpRequest->SetContentAsString(JsonBody);
{{/bodyParams.0}}
{{^bodyParams.0}}
// Form parameters
{{#formParams.0}}
// Form parameters added to try to generate a json body when no body parameters are specified.
FString JsonBody;
JsonWriter Writer = TJsonWriterFactory<>::Create(&JsonBody);
Writer->WriteObjectStart();
{{#formParams}}
{{#isFile}}
UE_LOG(Log{{unrealModuleName}}, Error, TEXT("Form parameter ({{baseName}}) was ignored, Files are not supported in json body"));
{{/isFile}}
{{^isFile}}
{{#required}}
Writer->WriteIdentifierPrefix(TEXT("{{baseName}}"));
WriteJsonValue(Writer, {{paramName}});
@@ -187,11 +192,13 @@ void {{classname}}::{{operationIdCamelCase}}Request::SetupHttpRequest(const FHtt
WriteJsonValue(Writer, {{paramName}}.GetValue());
}
{{/required}}
{{/isFile}}
{{/formParams}}
Writer->WriteObjectEnd();
Writer->Close();
HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));
HttpRequest->SetContentAsString(JsonBody);
{{/formParams.0}}
{{/bodyParams.0}}
}
else if (Consumes.Contains(TEXT("multipart/form-data")))

View File

@@ -94,12 +94,18 @@ FString Base64UrlEncode(const T& Value)
return Base64String;
}
template<typename T>
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline FStringFormatArg ToStringFormatArg(const T& Value)
{
return FStringFormatArg(Value);
}
template<typename T, typename std::enable_if<std::is_base_of<Model, T>::value, int>::type = 0>
inline FStringFormatArg ToStringFormatArg(const T& EnumModelValue)
{
return FStringFormatArg(T::EnumToString(EnumModelValue.Value));
}
inline FStringFormatArg ToStringFormatArg(const FDateTime& Value)
{
return FStringFormatArg(Value.ToIso8601());

View File

@@ -42,7 +42,7 @@ namespace {{packageName}}.Client
/// <returns>Filename</returns>
public static string SanitizeFilename(string filename)
{
Match match = Regex.Match(filename, @".*[/\\](.*)$");
Match match = Regex.Match(filename, ".*[/\\](.*)$");
return match.Success ? match.Groups[1].Value : filename;
}

View File

@@ -96,7 +96,7 @@ namespace {{packageName}}.{{clientPackage}}
/// <returns>Filename</returns>
public static string SanitizeFilename(string filename)
{
Match match = Regex.Match(filename, @".*[/\\](.*)$");
Match match = Regex.Match(filename, ".*[/\\](.*)$");
return match.Success ? match.Groups[1].Value : filename;
}

View File

@@ -310,6 +310,7 @@
{{/readOnlyVars}}
{{#validatable}}
{{^parentModel}}
{{>validatable}}
{{/parentModel}}
{{/validatable}}

View File

@@ -4,7 +4,7 @@
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
public IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> Validate(ValidationContext validationContext)
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
return this.BaseValidate(validationContext);
}
@@ -23,7 +23,7 @@
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
public IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> Validate(ValidationContext validationContext)
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
{{/discriminator}}
{{#parent}}
@@ -74,7 +74,7 @@
{{#pattern}}
{{^isByteArray}}
// {{{name}}} ({{{dataType}}}) pattern
Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
Regex regex{{{name}}} = new Regex("{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
if (false == regex{{{name}}}.Match(this.{{{name}}}{{#isUuid}}.ToString(){{/isUuid}}).Success)
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" });

View File

@@ -89,6 +89,27 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{/hasQueryParams}}
{{#allParams}}
{{#isPathParam}}
{{#isNumber}}
{{paramName}}Param, err := parseFloat32Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isNumber}}
{{#isFloat}}
{{paramName}}Param, err := parseFloat32Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isFloat}}
{{#isDouble}}
{{paramName}}Param, err := parseFloat64Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isDouble}}
{{#isLong}}
{{paramName}}Param, err := parseInt64Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
@@ -103,12 +124,40 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
return
}
{{/isInteger}}
{{^isNumber}}
{{^isFloat}}
{{^isDouble}}
{{^isLong}}
{{^isInteger}}
{{paramName}}Param := {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}
{{/isInteger}}{{/isLong}}
{{/isInteger}}
{{/isLong}}
{{/isDouble}}
{{/isFloat}}
{{/isNumber}}
{{/isPathParam}}
{{#isQueryParam}}
{{#isNumber}}
{{paramName}}Param, err := parseFloat32Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isNumber}}
{{#isFloat}}
{{paramName}}Param, err := parseFloat32Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isFloat}}
{{#isDouble}}
{{paramName}}Param, err := parseFloat64Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isDouble}}
{{#isLong}}
{{paramName}}Param, err := parseInt64Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
@@ -131,6 +180,27 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
}
{{/isBoolean}}
{{#isArray}}
{{#items.isNumber}}
{{paramName}}Param, err := parseFloat32ArrayParameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/items.isNumber}}
{{#items.isFloat}}
{{paramName}}Param, err := parseFloat32ArrayParameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/items.isFloat}}
{{#items.isDouble}}
{{paramName}}Param, err := parseFloat64ArrayParameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/items.isDouble}}
{{#items.isLong}}
{{paramName}}Param, err := parseInt64ArrayParameter(query.Get("{{baseName}}"), ",", {{required}})
if err != nil {
@@ -145,12 +215,21 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
return
}
{{/items.isInteger}}
{{^items.isNumber}}
{{^items.isFloat}}
{{^items.isDouble}}
{{^items.isLong}}
{{^items.isInteger}}
{{paramName}}Param := strings.Split(query.Get("{{baseName}}"), ",")
{{/items.isInteger}}
{{/items.isLong}}
{{/items.isDouble}}
{{/items.isFloat}}
{{/items.isNumber}}
{{/isArray}}
{{^isNumber}}
{{^isFloat}}
{{^isDouble}}
{{^isLong}}
{{^isInteger}}
{{^isBoolean}}
@@ -160,6 +239,9 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{/isBoolean}}
{{/isInteger}}
{{/isLong}}
{{/isDouble}}
{{/isFloat}}
{{/isNumber}}
{{/isQueryParam}}
{{#isFormParam}}
{{#isFile}}{{#isArray}}

View File

@@ -171,8 +171,8 @@ func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error
return file, nil
}
// parseInt64Parameter parses a string parameter to an int64.
func parseInt64Parameter(param string, required bool) (int64, error) {
// parseFloatParameter parses a string parameter to an int64.
func parseFloatParameter(param string, bitSize int, required bool) (float64, error) {
if param == "" {
if required {
return 0, errors.New(errMsgRequiredMissing)
@@ -181,25 +181,42 @@ func parseInt64Parameter(param string, required bool) (int64, error) {
return 0, nil
}
return strconv.ParseInt(param, 10, 64)
return strconv.ParseFloat(param, bitSize)
}
// parseFloat64Parameter parses a string parameter to an float64.
func parseFloat64Parameter(param string, required bool) (float64, error) {
return parseFloatParameter(param, 64, required)
}
// parseFloat32Parameter parses a string parameter to an float32.
func parseFloat32Parameter(param string, required bool) (float32, error) {
val, err := parseFloatParameter(param, 32, required)
return float32(val), err
}
// parseIntParameter parses a string parameter to an int64.
func parseIntParameter(param string, bitSize int, required bool) (int64, error) {
if param == "" {
if required {
return 0, errors.New(errMsgRequiredMissing)
}
return 0, nil
}
return strconv.ParseInt(param, 10, bitSize)
}
// parseInt64Parameter parses a string parameter to an int64.
func parseInt64Parameter(param string, required bool) (int64, error) {
return parseIntParameter(param, 64, required)
}
// parseInt32Parameter parses a string parameter to an int32.
func parseInt32Parameter(param string, required bool) (int32, error) {
if param == "" {
if required {
return 0, errors.New(errMsgRequiredMissing)
}
return 0, nil
}
val, err := strconv.ParseInt(param, 10, 32)
if err != nil {
return -1, err
}
return int32(val), nil
val, err := parseIntParameter(param, 32, required)
return int32(val), err
}
// parseBoolParameter parses a string parameter to a bool
@@ -220,6 +237,55 @@ func parseBoolParameter(param string, required bool) (bool, error) {
return bool(val), nil
}
// parseFloat64ArrayParameter parses a string parameter containing array of values to []Float64.
func parseFloat64ArrayParameter(param, delim string, required bool) ([]float64, error) {
if param == "" {
if required {
return nil, errors.New(errMsgRequiredMissing)
}
return nil, nil
}
str := strings.Split(param, delim)
floats := make([]float64, len(str))
for i, s := range str {
if v, err := strconv.ParseFloat(s, 64); err != nil {
return nil, err
} else {
floats[i] = v
}
}
return floats, nil
}
// parseFloat32ArrayParameter parses a string parameter containing array of values to []float32.
func parseFloat32ArrayParameter(param, delim string, required bool) ([]float32, error) {
if param == "" {
if required {
return nil, errors.New(errMsgRequiredMissing)
}
return nil, nil
}
str := strings.Split(param, delim)
floats := make([]float32, len(str))
for i, s := range str {
if v, err := strconv.ParseFloat(s, 32); err != nil {
return nil, err
} else {
floats[i] = float32(v)
}
}
return floats, nil
}
// parseInt64ArrayParameter parses a string parameter containing array of values to []int64.
func parseInt64ArrayParameter(param, delim string, required bool) ([]int64, error) {
if param == "" {

View File

@@ -725,16 +725,17 @@ func formatErrorMessage(status string, v interface{}) string {
str := ""
metaValue := reflect.ValueOf(v).Elem()
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
if metaValue.Kind() == reflect.Struct {
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
// status title (detail)
return strings.TrimSpace(fmt.Sprintf("%s %s", status, str))
}

View File

@@ -256,7 +256,7 @@ public class ApiClient {
{{#jsonb}}
defaultWebClientBuilder.addMediaSupport(jsonbConfig == null
? JsonbSupport.create()
: JsonbSupport.create(jsonbConfig));
: JsonbSupport.create(JsonbBuilder.create(jsonbConfig)));
{{/jsonb}}
{{#jackson}}
defaultWebClientBuilder.addMediaSupport(objectMapper == null

View File

@@ -54,6 +54,10 @@
<groupId>{{x-helidon-rootJavaEEDepPrefix}}.json.bind</groupId>
<artifactId>{{x-helidon-rootJavaEEDepPrefix}}.json.bind-api</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.media</groupId>
<artifactId>helidon-media-jsonb</artifactId>
</dependency>
{{/jsonb}}
<dependency>
<groupId>org.junit.jupiter</groupId>

View File

@@ -29,7 +29,7 @@
<version.logback>1.2.0</version.logback>
<version.junit>4.13.2</version.junit>
<version.mockito>2.1.0-beta.124</version.mockito>
<version.undertow>2.2.19.Final</version.undertow>
<version.undertow>2.2.24.Final</version.undertow>
<version.jsonpath>2.2.0</version.jsonpath>
<version.httpclient>4.5.13</version.httpclient>
<version.httpasyncclient>4.1.2</version.httpasyncclient>

View File

@@ -2,7 +2,7 @@
name = "{{{packageName}}}"
version = "{{{packageVersion}}}"
description = "{{{appName}}}"
authors = ["{{infoEmail}}{{^infoEmail}}team@openapitools.org{{/infoEmail}}"]
authors = ["{{infoName}}{{^infoName}}OpenAPI Generator Community{{/infoName}} <{{infoEmail}}{{^infoEmail}}team@openapitools.org{{/infoEmail}}>"]
license = "{{{licenseInfo}}}{{^licenseInfo}}NoLicense{{/licenseInfo}}"
readme = "README.md"
repository = "https://github.com/{{{gitRepoId}}}/{{{gitUserId}}}"
@@ -23,14 +23,15 @@ tornado = ">=4.2,<5"
pem = ">= 19.3.0"
pycryptodome = ">= 3.9.0"
{{/hasHttpSignatureMethods}}
pydantic = ">= 1.10.5"
pydantic = "^1.10.5"
aenum = ">=3.1.11"
[tool.poetry.dev-dependencies]
pytest = ">=7.2.1"
tox = ">=4.4.6"
flake8 = ">=6.0.0"
tox = ">=3.9.0"
flake8 = ">=4.0.0"
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

View File

@@ -1,7 +1,7 @@
python_dateutil >= 2.5.3
setuptools >= 21.0.0
urllib3 >= 1.25.3
pydantic >= 1.10.2
pydantic >= 1.10.5, < 2
aenum >= 3.1.11
{{#asyncio}}
aiohttp >= 3.0.0

View File

@@ -29,7 +29,7 @@ REQUIRES = [
"pem>=19.3.0",
"pycryptodome>=3.9.0",
{{/hasHttpSignatureMethods}}
"pydantic",
"pydantic >= 1.10.5, < 2",
"aenum"
]

View File

@@ -38,7 +38,7 @@ require 'json'
{{/required}}{{/allParams}} # @return [{{{returnType}}}{{^returnType}}nil{{/returnType}}]
describe '{{operationId}} test' do
it 'should work' do
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
end
end

View File

@@ -24,14 +24,14 @@ describe {{moduleName}}::{{classname}} do
describe 'test attribute "{{{name}}}"' do
it 'should work' do
{{#isEnum}}
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
# validator = Petstore::EnumTest::EnumAttributeValidator.new('{{{dataType}}}', [{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}])
# validator.allowable_values.each do |value|
# expect { instance.{{name}} = value }.not_to raise_error
# end
{{/isEnum}}
{{^isEnum}}
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
{{/isEnum}}
end
end

View File

@@ -21,7 +21,7 @@ extension {{projectName}}API {
{{#description}}
/** {{{.}}} */{{/description}}
{{#objcCompatible}}@objc {{/objcCompatible}}{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class {{classname}}{{#objcCompatible}} : NSObject{{/objcCompatible}} {
{{#objcCompatible}}@objcMembers {{/objcCompatible}}{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class {{classname}}{{#objcCompatible}} : NSObject{{/objcCompatible}} {
{{#operation}}
{{#allParams}}
{{#isEnum}}

View File

@@ -1,5 +1,5 @@
{{^objcCompatible}}{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} {{#useClasses}}final class{{/useClasses}}{{^useClasses}}struct{{/useClasses}} {{{classname}}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable{{#useJsonEncodable}}, JSONEncodable{{/useJsonEncodable}}{{/useVapor}}{{#vendorExtensions.x-swift-hashable}}, Hashable{{/vendorExtensions.x-swift-hashable}} {
{{/objcCompatible}}{{#objcCompatible}}@objc {{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} class {{classname}}: NSObject, Codable{{#useJsonEncodable}}, JSONEncodable{{/useJsonEncodable}} {
{{/objcCompatible}}{{#objcCompatible}}@objcMembers {{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} class {{classname}}: NSObject, Codable{{#useJsonEncodable}}, JSONEncodable{{/useJsonEncodable}} {
{{/objcCompatible}}
{{#allVars}}

View File

@@ -1,4 +1,4 @@
public enum {{classname}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable, JSONEncodable{{#vendorExtensions.x-swift-hashable}}, Hashable{{/vendorExtensions.x-swift-hashable}}{{/useVapor}} {
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum {{classname}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable, JSONEncodable{{#vendorExtensions.x-swift-hashable}}, Hashable{{/vendorExtensions.x-swift-hashable}}{{/useVapor}} {
{{#oneOf}}
case type{{.}}({{.}})
{{/oneOf}}

View File

@@ -79,7 +79,9 @@ export class ObjectSerializer {
return expectedType; // the type does not have a discriminator. use it.
} else {
if (data[discriminatorProperty]) {
var discriminatorType = data[discriminatorProperty];
var discriminatorValue = data[discriminatorProperty];
// if it has a mapping we need to map from discriminatorvalue to the actual type name
var discriminatorType = data.discriminatorTypeMap[discriminatorValue] || discriminatorValue;
if(typeMap[discriminatorType]){
return discriminatorType; // use the type given in the discriminator
} else {

View File

@@ -24,6 +24,11 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
{{#discriminator}}
static readonly discriminator: string | undefined = "{{discriminatorName}}";
static readonly discriminatorTypeMap = {
{{#mappedModels}}
"{{mappingName}}": "{{modelName}}"{{^-last}},{{/-last}}
{{/mappedModels}}
}
{{/discriminator}}
{{^discriminator}}
static readonly discriminator: string | undefined = undefined;
@@ -35,7 +40,7 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
{
"name": "{{name}}",
"baseName": "{{baseName}}",
"type": "{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}",
"type": "{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}}",
"format": "{{dataFormat}}"
}{{^-last}},
{{/-last}}
@@ -61,9 +66,14 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
this.{{name}} = "{{discriminatorValue}}";
{{/discriminatorValue}}
{{/allVars}}
{{#discriminatorName}}
{{#discriminator}}
{{^hasDiscriminatorWithNonEmptyMapping}}
{{#discriminatorName}}
this.{{discriminatorName}} = "{{classname}}";
{{/discriminatorName}}
{{/discriminatorName}}
{{/hasDiscriminatorWithNonEmptyMapping}}
{{/discriminator}}
}
}

View File

@@ -132,6 +132,7 @@ public class OpenAPINormalizerTest {
Schema schema3 = openAPI.getComponents().getSchemas().get("AnyOfTest");
assertNull(schema3.getAnyOf());
assertTrue(schema3 instanceof StringSchema);
assertTrue(schema3.getEnum().size() > 0);
}
@Test
@@ -151,6 +152,9 @@ public class OpenAPINormalizerTest {
assertEquals(schema5.getOneOf().size(), 3);
assertNull(schema5.getNullable());
Schema schema7 = openAPI.getComponents().getSchemas().get("Parent");
assertEquals(((Schema) schema7.getProperties().get("number")).getAnyOf().size(), 1);
Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
@@ -168,6 +172,9 @@ public class OpenAPINormalizerTest {
Schema schema6 = openAPI.getComponents().getSchemas().get("OneOfNullableTest");
assertEquals(schema6.getOneOf().size(), 2);
assertTrue(schema6.getNullable());
Schema schema8 = openAPI.getComponents().getSchemas().get("Parent");
assertEquals(((Schema) schema8.getProperties().get("number")).get$ref(), "#/components/schemas/Number");
}
@Test

View File

@@ -0,0 +1,109 @@
/*
* 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.elm;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.DateTimeSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.UUIDSchema;
import io.swagger.v3.oas.models.parameters.QueryParameter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.languages.ElmClientCodegen;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@SuppressWarnings("static-method")
public class ElmClientCodegenTest {
@DataProvider(name = "recursive-lists-of-uuid")
private static Schema[] recursiveListOfUuids() {
return recursiveListOfType(new UUIDSchema(), 6);
}
@Test(description = "Operation that takes list of UUID (and recursive lists of UUID) includes import from UUID", dataProvider = "recursive-lists-of-uuid")
public void operationThatTakesListOfListOfUuidImportsUuid(Schema p) throws Exception {
final ElmClientCodegen codegen = new ElmClientCodegen();
Operation operation = new Operation()
.operationId("opId")
.addParametersItem(new QueryParameter().name("listOfUuid").schema(p));
CodegenOperation co = codegen.fromOperation("/some/path", "get", operation, null);
OperationMap operationMap = new OperationMap();
operationMap.setOperation(co);
OperationsMap operationsMap = new OperationsMap();
operationsMap.setOperation(operationMap);
OperationsMap postProcessed = codegen.postProcessOperationsWithModels(operationsMap, Collections.emptyList());
Assert.assertEquals(postProcessed.get("includeUuid"), true);
}
@DataProvider(name = "recursive-lists-of-datetime")
private static Schema[] recursiveListOfDateTime() {
return recursiveListOfType(new DateTimeSchema(), 6);
}
@Test(description = "Operation that takes list of DateTime (and recursive lists of DateTime) includes import from Api.Time", dataProvider = "recursive-lists-of-datetime")
public void operationThatTakesListOfListOfDateTimeImportsApiTime(Schema p) throws Exception {
final ElmClientCodegen codegen = new ElmClientCodegen();
Operation operation = new Operation()
.operationId("opId")
.addParametersItem(new QueryParameter().name("listOfDateTime").schema(p));
CodegenOperation co = codegen.fromOperation("/some/path", "get", operation, null);
OperationMap operationMap = new OperationMap();
operationMap.setOperation(co);
OperationsMap operationsMap = new OperationsMap();
operationsMap.setOperation(operationMap);
OperationsMap postProcessed = codegen.postProcessOperationsWithModels(operationsMap, Collections.emptyList());
Assert.assertEquals(postProcessed.get("includeTime"), true);
}
// HELPERS
private static <TSchema extends Schema> Schema[] recursiveListOfType(TSchema type, int levelsOfRecursion) {
final List<Schema> output = new ArrayList<Schema>();
for (int levels = 0; levels < levelsOfRecursion; ++levels) {
ArraySchema baseSchema = new ArraySchema();
ArraySchema current = baseSchema;
for (int level = 0; level < levels; ++level) {
ArraySchema child = new ArraySchema();
current.items(child);
current = child;
}
current.items(type);
output.add(baseSchema);
}
return output.toArray(new Schema[0]);
}
}

View File

@@ -1954,4 +1954,32 @@ public class JavaClientCodegenTest {
" public Pet petType(String petType) {\n");
}
}
@Test
public void testForJavaNativeClientOverrideSetter() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/allOf_composition_discriminator.yaml", null, new ParseOptions()).getOpenAPI();
JavaClientCodegen codegen = new JavaClientCodegen();
codegen.setOutputDir(output.getAbsolutePath());
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
codegen.setLibrary(JavaClientCodegen.NATIVE);
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/client/model/Cat.java"), " @Override\n" +
" public Cat petType(String petType) {");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/client/model/Pet.java"), " }\n" +
"\n" +
" public Pet petType(String petType) {\n");
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright 2022 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright (c) 2022 Oracle and/or its affiliates
* Copyright 2022, 2023 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright (c) 2022, 2023 Oracle and/or its affiliates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -28,16 +28,20 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.openapitools.codegen.TestUtils.assertFileContains;
import static org.openapitools.codegen.java.assertions.JavaFileAssert.assertThat;
public class JavaHelidonSeClientCodegenTest {
private String outputPath;
private List<File> generatedFiles;
private DefaultGenerator generator;
@BeforeClass
@BeforeMethod
public void setup() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
@@ -45,16 +49,19 @@ public class JavaHelidonSeClientCodegenTest {
System.out.println("Generating java-helidon-client SE project in " + outputPath);
final CodegenConfigurator configurator = new CodegenConfigurator()
final CodegenConfigurator configurator = codegenConfigurator(new HashMap<>());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
generator = new DefaultGenerator();
generator.opts(clientOptInput);
}
private CodegenConfigurator codegenConfigurator(Map<String, Object> additionalProperties) {
return new CodegenConfigurator()
.setGeneratorName("java-helidon-client")
.setLibrary("se")
.setAdditionalProperties(additionalProperties)
.setInputSpec("src/test/resources/3_0/helidon/petstore-no-multipart-for-testing.yaml")
.setOutputDir(outputPath);
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(clientOptInput);
generatedFiles = generator.generate();
}
@DataProvider(name = "fileSuffix")
@@ -67,11 +74,13 @@ public class JavaHelidonSeClientCodegenTest {
@Test
public void testPom() {
generatedFiles = generator.generate();
TestUtils.ensureContainsFile(generatedFiles, new File(outputPath), "pom.xml");
}
@Test(dataProvider = "fileSuffix")
public void testPetApi(String fileSuffix) {
generatedFiles = generator.generate();
assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/client/api/PetApi" + fileSuffix + ".java"))
.assertMethod("addPet", "Pet")
.toFileAssert()
@@ -92,6 +101,7 @@ public class JavaHelidonSeClientCodegenTest {
@Test(dataProvider = "fileSuffix")
public void testStoreApi(String fileSuffix) {
generatedFiles = generator.generate();
assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/client/api/StoreApi" + fileSuffix + ".java"))
.assertMethod("deleteOrder", "String")
.toFileAssert()
@@ -105,6 +115,7 @@ public class JavaHelidonSeClientCodegenTest {
@Test(dataProvider = "fileSuffix")
public void testUserApi(String fileSuffix) {
generatedFiles = generator.generate();
assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/client/api/UserApi" + fileSuffix + ".java"))
.assertMethod("createUser", "User")
.toFileAssert()
@@ -119,4 +130,15 @@ public class JavaHelidonSeClientCodegenTest {
.assertMethod("updateUser", "String", "User")
.toFileAssert();
}
@Test
public void testJsonbSupport() {
Map<String, Object> additionalProperties = new HashMap<>();
additionalProperties.put("serializationLibrary", "jsonb");
final CodegenConfigurator configurator = codegenConfigurator(additionalProperties);
generator.opts(configurator.toClientOptInput()).generate();
assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/client/ApiClient.java"))
.fileContains("JsonbSupport.create(JsonbBuilder.create(jsonbConfig))");
assertFileContains(Paths.get(outputPath ,"pom.xml"), "<artifactId>helidon-media-jsonb</artifactId>");
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright 2022 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright (c) 2022 Oracle and/or its affiliates
* Copyright 2022, 2023 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright (c) 2022, 2023 Oracle and/or its affiliates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@ package org.openapitools.codegen.java.helidon.functional;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.openapitools.codegen.CodegenConstants.SERIALIZATION_LIBRARY;
public class FunctionalHelidonSEClientTest extends FunctionalHelidonClientBase {
@@ -27,4 +30,11 @@ public class FunctionalHelidonSEClientTest extends FunctionalHelidonClientBase {
library("se");
generatorName("java-helidon-client");
}
@Test
void buildJsonbProject() {
inputSpec("src/test/resources/3_0/petstore.yaml");
generate(createConfigurator().addAdditionalProperty(SERIALIZATION_LIBRARY, "jsonb"));
buildAndVerify("target/openapi-java-client.jar");
}
}

View File

@@ -89,7 +89,7 @@ public class TypeScriptAxiosClientCodegenTest {
codegen.additionalProperties().put("npmName", "@openapi/typescript-axios-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.setSupportsES6(true);
codegen.additionalProperties().put("supportsES6", true);
codegen.processOpts();
@@ -104,7 +104,7 @@ public class TypeScriptAxiosClientCodegenTest {
codegen.additionalProperties().put("npmName", "@openapi/typescript-axios-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.setSupportsES6(false);
codegen.additionalProperties().put("supportsES6", false);
codegen.processOpts();

View File

@@ -116,7 +116,7 @@ public class TypeScriptFetchClientCodegenTest {
codegen.additionalProperties().put("npmName", "@openapi/typescript-fetch-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.setSupportsES6(true);
codegen.additionalProperties().put("supportsES6", true);
codegen.processOpts();
@@ -131,7 +131,7 @@ public class TypeScriptFetchClientCodegenTest {
codegen.additionalProperties().put("npmName", "@openapi/typescript-fetch-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.setSupportsES6(false);
codegen.additionalProperties().put("supportsES6", false);
codegen.processOpts();

View File

@@ -752,3 +752,32 @@ components:
type: string
message:
type: string
Dog:
allOf:
- $ref: '#/components/schemas/Animal'
- type: object
properties:
breed:
type: string
Cat:
allOf:
- $ref: '#/components/schemas/Animal'
- type: object
properties:
declawed:
type: boolean
Animal:
type: object
discriminator:
propertyName: className
mapping:
DOG: '#/components/schemas/Dog'
CAT: '#/components/schemas/Cat'
required:
- className
properties:
className:
type: string
color:
type: string
default: red

View File

@@ -516,3 +516,16 @@ components:
format: date-time
description: A date
- $ref: '#/components/schemas/Query'
NumberPropertiesOnly:
type: object
properties:
number:
type: number
float:
type: number
format: float
double:
type: number
format: double
minimum: 0.8
maximum: 50.2

View File

@@ -36,4 +36,11 @@ components:
enum:
- A
- B
SingleAnyOfTest:
description: to test anyOf (enum string only)
anyOf:
- type: string
enum:
- A
- B

View File

@@ -42,4 +42,22 @@ components:
- type: integer
- type: string
- $ref: null
SingleAnyOfTest:
description: to test anyOf (enum string only)
anyOf:
- type: string
enum:
- A
- B
Parent:
type: object
properties:
number:
anyOf:
- $ref: '#/components/schemas/Number'
Number:
enum:
- one
- two
- three
type: string

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