Compare commits

..

21 Commits

Author SHA1 Message Date
William Cheng
3a502aab8d test the new option 2025-09-30 16:41:06 +08:00
William Cheng
fa242fcb46 Merge branch 'master' of https://github.com/ranjanp75/openapi-generator into ranjanp75-master 2025-09-30 16:37:24 +08:00
Beppe Catanese
ddb15d4b9d Delete docs/generators/postman.md (#22044) 2025-09-29 19:01:36 +08:00
Ranjan Prasad
17a184c2b0 Test cases fixes 2025-09-29 05:51:09 +05:30
William Cheng
885ea07b17 Prepare 7.17.0 (#22040)
* Revert "v7.16.0 release"

This reverts commit 31299af0fc.

* prepare 7.17.0-SNAPSHOT

* update doc, samples
2025-09-28 17:25:13 +08:00
William Cheng
c0b72ee970 update readme with 7.16.0 2025-09-28 16:23:38 +08:00
William Cheng
ee76a05def v7.16.0 release (#22039) 2025-09-28 16:01:01 +08:00
William Cheng
30096d63b7 Revert "fix(rust): Add anyOf support to Rust client generator (#21896)" (#22038)
This reverts commit ee40887d47.
2025-09-28 12:23:50 +08:00
Ranjan Prasad
0cee6d9419 Update docs 2025-09-28 05:10:35 +05:30
Ranjan Prasad
b40e4d81b4 Added enumUnknownDefaultCase property to python generator 2025-09-28 04:20:33 +05:30
Yonatan Karp-Rudin
44a3be170f fix(kotlin-spring): add missing constructor parentheses for hashmap models (#22029)
* fix(kotlin-spring): add missing constructor parentheses for hashmap models

This commit fixes a bug in the kotlin-spring generator where models
defined with additionalProperties would result in uncompilable code.
The generated data class was missing the constructor invocation '()'
when inheriting from a map type.

This has been corrected to only add parentheses when the parent is a map.

The existing samples have been regenerated to reflect this change.

* Trigger CI
2025-09-27 22:06:05 +08:00
Linh Tran Tuan
e38f6c0580 [Rust-Axum] Support AnyOf, AllOf (#21948)
* Support AnyOf, AllOf

* Update

* Fix

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update
2025-09-27 16:01:37 +08:00
Viacheslav Zavoruev
2afac1aa28 [typescript-axios]: withSeparateModelsAndApi handles importFileExtension (#22032)
Separate models are located in `modelPackage` folder with `index.ts` file. ESM requires an index file with the provided extension when `importFileExtension` is defined.
2025-09-27 09:55:26 +02:00
Alex Kondratev
bab5ca2452 [python] add async httpx support (#22021)
* [python] fix #19255 add async httpx support

* update docs

* 1. "async" parameter for templates
2. hand written tests for python-httpx
3. CI workflow updated

* fix mypy
2025-09-27 15:30:50 +08:00
William Cheng
c1931c10da Add tests with optional body for go-server (#22034)
* add tests with optional body for go-server

* update workfllow
2025-09-27 14:28:28 +08:00
Ihar Hrachyshka
d8d9744154 go: Fix missing imports for optional body params. (#22014)
Previous mustache template was using #isBodyParam outside of #operation
context, so it was not effective.

Even if we'd add the proper context, we'd then risk generating duplicate
imports for multiple matching parameters.

For this reason, this patch implements detection of an optional body
parameter in code, making sure the corresponding import is added just
once.

Fixes #19237
2025-09-27 14:16:53 +08:00
KaizenCode
dc0d5c6839 replace deprecated 'typings' field with standard 'types' in package.json (#21371)
* replace deprecated 'typings' field with standard 'types' in package.json

* regenerate samples after replacing 'typings' with 'types' field

---------

Co-authored-by: winiga <winiga@rocketmail.com>
2025-09-25 14:23:43 +02:00
jpfinne
89edad5b8a Add vendorExtensions.x-class-extra-annotation to oneOf interfaces (#22020) 2025-09-25 15:40:12 +08:00
William Cheng
258d971f42 kotlin client: add docstring to new function (#22025)
* kotlin client: add docstring

* fix
2025-09-25 15:09:47 +08:00
daberni
5e8dcc9f07 [kotlin] Fix defaultValue in query parameters (#22002) 2025-09-25 15:02:15 +08:00
William Cheng
67b24330c9 Add tests for jaxrs cxf swagger2 client (#22019)
* add test for jaxrs cxf swagger2 client

* revert
2025-09-24 17:15:08 +08:00
8340 changed files with 61499 additions and 8965 deletions

View File

@@ -6,13 +6,13 @@ on:
- 'samples/server/petstore/go-echo-server/**' - 'samples/server/petstore/go-echo-server/**'
- 'samples/server/petstore/go-api-server/**' - 'samples/server/petstore/go-api-server/**'
- 'samples/server/petstore/go-chi-server/**' - 'samples/server/petstore/go-chi-server/**'
- 'samples/server/others/go-server/no-body-path-params/**' - 'samples/server/others/go-server/**'
pull_request: pull_request:
paths: paths:
- 'samples/server/petstore/go-echo-server/**' - 'samples/server/petstore/go-echo-server/**'
- 'samples/server/petstore/go-api-server/**' - 'samples/server/petstore/go-api-server/**'
- 'samples/server/petstore/go-chi-server/**' - 'samples/server/petstore/go-chi-server/**'
- 'samples/server/others/go-server/no-body-path-params/**' - 'samples/server/others/go-server/**'
jobs: jobs:
build: build:
@@ -26,6 +26,7 @@ jobs:
- samples/server/petstore/go-api-server/ - samples/server/petstore/go-api-server/
- samples/server/petstore/go-chi-server/ - samples/server/petstore/go-chi-server/
- samples/server/others/go-server/no-body-path-params/ - samples/server/others/go-server/no-body-path-params/
- samples/server/others/go-server/optional-body/
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
- uses: actions/setup-go@v6 - uses: actions/setup-go@v6
@@ -58,4 +59,4 @@ jobs:
go mod tidy go mod tidy
- name: Run tests - name: Run tests
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: go test ./samples_tests -v run: go test ./samples_tests -v

View File

@@ -5,6 +5,7 @@ on:
paths: paths:
- 'samples/client/petstore/java/**' - 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/** - samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/** - samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/** - samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/** - samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -27,6 +28,7 @@ on:
paths: paths:
- 'samples/client/petstore/java/**' - 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/** - samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/** - samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/** - samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/** - samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -54,6 +56,7 @@ jobs:
matrix: matrix:
sample: sample:
# clients # clients
- samples/client/petstore/jaxrs-cxf-client-swagger2
- samples/client/petstore/jaxrs-cxf-client - samples/client/petstore/jaxrs-cxf-client
- samples/client/petstore/java/native - samples/client/petstore/java/native
- samples/client/petstore/java/native-async - samples/client/petstore/java/native-async

View File

@@ -34,6 +34,7 @@ jobs:
# server # server
- samples/server/petstore/kotlin-server-required-and-nullable-properties - samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3 - samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-additionalproperties
- samples/server/petstore/kotlin-springboot-delegate-nodefaults - samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request-cookie - samples/server/petstore/kotlin-springboot-request-cookie
- samples/server/petstore/kotlin-server/jaxrs-spec - samples/server/petstore/kotlin-server/jaxrs-spec
@@ -67,4 +68,4 @@ jobs:
arguments: wrapper arguments: wrapper
- name: Build - name: Build
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test run: ./gradlew build -x test

View File

@@ -76,4 +76,4 @@ jobs:
arguments: wrapper arguments: wrapper
- name: Build - name: Build
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test run: ./gradlew build -x test

View File

@@ -34,6 +34,7 @@ jobs:
- "3.13" - "3.13"
sample: sample:
- samples/openapi3/client/petstore/python-aiohttp - samples/openapi3/client/petstore/python-aiohttp
- samples/openapi3/client/petstore/python-httpx
- samples/openapi3/client/petstore/python - samples/openapi3/client/petstore/python
- samples/openapi3/client/petstore/python-lazyImports - samples/openapi3/client/petstore/python-lazyImports
services: services:

View File

@@ -1,43 +0,0 @@
name: Samples Ruby
on:
push:
paths:
- 'samples/client/echo_api/ruby-httpx/**'
- 'samples/client/echo_api/ruby-faraday/**'
- 'samples/client/echo_api/ruby-typhoeus/**'
pull_request:
paths:
- 'samples/client/echo_api/ruby-httpx/**'
- 'samples/client/echo_api/ruby-faraday/**'
- 'samples/client/echo_api/ruby-typhoeus/**'
jobs:
build:
name: Build Ruby
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- 'samples/client/echo_api/ruby-httpx/'
- 'samples/client/echo_api/ruby-faraday/'
- 'samples/client/echo_api/ruby-typhoeus/'
steps:
- uses: actions/checkout@v5
- name: Setup node.js
uses: actions/setup-node@v5
- name: Run echo server
run: |
git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server
(cd http-echo-server && npm install && npm start &)
- uses: actions/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: Install bundle
working-directory: ${{ matrix.sample }}
run: bundle install
- name: Run rspec
working-directory: ${{ matrix.sample }}
run: rspec

View File

@@ -1,18 +1,16 @@
name: Samples Ruby name: Samples Ruby
on: on:
push: push:
paths: paths:
- samples/client/petstore/ruby/** - 'samples/client/echo_api/ruby-httpx/**'
- samples/client/petstore/ruby-faraday/** - 'samples/client/echo_api/ruby-faraday/**'
- samples/client/petstore/ruby-httpx/** - 'samples/client/echo_api/ruby-typhoeus/**'
- samples/client/petstore/ruby-autoload/**
pull_request: pull_request:
paths: paths:
- samples/client/petstore/ruby/** - 'samples/client/echo_api/ruby-httpx/**'
- samples/client/petstore/ruby-faraday/** - 'samples/client/echo_api/ruby-faraday/**'
- samples/client/petstore/ruby-httpx/** - 'samples/client/echo_api/ruby-typhoeus/**'
- samples/client/petstore/ruby-autoload/**
jobs: jobs:
build: build:
@@ -22,28 +20,21 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
sample: sample:
- samples/client/petstore/ruby/ - 'samples/client/echo_api/ruby-httpx/'
#- samples/client/petstore/ruby-faraday/ - 'samples/client/echo_api/ruby-faraday/'
#- samples/client/petstore/ruby-httpx/ - 'samples/client/echo_api/ruby-typhoeus/'
#- samples/client/petstore/ruby-autoload/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
#- name: Add hosts to /etc/hosts - name: Setup node.js
# run: | uses: actions/setup-node@v5
# sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts - name: Run echo server
# cat /etc/hosts run: |
- uses: ruby/setup-ruby@v1 git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server
(cd http-echo-server && npm install && npm start &)
- uses: actions/setup-ruby@v1
with: with:
ruby-version: '3.4' # Not needed with a .ruby-version, .tool-versions or mise.toml ruby-version: 3.0
bundler-cache: true # runs 'bundle install' and caches installed gems automatically bundler-cache: true
- name: Install bundle - name: Install bundle
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: bundle install run: bundle install

View File

@@ -15,7 +15,7 @@
<div align="center"> <div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.16.0`): [Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.17.0`):
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator) [![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67) [![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
@@ -148,8 +148,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes | | OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- | | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.16.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.16.0-SNAPSHOT/) | 22.09.2025 | Minor release with breaking changes (with fallback) | | 7.17.0 (upcoming minor release) [SNAPSHOT](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) | 24.10.2025 | Minor release with breaking changes (with fallback) |
| [7.15.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.15.0) (latest stable release) | 22.08.2025 | Minor release with breaking changes (with fallback) | | [7.16.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.16.0) (latest stable release) | 28.09.2025 | Minor release with breaking changes (with fallback) |
| [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | Minor release with breaking changes (with fallback) | | [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.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) | | [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) | | [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
@@ -212,16 +212,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```sh ```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.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. 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/7.15.0/openapi-generator-cli-7.15.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar
``` ```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage. After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -456,7 +456,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli" To use a specific version of "openapi-generator-cli"
```sh ```sh
openapi-generator-cli version-manager set 7.15.0 openapi-generator-cli version-manager set 7.16.0
``` ```
Or install it as dev-dependency: Or install it as dev-dependency:
@@ -480,7 +480,7 @@ pip install openapi-generator-cli
To install a specific version To install a specific version
``` ```
pip install openapi-generator-cli==7.15.0 pip install openapi-generator-cli==7.16.0
``` ```
You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required) You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required)
@@ -506,7 +506,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`) (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 --> <!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar) You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar)
<!-- /RELEASE_VERSION --> <!-- /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` To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`

View File

@@ -0,0 +1,8 @@
generatorName: go-server
outputDir: samples/server/others/go-server/optional-body
inputSpec: modules/openapi-generator/src/test/resources/3_0/optional_body.yaml
templateDir: modules/openapi-generator/src/main/resources/go-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: petstoreserver
addResponseHeaders: true

View File

@@ -0,0 +1,8 @@
generatorName: jaxrs-cxf-client
outputDir: samples/client/petstore/jaxrs-cxf-client-swagger2
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/cxf
additionalProperties:
artifactId: jaxrs-cxf-petstore-swagger2
documentationProvider: swagger2
annotationLibrary: swagger2

View File

@@ -0,0 +1,14 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-additionalproperties
library: spring-boot
inputSpec: samples/server/petstore/kotlin-springboot-additionalproperties/src/main/resources/openapi.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: none
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
useSpringBoot3: "true"
requestMappingMode: api_interface

View File

@@ -7,6 +7,7 @@ additionalProperties:
packageName: petstore_api packageName: petstore_api
mapNumberTo: float mapNumberTo: float
poetry1: true poetry1: true
enumUnknownDefaultCase: true
nameMappings: nameMappings:
_type: underscore_type _type: underscore_type
type_: type_with_underscore type_: type_with_underscore

View File

@@ -0,0 +1,15 @@
generatorName: python
outputDir: samples/openapi3/client/petstore/python-httpx
inputSpec: modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/python
library: httpx
additionalProperties:
packageName: petstore_api
mapNumberTo: float
poetry1: true
nameMappings:
_type: underscore_type
type_: type_with_underscore
modelNameMappings:
# The OpenAPI spec ApiResponse conflicts with the internal ApiResponse
ApiResponse: ModelApiResponse

View File

@@ -61,4 +61,4 @@
- filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs" - filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs"
sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600 sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600
- filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs" - filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs"
sha256: e72fbf81a9849dc7abb7e2169f2fc355c8b1cf991c0e2ffc083126abd9e966e7 sha256: 1d3fb01f65e98290b1d3eece28014c7d3e3f2fdf18e7110249d3c591cc4642ab

View File

@@ -1,167 +0,0 @@
---
title: Documentation for the postman Generator
---
## METADATA
| Property | Value | Notes |
| -------- | ----- | ----- |
| generator name | postman | pass this to the generate command after -g |
| generator stability | BETA | |
| generator type | DOCUMENTATION | |
| generator default templating engine | mustache | |
| helpTxt | Generates a postman JSON file | |
## CONFIG OPTIONS
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|folderStrategy|whether to create folders according to the spec&rsquo;s paths or tags| |null|
|pathParamsAsVariables|whether to create Postman variables for path parameters| |false|
|postmanGuid|whether to convert placeholders (i.e. {{UNIQUE_REFERENCE}}) into Postman formula {{$guid}}| |null|
|postmanGuidPlaceholderName|name of the placeholder (i.e. {{UNIQUE_REFERENCE}}) to replace with Postman formula {{$guid}}| |null|
|postmanIsoTimestamp|whether to convert placeholders (i.e. {{ISO_TIMESTAMP}}) into Postman formula {{$isoTimestamp}}| |null|
|postmanIsoTimestampPlaceholderName|name of the placeholder (i.e. {{ISO_TIMESTAMP}}) to replace with Postman formula {{$isoTimestamp}}| |null|
|postmanVariables|whether to convert placeholders (i.e. {{VAR_1}}) into Postman variables| |null|
|requestParameterGeneration|whether to generate the request parameters based on the schema or the examples| |null|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
## LANGUAGE PRIMITIVES
<ul class="column-ul">
</ul>
## RESERVED WORDS
<ul class="column-ul">
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Uuid|✗|
|Array|✓|OAS2,OAS3
|Null|✗|OAS3
|AnyType|✗|OAS2,OAS3
|Object|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✗|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✓|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
|allOf|✗|OAS2,OAS3
|anyOf|✗|OAS3
|oneOf|✗|OAS3
|not|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✓|OAS3
|OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✓|OAS2,OAS3
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
|SignatureAuth|✗|OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@@ -22,10 +22,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|dateFormat|date format for query parameters| |%Y-%m-%d| |dateFormat|date format for query parameters| |%Y-%m-%d|
|datetimeFormat|datetime format for query parameters| |%Y-%m-%dT%H:%M:%S%z| |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| |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|
|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.| |false|
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false| |generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true| |hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|lazyImports|Enable lazy imports.| |false| |lazyImports|Enable lazy imports.| |false|
|library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3| |urllib3| |library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx| |urllib3|
|mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]| |mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]|
|packageName|python package name (convention: snake_case).| |openapi_client| |packageName|python package name (convention: snake_case).| |openapi_client|
|packageUrl|python package URL.| |null| |packageUrl|python package URL.| |null|

View File

@@ -77,6 +77,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>dyn</li> <li>dyn</li>
<li>else</li> <li>else</li>
<li>enum</li> <li>enum</li>
<li>errors</li>
<li>extern</li> <li>extern</li>
<li>false</li> <li>false</li>
<li>final</li> <li>final</li>
@@ -207,8 +208,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|Composite|✓|OAS2,OAS3 |Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3 |Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3 |Union|✗|OAS3
|allOf||OAS2,OAS3 |allOf||OAS2,OAS3
|anyOf||OAS3 |anyOf||OAS3
|oneOf|✓|OAS3 |oneOf|✓|OAS3
|not|✗|OAS3 |not|✗|OAS3

View File

@@ -22,7 +22,7 @@ npm install @openapitools/openapi-generator-cli -g
To install a specific version of the tool, pass the version during installation: To install a specific version of the tool, pass the version during installation:
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
```bash ```bash
openapi-generator-cli version-manager set 7.15.0 openapi-generator-cli version-manager set 7.16.0
``` ```
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
To install the tool as a dev dependency in your current project: To install the tool as a dev dependency in your current project:
@@ -119,18 +119,18 @@ docker run --rm \
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```bash ```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.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. 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.
```powershell ```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar
``` ```
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->

View File

@@ -16,7 +16,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin> <plugin>
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId> <artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.15.0</version> <version>7.16.0</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -6,7 +6,7 @@
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -97,7 +97,7 @@ task validateGoodSpec(type: org.openapitools.generator.gradle.plugin.tasks.Valid
[source,group] [source,group]
---- ----
plugins { plugins {
id "org.openapi.generator" version "7.15.0" id "org.openapi.generator" version "7.16.0"
} }
---- ----
@@ -113,7 +113,7 @@ buildscript {
// url "https://plugins.gradle.org/m2/" // url "https://plugins.gradle.org/m2/"
} }
dependencies { dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:7.15.0" classpath "org.openapitools:openapi-generator-gradle-plugin:7.16.0"
} }
} }
@@ -759,7 +759,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.android.tools.build:gradle:3.2.1'
classpath('org.openapitools:openapi-generator-gradle-plugin:7.15.0') { classpath('org.openapitools:openapi-generator-gradle-plugin:7.16.0') {
exclude group: 'com.google.guava' exclude group: 'com.google.guava'
} }
} }

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION # RELEASE_VERSION
openApiGeneratorVersion=7.16.0-SNAPSHOT openApiGeneratorVersion=7.17.0-SNAPSHOT
# /RELEASE_VERSION # /RELEASE_VERSION
# BEGIN placeholders # BEGIN placeholders

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -19,5 +19,5 @@ gradle generateGoWithInvalidSpec # expected outcome: BUILD FAILED
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example: The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash ```bash
gradle -PopenApiGeneratorVersion=7.15.0 openApiValidate gradle -PopenApiGeneratorVersion=7.16.0 openApiValidate
``` ```

View File

@@ -1,3 +1,3 @@
# RELEASE_VERSION # RELEASE_VERSION
openApiGeneratorVersion=7.16.0-SNAPSHOT openApiGeneratorVersion=7.17.0-SNAPSHOT
# /RELEASE_VERSION # /RELEASE_VERSION

View File

@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId> <artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.15.0</version> <version>7.16.0</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,7 +5,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -115,6 +115,15 @@ public class CodegenOperation {
return nonEmpty(bodyParams); return nonEmpty(bodyParams);
} }
/**
* Check if there's at least one optional body parameter
*
* @return true if optional body parameter exists, false otherwise
*/
public boolean getHasOptionalBodyParam() {
return nonEmpty(bodyParams) && nonEmpty(optionalParams) && bodyParams.stream().anyMatch(optionalParams::contains);
}
/** /**
* Check if there's at least one query parameter * Check if there's at least one query parameter
* *

View File

@@ -410,6 +410,7 @@ public class GoServerCodegen extends AbstractGoCodegen {
private void addConditionalImportInformation(OperationsMap operations) { private void addConditionalImportInformation(OperationsMap operations) {
boolean hasPathParams = false; boolean hasPathParams = false;
boolean hasBodyParams = false; boolean hasBodyParams = false;
boolean hasOptionalBodyParams = false;
for (CodegenOperation op : operations.getOperations().getOperation()) { for (CodegenOperation op : operations.getOperations().getOperation()) {
if (op.getHasPathParams()) { if (op.getHasPathParams()) {
@@ -418,10 +419,14 @@ public class GoServerCodegen extends AbstractGoCodegen {
if (op.getHasBodyParam()) { if (op.getHasBodyParam()) {
hasBodyParams = true; hasBodyParams = true;
} }
if (op.getHasOptionalBodyParam()) {
hasOptionalBodyParams = true;
}
} }
additionalProperties.put("hasPathParams", hasPathParams); additionalProperties.put("hasPathParams", hasPathParams);
additionalProperties.put("hasBodyParams", hasBodyParams); additionalProperties.put("hasBodyParams", hasBodyParams);
additionalProperties.put("hasOptionalBodyParams", hasOptionalBodyParams);
} }

View File

@@ -996,6 +996,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
} }
return objs; return objs;
} }
private Stream<List<CodegenProperty>> getAllVarProperties(CodegenModel model) { private Stream<List<CodegenProperty>> getAllVarProperties(CodegenModel model) {
return Stream.of(model.vars, model.allVars, model.optionalVars, model.requiredVars, model.readOnlyVars, model.readWriteVars); return Stream.of(model.vars, model.allVars, model.optionalVars, model.requiredVars, model.readOnlyVars, model.readWriteVars);
} }
@@ -1113,6 +1114,27 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
return false; return false;
} }
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
adjustEnumRefDefault(parameter);
}
/**
* Properly set the default value for enum (reference).
*
* @param param codegen parameter
*/
private void adjustEnumRefDefault(CodegenParameter param) {
if (StringUtils.isEmpty(param.defaultValue) || !(param.isEnum || param.isEnumRef)) {
return;
}
String type = StringUtils.defaultIfEmpty(param.datatypeWithEnum, param.dataType);
param.enumDefaultValue = toEnumVarName(param.defaultValue, type);
param.defaultValue = type + "." + param.enumDefaultValue;
}
@Override @Override
public void postProcess() { public void postProcess() {
System.out.println("################################################################################"); System.out.println("################################################################################");

View File

@@ -153,11 +153,13 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC).defaultValue("false")); cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC).defaultValue("false"));
cliOptions.add(new CliOption(POETRY1_FALLBACK, "Fallback to formatting pyproject.toml to Poetry 1.x format.")); cliOptions.add(new CliOption(POETRY1_FALLBACK, "Fallback to formatting pyproject.toml to Poetry 1.x format."));
cliOptions.add(new CliOption(LAZY_IMPORTS, "Enable lazy imports.").defaultValue(Boolean.FALSE.toString())); cliOptions.add(new CliOption(LAZY_IMPORTS, "Enable lazy imports.").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE_DESC).defaultValue("false"));
supportedLibraries.put("urllib3", "urllib3-based client"); supportedLibraries.put("urllib3", "urllib3-based client");
supportedLibraries.put("asyncio", "asyncio-based client"); supportedLibraries.put("asyncio", "asyncio-based client");
supportedLibraries.put("tornado", "tornado-based client (deprecated)"); supportedLibraries.put("tornado", "tornado-based client (deprecated)");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3"); supportedLibraries.put("httpx", "httpx-based client");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx");
libraryOption.setDefault(DEFAULT_LIBRARY); libraryOption.setDefault(DEFAULT_LIBRARY);
cliOptions.add(libraryOption); cliOptions.add(libraryOption);
setLibrary(DEFAULT_LIBRARY); setLibrary(DEFAULT_LIBRARY);
@@ -270,6 +272,10 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
additionalProperties.put(LAZY_IMPORTS, Boolean.valueOf(additionalProperties.get(LAZY_IMPORTS).toString())); additionalProperties.put(LAZY_IMPORTS, Boolean.valueOf(additionalProperties.get(LAZY_IMPORTS).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE)) {
setEnumUnknownDefaultCase(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE).toString()));
}
String modelPath = packagePath() + File.separatorChar + modelPackage.replace('.', File.separatorChar); String modelPath = packagePath() + File.separatorChar + modelPackage.replace('.', File.separatorChar);
String apiPath = packagePath() + File.separatorChar + apiPackage.replace('.', File.separatorChar); String apiPath = packagePath() + File.separatorChar + apiPackage.replace('.', File.separatorChar);
@@ -330,10 +336,15 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
if ("asyncio".equals(getLibrary())) { if ("asyncio".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("asyncio", "true"); additionalProperties.put("asyncio", "true");
} else if ("tornado".equals(getLibrary())) { } else if ("tornado".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("tornado", "true"); additionalProperties.put("tornado", "true");
} else if ("httpx".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("httpx/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("httpx", "true");
} else { } else {
supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py"));
} }

View File

@@ -99,6 +99,18 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
public RustAxumServerCodegen() { public RustAxumServerCodegen() {
super(); super();
// The `#[validate(nested)]` macro relies on an internal field named `errors` to accumulate validation results. Therefore, defining a struct like this will fail:
//
// ```rust
// struct A {
// #[validate(nested)]
// errors: B,
// }
// ```
//
// To avoid this, either rename the field to something other than "errors", or reserve it.
this.reservedWords.add("errors");
modifyFeatureSet(features -> features modifyFeatureSet(features -> features
.wireFormatFeatures(EnumSet.of( .wireFormatFeatures(EnumSet.of(
WireFormatFeature.JSON, WireFormatFeature.JSON,
@@ -112,7 +124,9 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
.schemaSupportFeatures(EnumSet.of( .schemaSupportFeatures(EnumSet.of(
SchemaSupportFeature.Simple, SchemaSupportFeature.Simple,
SchemaSupportFeature.Composite, SchemaSupportFeature.Composite,
SchemaSupportFeature.oneOf SchemaSupportFeature.oneOf,
SchemaSupportFeature.anyOf,
SchemaSupportFeature.allOf
)) ))
.excludeGlobalFeatures( .excludeGlobalFeatures(
GlobalFeature.Info, GlobalFeature.Info,
@@ -633,105 +647,163 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
return op; return op;
} }
private void postProcessOneOfModels(List<ModelMap> allModels) { private void postProcessPolymorphism(final List<ModelMap> allModels) {
final HashMap<String, List<String>> oneOfMapDiscriminator = new HashMap<>(); final HashMap<String, List<String>> discriminatorsForModel = new HashMap<>();
for (ModelMap mo : allModels) { for (final ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel(); final CodegenModel cm = mo.getModel();
final CodegenComposedSchemas cs = cm.getComposedSchemas(); final CodegenComposedSchemas cs = cm.getComposedSchemas();
if (cs != null) { if (cs != null) {
final List<CodegenProperty> csOneOf = cs.getOneOf(); final List<CodegenProperty> csOneOf = cs.getOneOf();
if (csOneOf != null) { if (csOneOf != null) {
for (CodegenProperty model : csOneOf) { processPolymorphismDataType(csOneOf);
// Generate a valid name for the enum variant.
// Mainly needed for primitive types.
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
.replace("<", "Of").replace(">", ""));
// Primitive type is not properly set, this overrides it to guarantee adequate model generation.
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
model.isPrimitiveType = true;
}
}
cs.setOneOf(csOneOf); cs.setOneOf(csOneOf);
cm.setComposedSchemas(cs); cm.setComposedSchemas(cs);
} }
final List<CodegenProperty> csAnyOf = cs.getAnyOf();
if (csAnyOf != null) {
processPolymorphismDataType(csAnyOf);
cs.setAnyOf(csAnyOf);
cm.setComposedSchemas(cs);
}
} }
if (cm.discriminator != null) { if (cm.discriminator != null) {
for (String model : cm.oneOf) { for (final String model : cm.oneOf) {
List<String> discriminators = oneOfMapDiscriminator.getOrDefault(model, new ArrayList<>()); final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator.getPropertyName()); discriminators.add(cm.discriminator.getPropertyName());
oneOfMapDiscriminator.put(model, discriminators); discriminatorsForModel.put(model, discriminators);
}
for (final String model : cm.anyOf) {
final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator.getPropertyName());
discriminatorsForModel.put(model, discriminators);
} }
} }
} }
final var blocking = new HashSet<String>();
for (ModelMap mo : allModels) { for (ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel(); final CodegenModel cm = mo.getModel();
for (CodegenProperty var : cm.vars) { final List<String> discriminators = discriminatorsForModel.get(cm.getSchemaName());
var.isDiscriminator = false; if (discriminators != null) {
// If the discriminator field is not a defined attribute in the variant structure, create it.
if (!discriminating(discriminators, cm)) {
final String discriminator = discriminators.get(0);
CodegenProperty property = new CodegenProperty();
// Static attributes
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with
property.openApiType = "string";
property.complexType = "string";
property.dataType = "String";
property.datatypeWithEnum = "String";
property.baseType = "string";
property.required = true;
property.isPrimitiveType = true;
property.isString = true;
property.isDiscriminator = true;
// Attributes based on the discriminator value
property.baseName = discriminator;
property.name = discriminator;
property.nameInCamelCase = camelize(discriminator);
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
property.nameInSnakeCase = underscore(discriminator).toUpperCase(Locale.ROOT);
property.getter = String.format(Locale.ROOT, "get%s", property.nameInPascalCase);
property.setter = String.format(Locale.ROOT, "set%s", property.nameInPascalCase);
property.defaultValueWithParam = String.format(Locale.ROOT, " = data.%s;", property.name);
// Attributes based on the model name
property.defaultValue = String.format(Locale.ROOT, "r#\"%s\"#.to_string()", cm.getSchemaName());
property.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
cm.vars.add(property);
}
} }
final List<String> discriminatorsForModel = oneOfMapDiscriminator.get(cm.getSchemaName()); if (cm.vars.stream().noneMatch(v -> v.isDiscriminator)) {
blocking.add(cm.getSchemaName());
}
}
if (discriminatorsForModel != null) { for (final ModelMap mo : allModels) {
for (String discriminator : discriminatorsForModel) { final CodegenModel cm = mo.getModel();
boolean hasDiscriminatorDefined = false; if (cm.discriminator != null) {
// if no discriminator in any of variant -> disable discriminator
for (CodegenProperty var : cm.vars) { if (cm.oneOf.stream().anyMatch(blocking::contains) || cm.anyOf.stream().anyMatch(blocking::contains)) {
if (var.baseName.equals(discriminator)) { cm.discriminator = null;
var.isDiscriminator = true;
hasDiscriminatorDefined = true;
break;
}
}
// If the discriminator field is not a defined attribute in the variant structure, create it.
if (!hasDiscriminatorDefined) {
CodegenProperty property = new CodegenProperty();
// Static attributes
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with
property.openApiType = "string";
property.complexType = "string";
property.dataType = "String";
property.datatypeWithEnum = "String";
property.baseType = "string";
property.required = true;
property.isPrimitiveType = true;
property.isString = true;
property.isDiscriminator = true;
// Attributes based on the discriminator value
property.baseName = discriminator;
property.name = discriminator;
property.nameInCamelCase = camelize(discriminator);
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
property.nameInSnakeCase = underscore(discriminator).toUpperCase(Locale.ROOT);
property.getter = String.format(Locale.ROOT, "get%s", property.nameInPascalCase);
property.setter = String.format(Locale.ROOT, "set%s", property.nameInPascalCase);
property.defaultValueWithParam = String.format(Locale.ROOT, " = data.%s;", property.name);
// Attributes based on the model name
property.defaultValue = String.format(Locale.ROOT, "r#\"%s\"#.to_string()", cm.getSchemaName());
property.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
cm.vars.add(property);
}
} }
} }
} }
} }
private static boolean discriminating(final List<String> discriminatorsForModel, final CodegenModel cm) {
resetDiscriminatorProperty(cm);
// Discriminator will be presented as enum tag -> One and only one tag is allowed
int countString = 0;
int countNonString = 0;
for (final CodegenProperty var : cm.vars) {
if (discriminatorsForModel.stream().anyMatch(discriminator -> var.baseName.equals(discriminator) || var.name.equals(discriminator))) {
if (var.isString) {
var.isDiscriminator = true;
++countString;
} else
++countNonString;
}
}
if (countString > 0 && (countNonString > 0 || countString > 1)) {
// at least two discriminator, one of them is string -> should not render serde tag
resetDiscriminatorProperty(cm);
}
return countNonString > 0 || countString > 0;
}
private static void resetDiscriminatorProperty(final CodegenModel cm) {
for (final CodegenProperty var : cm.vars) {
var.isDiscriminator = false;
}
}
private static void processPolymorphismDataType(final List<CodegenProperty> cp) {
final HashSet<String> dedupDataTypeWithEnum = new HashSet<>();
final HashMap<String, Integer> dedupDataType = new HashMap<>();
int idx = 0;
for (CodegenProperty model : cp) {
// Generate a valid name for the enum variant.
// Mainly needed for primitive types.
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
.replace("<", "Of").replace(">", "")).replace(" ", "").replace(",", "");
if (!dedupDataTypeWithEnum.add(model.datatypeWithEnum)) {
model.datatypeWithEnum += ++idx;
}
dedupDataType.put(model.getDataType(), dedupDataType.getOrDefault(model.getDataType(), 0) + 1);
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
model.isPrimitiveType = true;
}
}
for (CodegenProperty model : cp) {
if (dedupDataType.get(model.getDataType()) == 1) {
model.vendorExtensions.put("x-from-trait", true);
}
}
}
@Override @Override
public OperationsMap postProcessOperationsWithModels(final OperationsMap operationsMap, List<ModelMap> allModels) { public OperationsMap postProcessOperationsWithModels(final OperationsMap operationsMap, List<ModelMap> allModels) {
postProcessOneOfModels(allModels); postProcessPolymorphism(allModels);
final OperationMap operations = operationsMap.getOperations(); final OperationMap operations = operationsMap.getOperations();
operations.put("classnamePascalCase", camelize(operations.getClassname())); operations.put("classnamePascalCase", camelize(operations.getClassname()));
@@ -901,7 +973,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
// restore things to sensible values. // restore things to sensible values.
@Override @Override
public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) { public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) {
final Schema original_schema = ModelUtils.getSchemaFromRequestBody(body); final var original_schema = ModelUtils.getSchemaFromRequestBody(body);
CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName);
if (StringUtils.isNotBlank(original_schema.get$ref())) { if (StringUtils.isNotBlank(original_schema.get$ref())) {
@@ -920,10 +992,10 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
@Override @Override
public String toInstantiationType(final Schema p) { public String toInstantiationType(final Schema p) {
if (ModelUtils.isArraySchema(p)) { if (ModelUtils.isArraySchema(p)) {
final Schema inner = ModelUtils.getSchemaItems(p); final var inner = ModelUtils.getSchemaItems(p);
return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">"; return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) { } else if (ModelUtils.isMapSchema(p)) {
final Schema inner = ModelUtils.getAdditionalProperties(p); final var inner = ModelUtils.getAdditionalProperties(p);
return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">"; return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">";
} else { } else {
return null; return null;
@@ -952,6 +1024,10 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
@Override @Override
public String toDefaultValue(final Schema p) { public String toDefaultValue(final Schema p) {
String defaultValue = null; String defaultValue = null;
if (ModelUtils.isEnumSchema(p))
return null;
if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString()))) if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString())))
return "Nullable::Null"; return "Nullable::Null";
@@ -965,6 +1041,9 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} else if (ModelUtils.isNumberSchema(p)) { } else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) { if (p.getDefault() != null) {
defaultValue = p.getDefault().toString(); defaultValue = p.getDefault().toString();
if (!defaultValue.contains(".")) {
defaultValue += ".0";
}
} }
} else if (ModelUtils.isIntegerSchema(p)) { } else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) { if (p.getDefault() != null) {
@@ -1081,7 +1160,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
String cmd = System.getenv("RUST_POST_PROCESS_FILE"); String cmd = System.getenv("RUST_POST_PROCESS_FILE");
if (StringUtils.isEmpty(cmd)) { if (StringUtils.isEmpty(cmd)) {
cmd = "rustfmt"; cmd = "rustfmt";
command = new String[]{cmd, "--edition", "2021", fileName}; command = new String[]{cmd, "--edition", "2024", fileName};
} else { } else {
command = new String[]{cmd, fileName}; command = new String[]{cmd, fileName};
} }
@@ -1093,7 +1172,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} }
@Override @Override
protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema) { protected void updateParameterForString(CodegenParameter codegenParameter, final Schema parameterSchema) {
if (ModelUtils.isEmailSchema(parameterSchema)) { if (ModelUtils.isEmailSchema(parameterSchema)) {
codegenParameter.isEmail = true; codegenParameter.isEmail = true;
} else if (ModelUtils.isUUIDSchema(parameterSchema)) { } else if (ModelUtils.isUUIDSchema(parameterSchema)) {
@@ -1120,7 +1199,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
codegenParameter.isDecimal = true; codegenParameter.isDecimal = true;
codegenParameter.isPrimitiveType = true; codegenParameter.isPrimitiveType = true;
} }
if (Boolean.TRUE.equals(codegenParameter.isString)) { if (codegenParameter.isString) {
codegenParameter.isPrimitiveType = true; codegenParameter.isPrimitiveType = true;
} }
} }
@@ -1152,6 +1231,16 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
return null; return null;
} }
@Override
public String toVarName(String name) {
final var varName = super.toVarName(name);
if (varName.startsWith("r#"))
return "r_" + varName.substring(2);
return varName;
}
static class PathMethodOperations { static class PathMethodOperations {
public String path; public String path;
public ArrayList<MethodOperation> methodOperations; public ArrayList<MethodOperation> methodOperations;

View File

@@ -307,69 +307,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
mdl.getComposedSchemas().setOneOf(newOneOfs); mdl.getComposedSchemas().setOneOf(newOneOfs);
} }
// Handle anyOf schemas similarly to oneOf
// This is pragmatic since Rust's untagged enum will deserialize to the first matching variant
if (mdl.getComposedSchemas() != null && mdl.getComposedSchemas().getAnyOf() != null
&& !mdl.getComposedSchemas().getAnyOf().isEmpty()) {
List<CodegenProperty> newAnyOfs = mdl.getComposedSchemas().getAnyOf().stream()
.map(CodegenProperty::clone)
.collect(Collectors.toList());
List<Schema> schemas = ModelUtils.getInterfaces(model);
if (newAnyOfs.size() != schemas.size()) {
// For safety reasons, this should never happen unless there is an error in the code
throw new RuntimeException("anyOf size does not match the model");
}
Map<String, String> refsMapping = Optional.ofNullable(model.getDiscriminator())
.map(Discriminator::getMapping).orElse(Collections.emptyMap());
// Reverse mapped references to use as baseName for anyOf, but different keys may point to the same $ref.
// Thus, we group them by the value
Map<String, List<String>> mappedNamesByRef = refsMapping.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
));
for (int i = 0; i < newAnyOfs.size(); i++) {
CodegenProperty anyOf = newAnyOfs.get(i);
Schema schema = schemas.get(i);
if (mappedNamesByRef.containsKey(schema.get$ref())) {
// prefer mapped names if present
// remove mapping not in order not to reuse for the next occurrence of the ref
List<String> names = mappedNamesByRef.get(schema.get$ref());
String mappedName = names.remove(0);
anyOf.setBaseName(mappedName);
anyOf.setName(toModelName(mappedName));
} else if (!org.apache.commons.lang3.StringUtils.isEmpty(schema.get$ref())) {
// use $ref if it's reference
String refName = ModelUtils.getSimpleRef(schema.get$ref());
if (refName != null) {
String modelName = toModelName(refName);
anyOf.setName(modelName);
anyOf.setBaseName(refName);
}
} else if (anyOf.isArray) {
// If the type is an array, extend the name with the inner type to prevent name collisions
// in case multiple arrays with different types are defined. If the user has manually specified
// a name, use that name instead.
String collectionWithTypeName = toModelName(schema.getType()) + anyOf.containerTypeMapped + anyOf.items.dataType;
String anyOfName = Optional.ofNullable(schema.getTitle()).orElse(collectionWithTypeName);
anyOf.setName(anyOfName);
}
else {
// In-placed type (primitive), because there is no mapping or ref for it.
// use camelized `title` if present, otherwise use `type`
String anyOfName = Optional.ofNullable(schema.getTitle()).orElseGet(schema::getType);
anyOf.setName(toModelName(anyOfName));
}
}
// Set anyOf as oneOf for template processing since we want the same output
mdl.getComposedSchemas().setOneOf(newAnyOfs);
}
return mdl; return mdl;
} }

View File

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

View File

@@ -8,7 +8,9 @@ import org.junit.Test;
import org.junit.Before; import org.junit.Before;
import static org.junit.Assert.*; import static org.junit.Assert.*;
{{#useBeanValidation}}
import {{javaxPackage}}.validation.Valid; import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import {{javaxPackage}}.ws.rs.core.Response; import {{javaxPackage}}.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.ClientConfiguration; import org.apache.cxf.jaxrs.client.ClientConfiguration;

View File

@@ -13,7 +13,8 @@
@JsonSubTypes.Type(value = {{classname}}.class){{^-last}}, {{/-last}} @JsonSubTypes.Type(value = {{classname}}.class){{^-last}}, {{/-last}}
{{/interfaceModels}} {{/interfaceModels}}
}) })
{{/useDeductionForOneOfInterfaces}} {{/useDeductionForOneOfInterfaces}}{{#vendorExtensions.x-class-extra-annotation}}{{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}
{{/discriminator}} {{/discriminator}}
{{>generatedAnnotation}} {{>generatedAnnotation}}

View File

@@ -6,12 +6,10 @@ import (
{{#hasBodyParams}} {{#hasBodyParams}}
"encoding/json" "encoding/json"
{{/hasBodyParams}} {{/hasBodyParams}}
{{#isBodyParam}} {{#hasOptionalBodyParams}}
{{^required}}
"errors" "errors"
"io" "io"
{{/required}} {{/hasOptionalBodyParams}}
{{/isBodyParam}}
"net/http" "net/http"
"strings" "strings"
{{#imports}} "{{import}}" {{#imports}} "{{import}}"

View File

@@ -18,7 +18,7 @@
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}}, {{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}},
{{/-last}}{{/optionalVars}} {{/-last}}{{/optionalVars}}
){{/discriminator}}{{! no newline ){{/discriminator}}{{! no newline
}}{{#parent}} : {{{.}}}{{! no newline }}{{#parent}} : {{{.}}}{{#isMap}}(){{/isMap}}{{! no newline
}}{{#serializableModel}}{{! no newline }}{{#serializableModel}}{{! no newline
}}{{^vendorExtensions.x-kotlin-implements}}, Serializable{{/vendorExtensions.x-kotlin-implements}}{{! no newline }}{{^vendorExtensions.x-kotlin-implements}}, Serializable{{/vendorExtensions.x-kotlin-implements}}{{! no newline
}}{{#vendorExtensions.x-kotlin-implements}}, Serializable, {{! no newline }}{{#vendorExtensions.x-kotlin-implements}}, Serializable, {{! no newline

View File

@@ -28,10 +28,10 @@ To be able to use it, you will need these dependencies in your own package that
* urllib3 >= 2.1.0, < 3.0.0 * urllib3 >= 2.1.0, < 3.0.0
* python-dateutil >= 2.8.2 * python-dateutil >= 2.8.2
{{#asyncio}} {{#async}}
* aiohttp >= 3.8.4 * aiohttp >= 3.8.4
* aiohttp-retry >= 2.8.3 * aiohttp-retry >= 2.8.3
{{/asyncio}} {{/async}}
{{#tornado}} {{#tornado}}
* tornado >= 4.2, < 5 * tornado >= 4.2, < 5
{{/tornado}} {{/tornado}}

View File

@@ -32,14 +32,14 @@ class {{classname}}:
@validate_call @validate_call
{{#asyncio}}async {{/asyncio}}def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}: {{#async}}async {{/async}}def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}:
{{>partial_api}} {{>partial_api}}
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api( response_data = {{#async}}await {{/async}}self.api_client.call_api(
*_param, *_param,
_request_timeout=_request_timeout _request_timeout=_request_timeout
) )
{{#asyncio}}await {{/asyncio}}response_data.read() {{#async}}await {{/async}}response_data.read()
return self.api_client.response_deserialize( return self.api_client.response_deserialize(
response_data=response_data, response_data=response_data,
response_types_map=_response_types_map, response_types_map=_response_types_map,
@@ -47,14 +47,14 @@ class {{classname}}:
@validate_call @validate_call
{{#asyncio}}async {{/asyncio}}def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]: {{#async}}async {{/async}}def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]:
{{>partial_api}} {{>partial_api}}
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api( response_data = {{#async}}await {{/async}}self.api_client.call_api(
*_param, *_param,
_request_timeout=_request_timeout _request_timeout=_request_timeout
) )
{{#asyncio}}await {{/asyncio}}response_data.read() {{#async}}await {{/async}}response_data.read()
return self.api_client.response_deserialize( return self.api_client.response_deserialize(
response_data=response_data, response_data=response_data,
response_types_map=_response_types_map, response_types_map=_response_types_map,
@@ -62,10 +62,10 @@ class {{classname}}:
@validate_call @validate_call
{{#asyncio}}async {{/asyncio}}def {{operationId}}_without_preload_content{{>partial_api_args}} -> RESTResponseType: {{#async}}async {{/async}}def {{operationId}}_without_preload_content{{>partial_api_args}} -> RESTResponseType:
{{>partial_api}} {{>partial_api}}
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api( response_data = {{#async}}await {{/async}}self.api_client.call_api(
*_param, *_param,
_request_timeout=_request_timeout _request_timeout=_request_timeout
) )

View File

@@ -88,7 +88,7 @@ class ApiClient:
self.user_agent = '{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}' self.user_agent = '{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
self.client_side_validation = configuration.client_side_validation self.client_side_validation = configuration.client_side_validation
{{#asyncio}} {{#async}}
async def __aenter__(self): async def __aenter__(self):
return self return self
@@ -97,14 +97,14 @@ class ApiClient:
async def close(self): async def close(self):
await self.rest_client.close() await self.rest_client.close()
{{/asyncio}} {{/async}}
{{^asyncio}} {{^async}}
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass pass
{{/asyncio}} {{/async}}
@property @property
def user_agent(self): def user_agent(self):
@@ -257,7 +257,7 @@ class ApiClient:
{{#tornado}} {{#tornado}}
@tornado.gen.coroutine @tornado.gen.coroutine
{{/tornado}} {{/tornado}}
{{#asyncio}}async {{/asyncio}}def call_api( {{#async}}async {{/async}}def call_api(
self, self,
method, method,
url, url,
@@ -280,7 +280,7 @@ class ApiClient:
try: try:
# perform request and return response # perform request and return response
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.rest_client.request( response_data = {{#async}}await {{/async}}{{#tornado}}yield {{/tornado}}self.rest_client.request(
method, url, method, url,
headers=header_params, headers=header_params,
body=body, post_params=post_params, body=body, post_params=post_params,

View File

@@ -10,7 +10,7 @@ from pprint import pprint
{{> python_doc_auth_partial}} {{> python_doc_auth_partial}}
# Enter a context with an instance of the API client # Enter a context with an instance of the API client
{{#asyncio}}async {{/asyncio}}with {{{packageName}}}.ApiClient(configuration) as api_client: {{#async}}async {{/async}}with {{{packageName}}}.ApiClient(configuration) as api_client:
# Create an instance of the API class # Create an instance of the API class
api_instance = {{{packageName}}}.{{{classname}}}(api_client) api_instance = {{{packageName}}}.{{{classname}}}(api_client)
{{#allParams}} {{#allParams}}
@@ -21,7 +21,7 @@ from pprint import pprint
{{#summary}} {{#summary}}
# {{{.}}} # {{{.}}}
{{/summary}} {{/summary}}
{{#returnType}}api_response = {{/returnType}}{{#asyncio}}await {{/asyncio}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) {{#returnType}}api_response = {{/returnType}}{{#async}}await {{/async}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
{{#returnType}} {{#returnType}}
print("The response of {{classname}}->{{operationId}}:\n") print("The response of {{classname}}->{{operationId}}:\n")
pprint(api_response) pprint(api_response)

View File

@@ -8,31 +8,31 @@ import unittest
from {{apiPackage}}.{{classFilename}} import {{classname}} from {{apiPackage}}.{{classFilename}} import {{classname}}
class {{#operations}}Test{{classname}}(unittest.{{#asyncio}}IsolatedAsyncio{{/asyncio}}TestCase): class {{#operations}}Test{{classname}}(unittest.{{#async}}IsolatedAsyncio{{/async}}TestCase):
"""{{classname}} unit test stubs""" """{{classname}} unit test stubs"""
{{#asyncio}} {{#async}}
async def asyncSetUp(self) -> None: async def asyncSetUp(self) -> None:
self.api = {{classname}}() self.api = {{classname}}()
async def asyncTearDown(self) -> None: async def asyncTearDown(self) -> None:
await self.api.api_client.close() await self.api.api_client.close()
{{/asyncio}} {{/async}}
{{^asyncio}} {{^async}}
def setUp(self) -> None: def setUp(self) -> None:
self.api = {{classname}}() self.api = {{classname}}()
def tearDown(self) -> None: def tearDown(self) -> None:
pass pass
{{/asyncio}} {{/async}}
{{#operation}} {{#operation}}
{{#asyncio}} {{#async}}
async def test_{{operationId}}(self) -> None: async def test_{{operationId}}(self) -> None:
{{/asyncio}} {{/async}}
{{^asyncio}} {{^async}}
def test_{{operationId}}(self) -> None: def test_{{operationId}}(self) -> None:
{{/asyncio}} {{/async}}
"""Test case for {{{operationId}}} """Test case for {{{operationId}}}
{{#summary}} {{#summary}}

View File

@@ -8,7 +8,7 @@ from pprint import pprint
# Enter a context with an instance of the API client # Enter a context with an instance of the API client
{{#asyncio}}async {{/asyncio}}with {{{packageName}}}.ApiClient(configuration) as api_client: {{#async}}async {{/async}}with {{{packageName}}}.ApiClient(configuration) as api_client:
# Create an instance of the API class # Create an instance of the API class
api_instance = {{{packageName}}}.{{{classname}}}(api_client) api_instance = {{{packageName}}}.{{{classname}}}(api_client)
{{#allParams}} {{#allParams}}
@@ -19,7 +19,7 @@ from pprint import pprint
{{#summary}} {{#summary}}
# {{{.}}} # {{{.}}}
{{/summary}} {{/summary}}
{{#returnType}}api_response = {{/returnType}}{{#asyncio}}await {{/asyncio}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) {{#returnType}}api_response = {{/returnType}}{{#async}}await {{/async}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
{{#returnType}} {{#returnType}}
print("The response of {{classname}}->{{operationId}}:\n") print("The response of {{classname}}->{{operationId}}:\n")
pprint(api_response) pprint(api_response)

View File

@@ -7,9 +7,9 @@ import copy
import http.client as httplib import http.client as httplib
import logging import logging
from logging import FileHandler from logging import FileHandler
{{^asyncio}} {{^async}}
import multiprocessing import multiprocessing
{{/asyncio}} {{/async}}
import sys import sys
from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union
from typing_extensions import NotRequired, Self from typing_extensions import NotRequired, Self
@@ -395,13 +395,13 @@ conf = {{{packageName}}}.Configuration(
Set this to the SNI value expected by the server. Set this to the SNI value expected by the server.
""" """
{{#asyncio}} {{#async}}
self.connection_pool_maxsize = 100 self.connection_pool_maxsize = 100
"""This value is passed to the aiohttp to limit simultaneous connections. """This value is passed to the aiohttp to limit simultaneous connections.
Default values is 100, None means no-limit. Default values is 100, None means no-limit.
""" """
{{/asyncio}} {{/async}}
{{^asyncio}} {{^async}}
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
"""urllib3 connection pool's maximum number of connections saved """urllib3 connection pool's maximum number of connections saved
per pool. urllib3 uses 1 connection as default value, but this is per pool. urllib3 uses 1 connection as default value, but this is
@@ -409,7 +409,7 @@ conf = {{{packageName}}}.Configuration(
requests to the same host, which is often the case here. requests to the same host, which is often the case here.
cpu_count * 5 is used as default value to increase performance. cpu_count * 5 is used as default value to increase performance.
""" """
{{/asyncio}} {{/async}}
self.proxy: Optional[str] = None self.proxy: Optional[str] = None
"""Proxy URL """Proxy URL

View File

@@ -0,0 +1,185 @@
# coding: utf-8
{{>partial_header}}
import io
import json
import re
import ssl
from typing import Optional, Union
import httpx
from {{packageName}}.exceptions import ApiException, ApiValueError
RESTResponseType = httpx.Response
class RESTResponse(io.IOBase):
def __init__(self, resp) -> None:
self.response = resp
self.status = resp.status_code
self.reason = resp.reason_phrase
self.data = None
async def read(self):
if self.data is None:
self.data = await self.response.aread()
return self.data
def getheaders(self):
"""Returns a CIMultiDictProxy of the response headers."""
return self.response.headers
def getheader(self, name, default=None):
"""Returns a given response header."""
return self.response.headers.get(name, default)
class RESTClientObject:
def __init__(self, configuration) -> None:
# maxsize is number of requests to host that are allowed in parallel
self.maxsize = configuration.connection_pool_maxsize
self.ssl_context = ssl.create_default_context(
cafile=configuration.ssl_ca_cert,
cadata=configuration.ca_cert_data,
)
if configuration.cert_file:
self.ssl_context.load_cert_chain(
configuration.cert_file, keyfile=configuration.key_file
)
if not configuration.verify_ssl:
self.ssl_context.check_hostname = False
self.ssl_context.verify_mode = ssl.CERT_NONE
self.proxy = configuration.proxy
self.proxy_headers = configuration.proxy_headers
self.pool_manager: Optional[httpx.AsyncClient] = None
async def close(self):
if self.pool_manager is not None:
await self.pool_manager.aclose()
async def request(
self,
method,
url,
headers=None,
body=None,
post_params=None,
_request_timeout=None):
"""Execute request
:param method: http request method
:param url: http request url
:param headers: http request headers
:param body: request json body, for `application/json`
:param post_params: request post parameters,
`application/x-www-form-urlencoded`
and `multipart/form-data`
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
"""
method = method.upper()
assert method in [
'GET',
'HEAD',
'DELETE',
'POST',
'PUT',
'PATCH',
'OPTIONS'
]
if post_params and body:
raise ApiValueError(
"body parameter cannot be used with post_params parameter."
)
post_params = post_params or {}
headers = headers or {}
timeout = _request_timeout or 5 * 60
if 'Content-Type' not in headers:
headers['Content-Type'] = 'application/json'
args = {
"method": method,
"url": url,
"timeout": timeout,
"headers": headers
}
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
if re.search('json', headers['Content-Type'], re.IGNORECASE):
if body is not None:
args["json"] = body
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
args["data"] = dict(post_params)
elif headers['Content-Type'] == 'multipart/form-data':
# must del headers['Content-Type'], or the correct
# Content-Type which generated by httpx
del headers['Content-Type']
files = []
data = {}
for param in post_params:
k, v = param
if isinstance(v, tuple) and len(v) == 3:
files.append((k, v))
else:
# Ensures that dict objects are serialized
if isinstance(v, dict):
v = json.dumps(v)
elif isinstance(v, int):
v = str(v)
data[k] = v
if files:
args["files"] = files
if data:
args["data"] = data
# Pass a `bytes` parameter directly in the body to support
# other content types than Json when `body` argument is provided
# in serialized form
elif isinstance(body, str) or isinstance(body, bytes):
args["data"] = body
else:
# Cannot generate the request from given parameters
msg = """Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
if self.pool_manager is None:
self.pool_manager = self._create_pool_manager()
r = await self.pool_manager.request(**args)
return RESTResponse(r)
def _create_pool_manager(self) -> httpx.AsyncClient:
limits = httpx.Limits(max_connections=self.maxsize)
proxy = None
if self.proxy:
proxy = httpx.Proxy(
url=self.proxy,
headers=self.proxy_headers
)
return httpx.AsyncClient(
limits=limits,
proxy=proxy,
verify=self.ssl_context,
trust_env=True
)

View File

@@ -24,6 +24,13 @@ class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum):
def from_json(cls, json_str: str) -> Self: def from_json(cls, json_str: str) -> Self:
"""Create an instance of {{classname}} from a JSON string""" """Create an instance of {{classname}} from a JSON string"""
return cls(json.loads(json_str)) return cls(json.loads(json_str))
{{#enumUnknownDefaultCase}}
@classmethod
def _missing_(cls, value):
"""Handle unknown enum values"""
return cls.UNKNOWN_DEFAULT_OPEN_API
{{/enumUnknownDefaultCase}}
{{#defaultValue}} {{#defaultValue}}

View File

@@ -39,6 +39,9 @@ python-dateutil = ">= 2.8.2"
aiohttp = ">= 3.8.4" aiohttp = ">= 3.8.4"
aiohttp-retry = ">= 2.8.3" aiohttp-retry = ">= 2.8.3"
{{/asyncio}} {{/asyncio}}
{{#httpx}}
httpx = ">= 0.28.1"
{{/httpx}}
{{#tornado}} {{#tornado}}
tornado = ">=4.2, <5" tornado = ">=4.2, <5"
{{/tornado}} {{/tornado}}
@@ -58,10 +61,10 @@ requires-python = ">=3.9"
dependencies = [ dependencies = [
"urllib3 (>=2.1.0,<3.0.0)", "urllib3 (>=2.1.0,<3.0.0)",
"python-dateutil (>=2.8.2)", "python-dateutil (>=2.8.2)",
{{#asyncio}} {{#async}}
"aiohttp (>=3.8.4)", "aiohttp (>=3.8.4)",
"aiohttp-retry (>=2.8.3)", "aiohttp-retry (>=2.8.3)",
{{/asyncio}} {{/async}}
{{#tornado}} {{#tornado}}
"tornado (>=4.2,<5)", "tornado (>=4.2,<5)",
{{/tornado}} {{/tornado}}

View File

@@ -4,6 +4,9 @@ python_dateutil >= 2.8.2
aiohttp >= 3.8.4 aiohttp >= 3.8.4
aiohttp-retry >= 2.8.3 aiohttp-retry >= 2.8.3
{{/asyncio}} {{/asyncio}}
{{#httpx}}
httpx = ">= 0.28.1"
{{/httpx}}
{{#tornado}} {{#tornado}}
tornado = ">= 4.2, < 5" tornado = ">= 4.2, < 5"
{{/tornado}} {{/tornado}}

View File

@@ -21,6 +21,9 @@ REQUIRES = [
"aiohttp >= 3.8.4", "aiohttp >= 3.8.4",
"aiohttp-retry >= 2.8.3", "aiohttp-retry >= 2.8.3",
{{/asyncio}} {{/asyncio}}
{{#httpx}}
"httpx >= 0.28.1",
{{/httpx}}
{{#tornado}} {{#tornado}}
"tornado>=4.2, < 5", "tornado>=4.2, < 5",
{{/tornado}} {{/tornado}}

View File

@@ -524,7 +524,7 @@ pub fn check_xss_map<T>(v: &std::collections::HashMap<String, T>) -> std::result
/// Enumeration of values. /// Enumeration of values.
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` /// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
/// which helps with FFI. /// which helps with FFI.
#[allow(non_camel_case_types)] #[allow(non_camel_case_types, clippy::large_enum_variant)]
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] #[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
@@ -751,17 +751,38 @@ impl std::str::FromStr for {{{classname}}} {
{{^arrayModelType}} {{^arrayModelType}}
{{! general struct}} {{! general struct}}
{{#anyOf.size}} {{#anyOf.size}}
/// Any of: {{#discriminator}}
{{#anyOf}} #[derive(Debug, Clone, PartialEq, serde::Deserialize)]
/// - {{{.}}} #[serde(tag = "{{{propertyBaseName}}}")]
{{/anyOf}} {{/discriminator}}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] {{^discriminator}}
pub struct {{{classname}}}(Box<serde_json::value::RawValue>); #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
{{/discriminator}}
#[allow(non_camel_case_types, clippy::large_enum_variant)]
pub enum {{{classname}}} {
{{#composedSchemas}}
{{#anyOf}}
{{{datatypeWithEnum}}}({{{dataType}}}),
{{/anyOf}}
{{/composedSchemas}}
}
impl validator::Validate for {{{classname}}} impl validator::Validate for {{{classname}}}
{ {
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> { fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
std::result::Result::Ok(()) match self {
{{#composedSchemas}}
{{#anyOf}}
{{^isModel}}
Self::{{{datatypeWithEnum}}}(_) => std::result::Result::Ok(()),
{{/isModel}}
{{#isModel}}
Self::{{{datatypeWithEnum}}}(v) => v.validate(),
{{/isModel}}
{{/anyOf}}
{{/composedSchemas}}
}
} }
} }
@@ -776,11 +797,32 @@ impl std::str::FromStr for {{{classname}}} {
} }
} }
impl PartialEq for {{{classname}}} { {{#discriminator}}
fn eq(&self, other: &Self) -> bool { impl serde::Serialize for {{{classname}}} {
self.0.get() == other.0.get() fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
match self {
{{#composedSchemas}}
{{#anyOf}}
Self::{{{datatypeWithEnum}}}(x) => x.serialize(serializer),
{{/anyOf}}
{{/composedSchemas}}
}
} }
} }
{{/discriminator}}
{{#composedSchemas}}
{{#anyOf}}
{{#vendorExtensions.x-from-trait}}
impl From<{{{dataType}}}> for {{{classname}}} {
fn from(value: {{{dataType}}}) -> Self {
Self::{{{datatypeWithEnum}}}(value)
}
}
{{/vendorExtensions.x-from-trait}}
{{/anyOf}}
{{/composedSchemas}}
{{/anyOf.size}} {{/anyOf.size}}
{{#oneOf.size}} {{#oneOf.size}}
@@ -792,11 +834,11 @@ impl PartialEq for {{{classname}}} {
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(untagged)] #[serde(untagged)]
{{/discriminator}} {{/discriminator}}
#[allow(non_camel_case_types)] #[allow(non_camel_case_types, clippy::large_enum_variant)]
pub enum {{{classname}}} { pub enum {{{classname}}} {
{{#composedSchemas}} {{#composedSchemas}}
{{#oneOf}} {{#oneOf}}
{{{datatypeWithEnum}}}(Box<{{{dataType}}}>), {{{datatypeWithEnum}}}({{{dataType}}}),
{{/oneOf}} {{/oneOf}}
{{/composedSchemas}} {{/composedSchemas}}
} }
@@ -807,18 +849,29 @@ impl validator::Validate for {{{classname}}}
match self { match self {
{{#composedSchemas}} {{#composedSchemas}}
{{#oneOf}} {{#oneOf}}
{{#isPrimitiveType}} {{^isModel}}
Self::{{{datatypeWithEnum}}}(_) => std::result::Result::Ok(()), Self::{{{datatypeWithEnum}}}(_) => std::result::Result::Ok(()),
{{/isPrimitiveType}} {{/isModel}}
{{^isPrimitiveType}} {{#isModel}}
Self::{{{datatypeWithEnum}}}(x) => x.validate(), Self::{{{datatypeWithEnum}}}(v) => v.validate(),
{{/isPrimitiveType}} {{/isModel}}
{{/oneOf}} {{/oneOf}}
{{/composedSchemas}} {{/composedSchemas}}
} }
} }
} }
/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value
/// as specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde deserializer
impl std::str::FromStr for {{{classname}}} {
type Err = serde_json::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
{{#discriminator}} {{#discriminator}}
impl serde::Serialize for {{{classname}}} { impl serde::Serialize for {{{classname}}} {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -834,29 +887,18 @@ impl serde::Serialize for {{{classname}}} {
} }
{{/discriminator}} {{/discriminator}}
{{#composedSchemas}} {{#composedSchemas}}
{{#oneOf}} {{#oneOf}}
{{#vendorExtensions.x-from-trait}}
impl From<{{{dataType}}}> for {{{classname}}} { impl From<{{{dataType}}}> for {{{classname}}} {
fn from(value: {{{dataType}}}) -> Self { fn from(value: {{{dataType}}}) -> Self {
Self::{{{datatypeWithEnum}}}(Box::new(value)) Self::{{{datatypeWithEnum}}}(value)
} }
} }
{{/vendorExtensions.x-from-trait}}
{{/oneOf}} {{/oneOf}}
{{/composedSchemas}} {{/composedSchemas}}
/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value
/// as specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde deserializer
impl std::str::FromStr for {{{classname}}} {
type Err = serde_json::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
{{/oneOf.size}} {{/oneOf.size}}
{{^anyOf.size}} {{^anyOf.size}}
{{^oneOf.size}} {{^oneOf.size}}
@@ -871,8 +913,10 @@ pub struct {{{classname}}} {
/// Note: inline enums are not fully supported by openapi-generator /// Note: inline enums are not fully supported by openapi-generator
{{/isEnum}} {{/isEnum}}
{{#isDiscriminator}} {{#isDiscriminator}}
{{#isString}}
#[serde(default = "{{{classname}}}::_name_for_{{{name}}}")] #[serde(default = "{{{classname}}}::_name_for_{{{name}}}")]
#[serde(serialize_with = "{{{classname}}}::_serialize_{{{name}}}")] #[serde(serialize_with = "{{{classname}}}::_serialize_{{{name}}}")]
{{/isString}}
{{/isDiscriminator}} {{/isDiscriminator}}
#[serde(rename = "{{{baseName}}}")] #[serde(rename = "{{{baseName}}}")]
{{#hasValidation}} {{#hasValidation}}
@@ -989,9 +1033,9 @@ pub struct {{{classname}}} {
{{/vars}} {{/vars}}
} }
{{#vars}} {{#vars}}
{{#isDiscriminator}} {{#isDiscriminator}}
{{#isString}}
impl {{{classname}}} { impl {{{classname}}} {
fn _name_for_{{{name}}}() -> String { fn _name_for_{{{name}}}() -> String {
String::from("{{{classname}}}") String::from("{{{classname}}}")
@@ -1004,10 +1048,10 @@ impl {{{classname}}} {
s.serialize_str(&Self::_name_for_{{{name}}}()) s.serialize_str(&Self::_name_for_{{{name}}}())
} }
} }
{{/isString}}
{{/isDiscriminator}} {{/isDiscriminator}}
{{/vars}} {{/vars}}
{{#vars}} {{#vars}}
{{#hasValidation}} {{#hasValidation}}
{{#pattern}} {{#pattern}}
@@ -1035,9 +1079,9 @@ fn validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowerc
impl {{{classname}}} { impl {{{classname}}} {
#[allow(clippy::new_without_default, clippy::too_many_arguments)] #[allow(clippy::new_without_default, clippy::too_many_arguments)]
pub fn new({{#vars}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/vars}}) -> {{{classname}}} { pub fn new({{#vars}}{{^isDiscriminator}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/isDiscriminator}}{{#isDiscriminator}}{{^isString}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/isString}}{{/isDiscriminator}}{{/vars}}) -> {{{classname}}} {
{{{classname}}} { {{{classname}}} {
{{#vars}} {{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}, {{#vars}} {{^isDiscriminator}}{{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}{{/isDiscriminator}}{{#isDiscriminator}}{{#isString}}{{{name}}}: Self::_name_for_{{{name}}}(){{/isString}}{{^isString}}{{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}{{/isString}}{{/isDiscriminator}},
{{/vars}} {{/vars}}
} }
} }
@@ -1075,7 +1119,7 @@ impl std::fmt::Display for {{{classname}}} {
{{/isArray}} {{/isArray}}
{{#isArray}} {{#isArray}}
{{#isNullable}} {{#isNullable}}
Some(self.{{{name}}}.as_ref().map_or(vec!["null".to_string()], |x| x.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))), Some(self.{{{name}}}.as_ref().map_or("null".to_string(), |x| x.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))),
{{/isNullable}} {{/isNullable}}
{{^isNullable}} {{^isNullable}}
Some(self.{{{name}}}.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",")), Some(self.{{{name}}}.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",")),
@@ -1226,7 +1270,6 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<{{{classname
} }
} }
} }
{{/oneOf.size}} {{/oneOf.size}}
{{/anyOf.size}} {{/anyOf.size}}

View File

@@ -121,145 +121,80 @@ impl Default for {{classname}} {
{{!-- for non-enum schemas --}} {{!-- for non-enum schemas --}}
{{^isEnum}} {{^isEnum}}
{{^discriminator}} {{^discriminator}}
{{#composedSchemas}} {{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
{{#oneOf}} {{/vendorExtensions.x-rust-has-byte-array}}{{#oneOf.isEmpty}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
{{#-first}} pub struct {{{classname}}} {
{{! Model with composedSchemas.oneOf - generate enum}} {{#vars}}
{{#description}}
/// {{{.}}}
{{/description}}
{{#isByteArray}}
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/vendorExtensions.isMandatory}}
{{/isByteArray}}
#[serde(rename = "{{{baseName}}}"{{^required}}{{#isNullable}}, default{{^isByteArray}}, with = "::serde_with::rust::double_option"{{/isByteArray}}{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}, deserialize_with = "Option::deserialize"{{/isNullable}}{{/required}})]
pub {{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums Start
}}{{^isEnum}}{{!
### Models
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
### Primative datatypes
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
### Non-Enums End
}}{{/isEnum}}{{!
### Option End (and trailing comma)
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
{{/vars}}
}
impl {{{classname}}} {
{{#description}}
/// {{{.}}}
{{/description}}
pub fn new({{#requiredVars}}{{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
### Option End
}}{{#isNullable}}>{{/isNullable}}{{!
### Comma for next arguement
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
{{{classname}}} {
{{#vars}}
{{{name}}}{{^required}}: None{{/required}}{{#required}}{{#isModel}}{{^avoidBoxedModels}}: {{^isNullable}}Box::new({{{name}}}){{/isNullable}}{{#isNullable}}if let Some(x) = {{{name}}} {Some(Box::new(x))} else {None}{{/isNullable}}{{/avoidBoxedModels}}{{/isModel}}{{/required}},
{{/vars}}
}
}
}
{{/oneOf.isEmpty}}
{{^oneOf.isEmpty}}
{{! TODO: add other vars that are not part of the oneOf}}
{{#description}}
/// {{{.}}}
{{/description}}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum {{classname}} { pub enum {{classname}} {
{{/-first}} {{#composedSchemas.oneOf}}
{{/oneOf}}
{{/composedSchemas}}
{{#composedSchemas}}
{{#oneOf}}
{{#description}} {{#description}}
/// {{{.}}} /// {{{.}}}
{{/description}} {{/description}}
{{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}), {{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}),
{{/oneOf}} {{/composedSchemas.oneOf}}
{{/composedSchemas}}
{{#composedSchemas}}
{{#oneOf}}
{{#-last}}
} }
impl Default for {{classname}} { impl Default for {{classname}} {
fn default() -> Self { fn default() -> Self {
{{#oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/oneOf}} {{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/composedSchemas.oneOf}}
} }
} }
{{/-last}} {{/oneOf.isEmpty}}
{{/oneOf}}
{{^oneOf}}
{{! composedSchemas exists but no oneOf - generate normal struct}}
{{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
{{/vendorExtensions.x-rust-has-byte-array}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct {{{classname}}} {
{{#vars}}
{{#description}}
/// {{{.}}}
{{/description}}
{{#isByteArray}}
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/vendorExtensions.isMandatory}}
{{/isByteArray}}
#[serde(rename = "{{{baseName}}}"{{^required}}{{#isNullable}}, default{{^isByteArray}}, with = "::serde_with::rust::double_option"{{/isByteArray}}{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}, deserialize_with = "Option::deserialize"{{/isNullable}}{{/required}})]
pub {{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums Start
}}{{^isEnum}}{{!
### Models
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
### Primative datatypes
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
### Non-Enums End
}}{{/isEnum}}{{!
### Option End (and trailing comma)
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
{{/vars}}
}
impl {{{classname}}} {
{{#description}}
/// {{{.}}}
{{/description}}
pub fn new({{#requiredVars}}{{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
### Option End
}}{{#isNullable}}>{{/isNullable}}{{!
### Comma for next arguement
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
{{{classname}}} {
{{#vars}}
{{{name}}}{{^required}}: None{{/required}}{{#required}}{{#isModel}}{{^avoidBoxedModels}}: {{^isNullable}}Box::new({{{name}}}){{/isNullable}}{{#isNullable}}if let Some(x) = {{{name}}} {Some(Box::new(x))} else {None}{{/isNullable}}{{/avoidBoxedModels}}{{/isModel}}{{/required}},
{{/vars}}
}
}
}
{{/oneOf}}
{{/composedSchemas}}
{{^composedSchemas}}
{{! Normal struct without composedSchemas}}
{{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
{{/vendorExtensions.x-rust-has-byte-array}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct {{{classname}}} {
{{#vars}}
{{#description}}
/// {{{.}}}
{{/description}}
{{#isByteArray}}
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/vendorExtensions.isMandatory}}
{{/isByteArray}}
#[serde(rename = "{{{baseName}}}"{{^required}}{{#isNullable}}, default{{^isByteArray}}, with = "::serde_with::rust::double_option"{{/isByteArray}}{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}, deserialize_with = "Option::deserialize"{{/isNullable}}{{/required}})]
pub {{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums Start
}}{{^isEnum}}{{!
### Models
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
### Primative datatypes
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
### Non-Enums End
}}{{/isEnum}}{{!
### Option End (and trailing comma)
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
{{/vars}}
}
impl {{{classname}}} {
{{#description}}
/// {{{.}}}
{{/description}}
pub fn new({{#requiredVars}}{{{name}}}: {{!
### Option Start
}}{{#isNullable}}Option<{{/isNullable}}{{!
### Enums
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
### Non-Enums
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
### Option End
}}{{#isNullable}}>{{/isNullable}}{{!
### Comma for next arguement
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
{{{classname}}} {
{{#vars}}
{{{name}}}{{^required}}: None{{/required}}{{#required}}{{#isModel}}{{^avoidBoxedModels}}: {{^isNullable}}Box::new({{{name}}}){{/isNullable}}{{#isNullable}}if let Some(x) = {{{name}}} {Some(Box::new(x))} else {None}{{/isNullable}}{{/avoidBoxedModels}}{{/isModel}}{{/required}},
{{/vars}}
}
}
}
{{/composedSchemas}}
{{/discriminator}} {{/discriminator}}
{{/isEnum}} {{/isEnum}}
{{!-- for properties that are of enum type --}} {{!-- for properties that are of enum type --}}

View File

@@ -22,7 +22,7 @@ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObj
import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '{{apiRelativeToRoot}}base{{importFileExtension}}'; import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '{{apiRelativeToRoot}}base{{importFileExtension}}';
{{#imports}} {{#imports}}
// @ts-ignore // @ts-ignore
import type { {{classname}} } from '{{apiRelativeToRoot}}{{tsModelPackage}}{{importFileExtension}}'; import type { {{classname}} } from '{{apiRelativeToRoot}}{{tsModelPackage}}{{#importFileExtension}}/index{{importFileExtension}}{{/importFileExtension}}';
{{/imports}} {{/imports}}
{{/withSeparateModelsAndApi}} {{/withSeparateModelsAndApi}}
{{^withSeparateModelsAndApi}} {{^withSeparateModelsAndApi}}

View File

@@ -5,4 +5,4 @@
export * from "./api{{importFileExtension}}"; export * from "./api{{importFileExtension}}";
export * from "./configuration{{importFileExtension}}"; export * from "./configuration{{importFileExtension}}";
{{#withSeparateModelsAndApi}}export * from "./{{tsModelPackage}}{{importFileExtension}}";{{/withSeparateModelsAndApi}} {{#withSeparateModelsAndApi}}export * from "./{{tsModelPackage}}{{#importFileExtension}}/index{{importFileExtension}}{{/importFileExtension}}";{{/withSeparateModelsAndApi}}

View File

@@ -15,7 +15,7 @@
{{/packageAsSourceOnlyLibrary}} {{/packageAsSourceOnlyLibrary}}
{{^packageAsSourceOnlyLibrary}} {{^packageAsSourceOnlyLibrary}}
"main": "./dist/index.js", "main": "./dist/index.js",
"typings": "./dist/index.d.ts", "types": "./dist/index.d.ts",
{{#supportsES6}} {{#supportsES6}}
"module": "./dist/esm/index.js", "module": "./dist/esm/index.js",
"sideEffects": false, "sideEffects": false,

View File

@@ -3982,4 +3982,21 @@ public class JavaClientCodegenTest {
} }
assertTrue(speciesSeen); assertTrue(speciesSeen);
} }
@Test
public void testOneOfClassWithAnnotation() throws IOException {
final Map<String, File> files = generateFromContract("src/test/resources/3_0/java/oneOf-with-annotations.yaml", RESTCLIENT);
JavaFileAssert.assertThat(files.get("Fruit.java"))
.isNormalClass()
.assertTypeAnnotations().containsWithName("SuppressWarnings");
}
@Test
public void testOneOfInterfaceWithAnnotation() throws IOException {
final Map<String, File> files = generateFromContract("src/test/resources/3_0/java/oneOf-with-annotations.yaml", RESTCLIENT,
Map.of(USE_ONE_OF_INTERFACES, "true"));
JavaFileAssert.assertThat(files.get("Fruit.java"))
.isInterface()
.assertTypeAnnotations().containsWithName("SuppressWarnings");
}
} }

View File

@@ -5730,4 +5730,12 @@ public class SpringCodegenTest {
javaFileAssert javaFileAssert
.hasImports("java.util.concurrent.atomic.AtomicInteger"); .hasImports("java.util.concurrent.atomic.AtomicInteger");
} }
@Test
public void testOneOfInterfaceWithAnnotation() throws IOException {
final Map<String, File> files = generateFromContract("src/test/resources/3_0/java/oneOf-with-annotations.yaml", SPRING_BOOT);
JavaFileAssert.assertThat(files.get("Fruit.java"))
.isInterface()
.assertTypeAnnotations().containsWithName("SuppressWarnings");
}
} }

View File

@@ -91,6 +91,24 @@ public class KotlinClientCodegenApiTest {
assertFileContainsLine(lines, "suspend fun deletePet(@Path(\"petId\") petId: kotlin.Long, @Header(\"api_key\") apiKey: kotlin.String? = null)" + expectedUnitResponse); assertFileContainsLine(lines, "suspend fun deletePet(@Path(\"petId\") petId: kotlin.Long, @Header(\"api_key\") apiKey: kotlin.String? = null)" + expectedUnitResponse);
} }
@Test
public void testEnumDefaultForReferencedSchemaParameterJvmOkhttp4() throws IOException {
OpenAPI openAPI = readOpenAPI("3_0/kotlin/enum-default-query.yaml");
KotlinClientCodegen codegen = createCodegen(ClientLibrary.JVM_OKHTTP4);
codegen.additionalProperties().put("enumPropertyNaming", "UPPERCASE");
ClientOptInput input = createClientOptInput(openAPI, codegen);
DefaultGenerator generator = new DefaultGenerator();
enableOnlyApiGeneration(generator);
List<File> files = generator.opts(input).generate();
File statusApi = files.stream().filter(file -> file.getName().equals("StatusApi.kt")).findAny().orElseThrow();
assertFileContains(statusApi.toPath(), "state: PetStatus? = PetStatus.AVAILABLE");
}
private static void assertFileContainsLine(List<String> lines, String line) { private static void assertFileContainsLine(List<String> lines, String line) {
Assert.assertListContains(lines, s -> s.equals(line), line); Assert.assertListContains(lines, s -> s.equals(line), line);
} }

View File

@@ -26,6 +26,8 @@ import io.swagger.v3.parser.core.models.ParseOptions;
import io.swagger.v3.parser.util.SchemaTypeUtil; import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.languages.PythonClientCodegen; import org.openapitools.codegen.languages.PythonClientCodegen;
import org.openapitools.codegen.languages.features.CXFServerFeatures; import org.openapitools.codegen.languages.features.CXFServerFeatures;
import org.testng.Assert; import org.testng.Assert;
@@ -38,6 +40,8 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@@ -47,6 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileContains;
import static org.openapitools.codegen.TestUtils.assertFileExists; import static org.openapitools.codegen.TestUtils.assertFileExists;
import static org.openapitools.codegen.TestUtils.assertFileNotContains;
public class PythonClientCodegenTest { public class PythonClientCodegenTest {
@@ -685,4 +690,120 @@ public class PythonClientCodegenTest {
// Verify it does NOT use the legacy string format // Verify it does NOT use the legacy string format
TestUtils.assertFileNotContains(pyprojectPath, "license = \"BSD-3-Clause\""); TestUtils.assertFileNotContains(pyprojectPath, "license = \"BSD-3-Clause\"");
} }
@Test(description = "test enumUnknownDefaultCase option")
public void testEnumUnknownDefaultCaseOption() {
final PythonClientCodegen codegen = new PythonClientCodegen();
// Test default value is false
codegen.processOpts();
Assert.assertEquals(codegen.getEnumUnknownDefaultCase(), Boolean.FALSE);
// Test setting via additionalProperties
codegen.additionalProperties().put(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, "true");
codegen.processOpts();
Assert.assertEquals(codegen.getEnumUnknownDefaultCase(), Boolean.TRUE);
}
@Test(description = "test enum model generation with enumUnknownDefaultCase")
public void testEnumModelWithUnknownDefaultCase() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/enum_unknown_default_case.yaml");
final PythonClientCodegen codegen = new PythonClientCodegen();
// Enable enumUnknownDefaultCase
codegen.additionalProperties().put(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, "true");
codegen.setOpenAPI(openAPI);
codegen.processOpts();
// Verify that enumUnknownDefaultCase is set
Assert.assertEquals(codegen.getEnumUnknownDefaultCase(), Boolean.TRUE);
// Process all models to trigger enum processing
Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
Map<String, ModelsMap> allModels = new HashMap<>();
for (String modelName : schemas.keySet()) {
Schema schema = schemas.get(modelName);
CodegenModel cm = codegen.fromModel(modelName, schema);
ModelsMap modelsMap = new ModelsMap();
modelsMap.setModels(Collections.singletonList(new ModelMap(Collections.singletonMap("model", cm))));
allModels.put(modelName, modelsMap);
}
// Post-process to add enumVars
allModels = codegen.postProcessAllModels(allModels);
// Get the ColorEnum model
CodegenModel colorEnum = null;
for (Map.Entry<String, ModelsMap> entry : allModels.entrySet()) {
if ("ColorEnum".equals(entry.getKey())) {
colorEnum = entry.getValue().getModels().get(0).getModel();
break;
}
}
Assert.assertNotNull(colorEnum);
Assert.assertNotNull(colorEnum.allowableValues);
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) colorEnum.allowableValues.get("enumVars");
Assert.assertNotNull(enumVars);
// Check that we have the expected enum values including UNKNOWN_DEFAULT_OPEN_API
Assert.assertTrue(enumVars.stream().anyMatch(var -> "'RED'".equals(var.get("value"))));
Assert.assertTrue(enumVars.stream().anyMatch(var -> "'GREEN'".equals(var.get("value"))));
Assert.assertTrue(enumVars.stream().anyMatch(var -> "'BLUE'".equals(var.get("value"))));
Assert.assertTrue(enumVars.stream().anyMatch(var -> "'YELLOW'".equals(var.get("value"))));
Assert.assertTrue(enumVars.stream().anyMatch(var -> "'unknown_default_open_api'".equals(var.get("value"))));
}
@Test(description = "test enum generation with enumUnknownDefaultCase enabled")
public void testEnumGenerationWithUnknownDefaultCase() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("python")
.setInputSpec("src/test/resources/3_0/enum_unknown_default_case.yaml")
.setOutputDir(outputPath)
.addAdditionalProperty(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, "true");
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
Path enumFile = Paths.get(outputPath, "openapi_client", "models", "color_enum.py");
// Check that UNKNOWN_DEFAULT_OPEN_API is added (with single quotes as Python generates)
TestUtils.assertFileContains(enumFile, "UNKNOWN_DEFAULT_OPEN_API = 'unknown_default_open_api'");
// Check that _missing_ method is added
TestUtils.assertFileContains(enumFile, "@classmethod");
TestUtils.assertFileContains(enumFile, "def _missing_(cls, value):");
TestUtils.assertFileContains(enumFile, "return cls.UNKNOWN_DEFAULT_OPEN_API");
}
@Test(description = "test enum generation with enumUnknownDefaultCase disabled")
public void testEnumGenerationWithoutUnknownDefaultCase() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("python")
.setInputSpec("src/test/resources/3_0/enum_unknown_default_case.yaml")
.setOutputDir(outputPath)
.addAdditionalProperty(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, "false");
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
Path enumFile = Paths.get(outputPath, "openapi_client", "models", "color_enum.py");
// Check that UNKNOWN_DEFAULT_OPEN_API is NOT added
TestUtils.assertFileNotContains(enumFile, "UNKNOWN_DEFAULT_OPEN_API");
// Check that _missing_ method is NOT added
TestUtils.assertFileNotContains(enumFile, "def _missing_(cls, value):");
}
} }

View File

@@ -271,37 +271,4 @@ public class RustClientCodegenTest {
TestUtils.assertFileExists(outputPath); TestUtils.assertFileExists(outputPath);
TestUtils.assertFileContains(outputPath, enumSpec); TestUtils.assertFileContains(outputPath, enumSpec);
} }
@Test
public void testAnyOfSupport() throws IOException {
Path target = Files.createTempDirectory("test-anyof");
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("rust")
.setInputSpec("src/test/resources/3_0/rust/rust-anyof-test.yaml")
.setSkipOverwrite(false)
.setOutputDir(target.toAbsolutePath().toString().replace("\\", "/"));
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
// Test that ModelIdentifier generates an untagged enum, not an empty struct
Path modelIdentifierPath = Path.of(target.toString(), "/src/models/model_identifier.rs");
TestUtils.assertFileExists(modelIdentifierPath);
// Should generate an untagged enum
TestUtils.assertFileContains(modelIdentifierPath, "#[serde(untagged)]");
TestUtils.assertFileContains(modelIdentifierPath, "pub enum ModelIdentifier");
// Should have String variant (for anyOf with string types)
TestUtils.assertFileContains(modelIdentifierPath, "String(String)");
// Should NOT generate an empty struct
TestUtils.assertFileNotContains(modelIdentifierPath, "pub struct ModelIdentifier {");
TestUtils.assertFileNotContains(modelIdentifierPath, "pub fn new()");
// Test AnotherAnyOfTest with mixed types
Path anotherTestPath = Path.of(target.toString(), "/src/models/another_any_of_test.rs");
TestUtils.assertFileExists(anotherTestPath);
TestUtils.assertFileContains(anotherTestPath, "#[serde(untagged)]");
TestUtils.assertFileContains(anotherTestPath, "pub enum AnotherAnyOfTest");
}
} }

View File

@@ -0,0 +1,56 @@
openapi: 3.0.0
info:
title: Enum Test API
description: API for testing enum generation with enumUnknownDefaultCase
version: 1.0.0
paths:
/colors:
get:
summary: Get color
operationId: getColor
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ColorResponse'
components:
schemas:
ColorResponse:
type: object
required:
- color
- status
properties:
color:
$ref: '#/components/schemas/ColorEnum'
status:
$ref: '#/components/schemas/StatusEnum'
priority:
$ref: '#/components/schemas/PriorityEnum'
ColorEnum:
type: string
description: Available colors
enum:
- RED
- GREEN
- BLUE
- YELLOW
StatusEnum:
type: string
description: Status values
enum:
- PENDING
- APPROVED
- REJECTED
- IN_PROGRESS
PriorityEnum:
type: integer
description: Priority levels
enum:
- 1
- 2
- 3
- 4
- 5

View File

@@ -0,0 +1,44 @@
openapi: 3.0.1
info:
title: fruity
version: 0.0.1
paths:
/:
get:
responses:
'200':
description: desc
content:
application/json:
schema:
$ref: '#/components/schemas/fruit'
components:
schemas:
fruit:
title: fruit
x-class-extra-annotation: '@SuppressWarnings("unchecked")'
properties:
color:
type: string
oneOf:
- $ref: '#/components/schemas/apple'
- $ref: '#/components/schemas/banana'
- $ref: '#/components/schemas/orange'
apple:
title: apple
type: object
properties:
kind:
type: string
banana:
title: banana
type: object
properties:
count:
type: number
orange:
title: orange
type: object
properties:
sweet:
type: boolean

View File

@@ -0,0 +1,26 @@
openapi: 3.0.1
info:
title: Enum default test
version: 1.0.0
paths:
/status:
get:
tags:
- Status
operationId: getStatus
parameters:
- name: state
in: query
schema:
$ref: '#/components/schemas/PetStatus'
responses:
'200':
description: OK
components:
schemas:
PetStatus:
type: string
enum:
- available
- pending
default: available

View File

@@ -0,0 +1,35 @@
openapi: 3.0.3
info:
title: optional body
version: 1.0.1
servers:
- url: https://api.123.com/api/v1
tags:
- name: just-api
description: Everything about API functions
paths:
/silly:
post:
tags:
- just-api
operationId: send_optional_payload
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Payload"
responses:
'200':
description: Successful operation
content:
application/text:
schema:
type: string
components:
schemas:
Payload:
type: object
properties:
token:
type: string
description: Some kind of token - usually received by Email

View File

@@ -31,7 +31,6 @@ paths:
$ref: '#/components/schemas/Foo' $ref: '#/components/schemas/Foo'
/pet: /pet:
servers: servers:
- url: 'http://127.0.0.1/v2'
- url: 'http://petstore.swagger.io/v2' - url: 'http://petstore.swagger.io/v2'
- url: 'http://path-server-test.petstore.local/v2' - url: 'http://path-server-test.petstore.local/v2'
- url: 'http://{server}.swagger.io:{port}/v2' - url: 'http://{server}.swagger.io:{port}/v2'
@@ -189,7 +188,6 @@ paths:
deprecated: true deprecated: true
'/pet/{petId}': '/pet/{petId}':
servers: servers:
- url: 'http://127.0.0.1/v2'
- url: 'http://petstore.swagger.io/v2' - url: 'http://petstore.swagger.io/v2'
- url: 'http://path-server-test.petstore.local/v2' - url: 'http://path-server-test.petstore.local/v2'
- url: 'http://{server}.swagger.io:{port}/v2' - url: 'http://{server}.swagger.io:{port}/v2'
@@ -1360,8 +1358,6 @@ paths:
200: 200:
description: OK description: OK
servers: servers:
- url: https://127.0.0.1/v2
description: The local server without variables
- url: 'http://{server}.swagger.io:{port}/v2' - url: 'http://{server}.swagger.io:{port}/v2'
description: petstore server description: petstore server
variables: variables:
@@ -1384,6 +1380,8 @@ servers:
- 'v1' - 'v1'
- 'v2' - 'v2'
default: 'v2' default: 'v2'
- url: https://127.0.0.1/no_varaible
description: The local server without variables
- url: http://server.{version}.openapi-generator.tech - url: http://server.{version}.openapi-generator.tech
description: The openapi-generator test server description: The openapi-generator test server
variables: variables:

View File

@@ -1,42 +0,0 @@
openapi: 3.0.0
info:
title: Rust anyOf Test
version: 1.0.0
paths:
/model:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/TestResponse'
components:
schemas:
TestResponse:
type: object
properties:
model:
$ref: '#/components/schemas/ModelIdentifier'
status:
type: string
ModelIdentifier:
description: Model identifier that can be a string or specific enum value
anyOf:
- type: string
description: Any model name as string
- type: string
enum:
- gpt-4
- gpt-3.5-turbo
- dall-e-3
description: Known model enum values
AnotherAnyOfTest:
description: Another test case with different types
anyOf:
- type: string
- type: integer
- type: array
items:
type: string

View File

@@ -15,7 +15,7 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<name>openapi-generator-project</name> <name>openapi-generator-project</name>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.16.0-SNAPSHOT</version> <version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<url>https://github.com/openapitools/openapi-generator</url> <url>https://github.com/openapitools/openapi-generator</url>
<scm> <scm>

View File

@@ -1 +1 @@
7.16.0-SNAPSHOT 7.17.0-SNAPSHOT

View File

@@ -6,7 +6,7 @@ This C# SDK is automatically generated by the [OpenAPI Generator](https://openap
- API version: 0.1.0 - API version: 0.1.0
- SDK version: 1.0.0 - SDK version: 1.0.0
- Generator version: 7.16.0-SNAPSHOT - Generator version: 7.17.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.CSharpClientCodegen - Build package: org.openapitools.codegen.languages.CSharpClientCodegen
<a id="frameworks-supported"></a> <a id="frameworks-supported"></a>

View File

@@ -1 +1 @@
7.16.0-SNAPSHOT 7.17.0-SNAPSHOT

View File

@@ -7,7 +7,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat
- API version: 0.1.0 - API version: 0.1.0
- Package version: 1.0.0 - Package version: 1.0.0
- Generator version: 7.16.0-SNAPSHOT - Generator version: 7.17.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.GoClientCodegen - Build package: org.openapitools.codegen.languages.GoClientCodegen
## Installation ## Installation

View File

@@ -1 +1 @@
7.16.0-SNAPSHOT 7.17.0-SNAPSHOT

View File

@@ -7,7 +7,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat
- API version: 0.1.0 - API version: 0.1.0
- Package version: 1.0.0 - Package version: 1.0.0
- Generator version: 7.16.0-SNAPSHOT - Generator version: 7.17.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.GoClientCodegen - Build package: org.openapitools.codegen.languages.GoClientCodegen
## Installation ## Installation

View File

@@ -1 +1 @@
7.16.0-SNAPSHOT 7.17.0-SNAPSHOT

View File

@@ -4,7 +4,7 @@ Echo Server API
- API version: 0.1.0 - API version: 0.1.0
- Generator version: 7.16.0-SNAPSHOT - Generator version: 7.17.0-SNAPSHOT
Echo Server API Echo Server API

View File

@@ -81,7 +81,7 @@ import org.openapitools.client.auth.Authentication;
import org.openapitools.client.auth.HttpBasicAuth; import org.openapitools.client.auth.HttpBasicAuth;
import org.openapitools.client.auth.HttpBearerAuth; import org.openapitools.client.auth.HttpBearerAuth;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class ApiClient extends JavaTimeFormatter { public class ApiClient extends JavaTimeFormatter {
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>(); protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>(); protected Map<String, String> defaultCookieMap = new HashMap<String, String>();

View File

@@ -16,7 +16,7 @@ package org.openapitools.client;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class ApiException extends Exception { public class ApiException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -17,7 +17,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public abstract class BaseApi { public abstract class BaseApi {
protected ApiClient apiClient; protected ApiClient apiClient;

View File

@@ -17,7 +17,7 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier; import java.util.function.Supplier;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class Configuration { public class Configuration {
public static final String VERSION = "0.1.0"; public static final String VERSION = "0.1.0";

View File

@@ -20,7 +20,7 @@ import java.time.format.DateTimeParseException;
* Class that add parsing/formatting support for Java 8+ {@code OffsetDateTime} class. * Class that add parsing/formatting support for Java 8+ {@code OffsetDateTime} class.
* It's generated for java clients when {@code AbstractJavaCodegen#dateLibrary} specified as {@code java8}. * It's generated for java clients when {@code AbstractJavaCodegen#dateLibrary} specified as {@code java8}.
*/ */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class JavaTimeFormatter { public class JavaTimeFormatter {
private DateTimeFormatter offsetDateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; private DateTimeFormatter offsetDateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;

View File

@@ -13,7 +13,7 @@
package org.openapitools.client; package org.openapitools.client;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class Pair { public class Pair {
private final String name; private final String name;
private final String value; private final String value;

View File

@@ -22,7 +22,7 @@ import java.text.DecimalFormat;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class RFC3339DateFormat extends DateFormat { public class RFC3339DateFormat extends DateFormat {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");

View File

@@ -28,7 +28,7 @@ import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature;
import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class RFC3339InstantDeserializer<T extends Temporal> extends InstantDeserializer<T> { public class RFC3339InstantDeserializer<T extends Temporal> extends InstantDeserializer<T> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static boolean DEFAULT_NORMALIZE_ZONE_ID = JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault(); private final static boolean DEFAULT_NORMALIZE_ZONE_ID = JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault();

View File

@@ -19,7 +19,7 @@ import java.time.ZonedDateTime;
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.Module.SetupContext; import com.fasterxml.jackson.databind.Module.SetupContext;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class RFC3339JavaTimeModule extends SimpleModule { public class RFC3339JavaTimeModule extends SimpleModule {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -18,7 +18,7 @@ import java.util.Map;
/** /**
* Representing a Server configuration. * Representing a Server configuration.
*/ */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class ServerConfiguration { public class ServerConfiguration {
public String URL; public String URL;
public String description; public String description;

View File

@@ -18,7 +18,7 @@ import java.util.HashSet;
/** /**
* Representing a Server Variable for server URL template substitution. * Representing a Server Variable for server URL template substitution.
*/ */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class ServerVariable { public class ServerVariable {
public String description; public String description;
public String defaultValue; public String defaultValue;

View File

@@ -16,7 +16,7 @@ package org.openapitools.client;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class StringUtil { public class StringUtil {
/** /**
* Check if the given array contains the given value (with case-insensitive comparison). * Check if the given array contains the given value (with case-insensitive comparison).

View File

@@ -30,7 +30,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class AuthApi extends BaseApi { public class AuthApi extends BaseApi {
public AuthApi() { public AuthApi() {

View File

@@ -34,7 +34,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class BodyApi extends BaseApi { public class BodyApi extends BaseApi {
public BodyApi() { public BodyApi() {

View File

@@ -31,7 +31,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class FormApi extends BaseApi { public class FormApi extends BaseApi {
public FormApi() { public FormApi() {

View File

@@ -31,7 +31,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0-SNAPSHOT") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
public class HeaderApi extends BaseApi { public class HeaderApi extends BaseApi {
public HeaderApi() { public HeaderApi() {

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