Compare commits

...

43 Commits

Author SHA1 Message Date
William Cheng
2fb26c362e update kotlin samples 2025-05-11 23:43:24 +08:00
Ross Sullivan
9981a408d1
[kotlin] Added path sanitization in javadoc comments (#20767)
* [kotlin] Added path sanitization in javadoc comments

* added sample as regression test

* Added samples/client/others/kotlin-jvm-okhttp-path-comments to github workflow
2025-05-11 23:23:50 +08:00
Mostafa Aghajani
91630b8591
feat: add default values support to Avro schema generator with related test cases (#21226) 2025-05-11 22:48:53 +08:00
Alex B
57bf6925bb
[Java] Make Java ApiClient extendable (#21251)
* Make all Java ApiClients in templates extendable

* Make all Java ApiClients in samples extendable

* Fix compilation of enum constructor

* Fix compilation of enum constructor in templates
2025-05-11 22:47:40 +08:00
Jonas Renggli
be17698320
[php-flight] fix: remove trailing spaces (#21254)
According to the Guidelines for Contributing
(https://github.com/OpenAPITools/openapi-generator/blob/master/CONTRIBUTING.md)
generated PHP code should conform to PSR-12
(https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md).

There are some minor violations regarding the following rule

> There MUST NOT be trailing whitespace at the end of lines.

This change removes trailing spaces in generated code.
2025-05-11 22:32:27 +08:00
DavidGrath
2fd1ee66cc
Added ANTLR. Fix Issue #20960 (#21230)
* Added ANTLR. Started work on issue 20960

* Ran generation scripts

* Excluded ANTLR generated files from JavaDoc generation

* Whitespace fix
2025-05-11 22:31:54 +08:00
Jonas Renggli
6344bfa779
[php-flight] fix: use static PHPUnit assertions (#21253)
Static analysis tools such as PHPStan report errors when dynamic calls are used
for static methods.

```
ERROR Dynamic call to static method PHPUnit\Framework\Assert::assertEquals().
```

According to the source code of PHPUnit
(https://github.com/sebastianbergmann/phpunit/blob/9.5.0/src/Framework/Assert.php)
the function is indeed static.

```php
public static function assertTrue($condition, string $message = ''): void
```

This change updates to PHP Flight test template `register_routes_test.mustache`
to use static calls for PHPUnit assertions.
2025-05-11 22:22:34 +08:00
Amin Ya
66e8c932c3
[cpp-rest-sdk] support serializing model base as parameters (#21235)
* [cpp-rest-sdk] support serializing models as parameters

This fixes the code generation for the cases where the model is referenced as a parameter

* [cpprest-sdk] avoid newlines when no model import
2025-05-11 21:52:09 +08:00
Billy Booth
d6c4634269
[csharp] Add missing ConfigureAwait(false) for csharp generator (#21244)
* [csharp] ApiClient.mustache: Apply ConfigureAwait(false) consistently

* [csharp] Update samples to include 59936f29f00
2025-05-09 12:02:38 +08:00
Eric Rolli
bb811db2a2
[JavaJaxRs] generate getValue() for enums with the correct type (#21183)
* [JavaJaxRs] enumClass.mustache added getValue()

JavaJaxRs enums are missing getValue() method returning the correct data type.

* Update InlineObject2.java added getValue() for enums

* Update Pet.java added getValue() to enum

* Update BigCat.java added getValue for enum

* Update EnumArrays.java added getValue() to enum

* Update EnumArrays.java added getValue() to enum

* Update EnumTest.java added getValue() to enums

* Update MapTest.java added getValue() to enum

* Update Order.java added getValue() to enum

* Update Pet.java added getValue() to enum

* Update EnumArrays.java added getValue() to enums

* Update EnumTest.java added getValue() to enums

* Update MapTest.java added getValue() to enum

* Update Order.java added getValue() to enum

* Update ParentWithNullable.java added getValue() to enum

* Update BigCat.java added getValue() to enum

* Update EnumArrays.java added getValue() to enums

* Update EnumTest.java added getValue() to enums

* Update MapTest.java added getValue() to enum

* Update Order.java added getValue() to enum

* Update Pet.java added getValue() to enum

* Update BigCat.java added getValue() to enum

* Update EnumArrays.java added getValue() to enums

* Update EnumTest.java added getValue() to enums

* Update MapTest.java added getValue() to enum

* Update Order.java added getValue() to enum

* Update Pet.java added getValue to enum

* Update EnumArrays.java added getValue() to enum

* Update EnumTest.java added getValue() to enums

* Update MapTest.java added getValue() to enum

* Update Order.java added getValue() to enum

* Update ParentWithNullable.java added getValue() to enum

* Update Pet.java added getValue() to enum

* Update EnumTest.java getValue() with Integer

* Update EnumTest.java
2025-05-09 11:15:20 +08:00
martin-mfg
b55ae3caa8
update documentation about lambdas (#21241) 2025-05-09 11:00:53 +08:00
ksn-partisia
ecd5d253a8
[Bug] [Java] Fix java compilation warnings in RFC3339JavaTimeModule and RFC3339InstantDeserializer (#21243)
* Fix java compilation warnings in RFC3339JavaTimeModule and RFC3339InstantDeserializer

* Regen missing samples
2025-05-09 11:00:07 +08:00
Philip Thomas Casado
4cffd32f87
[Feat][Typescript Angular] Implement deepObject query params (OAS3.0) (#21108)
* feature: implement deepObject query params as per documentation.
Closes OpenAPITools/openapi-generator#19342.

* chore: regenerate samples.

* chore: symplify code (via @joscha)

* chore: regenerate samples

* test: add integration test for typescript-angular deepObject query params

* fix: typo in the integration tests path

* chore: use node v18 for integration tests

* chore: make ES6 compliant

* chore: make test name semantically accurate

* chore: regenerate samples

* test: add angular v16 deep-object test

* chore: delete previous bespoke test for deep objects (uses test introduced in 71629f8d9a instead)

* chore: restore missing OAS for deep object API tests

* test: move angular deepObject tests to v19 and delete v16 ones

* test: atomic deepObject test on service rather than integration with app component

* chore: clean up superfluous import
2025-05-07 16:40:02 +02:00
Juanpe Araque
f2813716fb
[Python] Add __all__ variable in the package __init__.py file for Python APIs (#21185)
* Add __all__ to the package __init__.py file for Python APIs

* Remove empty line before closing bracket

* Add missing samples
2025-05-07 15:59:49 +08:00
Amin Ya
3048fb02e1
[cpp-rest-sdk] remove U macro definition from public headers (#21221)
Cpprest has a public U macro definition that causes build errors in libraries as U is a common name for template parameters. This PR fixes the issue by turning it off.

[microsoft/cpprestsdk@411a109/Release/include/cpprest/details/basic_types.h#L87](411a109150/Release/include/cpprest/details/basic_types.h (L87))

Related to https://github.com/microsoft/cpprestsdk/issues/1805 and https://github.com/fmtlib/fmt/issues/4180
2025-05-07 15:08:38 +08:00
martin-mfg
5117616b53
CodegenOperation & CodegenProperty: turn fields into getters (#21225)
* turn fields into getters

* update samples
2025-05-07 15:04:04 +08:00
William Cheng
5e5a053bfa
update PR tempalte, issue template, link to validator (#21232) 2025-05-07 14:39:37 +08:00
Amin Ya
f5b8fd6f5e
[cpp-rest-sdk] fix finding of the crypto libraries (#21219)
* [cpp-rest-sdk] fix finding of the crypto libraries

This fixes finding of the crypto for cpprest sdk via find_library. It also bumps the minimum CMake version to 3.10 to avoid deprecation warnings

* docs: add myself as a technical committee member
2025-05-07 14:30:18 +08:00
Amin Ya
4b2abdf48d
fix: fix dev container failing to build (#21218)
The dev container fails to build because of the outdated docker-in-docker feature. This updates the docker-in-docker and fixes the build. I also updated the docker compose references in the docs.
2025-05-05 15:34:02 +08:00
William Cheng
2010c2a60a
Add workflow to test Elixir clients (#21214)
* add elixir workflow

* update

* fix

* add elixir workflow (#21215)

* update tests to use built-in json module instead of jason

* update base_url

* temporarily disable type-casting for dates

* retry failing tests

* update spec to use localhost

* add petsore local server to workflow

---------

Co-authored-by: Enrique Fernández <enrique@bluelabs.eu>
2025-05-05 15:32:05 +08:00
devhl-labs
41012588dd
ignore date length validation (#21217) 2025-05-05 15:06:22 +08:00
martin-mfg
e22d079bb0
ensure correct value for hasParams (#21209)
* turn hasParams into getter

* restore hasRequiredParams
2025-05-05 00:49:01 +08:00
Enrique Fernández
d38898a4d0
fix: delete unused file (#21213) 2025-05-04 23:39:17 +08:00
Ross Sullivan
652d4ed95c
Remove duplicate oneOf schemas during pre-processing (#21174)
* fix: Remove duplicate oneOf schemas during pre-processing

* chore: Updated samples

* fix: Fixed regression with oneOf+discriminator

* fix: Fixed possible null pointer during schema preprocessing

* refactor: Moved oneOf deduplication to OpenAPINormalizer
2025-05-04 23:30:42 +08:00
Devon
104ceb9c16
Java: Optimize HashSet Initialization (#21205)
* Optimize HashSet Initialization

Noticed this while debugging - we can avoid wasting memory/cpu creating 16 buckets when we only need one or a few.

* generate samples

* use Arrays.asList
2025-05-04 22:56:33 +08:00
Enrique Fernández
0389a99cec
simplify connection module (#21158) 2025-05-04 22:51:35 +08:00
devhl-labs
f3af25b10c
fixed encoding (#21207) 2025-05-04 22:30:40 +08:00
devhl-labs
56fe7e3286
[csharp] Fixed duplicate property names (#21206)
* fixed duplicate property names

* discard samples

* discard samples

* added new sample
2025-05-04 22:29:12 +08:00
Enrique Fernández
ac77339fcd
[chore][elixir] update dependencies (#21210)
* chore: bump tesla version

* chore: bump ex_doc version

* chore: bump dialyxir version
2025-05-04 22:27:26 +08:00
Jaime Sánchez
3c664d1a59
[java] [spring] Fix multipart optional params error compilation using delegates (#20793)
* fix spring multipart optional parameters

* use optional only in not required params

* remove debug line

---------

Co-authored-by: Jaime Sanchez <jaime.sanchezf@externos.santalucia.es>
Co-authored-by: William Cheng <wing328hk@gmail.com>
2025-04-30 14:28:38 +08:00
Andrew Wilson
76540e591f
Improve Kotlin Misk OpenApi Generator (#21165)
* first pass

* fixing types

* fixing action

* updating samples

* updating files

* adding guido

* fixing misk

* removing old files

* cleaning generated files

* cleaning generated files

* adding back in license

* first pass

* second pass

* third pass

* typo

* fixup

* fixup 2

* fixup 3

* fixup 4

* fixup 5

* fixup 6

* fixing api override

* fixing docs

* fixing docs json

* fix misk version

* add action prefix

* fixup

* fixup 2

* fixup 3

* fixup 4

* fixup 5
2025-04-30 01:53:32 +08:00
kenji yoshida
56eb8f7bc9
update akka-http and pekko-http server generator and example (#21166) 2025-04-30 01:46:49 +08:00
Akihito Nakano
3bac186b2f
Fix the layout issue in the donation message (#21184)
The emoji might not render correctly for Windows users.
2025-04-30 01:45:41 +08:00
William Cheng
d04c0ddbb4
minor fix to javadoc (#21177) 2025-04-29 15:58:16 +08:00
RickyMa
afa135f93d
[cpprestsdk] Support passing enum request parameters (#20836)
* [cpprestsdk] Support passing enum request parameters

* Add a fake endpoint to test enum request parameters

* Add auto-generated sample codes

* Update to date with master branch

---------

Co-authored-by: leslizhang <453688819@qq.com>
2025-04-29 15:54:07 +08:00
Simon Podlipsky
2327562af4
fix(php-nextgen): do not call static methods dynamically (#21163) 2025-04-29 15:29:52 +08:00
martin-mfg
daeffde719
fix vertxFuture setting (#21176) 2025-04-29 15:07:30 +08:00
martin-mfg
9a289e9713
adjust jersey2/jersey3 templates (#21171)
* respect useJakartaEE in jersey3

* useJakarteEE=true in jersey3 samples

* don't force jakarta package for jersey3

* adjust whitespace between jersey2 and jersey3

* enforce useJakartaEe for jersey3, warn on misuse for jersey 2

* set useJakartaEe for jersey3, generate samples
2025-04-29 15:01:43 +08:00
martin-mfg
3fadfe3889
fix documentation versions (#21175) 2025-04-29 15:01:16 +08:00
Oliver Fast
65c312653a
fix(typescript-fetch): Use null as a value when the date value is nullable (#21133)
* fix use null when available for dates

* generated typescript-fetch-default-v3.0 sample

* ran all typescript examples
2025-04-28 10:59:48 +02:00
William Cheng
29b6b771d7
add unified.to to bronze sponsor list (#21160) 2025-04-27 23:58:17 +08:00
William Cheng
9eefc09487 update readme 2025-04-27 22:07:23 +08:00
William Cheng
dbf720c093
Prepare 7.14.0 release (#21159)
* Revert "v7.13.0 release (#21157)"

This reverts commit 4b805ff6b7ac5bd2557555810357569fe2677311.

* prepare v7.14.0 release

* update samples
2025-04-27 22:04:03 +08:00
8042 changed files with 25810 additions and 12022 deletions

View File

@ -11,10 +11,9 @@
},
"ghcr.io/devcontainers/features/rust:1": {},
"ghcr.io/snebjorn/devcontainer-feature/chromium:latest": {},
"docker-in-docker": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"moby": true,
"dockerDashComposeVersion": "v1"
"moby": true
}
},
// Configure tool-specific properties.

4
.github/CODEOWNERS vendored
View File

@ -28,3 +28,7 @@ modules/openapi-generator/src/main/resources/cpp-qt-client/**/* @martindelille
samples/client/petstore/cpp-qt/**/* @martindelille
modules/openapi-generator/src/main/resources/cpp-qt-client/**/* @muttleyxd
samples/client/petstore/cpp-qt/**/* @muttleyxd
# cpp-rest-client technical committee
modules/openapi-generator/src/main/resources/cpp-rest-client/**/* @aminya
samples/client/petstore/cpp-restsdk/**/* @aminya

View File

@ -10,7 +10,7 @@ assignees: ''
#### Bug Report Checklist
- [ ] Have you provided a full/minimal spec to reproduce the issue?
- [ ] Have you validated the input using an OpenAPI validator ([example](https://apitools.dev/swagger-parser/online/))?
- [ ] Have you validated the input using an OpenAPI validator?
- [ ] Have you [tested with the latest master](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) to confirm the issue still exists?
- [ ] Have you searched for related issues/PRs?
- [ ] What's the actual output vs expected output?

View File

@ -11,7 +11,7 @@
./bin/generate-samples.sh ./bin/configs/*.yaml || exit
./bin/utils/export_docs_generators.sh || exit
```
(For Windows users, please run the script in [Git BASH](https://gitforwindows.org/))
(For Windows users, please run the script in [WSL](https://learn.microsoft.com/en-us/windows/wsl/install))
Commit all changed files.
This is important, as CI jobs will verify _all_ generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.

View File

@ -144,6 +144,7 @@ jobs:
run: |
rm -rf samples/client/petstore/csharp/generichost/latest/HelloWorld
rm -rf samples/client/petstore/csharp/generichost/latest/Tags
rm -rf samples/client/petstore/csharp/generichost/latest/OneOfList
rm -rf samples/client/petstore/csharp/generichost/net8/AllOf
rm -rf samples/client/petstore/csharp/generichost/net8/AnyOf

View File

@ -25,6 +25,7 @@ jobs:
sample:
- samples/client/petstore/csharp/generichost/latest/Tags
- samples/client/petstore/csharp/generichost/latest/HelloWorld
- samples/client/petstore/csharp/generichost/latest/OneOfList
- samples/client/petstore/csharp/generichost/net9/AllOf
- samples/client/petstore/csharp/generichost/net9/AnyOf
- samples/client/petstore/csharp/generichost/net9/AnyOfNoCompare

39
.github/workflows/samples-elixir.yaml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Samples Elixir
on:
push:
paths:
- samples/client/petstore/elixir/**
pull_request:
paths:
- samples/client/petstore/elixir/**
jobs:
build:
runs-on: ubuntu-latest
name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
strategy:
matrix:
otp: ['25.3.2', '26.2.5', '27.3.3']
elixir: ['1.18.3']
sample:
- samples/client/petstore/elixir/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: ${{matrix.otp}}
elixir-version: ${{matrix.elixir}}
- name: mix deps.get
run: mix deps.get
working-directory: ${{ matrix.sample }}
- name: mix test
run: mix test
working-directory: ${{ matrix.sample }}

View File

@ -65,6 +65,7 @@ jobs:
- samples/client/echo_api/kotlin-jvm-spring-3-restclient
- samples/client/petstore/kotlin-name-parameter-mappings
- samples/client/others/kotlin-jvm-okhttp-parameter-tests
- samples/client/others/kotlin-jvm-okhttp-path-comments
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4

View File

@ -48,6 +48,7 @@ jobs:
- samples/server/others/kotlin-server/jaxrs-spec-array-response
- samples/server/petstore/kotlin-spring-cloud
- samples/server/petstore/kotlin-misk
- samples/server/petstore/kotlin-misk-config
# comment out due to gradle build failure
#- samples/server/petstore/kotlin-spring-default
# no build.gradle file

View File

@ -74,8 +74,8 @@ elif [ "$NODE_INDEX" = "3" ]; then
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
#nvm install stable
# install v16 instead of the latest stable version
nvm install 16
nvm alias default 16
nvm install 18
nvm alias default 18
node --version
# Each step uses the same `$BASH_ENV`, so need to modify it

View File

@ -15,7 +15,7 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.13.0`):
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.14.0`):
[![Build Status](https://api.travis-ci.com/OpenAPITools/openapi-generator.svg?branch=master&status=passed)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
@ -74,6 +74,7 @@ If you find OpenAPI Generator useful for work, please consider asking your compa
[<img src="https://openapi-generator.tech/img/companies/route4me.png" width="128" height="128">](https://route4me.com/?utm_source=openapi-generator&utm_medium=sponsorship&utm_campaign=oss-sponsorship)
[<img src="https://openapi-generator.tech/img/companies/dm.png" width="128" height="128">](https://www.dotcom-monitor.com/sponsoring-open-source-projects/?utm_source=openapi-generator&utm_medium=sponsorship&utm_campaign=oss-sponsorship)
[<img src="https://openapi-generator.tech/img/companies/clickit.jpg" width="128" height="128">](https://www.clickittech.com/?utm_source=openapi-generator&utm_medium=sponsorship&utm_campaign=oss-sponsorship)
[<img src="https://openapi-generator.tech/img/companies/unified_to.jpg" width="128" height="128">](https://unified.to/?utm_source=openapi-generator&utm_medium=sponsorship&utm_campaign=oss-sponsorship)
#### Thank you GoDaddy for sponsoring the domain names, Linode for sponsoring the VPS, Checkly for sponsoring the API monitoring and Gradle for sponsoring Develocity
@ -96,31 +97,47 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
## Table of contents
- [OpenAPI Generator](#openapi-generator)
- [Sponsors](#sponsors)
- [Thank you to our bronze sponsors!](#thank-you-to-our-bronze-sponsors)
- [Thank you GoDaddy for sponsoring the domain names, Linode for sponsoring the VPS, Checkly for sponsoring the API monitoring and Gradle for sponsoring Develocity](#thank-you-godaddy-for-sponsoring-the-domain-names-linode-for-sponsoring-the-vps-checkly-for-sponsoring-the-api-monitoring-and-gradle-for-sponsoring-develocity)
- [Overview](#overview)
- [Table of Contents](#table-of-contents)
- [Table of contents](#table-of-contents)
- [1 - Installation](#1---installation)
- [1.1 - Compatibility](#11---compatibility)
- [1.2 - Artifacts on Maven Central](#12---artifacts-on-maven-central)
- [1.3 - Download JAR](#13---download-jar)
- [Launcher Script](#launcher-script)
- [1.4 - Build Projects](#14---build-projects)
- [Nix users](#nix-users)
- [1.5 - Homebrew](#15---homebrew)
- [1.6 - Docker](#16---docker)
- [Public Pre-built Docker images](#public-pre-built-docker-images)
- [OpenAPI Generator CLI Docker Image](#openapi-generator-cli-docker-image)
- [OpenAPI Generator Online Docker Image](#openapi-generator-online-docker-image)
- [Development in docker](#development-in-docker)
- [Troubleshooting](#troubleshooting)
- [Run Docker in Vagrant](#run-docker-in-vagrant)
- [1.7 - NPM](#17---npm)
- [1.8 - pip](#18---pip)
- [2 - Getting Started](#2---getting-started)
- [3 - Usage](#3---usage)
- [To generate a sample client library](#to-generate-a-sample-client-library)
- [3.1 - Customization](#31---customization)
- [3.2 - Workflow Integration](#32---workflow-integration-maven-gradle-github-cicd)
- [3.3 - Online Generators](#33---online-openapi-generator)
- [3.4 - License Information on Generated Code](#34---license-information-on-generated-code)
- [3.2 - Workflow Integration (Maven, Gradle, Github, CI/CD)](#32---workflow-integration-maven-gradle-github-cicd)
- [3.3 - Online OpenAPI generator](#33---online-openapi-generator)
- [3.4 - License information on Generated Code](#34---license-information-on-generated-code)
- [3.5 - IDE Integration](#35---ide-integration)
- [4 - Companies/Projects using OpenAPI Generator](#4---companiesprojects-using-openapi-generator)
- [5 - Presentations/Videos/Tutorials/Books](#5---presentationsvideostutorialsbooks)
- [6 - About Us](#6---about-us)
- [6.1 - OpenAPI Generator Core Team](#61---openapi-generator-core-team)
- [Core Team Members](#core-team-members)
- [Template Creator](#template-creator)
- [How to join the core team](#how-to-join-the-core-team)
- [6.2 - OpenAPI Generator Technical Committee](#62---openapi-generator-technical-committee)
- [Members of Technical Committee](#members-of-technical-committee)
- [6.3 - History of OpenAPI Generator](#63---history-of-openapi-generator)
- [Founding Members (alphabetical order):](#founding-members-alphabetical-order)
- [7 - License](#7---license)
## [1 - Installation](#table-of-contents)
@ -131,8 +148,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.13.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.13.0-SNAPSHOT/) | 02.04.2025 | Minor release with breaking changes (with fallback) |
| [7.12.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.12.0) (latest stable release) | 28.02.2025 | Minor release with breaking changes (with fallback) |
| 7.14.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.14.0-SNAPSHOT/) | 29.05.2025 | Minor release with breaking changes (with fallback) |
| [7.13.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.13.0) (latest stable release) | 27.04.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) |
| [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) |
@ -195,16 +212,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.13.0/openapi-generator-cli-7.13.0.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.13.0/openapi-generator-cli-7.13.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.13.0/openapi-generator-cli-7.13.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@ -439,7 +456,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 7.12.0
openapi-generator-cli version-manager set 7.13.0
```
Or install it as dev-dependency:
@ -463,7 +480,7 @@ pip install openapi-generator-cli
To install a specific version
```
pip install openapi-generator-cli==7.12.0
pip install openapi-generator-cli==7.13.0
```
You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required)
@ -489,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`)
<!-- 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.12.0/openapi-generator-cli-7.12.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.13.0/openapi-generator-cli-7.13.0.jar)
<!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
@ -1218,7 +1235,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Apex | |
| Bash | @frol (2017/07) @bkryza (2017/08) @kenjones-cisco (2017/09) |
| C | @zhemant (2018/11) @ityuhui (2019/12) @michelealbano (2020/03) @eafer (2024/12) |
| C++ | @ravinikam (2017/07) @stkrwork (2017/07) @etherealjoy (2018/02) @martindelille (2018/03) @muttleyxd (2019/08) |
| C++ | @ravinikam (2017/07) @stkrwork (2017/07) @etherealjoy (2018/02) @martindelille (2018/03) @muttleyxd (2019/08) @aminya (2025/05) |
| C# | @mandrean (2017/08) @shibayan (2020/02) @Blackclaws (2021/03) @lucamazzanti (2021/05) @iBicha (2023/07) |
| Clojure | |
| Crystal | @cyangle (2021/01) |

View File

@ -45,6 +45,7 @@ build_script:
test_script:
- dotnet test samples\client\petstore\csharp\generichost\latest\Tags\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
- dotnet test samples\client\petstore\csharp\generichost\latest\HelloWorld\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
- dotnet test samples\client\petstore\csharp\generichost\latest\OneOfList\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
- dotnet test samples\client\petstore\csharp\generichost\net9\AllOf\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
- dotnet test samples\client\petstore\csharp\generichost\net9\AnyOf\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj

View File

@ -0,0 +1,4 @@
generatorName: avro-schema
outputDir: samples/openapi3/schema/petstore/avro-schema-issue6268
inputSpec: modules/openapi-generator/src/test/resources/3_0/issue6268.yaml
templateDir: modules/openapi-generator/src/main/resources/avro-schema

View File

@ -0,0 +1,8 @@
generatorName: csharp
outputDir: samples/client/petstore/csharp/generichost/latest/OneOfList
inputSpec: modules/openapi-generator/src/test/resources/bugs/issue_20739.yaml
templateDir: modules/openapi-generator/src/main/resources/csharp
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
modelPropertySorting: alphabetical
operationParameterSorting: alphabetical

View File

@ -0,0 +1,8 @@
generatorName: kotlin
outputDir: samples/client/others/kotlin-jvm-okhttp-path-comments
library: jvm-okhttp4
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/issue20618-path-comments.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
additionalProperties:
artifactId: kotlin-petstore-okhttp4-path-comments

View File

@ -0,0 +1,11 @@
generatorName: kotlin-misk
outputDir: samples/server/petstore/kotlin-misk-config
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-misk
validateSpec: false
additionalProperties:
hideGenerationTimestamp: "true"
moduleClassName: "PetStoreModule"
generateStubImplClasses: true
addModelMoshiJsonAnnotation: true
actionPathPrefix : "samplePrefix"

View File

@ -2,7 +2,6 @@ generatorName: kotlin-misk
outputDir: samples/server/petstore/kotlin-misk
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-misk
validateSpec: false
additionalProperties:
hideGenerationTimestamp: "true"
moduleClassName: "PetStoreModule"

View File

@ -0,0 +1,8 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v19/builds/deep-object
inputSpec: modules/openapi-generator/src/test/resources/3_0/deep-object-query.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 19.0.0
npmName: sample-angular-19-0-0-deep-object
supportsES6: true

View File

@ -18,11 +18,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|actionPathPrefix|Prefix for action path| ||
|addModelMoshiJsonAnnotation|Add a Moshi JSON adapter annotation to all model classes| |true|
|additionalModelTypeAnnotations|Additional annotations for model type(class level annotations). List separated by semicolon(;) or new line (Linux or Windows)| |null|
|apiSuffix|suffix for api classes| |Api|
|artifactId|Generated artifact id (name of jar).| |null|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|generateStubImplClasses|Generate Stub Impl Classes| |false|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|modelMutable|Create mutable models| |false|
|moduleClassName|Name of the generated module class| |OpenApiModule|
@ -273,7 +276,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON||OAS2,OAS3
|JSON||OAS2,OAS3
|XML|✗|OAS2,OAS3
|PROTOBUF|✓|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@ -18,7 +18,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|akkaHttpVersion|The version of akka-http| |10.1.10|
|akkaHttpVersion|The version of akka-http| |10.2.9|
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|apiPackage|package for generated api classes| |null|
|artifactId|artifactId| |openapi-scala-akka-http-server|

View File

@ -119,18 +119,18 @@ docker run --rm \
<!-- 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):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.9.0/openapi-generator-cli-7.9.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar`
For **Mac/Linux** users:
```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.9.0/openapi-generator-cli-7.9.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.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.
```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.9.0/openapi-generator-cli-7.9.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar
```
<!-- /RELEASE_VERSION -->

View File

@ -820,15 +820,21 @@ Many generators (*those extending DefaultCodegen*) come with a small set of lamb
- `lowercase` - Converts all of the characters in this fragment to lower case using the rules of the `ROOT` locale.
- `uppercase` - Converts all of the characters in this fragment to upper case using the rules of the `ROOT` locale.
- `snakecase` - Converts text in a fragment to snake case. For example `once upon a time` to `once_upon_a_time`.
- `titlecase` - Converts text in a fragment to title case. For example `once upon a time` to `Once Upon A Time`.
- `kebabcase` - Converts text in a fragment to snake case. For example `Once Upon A Time` to `once-upon-a-time`.
- `pascalcase` - Converts text in a fragment to snake case. For example `once upon a time` to `OnceUponATime`.
- `camelcase` - Converts text in a fragment to camelCase. For example `Input-text` to `inputText`.
- `uncamelize` - Converts text in a fragment from camelCase or PascalCase to a string of words separated by whitespaces. For example `inputText` to `Input Text`.
- `forwardslash` - Replaces all occurrences of `\/`, `\` and `//` in a fragment by `/`.
- `backslash` - Replaces all occurrences `/` in a fragment by `\`.
- `doublequote` - Prepends `"` to the beginning and appends `"` to the end of a fragment.
- `indented` - Prepends 4 spaces indention from second line of a fragment on. First line will be indented by Mustache.
- `indented_8` - Prepends 8 spaces indention from second line of a fragment on. First line will be indented by Mustache.
- `indented_12` - Prepends 12 spaces indention from second line of a fragment on. First line will be indented by Mustache.
- `indented_16` -Prepends 16 spaces indention from second line of a fragment on. First line will be indented by Mustache.
Lambda is invoked by `lambda.[lambda name]` expression. For example: `{{#lambda.lowercase}}FRAGMENT TO LOWERCASE{{/lambda.lowercase}}` to lower case text between `lambda.lowercase`.
Some generators provide additional lambdas. Lambda is invoked by `lambda.[lambda name]` expression. For example: `{{#lambda.lowercase}}FRAGMENT TO LOWERCASE{{/lambda.lowercase}}` to lower case text between `lambda.lowercase`.
## Extensions

View File

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

View File

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

View File

@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.13.0
openApiGeneratorVersion=7.14.0-SNAPSHOT
# /RELEASE_VERSION
# BEGIN placeholders

View File

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

View File

@ -1,3 +1,3 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.13.0
openApiGeneratorVersion=7.14.0-SNAPSHOT
# /RELEASE_VERSION

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.13.0</version>
<version>7.14.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath>
</parent>
@ -145,6 +145,43 @@
<artifactId>maven-release-plugin</artifactId>
<version>${maven-release-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.13.2</version>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>${basedir}/src/test/antlr4</sourceDirectory>
<libDirectory>${basedir}/src/test/antlr4/imports</libDirectory>
<outputDirectory>${project.build.directory}/generated-test-sources/antlr4</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-test-sources/antlr4</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
@ -464,6 +501,12 @@
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>

View File

@ -118,7 +118,6 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
* p2:
* type: string
*
* @return the discriminator.
*/
@Getter public CodegenDiscriminator discriminator;
@Getter @Setter

View File

@ -24,15 +24,13 @@ import java.util.*;
public class CodegenOperation {
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams,
public boolean hasAuthMethods, hasConsumes, hasProduces, hasOptionalParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isVoid = false,
hasVersionHeaders = false, hasVersionQueryParams = false,
isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, defaultReturnType = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, hasOnlyDefaultResponse = false, hasConstantParams = false,
hasErrorResponseObject, // if 4xx, 5xx responses have at least one error object defined
hasSingleParam = false; // if the operation has only one parameter;
isDeprecated, isCallbackRequest, uniqueItems,
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
public CodegenProperty returnProperty;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
@ -81,6 +79,33 @@ public class CodegenOperation {
return params != null && !params.isEmpty();
}
/**
* Check if there's at least one parameter
*
* @return true if parameter exists, false otherwise
*/
public boolean getHasParams() {
return nonEmpty(allParams);
}
/**
* Check if there's at least one required parameter
*
* @return true if required parameter exists, false otherwise
*/
public boolean getHasRequiredParam() {
return nonEmpty(requiredParams);
}
/**
* Check if there's exactly one parameter
*
* @return true if exactly one parameter exists, false otherwise
*/
public boolean getHasSingleParam() {
return allParams.size() == 1;
}
/**
* Check if there's at least one body parameter
*
@ -362,9 +387,7 @@ public class CodegenOperation {
sb.append(", hasAuthMethods=").append(hasAuthMethods);
sb.append(", hasConsumes=").append(hasConsumes);
sb.append(", hasProduces=").append(hasProduces);
sb.append(", hasParams=").append(hasParams);
sb.append(", hasOptionalParams=").append(hasOptionalParams);
sb.append(", hasRequiredParams=").append(hasRequiredParams);
sb.append(", returnTypeIsPrimitive=").append(returnTypeIsPrimitive);
sb.append(", returnSimpleType=").append(returnSimpleType);
sb.append(", subresourceOperation=").append(subresourceOperation);
@ -377,16 +400,7 @@ public class CodegenOperation {
sb.append(", isResponseFile=").append(isResponseFile);
sb.append(", isResponseOptional=").append(isResponseOptional);
sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
sb.append(", hasOnlyDefaultResponse=").append(hasOnlyDefaultResponse);
sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
sb.append(", hasSingleParam=").append(hasSingleParam);
sb.append(", isRestfulIndex=").append(isRestfulIndex);
sb.append(", isRestfulShow=").append(isRestfulShow);
sb.append(", isRestfulCreate=").append(isRestfulCreate);
sb.append(", isRestfulUpdate=").append(isRestfulUpdate);
sb.append(", isRestfulDestroy=").append(isRestfulDestroy);
sb.append(", isRestful=").append(isRestful);
sb.append(", isDeprecated=").append(isDeprecated);
sb.append(", isCallbackRequest=").append(isCallbackRequest);
sb.append(", uniqueItems='").append(uniqueItems);
@ -445,9 +459,7 @@ public class CodegenOperation {
return hasAuthMethods == that.hasAuthMethods &&
hasConsumes == that.hasConsumes &&
hasProduces == that.hasProduces &&
hasParams == that.hasParams &&
hasOptionalParams == that.hasOptionalParams &&
hasRequiredParams == that.hasRequiredParams &&
returnTypeIsPrimitive == that.returnTypeIsPrimitive &&
returnSimpleType == that.returnSimpleType &&
subresourceOperation == that.subresourceOperation &&
@ -459,16 +471,7 @@ public class CodegenOperation {
isResponseFile == that.isResponseFile &&
isResponseOptional == that.isResponseOptional &&
hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse &&
hasOnlyDefaultResponse == that.hasOnlyDefaultResponse &&
hasErrorResponseObject == that.hasErrorResponseObject &&
hasSingleParam == that.hasSingleParam &&
isRestfulIndex == that.isRestfulIndex &&
isRestfulShow == that.isRestfulShow &&
isRestfulCreate == that.isRestfulCreate &&
isRestfulUpdate == that.isRestfulUpdate &&
isRestfulDestroy == that.isRestfulDestroy &&
isRestful == that.isRestful &&
isDeprecated == that.isDeprecated &&
isCallbackRequest == that.isCallbackRequest &&
uniqueItems == that.uniqueItems &&
@ -522,16 +525,15 @@ public class CodegenOperation {
@Override
public int hashCode() {
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasOptionalParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isVoid, isResponseBinary, isResponseFile, isResponseOptional, hasReference,
hasDefaultResponse, hasOnlyDefaultResponse, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,
isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,
returnBaseType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse,
discriminator, consumes, produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams,
pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
vendorExtensions, nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase,
operationIdSnakeCase, hasErrorResponseObject, hasSingleParam, requiredAndNotNullableParams, notNullableParams, constantParams);
operationIdSnakeCase, hasErrorResponseObject, requiredAndNotNullableParams, notNullableParams, constantParams);
}
}

View File

@ -128,7 +128,6 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
public boolean exclusiveMaximum;
@Setter public boolean required;
public boolean deprecated;
public boolean hasMoreNonReadOnly; // for model constructor, true if next property is not readonly
public boolean isPrimitiveType;
public boolean isModel;
/**
@ -995,7 +994,6 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
sb.append(", exclusiveMaximum=").append(exclusiveMaximum);
sb.append(", required=").append(required);
sb.append(", deprecated=").append(deprecated);
sb.append(", hasMoreNonReadOnly=").append(hasMoreNonReadOnly);
sb.append(", isPrimitiveType=").append(isPrimitiveType);
sb.append(", isModel=").append(isModel);
sb.append(", isContainer=").append(isContainer);
@ -1092,7 +1090,6 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
exclusiveMaximum == that.exclusiveMaximum &&
required == that.required &&
deprecated == that.deprecated &&
hasMoreNonReadOnly == that.hasMoreNonReadOnly &&
isPrimitiveType == that.isPrimitiveType &&
isModel == that.isModel &&
isContainer == that.isContainer &&
@ -1209,7 +1206,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
defaultValueWithParam, baseType, containerType, containerTypeMapped, title, unescapedDescription,
maxLength, minLength, pattern, example, jsonSchema, minimum, maximum,
exclusiveMinimum, exclusiveMaximum, required, deprecated,
hasMoreNonReadOnly, isPrimitiveType, isModel, isContainer, isString, isNumeric,
isPrimitiveType, isModel, isContainer, isString, isNumeric,
isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isFile,
isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isPassword, isFreeFormObject,
isArray, isMap, isOptional, isEnum, isInnerEnum, isEnumRef, isAnyType, isReadOnly, isWriteOnly, isNullable, isShort,

View File

@ -404,6 +404,8 @@ public class DefaultCodegen implements CodegenConfig {
* If common lambdas are not desired, override addMustacheLambdas() method
* and return empty builder.
*
* Corresponding user documentation: docs/templating.md, section "Mustache Lambdas"
*
* @return preinitialized map with common lambdas
*/
protected ImmutableMap.Builder<String, Lambda> addMustacheLambdas() {
@ -959,11 +961,11 @@ public class DefaultCodegen implements CodegenConfig {
@Override
@SuppressWarnings("static-method")
public void postProcess() {
System.out.println("################################################################################");
System.out.println("############################################################################################");
System.out.println("# Thanks for using OpenAPI Generator. #");
System.out.println("# Please consider donation to help us maintain this project \uD83D\uDE4F #");
System.out.println("# We appreciate your support! Please consider donation to help us maintain this project. #");
System.out.println("# https://opencollective.com/openapi_generator/donate #");
System.out.println("################################################################################");
System.out.println("############################################################################################");
}
// override with any special post-processing
@ -4834,22 +4836,6 @@ public class DefaultCodegen implements CodegenConfig {
// legacy support
op.nickname = op.operationId;
if (op.allParams.size() > 0) {
op.hasParams = true;
}
op.hasRequiredParams = op.requiredParams.size() > 0;
// check if the operation has only a single parameter
op.hasSingleParam = op.allParams.size() == 1;
// set Restful Flag
op.isRestfulShow = op.isRestfulShow();
op.isRestfulIndex = op.isRestfulIndex();
op.isRestfulCreate = op.isRestfulCreate();
op.isRestfulUpdate = op.isRestfulUpdate();
op.isRestfulDestroy = op.isRestfulDestroy();
op.isRestful = op.isRestful();
return op;
}
@ -8678,6 +8664,5 @@ public class DefaultCodegen implements CodegenConfig {
operation.allParams.add(p);
}
}
operation.hasParams = !operation.allParams.isEmpty();
}
}

View File

@ -922,6 +922,9 @@ public class OpenAPINormalizer {
}
protected Schema normalizeOneOf(Schema schema, Set<Schema> visitedSchemas) {
// Remove duplicate oneOf entries
ModelUtils.deduplicateOneOfSchema(schema);
// simplify first as the schema may no longer be a oneOf after processing the rule below
schema = processSimplifyOneOf(schema);
@ -1405,7 +1408,6 @@ public class OpenAPINormalizer {
* then simply it to just boolean.
*
* @param schema Schema
* @return Schema
*/
protected void processSimplifyBooleanEnum(Schema schema) {
if (!getRule(SIMPLIFY_BOOLEAN_ENUM)) {
@ -1425,7 +1427,6 @@ public class OpenAPINormalizer {
* then add x-unsigned to use unsigned integer/long instead.
*
* @param schema Schema
* @return Schema
*/
protected void processAddUnsignedToIntegerWithInvalidMaxValue(Schema schema) {
if (!getRule(ADD_UNSIGNED_TO_INTEGER_WITH_INVALID_MAX_VALUE)) {

View File

@ -625,10 +625,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
CodegenComposedSchemas composedSchemas = model.getComposedSchemas();
if (composedSchemas != null) {
Set<String> composedPropertyNames = new HashSet<String>();
List<CodegenProperty> allOf = composedSchemas.getAllOf();
if (allOf != null) {
for (CodegenProperty property : allOf) {
property.name = patchPropertyName(model, camelize(property.baseType));
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
patchPropertyVendorExtensions(property);
}
}
@ -637,7 +638,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (anyOf != null) {
removePropertiesDeclaredInComposedTypes(objs, model, anyOf);
for (CodegenProperty property : anyOf) {
property.name = patchPropertyName(model, camelize(property.baseType));
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
property.isNullable = true;
patchPropertyVendorExtensions(property);
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
@ -648,7 +649,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (oneOf != null) {
removePropertiesDeclaredInComposedTypes(objs, model, oneOf);
for (CodegenProperty property : oneOf) {
property.name = patchPropertyName(model, camelize(property.baseType));
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
property.isNullable = true;
patchPropertyVendorExtensions(property);
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
@ -715,13 +716,27 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
protected void removePropertiesDeclaredInComposedTypes(Map<String, ModelsMap> objs, CodegenModel model, List<CodegenProperty> composedProperties) {
}
private String patchPropertyName(CodegenModel model, String value) {
private String patchPropertyName(CodegenModel model, String value, Set<String> composedPropertyNames) {
String name = escapeReservedWord(model, value);
if (name.startsWith(AbstractCSharpCodegen.invalidParameterNamePrefix)) {
name = AbstractCSharpCodegen.invalidPropertyNamePrefix + name.substring(AbstractCSharpCodegen.invalidParameterNamePrefix.length());
}
// ensure the name we use for a composed property does not already exist as a property or composed property
// only do this if the set of composed property names was provided to ensure this method is idempotent
// we would not calling this method multiple times to result in different values
if (composedPropertyNames != null) {
String tmpName = name;
long count = model.allVars.stream().map(v -> v.name).filter(n -> n.equals(tmpName)).count() + composedPropertyNames.stream().filter(n -> n.equals(tmpName)).count();
if (count > 0) {
name = name + count++;
}
composedPropertyNames.add(name);
}
return name;
}
@ -753,7 +768,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchPropertyVendorExtensions(property);
property.name = patchPropertyName(model, property.name);
property.name = patchPropertyName(model, property.name, null);
String[] nestedTypes = {"List", "Collection", "ICollection", "Dictionary"};

View File

@ -157,7 +157,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
* -- SETTER --
* Set whether discriminator value lookup is case-sensitive or not.
*
* @param discriminatorCaseSensitive true if the discriminator value lookup should be case-sensitive.
*/
@Setter protected boolean discriminatorCaseSensitive = true;
@Getter @Setter
@ -2387,7 +2386,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
operation.allParams.add(p);
}
}
operation.hasParams = !operation.allParams.isEmpty();
}
private boolean shouldBeImplicitHeader(CodegenParameter parameter) {

View File

@ -16,6 +16,7 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.io.FilenameUtils;
@ -25,6 +26,7 @@ import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -153,6 +155,25 @@ public class AvroSchemaCodegen extends DefaultCodegen implements CodegenConfig {
}
}
/**
* Return the default value of the property
*
* @param p OpenAPI property object
* @return string presentation of the default value of the property
*/
@Override
public String toDefaultValue(Schema p) {
if (p.getDefault() == null) {
return null;
}
if (ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p) || ModelUtils.isStringSchema(p)) {
return "\"" + p.getDefault().toString() + "\"";
}
return p.getDefault().toString();
}
@Override
public CodegenType getTag() {
return CodegenType.SCHEMA;

View File

@ -60,9 +60,9 @@ public class ElixirClientCodegen extends DefaultCodegen {
String supportedElixirVersion = "1.18";
List<String> extraApplications = Arrays.asList(":logger");
List<String> deps = Arrays.asList(
"{:tesla, \"~> 1.7\"}",
"{:ex_doc, \"~> 0.30\", only: :dev, runtime: false}",
"{:dialyxir, \"~> 1.3\", only: [:dev, :test], runtime: false}");
"{:tesla, \"~> 1.14\"}",
"{:ex_doc, \"~> 0.37.3\", only: :dev, runtime: false}",
"{:dialyxir, \"~> 1.4\", only: [:dev, :test], runtime: false}");
public ElixirClientCodegen() {
super();
@ -712,7 +712,6 @@ public class ElixirClientCodegen extends DefaultCodegen {
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
@ -722,12 +721,6 @@ public class ElixirClientCodegen extends DefaultCodegen {
this.isMultipart = o.isMultipart;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;

View File

@ -417,7 +417,6 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
@ -429,12 +428,6 @@ public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig
this.isResponseFile = o.isResponseFile;
this.isResponseOptional = o.isResponseOptional;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;

View File

@ -507,7 +507,6 @@ public class ErlangProperCodegen extends DefaultCodegen implements CodegenConfig
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
@ -517,12 +516,6 @@ public class ErlangProperCodegen extends DefaultCodegen implements CodegenConfig
this.isMultipart = o.isMultipart;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;

View File

@ -137,6 +137,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Setter protected String gradleProperties;
@Setter protected String errorObjectType;
@Getter @Setter protected boolean failOnUnknownProperties = false;
@Setter protected boolean supportVertxFuture = false;
protected String authFolder;
/**
* Serialization library.
@ -244,7 +245,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(SUPPORT_URL_QUERY, "Generate toUrlQueryString in POJO (default to true). Available on `native`, `apache-httpclient` libraries."));
cliOptions.add(CliOption.newBoolean(USE_ENUM_CASE_INSENSITIVE, "Use `equalsIgnoreCase` when String for enum comparison", useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", this.failOnUnknownProperties));
cliOptions.add(CliOption.newBoolean(SUPPORT_VERTX_FUTURE, "Also generate api methods that return a vertx Future instead of taking a callback. Only `vertx` supports this option. Requires vertx 4 or greater."));
cliOptions.add(CliOption.newBoolean(SUPPORT_VERTX_FUTURE, "Also generate api methods that return a vertx Future instead of taking a callback. Only `vertx` supports this option. Requires vertx 4 or greater.", this.supportVertxFuture));
supportedLibraries.put(JERSEY2, "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.17.1");
supportedLibraries.put(JERSEY3, "HTTP client: Jersey client 3.1.1. JSON processing: Jackson 2.17.1");
@ -421,6 +422,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
convertPropertyToStringAndWriteBack(ERROR_OBJECT_TYPE, this::setErrorObjectType);
convertPropertyToBooleanAndWriteBack(WEBCLIENT_BLOCKING_OPERATIONS, op -> webclientBlockingOperations = op);
convertPropertyToBooleanAndWriteBack(FAIL_ON_UNKNOWN_PROPERTIES, this::setFailOnUnknownProperties);
convertPropertyToBooleanAndWriteBack(SUPPORT_VERTX_FUTURE, this::setSupportVertxFuture);
// add URL query deepObject support to native, apache-httpclient by default
if (!additionalProperties.containsKey(SUPPORT_URL_QUERY)) {
@ -587,6 +589,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
// The flag below should be set for all Java libraries, but the templates need to be ported
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
if (useJakartaEe) {
LOGGER.warn("Jersey 2 is not compatible with Jakarta EE. Please use Jersey 3 or set {} to false.", USE_JAKARTA_EE);
}
} else if (libJersey3) {
additionalProperties.put("jersey3", true);
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
@ -603,6 +608,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
// The flag below should be set for all Java libraries, but the templates need to be ported
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
setUseJakartaEe(true);
applyJakartaPackage();
} else if (libNative) {
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));

View File

@ -40,6 +40,35 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.samskivert.mustache.Mustache;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.VendorExtension;
import org.openapitools.codegen.meta.features.ClientModificationFeature;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.GlobalFeature;
import org.openapitools.codegen.meta.features.ParameterFeature;
import org.openapitools.codegen.meta.features.SchemaSupportFeature;
import org.openapitools.codegen.meta.features.SecurityFeature;
import org.openapitools.codegen.meta.features.WireFormatFeature;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.ReplaceAllLambda;
import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.Collections.sort;
public class KotlinClientCodegen extends AbstractKotlinCodegen {
@ -536,6 +565,10 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
}
writer.write(content);
});
// When a path is added to a Javadoc, if it ends with a `/*` is will cause a compiler error
// as the parser interrupts that as a start of a multiline comment.
// We replace paths like `/v1/foo/*` with `/v1/foo/<*>` to avoid this
additionalProperties.put("sanitizePathComment", new ReplaceAllLambda("\\/\\*", "/<*>"));
}
private void processDateLibrary() {

View File

@ -47,17 +47,28 @@ import static org.openapitools.codegen.utils.StringUtils.camelize;
public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements BeanValidationFeatures {
public static final String MODULE_CLASS_NAME = "moduleClassName";
private final Logger LOGGER = LoggerFactory.getLogger(KotlinMiskServerCodegen.class);
public static final String MODULE_CLASS_NAME = "moduleClassName";
public static final String ACTION_PATH_PREFIX = "actionPathPrefix";
private static final String ROOT_PACKAGE = "rootPackage";
public static final String GENERATE_STUB_IMPL_CLASSES = "generateStubImplClasses";
public static final String ADD_MODEL_MOSHI_JSON_ANNOTATION = "addModelMoshiJsonAnnotation";
private boolean useBeanValidation = true;
@Setter
private boolean generateStubImplClasses = false;
@Setter
private boolean addModelMoshiJsonAnnotation = true;
protected String rootPackage = "org.openapitools.server.api";
protected String apiVersion = "1.0.0-SNAPSHOT";
@Setter protected String moduleClassName = "OpenApiModule";
@Setter protected String actionPathPrefix = "";
@Override
public CodegenType getTag() {
@ -78,10 +89,12 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
super();
addSwitch(USE_BEANVALIDATION, "Use BeanValidation API annotations to validate data types", useBeanValidation);
addSwitch(GENERATE_STUB_IMPL_CLASSES, "Generate Stub Impl Classes", generateStubImplClasses);
addSwitch(ADD_MODEL_MOSHI_JSON_ANNOTATION, "Add a Moshi JSON adapter annotation to all model classes", addModelMoshiJsonAnnotation);
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.PROTOBUF))
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.PROTOBUF))
.securityFeatures(EnumSet.noneOf(
SecurityFeature.class
))
@ -108,6 +121,7 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
outputFolder = "generated-code" + File.separator + "kotlin-misk";
addOption(MODULE_CLASS_NAME, "Name of the generated module class", moduleClassName);
addOption(ACTION_PATH_PREFIX, "Prefix for action path", actionPathPrefix);
apiTestTemplateFiles.clear();
apiTestTemplateFiles.put("api_test.mustache", ".kt");
@ -122,8 +136,12 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
apiTemplateFiles.clear();
apiTemplateFiles.put("apiAction.mustache", "Action.kt");
if (generateStubImplClasses) {
apiTemplateFiles.put("apiImpl.mustache", "Impl.kt");
apiTemplateFiles.put("apiInterface.mustache", ".kt");
}
modelTemplateFiles.put("model.mustache", ".kt");
apiPackage = rootPackage + ".api";
@ -148,13 +166,27 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
if (additionalProperties.containsKey(MODULE_CLASS_NAME)) {
setModuleClassName((String) additionalProperties.get(MODULE_CLASS_NAME));
}
additionalProperties.put(MODULE_CLASS_NAME, moduleClassName);
writePropertyBack(MODULE_CLASS_NAME, moduleClassName);
if (additionalProperties.containsKey(ACTION_PATH_PREFIX)) {
setActionPathPrefix((String) additionalProperties.get(ACTION_PATH_PREFIX));
}
writePropertyBack(ACTION_PATH_PREFIX, actionPathPrefix);
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
if (additionalProperties.containsKey(GENERATE_STUB_IMPL_CLASSES)) {
setGenerateStubImplClasses(convertPropertyToBoolean(GENERATE_STUB_IMPL_CLASSES));
}
writePropertyBack(GENERATE_STUB_IMPL_CLASSES, generateStubImplClasses);
if (additionalProperties.containsKey(ADD_MODEL_MOSHI_JSON_ANNOTATION)) {
setAddModelMoshiJsonAnnotation(convertPropertyToBoolean(ADD_MODEL_MOSHI_JSON_ANNOTATION));
}
writePropertyBack(ADD_MODEL_MOSHI_JSON_ANNOTATION, addModelMoshiJsonAnnotation);
applyJakartaPackage();
String apiModuleFolder = (sourceFolder + File.separator + apiPackage).replace(".", File.separator);
@ -211,6 +243,7 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
result.put("application/grpc", "MediaTypes.APPLICATION_GRPC");
result.put("application/javascript", "MediaTypes.APPLICATION_JAVASCRIPT");
result.put("application/json", "MediaTypes.APPLICATION_JSON");
result.put("application/jwt", "MediaTypes.APPLICATION_JWT");
result.put("application/octetstream", "MediaTypes.APPLICATION_OCTETSTREAM");
result.put("application/pdf", "MediaTypes.APPLICATION_OCTETSTREAM");
result.put("application/x-protobuf", "MediaTypes.APPLICATION_PROTOBUF");
@ -219,10 +252,11 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
result.put("application/zip", "MediaTypes.APPLICATION_ZIP");
result.put("image/gif", "MediaTypes.IMAGE_GIF");
result.put("image/x-icon", "MediaTypes.IMAGE_ICO");
result.put("image/jpeg", "MediaTypes.IMAGE_JPEG");
result.put("image/png", "MediaTypes.IMAGE_PNG");
result.put("image/svg+xml", "MediaTypes.IMAGE_SVG");
result.put("image/x-icon", "MediaTypes.IMAGE_ICO");
result.put("image/tiff", "MediaTypes.IMAGE_TIFF");
result.put("multipart/form-data", "MediaTypes.FORM_DATA");

View File

@ -51,7 +51,7 @@ public class ScalaAkkaHttpServerCodegen extends AbstractScalaCodegen implements
public static final String AKKA_HTTP_VERSION_DESC = "The version of akka-http";
public static final String PEKKO_HTTP_VERSION = "pekkoHttpVersion";
public static final String PEKKO_HTTP_VERSION_DESC = "The version of pekko-http";
public static final String DEFAULT_AKKA_HTTP_VERSION = "10.1.10";
public static final String DEFAULT_AKKA_HTTP_VERSION = "10.2.9";
public static final String DEFAULT_PEKKO_HTTP_VERSION = "1.1.0";
public static final String GENERATE_AS_MANAGED_SOURCES = "asManagedSources";

View File

@ -1271,7 +1271,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
this.exclusiveMaximum = cp.exclusiveMaximum;
this.required = cp.required;
this.deprecated = cp.deprecated;
this.hasMoreNonReadOnly = cp.hasMoreNonReadOnly;
this.isPrimitiveType = cp.isPrimitiveType;
this.isModel = cp.isModel;
this.isContainer = cp.isContainer;
@ -1379,9 +1378,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.hasRequiredParams = o.hasRequiredParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
@ -1392,12 +1389,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
this.isResponseFile = o.isResponseFile;
this.isResponseOptional = o.isResponseOptional;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.isDeprecated = o.isDeprecated;
this.isCallbackRequest = o.isCallbackRequest;
this.uniqueItems = o.uniqueItems;

View File

@ -348,9 +348,7 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.hasRequiredParams = o.hasRequiredParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
@ -360,12 +358,6 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
this.isResponseBinary = o.isResponseBinary;
this.isResponseFile = o.isResponseFile;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.isDeprecated = o.isDeprecated;
this.isCallbackRequest = o.isCallbackRequest;
this.path = o.path;

View File

@ -24,8 +24,8 @@ public class TemplateManagerOptions {
/**
* Constructs a new instance of {@link TemplateManagerOptions}
*
* @param minimalUpdate See {@link #isMinimalUpdate()}
* @param skipOverwrite See {@link #isSkipOverwrite()}
* @param minimalUpdate Minimal update
* @param skipOverwrite Skip overwrite
*/
public TemplateManagerOptions(boolean minimalUpdate, boolean skipOverwrite) {
this.minimalUpdate = minimalUpdate;

View File

@ -2243,6 +2243,23 @@ public class ModelUtils {
return schema;
}
/**
* Removes duplicate `oneOf` from a given schema if it does not also have a discriminator.
*
* @param schema Schema
*/
public static void deduplicateOneOfSchema(Schema<?> schema) {
if (schema.getOneOf() == null) {
return;
}
if (schema.getDiscriminator() != null) {
return; // Duplicate oneOf are allowed if there is a discriminator that can be used to separate them.
}
Set<Schema> deduplicated = new LinkedHashSet<>(schema.getOneOf());
schema.setOneOf(new ArrayList<>(deduplicated));
}
/**
* Check if the schema is of type 'null' or schema itself is pointing to null
* <p>

View File

@ -65,9 +65,9 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, String> defaultCookieMap = new HashMap<String, String>();
private String basePath = "{{{basePath}}}";
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String basePath = "{{{basePath}}}";
protected List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
"{{{url}}}",
@ -95,18 +95,18 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
){{/-last}}{{/servers}});
protected Integer serverIndex = 0;
protected Map<String, String> serverVariables = null;
private boolean debugging = false;
private int connectionTimeout = 0;
protected boolean debugging = false;
protected int connectionTimeout = 0;
private Client httpClient;
private ObjectMapper objectMapper;
protected Client httpClient;
protected ObjectMapper objectMapper;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
private int statusCode;
private Map<String, List<String>> responseHeaders;
protected int statusCode;
protected Map<String, List<String>> responseHeaders;
private DateFormat dateFormat;
protected DateFormat dateFormat;
public ApiClient() {
objectMapper = new ObjectMapper();
@ -688,7 +688,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param collectionQueryParams The collection query parameters
* @return The full URL
*/
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams) {
protected String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams) {
String baseURL;
if (serverIndex != null) {
if (serverIndex < 0 || serverIndex >= servers.size()) {
@ -741,7 +741,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return url.toString();
}
private ClientResponse getAPIResponse(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames) throws ApiException {
protected ClientResponse getAPIResponse(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames) throws ApiException {
if (body != null && !formParams.isEmpty()) {
throw new ApiException(500, "Cannot have body and form params");
}
@ -854,7 +854,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param headerParams Header parameters
* @param cookieParams Cookie parameters
*/
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
protected void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
@ -867,7 +867,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param formParams Form parameters
* @return HTTP form encoded parameters
*/
private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) {
protected String getXWWWFormUrlencodedParams(Map<String, Object> formParams) {
StringBuilder formParamBuilder = new StringBuilder();
for (Entry<String, Object> param : formParams.entrySet()) {

View File

@ -19,7 +19,7 @@ import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
{{>generatedAnnotation}}
public class RFC3339InstantDeserializer<T extends Temporal> extends InstantDeserializer<T> {
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_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS
= JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault();

View File

@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
{{>generatedAnnotation}}
public class RFC3339JavaTimeModule extends SimpleModule {
private static final long serialVersionUID = 1L;
public RFC3339JavaTimeModule() {
super("RFC3339JavaTimeModule");

View File

@ -87,9 +87,9 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, String> defaultCookieMap = new HashMap<String, String>();
private String basePath = "{{{basePath}}}";
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String basePath = "{{{basePath}}}";
protected List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
"{{{url}}}",
@ -117,22 +117,22 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
){{/-last}}{{/servers}});
protected Integer serverIndex = 0;
protected Map<String, String> serverVariables = null;
private boolean debugging = false;
private int connectionTimeout = 0;
protected boolean debugging = false;
protected int connectionTimeout = 0;
private CloseableHttpClient httpClient;
private ObjectMapper objectMapper;
protected CloseableHttpClient httpClient;
protected ObjectMapper objectMapper;
protected String tempFolderPath = null;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
private Map<Long, Integer> lastStatusCodeByThread = new ConcurrentHashMap<>();
private Map<Long, Map<String, List<String>>> lastResponseHeadersByThread = new ConcurrentHashMap<>();
protected Map<Long, Integer> lastStatusCodeByThread = new ConcurrentHashMap<>();
protected Map<Long, Map<String, List<String>>> lastResponseHeadersByThread = new ConcurrentHashMap<>();
private DateFormat dateFormat;
protected DateFormat dateFormat;
// Methods that can have a request body
private static List<String> bodyMethods = Arrays.asList("POST", "PUT", "DELETE", "PATCH");
protected static List<String> bodyMethods = Arrays.asList("POST", "PUT", "DELETE", "PATCH");
public ApiClient(CloseableHttpClient httpClient) {
objectMapper = new ObjectMapper();
@ -757,7 +757,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* Parse content type object from header value
*/
private ContentType getContentType(String headerValue) throws ApiException {
protected ContentType getContentType(String headerValue) throws ApiException {
try {
return ContentType.parse(headerValue);
} catch (UnsupportedCharsetException e) {
@ -768,7 +768,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* Get content type of a response or null if one was not provided
*/
private String getResponseMimeType(HttpResponse response) throws ApiException {
protected String getResponseMimeType(HttpResponse response) throws ApiException {
Header contentTypeHeader = response.getFirstHeader("Content-Type");
if (contentTypeHeader != null) {
return getContentType(contentTypeHeader.getValue()).getMimeType();
@ -877,7 +877,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private File downloadFileFromResponse(CloseableHttpResponse response) throws IOException {
protected File downloadFileFromResponse(CloseableHttpResponse response) throws IOException {
Header contentDispositionHeader = response.getFirstHeader("Content-Disposition");
String contentDisposition = contentDispositionHeader == null ? null : contentDispositionHeader.getValue();
File file = prepareDownloadFile(contentDisposition);
@ -948,7 +948,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param urlQueryDeepObject URL query string of the deep object parameters
* @return The full URL
*/
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams, String urlQueryDeepObject) {
protected String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams, String urlQueryDeepObject) {
String baseURL = getBaseURL();
final StringBuilder url = new StringBuilder();
@ -1127,7 +1127,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param headerParams Header parameters
* @param cookieParams Cookie parameters
*/
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
protected void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);

View File

@ -54,16 +54,16 @@ import feign.Retryer;
{{>generatedAnnotation}}
public class ApiClient {
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
protected static final Logger log = Logger.getLogger(ApiClient.class.getName());
public interface Api {}
{{#jackson}}
protected ObjectMapper objectMapper;
{{/jackson}}
private String basePath = "{{{basePath}}}";
private Map<String, RequestInterceptor> apiAuthorizations;
private Feign.Builder feignBuilder;
protected String basePath = "{{{basePath}}}";
protected Map<String, RequestInterceptor> apiAuthorizations;
protected Feign.Builder feignBuilder;
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, RequestInterceptor>();
@ -167,7 +167,7 @@ public class ApiClient {
}
{{#jackson}}
private ObjectMapper createObjectMapper() {
protected ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
@ -194,7 +194,7 @@ public class ApiClient {
{{/jackson}}
{{#hasOAuthMethods}}
private RequestInterceptor buildOauthRequestInterceptor(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
protected RequestInterceptor buildOauthRequestInterceptor(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
switch (flow) {
case PASSWORD:
return new OauthPasswordGrant(tokenUrl, scopes);
@ -375,7 +375,7 @@ public class ApiClient {
feignBuilder.requestInterceptor(authorization);
}
private <T extends RequestInterceptor> T getAuthorization(Class<T> type) {
protected <T extends RequestInterceptor> T getAuthorization(Class<T> type) {
return (T) apiAuthorizations.values()
.stream()
.filter(requestInterceptor -> type.isAssignableFrom(requestInterceptor.getClass()))

View File

@ -25,14 +25,14 @@ import java.io.OutputStream;
{{>generatedAnnotation}}
public class ApiClient {
private final String basePath;
private final HttpRequestFactory httpRequestFactory;
private final ObjectMapper objectMapper;
protected final String basePath;
protected final HttpRequestFactory httpRequestFactory;
protected final ObjectMapper objectMapper;
private static final String defaultBasePath = "{{basePath}}";
protected static final String defaultBasePath = "{{basePath}}";
// A reasonable default object mapper. Client can pass in a chosen ObjectMapper anyway, this is just for reasonable defaults.
private static ObjectMapper createDefaultObjectMapper() {
protected static ObjectMapper createDefaultObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper()
{{#failOnUnknownProperties}}
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
@ -84,7 +84,7 @@ public class ApiClient {
public class JacksonJsonHttpContent extends AbstractHttpContent {
/* A POJO that can be serialized with a com.fasterxml Jackson ObjectMapper */
private final Object data;
protected final Object data;
public JacksonJsonHttpContent(Object data) {
super(Json.MEDIA_TYPE);

View File

@ -85,13 +85,13 @@ import {{invokerPackage}}.auth.OAuth;
*/
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private static final Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$");
protected static final Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$");
protected Map<String, String> defaultHeaderMap = new HashMap<>();
protected Map<String, String> defaultCookieMap = new HashMap<>();
protected String basePath = "{{{basePath}}}";
protected String userAgent;
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
protected static final Logger log = Logger.getLogger(ApiClient.class.getName());
protected List<ServerConfiguration> servers = new ArrayList<>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
@ -175,7 +175,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
protected boolean debugging = false;
protected ClientConfig clientConfig;
protected int connectionTimeout = 0;
private int readTimeout = 0;
protected int readTimeout = 0;
protected Client httpClient;
protected JSON json;
@ -373,14 +373,14 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return this;
}
private void updateBasePath() {
protected void updateBasePath() {
if (serverIndex != null) {
setBasePath(servers.get(serverIndex).URL(serverVariables));
}
}
{{#hasOAuthMethods}}
private void setOauthBasePath(String basePath) {
protected void setOauthBasePath(String basePath) {
for(Authentication auth : authentications.values()) {
if (auth instanceof OAuth) {
((OAuth) auth).setBasePath(basePath);
@ -1029,7 +1029,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param key Key of the object
* @param multiPart MultiPart to add the form param to
*/
private void addParamToMultipart(Object value, String key, MultiPart multiPart) {
protected void addParamToMultipart(Object value, String key, MultiPart multiPart) {
if (value instanceof File) {
File file = (File) value;
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key)
@ -1350,7 +1350,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
protected Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
Response response;
if ("POST".equals(method)) {
response = invocationBuilder.post(entity);
@ -1412,7 +1412,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return clientConfig;
}
private void applyDebugSetting(ClientConfig clientConfig) {
protected void applyDebugSetting(ClientConfig clientConfig) {
if (debugging) {
clientConfig.register(new LoggingFeature(java.util.logging.Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), java.util.logging.Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 1024*50 /* Log payloads up to 50K */));
clientConfig.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY, LoggingFeature.Verbosity.PAYLOAD_ANY);

View File

@ -85,13 +85,13 @@ import {{invokerPackage}}.auth.OAuth;
*/
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private static final Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$");
protected static final Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$");
protected Map<String, String> defaultHeaderMap = new HashMap<>();
protected Map<String, String> defaultCookieMap = new HashMap<>();
protected String basePath = "{{{basePath}}}";
protected String userAgent;
private static final Logger log = Logger.getLogger(ApiClient.class.getName());
protected static final Logger log = Logger.getLogger(ApiClient.class.getName());
protected List<ServerConfiguration> servers = new ArrayList<>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
@ -175,7 +175,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
protected boolean debugging = false;
protected ClientConfig clientConfig;
protected int connectionTimeout = 0;
private int readTimeout = 0;
protected int readTimeout = 0;
protected Client httpClient;
protected JSON json;
@ -373,14 +373,14 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return this;
}
private void updateBasePath() {
protected void updateBasePath() {
if (serverIndex != null) {
setBasePath(servers.get(serverIndex).URL(serverVariables));
}
}
{{#hasOAuthMethods}}
private void setOauthBasePath(String basePath) {
protected void setOauthBasePath(String basePath) {
for(Authentication auth : authentications.values()) {
if (auth instanceof OAuth) {
((OAuth) auth).setBasePath(basePath);
@ -1029,7 +1029,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param key Key of the object
* @param multiPart MultiPart to add the form param to
*/
private void addParamToMultipart(Object value, String key, MultiPart multiPart) {
protected void addParamToMultipart(Object value, String key, MultiPart multiPart) {
if (value instanceof File) {
File file = (File) value;
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key)
@ -1350,7 +1350,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
protected Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
Response response;
if ("POST".equals(method)) {
response = invocationBuilder.post(entity);
@ -1412,7 +1412,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return clientConfig;
}
private void applyDebugSetting(ClientConfig clientConfig) {
protected void applyDebugSetting(ClientConfig clientConfig) {
if (debugging) {
clientConfig.register(new LoggingFeature(java.util.logging.Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), java.util.logging.Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 1024*50 /* Log payloads up to 50K */));
clientConfig.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY, LoggingFeature.Verbosity.PAYLOAD_ANY);

View File

@ -12,8 +12,8 @@ import {{javaxPackage}}.ws.rs.core.GenericType;
{{/imports}}
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import java.util.ArrayList;

View File

@ -17,8 +17,8 @@ import java.util.List;
import java.util.Map;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
/**

View File

@ -152,7 +152,6 @@ dependencies {
{{#useReflectionEqualsHashCode}}
implementation "org.apache.commons:commons-lang3:$commons_lang3_version"
{{/useReflectionEqualsHashCode}}
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
}

View File

@ -42,8 +42,8 @@ import android.os.Parcelable;
import android.os.Parcel;
{{/parcelableModel}}
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#performBeanValidation}}
import org.hibernate.validator.constraints.*;

View File

@ -408,8 +408,14 @@
<jackson-version>2.17.1</jackson-version>
<jackson-databind-version>2.17.1</jackson-databind-version>
<jackson-databind-nullable-version>0.2.6</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
<junit-version>5.10.0</junit-version>
{{#hasHttpSignatureMethods}}
<http-signature-version>1.8</http-signature-version>

View File

@ -45,17 +45,17 @@ import static java.nio.charset.StandardCharsets.UTF_8;
{{>generatedAnnotation}}
public class ApiClient {
private HttpClient.Builder builder;
private ObjectMapper mapper;
private String scheme;
private String host;
private int port;
private String basePath;
private Consumer<HttpRequest.Builder> interceptor;
private Consumer<HttpResponse<InputStream>> responseInterceptor;
private Consumer<HttpResponse<String>> asyncResponseInterceptor;
private Duration readTimeout;
private Duration connectTimeout;
protected HttpClient.Builder builder;
protected ObjectMapper mapper;
protected String scheme;
protected String host;
protected int port;
protected String basePath;
protected Consumer<HttpRequest.Builder> interceptor;
protected Consumer<HttpResponse<InputStream>> responseInterceptor;
protected Consumer<HttpResponse<String>> asyncResponseInterceptor;
protected Duration readTimeout;
protected Duration connectTimeout;
public static String valueToString(Object value) {
if (value == null) {
@ -200,7 +200,7 @@ public class ApiClient {
return mapper;
}
private String getDefaultBaseUri() {
protected String getDefaultBaseUri() {
return "{{{basePath}}}";
}

View File

@ -77,7 +77,7 @@ import {{invokerPackage}}.auth.AWS4Auth;
*/
public class ApiClient {
private String basePath = "{{{basePath}}}";
protected String basePath = "{{{basePath}}}";
protected List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
"{{{url}}}",
@ -105,29 +105,29 @@ public class ApiClient {
){{/-last}}{{/servers}});
protected Integer serverIndex = 0;
protected Map<String, String> serverVariables = null;
private boolean debugging = false;
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, String> defaultCookieMap = new HashMap<String, String>();
private String tempFolderPath = null;
protected boolean debugging = false;
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String tempFolderPath = null;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
private DateFormat dateFormat;
private DateFormat datetimeFormat;
private boolean lenientDatetimeFormat;
private int dateLength;
protected DateFormat dateFormat;
protected DateFormat datetimeFormat;
protected boolean lenientDatetimeFormat;
protected int dateLength;
private InputStream sslCaCert;
private boolean verifyingSsl;
private KeyManager[] keyManagers;
protected InputStream sslCaCert;
protected boolean verifyingSsl;
protected KeyManager[] keyManagers;
private OkHttpClient httpClient;
private JSON json;
protected OkHttpClient httpClient;
protected JSON json;
private HttpLoggingInterceptor loggingInterceptor;
protected HttpLoggingInterceptor loggingInterceptor;
{{#dynamicOperations}}
private Map<String, ApiOperation> operationLookupMap = new HashMap<>();
protected Map<String, ApiOperation> operationLookupMap = new HashMap<>();
{{/dynamicOperations}}
/**
@ -243,11 +243,11 @@ public class ApiClient {
{{/-first}}
{{/oauthMethods}}
{{/hasOAuthMethods}}
private void initHttpClient() {
protected void initHttpClient() {
initHttpClient(Collections.<Interceptor>emptyList());
}
private void initHttpClient(List<Interceptor> interceptors) {
protected void initHttpClient(List<Interceptor> interceptors) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addNetworkInterceptor(getProgressInterceptor());
for (Interceptor interceptor: interceptors) {
@ -261,7 +261,7 @@ public class ApiClient {
httpClient = builder.build();
}
private void init() {
protected void init() {
verifyingSsl = true;
json = new JSON();
@ -1715,7 +1715,7 @@ public class ApiClient {
* @param key The key of the Header element
* @param file The file to add to the Header
*/
private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, File file) {
protected void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, File file) {
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\"");
MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
mpBuilder.addPart(partHeaders, RequestBody.create(file, mediaType));
@ -1728,7 +1728,7 @@ public class ApiClient {
* @param key The key of the Header element
* @param obj The complex object to add to the Header
*/
private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, Object obj) {
protected void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, Object obj) {
RequestBody requestBody;
if (obj instanceof String) {
requestBody = RequestBody.create((String) obj, MediaType.parse("text/plain"));
@ -1750,7 +1750,7 @@ public class ApiClient {
* Get network interceptor to add it to the httpClient to track download progress for
* async requests.
*/
private Interceptor getProgressInterceptor() {
protected Interceptor getProgressInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
@ -1771,7 +1771,7 @@ public class ApiClient {
* Apply SSL related settings to httpClient according to the current values of
* verifyingSsl and sslCaCert.
*/
private void applySslSettings() {
protected void applySslSettings() {
try {
TrustManager[] trustManagers;
HostnameVerifier hostnameVerifier;
@ -1833,7 +1833,7 @@ public class ApiClient {
}
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
protected KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, password);
@ -1861,7 +1861,7 @@ public class ApiClient {
return this;
}
private void addOperationLookupEntry(String path, String method, Operation operation) {
protected void addOperationLookupEntry(String path, String method, Operation operation) {
if ( operation != null && operation.getOperationId() != null) {
operationLookupMap.put(
operation.getOperationId(),
@ -1921,7 +1921,7 @@ public class ApiClient {
* @return The string representation of the HTTP request body
* @throws {{invokerPackage}}.ApiException If fail to serialize the request body object into a string
*/
private String requestBodyToString(RequestBody requestBody) throws ApiException {
protected String requestBodyToString(RequestBody requestBody) throws ApiException {
if (requestBody != null) {
try {
final Buffer buffer = new Buffer();

View File

@ -322,16 +322,20 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
static {
// a set of all properties/fields (JSON key names)
openapiFields = new HashSet<String>();
{{#allVars}}
openapiFields.add("{{baseName}}");
{{/allVars}}
{{#hasVars}}
openapiFields = new HashSet<String>(Arrays.asList({{#allVars}}"{{baseName}}"{{^-last}}, {{/-last}}{{/allVars}}));
{{/hasVars}}
{{^hasVars}}
openapiFields = new HashSet<String>(0);
{{/hasVars}}
// a set of required properties/fields (JSON key names)
openapiRequiredFields = new HashSet<String>();
{{#requiredVars}}
openapiRequiredFields.add("{{baseName}}");
{{/requiredVars}}
{{#hasRequired}}
openapiRequiredFields = new HashSet<String>(Arrays.asList({{#requiredVars}}"{{baseName}}"{{^-last}}, {{/-last}}{{/requiredVars}}));
{{/hasRequired}}
{{^hasRequired}}
openapiRequiredFields = new HashSet<String>(0);
{{/hasRequired}}
}
/**

View File

@ -19,9 +19,9 @@ public class ApiClient {
public static final String BASE_URI = "{{.}}";
{{/basePath}}
private final Config config;
protected final Config config;
private ApiClient(Config config) {
protected ApiClient(Config config) {
this.config = config;
}
@ -38,7 +38,7 @@ public class ApiClient {
{{/apiInfo}}
public static class Config {
private Supplier<RequestSpecBuilder> reqSpecSupplier = () -> new RequestSpecBuilder()
protected Supplier<RequestSpecBuilder> reqSpecSupplier = () -> new RequestSpecBuilder()
{{#basePath}}.setBaseUri(BASE_URI){{/basePath}}
.setConfig(config().objectMapperConfig(objectMapperConfig().defaultObjectMapper({{#gson}}gson(){{/gson}}{{#jackson}}jackson(){{/jackson}})));

View File

@ -74,26 +74,26 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public enum CollectionFormat {
CSV(","), TSV("\t"), SSV(" "), PIPES("|"), MULTI(null);
private final String separator;
protected final String separator;
CollectionFormat(String separator) {
this.separator = separator;
}
private String collectionToString(Collection<?> collection) {
protected String collectionToString(Collection<?> collection) {
return StringUtils.collectionToDelimitedString(collection, separator);
}
}
private final HttpHeaders defaultHeaders = new HttpHeaders();
private final MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<>();
protected final HttpHeaders defaultHeaders = new HttpHeaders();
protected final MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<>();
private String basePath = "{{basePath}}";
protected String basePath = "{{basePath}}";
private final RestClient restClient;
private final DateFormat dateFormat;
private final ObjectMapper objectMapper;
protected final RestClient restClient;
protected final DateFormat dateFormat;
protected final ObjectMapper objectMapper;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
public ApiClient() {
@ -118,7 +118,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
this.init();
}
private ApiClient(RestClient restClient, DateFormat format) {
protected ApiClient(RestClient restClient, DateFormat format) {
this(restClient, createDefaultObjectMapper(format), format);
}
@ -626,7 +626,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param uriParams The path parameters
* return templatized query string
*/
private String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
protected String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> {
if (CollectionUtils.isEmpty(values)) {
@ -652,7 +652,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return queryBuilder.toString();
}
private RestClient.RequestBodySpec prepareRequest(String path, HttpMethod method, Map<String, Object> pathParams,
protected RestClient.RequestBodySpec prepareRequest(String path, HttpMethod method, Map<String, Object> pathParams,
MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams,
MultiValueMap<String, String> cookieParams, MultiValueMap<String, Object> formParams, List<MediaType> accept,
MediaType contentType, String[] authNames) {
@ -728,7 +728,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param cookies map all cookies
* @return header string for cookies.
*/
private String buildCookieHeader(MultiValueMap<String, String> cookies) {
protected String buildCookieHeader(MultiValueMap<String, String> cookies) {
final StringBuilder cookieValue = new StringBuilder();
String delimiter = "";
for (final Map.Entry<String, List<String>> entry : cookies.entrySet()) {

View File

@ -56,21 +56,21 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private Map<String, String> defaultCookieMap = new HashMap<String, String>();
private String basePath = "{{{basePath}}}";
private boolean debugging = false;
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String basePath = "{{{basePath}}}";
protected boolean debugging = false;
private Client httpClient;
private JSON json;
private String tempFolderPath = null;
protected Client httpClient;
protected JSON json;
protected String tempFolderPath = null;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
private int statusCode;
private Map<String, List<String>> responseHeaders;
protected int statusCode;
protected Map<String, List<String>> responseHeaders;
private DateFormat dateFormat;
protected DateFormat dateFormat;
public ApiClient() {
json = new JSON();
@ -707,7 +707,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private Response invoke(Invocation.Builder invocationBuilder, String method, Entity<?> entity) throws ApiException {
protected Response invoke(Invocation.Builder invocationBuilder, String method, Entity<?> entity) throws ApiException {
Response response = null;
if ("GET".equals(method)) {
@ -736,7 +736,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* Build the Client used to make HTTP requests.
*/
private Client buildHttpClient(boolean debugging) {
protected Client buildHttpClient(boolean debugging) {
final ClientConfiguration clientConfig = new ClientConfiguration(ResteasyProviderFactory.getInstance());
clientConfig.register(json);
if(debugging){
@ -744,7 +744,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
return ClientBuilder.newClient(clientConfig);
}
private Map<String, List<String>> buildResponseHeaders(Response response) {
protected Map<String, List<String>> buildResponseHeaders(Response response) {
Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
for (Entry<String, List<Object>> entry: response.getHeaders().entrySet()) {
List<Object> values = entry.getValue();
@ -762,7 +762,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
*
* @param authNames The authentications to apply
*/
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
protected void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);

View File

@ -93,33 +93,33 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public enum CollectionFormat {
CSV(","), TSV("\t"), SSV(" "), PIPES("|"), MULTI(null);
private final String separator;
protected final String separator;
private CollectionFormat(String separator) {
CollectionFormat(String separator) {
this.separator = separator;
}
private String collectionToString(Collection<?> collection) {
protected String collectionToString(Collection<?> collection) {
return StringUtils.collectionToDelimitedString(collection, separator);
}
}
private boolean debugging = false;
protected boolean debugging = false;
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();
protected HttpHeaders defaultHeaders = new HttpHeaders();
protected MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();
private int maxAttemptsForRetry = {{maxAttemptsForRetry}};
protected int maxAttemptsForRetry = {{maxAttemptsForRetry}};
private long waitTimeMillis = {{waitTimeMillis}};
protected long waitTimeMillis = {{waitTimeMillis}};
private String basePath = "{{basePath}}";
protected String basePath = "{{basePath}}";
private RestTemplate restTemplate;
protected RestTemplate restTemplate;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
private DateFormat dateFormat;
protected DateFormat dateFormat;
public ApiClient() {
this.restTemplate = buildRestTemplate();
@ -852,7 +852,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param cookies map all cookies
* @return header string for cookies.
*/
private String buildCookieHeader(MultiValueMap<String, String> cookies) {
protected String buildCookieHeader(MultiValueMap<String, String> cookies) {
final StringBuilder cookieValue = new StringBuilder();
String delimiter = "";
for (final Map.Entry<String, List<String>> entry : cookies.entrySet()) {
@ -906,8 +906,8 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private final Log log = LogFactory.getLog(ApiClientHttpRequestInterceptor.class);
protected class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
protected final Log log = LogFactory.getLog(ApiClientHttpRequestInterceptor.class);
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
@ -917,21 +917,21 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return response;
}
private void logRequest(HttpRequest request, byte[] body) throws UnsupportedEncodingException {
protected void logRequest(HttpRequest request, byte[] body) throws UnsupportedEncodingException {
log.info("URI: " + request.getURI());
log.info("HTTP Method: " + request.getMethod());
log.info("HTTP Headers: " + headersToString(request.getHeaders()));
log.info("Request Body: " + new String(body, StandardCharsets.UTF_8));
}
private void logResponse(ClientHttpResponse response) throws IOException {
protected void logResponse(ClientHttpResponse response) throws IOException {
log.info("HTTP Status Code: " + response.getStatusCode().value());
log.info("Status Text: " + response.getStatusText());
log.info("HTTP Headers: " + headersToString(response.getHeaders()));
log.info("Response Body: " + bodyToString(response.getBody()));
}
private String headersToString(HttpHeaders headers) {
protected String headersToString(HttpHeaders headers) {
if(headers == null || headers.isEmpty()) {
return "";
}
@ -948,7 +948,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return builder.toString();
}
private String bodyToString(InputStream body) throws IOException {
protected String bodyToString(InputStream body) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(body, StandardCharsets.UTF_8));
String line = bufferedReader.readLine();

View File

@ -55,11 +55,11 @@ import java.util.HashMap;
public class ApiClient {
private Map<String, Interceptor> apiAuthorizations;
private OkHttpClient.Builder okBuilder;
private Retrofit.Builder adapterBuilder;
private JSON json;
private OkHttpClient okHttpClient;
protected Map<String, Interceptor> apiAuthorizations;
protected OkHttpClient.Builder okBuilder;
protected Retrofit.Builder adapterBuilder;
protected JSON json;
protected OkHttpClient okHttpClient;
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
@ -426,8 +426,8 @@ public class ApiClient {
* expected type is String, then just return the body string.
*/
class GsonResponseBodyConverterToString<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final Type type;
protected final Gson gson;
protected final Type type;
GsonResponseBodyConverterToString(Gson gson, Type type) {
this.gson = gson;
@ -447,14 +447,14 @@ class GsonResponseBodyConverterToString<T> implements Converter<ResponseBody, T>
class GsonCustomConverterFactory extends Converter.Factory
{
private final Gson gson;
private final GsonConverterFactory gsonConverterFactory;
protected final Gson gson;
protected final GsonConverterFactory gsonConverterFactory;
public static GsonCustomConverterFactory create(Gson gson) {
return new GsonCustomConverterFactory(gson);
}
private GsonCustomConverterFactory(Gson gson) {
protected GsonCustomConverterFactory(Gson gson) {
if (gson == null)
throw new NullPointerException("gson == null");
this.gson = gson;

View File

@ -31,13 +31,13 @@ import {{invokerPackage}}.auth.Authentication;
public class ApiClient {
/** Underlying HTTP-client */
private WSClient wsClient;
protected WSClient wsClient;
/** Supported auths */
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
/** API base path */
private String basePath = "{{{basePath}}}";
protected String basePath = "{{{basePath}}}";
public ApiClient(WSClient wsClient) {
this();

View File

@ -31,13 +31,13 @@ import {{invokerPackage}}.auth.Authentication;
public class ApiClient {
/** Underlying HTTP-client */
private WSClient wsClient;
protected WSClient wsClient;
/** Supported auths */
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
/** API base path */
private String basePath = "{{{basePath}}}";
protected String basePath = "{{{basePath}}}";
public ApiClient(WSClient wsClient) {
this();

View File

@ -37,22 +37,22 @@ import {{invokerPackage}}.auth.Authentication;
public class ApiClient {
/** Underlying HTTP-client */
private WSClient wsClient;
protected WSClient wsClient;
/** Creates HTTP call instances */
private Play26CallFactory callFactory;
protected Play26CallFactory callFactory;
/** Create {@link java.util.concurrent.CompletionStage} instances from HTTP calls */
private Play26CallAdapterFactory callAdapterFactory;
protected Play26CallAdapterFactory callAdapterFactory;
/** Supported auths */
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
/** API base path */
private String basePath = "{{{basePath}}}";
protected String basePath = "{{{basePath}}}";
/** Default ObjectMapper */
private ObjectMapper defaultMapper;
protected ObjectMapper defaultMapper;
public ApiClient(WSClient wsClient) {
this();

View File

@ -49,21 +49,21 @@ import static java.util.stream.Collectors.toMap;
{{>generatedAnnotation}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
private static final OpenOptions FILE_DOWNLOAD_OPTIONS = new OpenOptions().setCreate(true).setTruncateExisting(true);
protected static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
protected static final OpenOptions FILE_DOWNLOAD_OPTIONS = new OpenOptions().setCreate(true).setTruncateExisting(true);
private final Vertx vertx;
private final JsonObject config;
private final String identifier;
protected final Vertx vertx;
protected final JsonObject config;
protected final String identifier;
private MultiMap defaultHeaders = MultiMap.caseInsensitiveMultiMap();
private MultiMap defaultCookies = MultiMap.caseInsensitiveMultiMap();
private Map<String, Authentication> authentications;
private String basePath = "{{{basePath}}}";
private DateFormat dateFormat;
private ObjectMapper objectMapper;
private String downloadsDir = "";
private int timeout = -1;
protected MultiMap defaultHeaders = MultiMap.caseInsensitiveMultiMap();
protected MultiMap defaultCookies = MultiMap.caseInsensitiveMultiMap();
protected Map<String, Authentication> authentications;
protected String basePath = "{{{basePath}}}";
protected DateFormat dateFormat;
protected ObjectMapper objectMapper;
protected String downloadsDir = "";
protected int timeout = -1;
public ApiClient(Vertx vertx, JsonObject config) {
Objects.requireNonNull(vertx, "Vertx must not be null");
@ -385,7 +385,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param mime MIME
* @return True if the MIME type is JSON
*/
private boolean isJsonMime(String mime) {
protected boolean isJsonMime(String mime) {
String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
return mime != null && (mime.matches(jsonMime) || mime.equalsIgnoreCase("application/json-patch+json"));
}
@ -523,7 +523,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
private String buildCookieHeader(MultiMap cookies) {
protected String buildCookieHeader(MultiMap cookies) {
final StringBuilder cookieValue = new StringBuilder();
String delimiter = "";
for (final Map.Entry<String, String> entry : cookies.entries()) {
@ -680,7 +680,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public static class AuthInfo {
private final Map<String, Authentication> authentications = new LinkedHashMap<>();{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
protected final Map<String, Authentication> authentications = new LinkedHashMap<>();{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
public void add{{#lambda.pascalcase}}{{name}}{{/lambda.pascalcase}}Authentication(String username, String password) {
HttpBasicAuth auth = new HttpBasicAuth();

View File

@ -89,28 +89,28 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public enum CollectionFormat {
CSV(","), TSV("\t"), SSV(" "), PIPES("|"), MULTI(null);
private final String separator;
private CollectionFormat(String separator) {
protected final String separator;
CollectionFormat(String separator) {
this.separator = separator;
}
private String collectionToString(Collection<?> collection) {
protected String collectionToString(Collection<?> collection) {
return StringUtils.collectionToDelimitedString(collection, separator);
}
}
private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
protected static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();
protected HttpHeaders defaultHeaders = new HttpHeaders();
protected MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();
private String basePath = "{{basePath}}";
protected String basePath = "{{basePath}}";
private final WebClient webClient;
private final DateFormat dateFormat;
private final ObjectMapper objectMapper;
protected final WebClient webClient;
protected final DateFormat dateFormat;
protected final ObjectMapper objectMapper;
private Map<String, Authentication> authentications;
protected Map<String, Authentication> authentications;
public ApiClient() {
@ -135,7 +135,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
this(Optional.ofNullable(webClient).orElseGet(() -> buildWebClient(mapper.copy())), format);
}
private ApiClient(WebClient webClient, DateFormat format) {
protected ApiClient(WebClient webClient, DateFormat format) {
this.webClient = webClient;
this.dateFormat = format;
this.objectMapper = createDefaultObjectMapper(format);
@ -634,7 +634,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param uriParams The path parameters
* return templatized query string
*/
private String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
protected String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> {
if (CollectionUtils.isEmpty(values)) {
@ -660,7 +660,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return queryBuilder.toString();
}
private WebClient.RequestBodySpec prepareRequest(String path, HttpMethod method, Map<String, Object> pathParams,
protected WebClient.RequestBodySpec prepareRequest(String path, HttpMethod method, Map<String, Object> pathParams,
MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams,
MultiValueMap<String, String> cookieParams, MultiValueMap<String, Object> formParams, List<MediaType> accept,
MediaType contentType, String[] authNames) {

View File

@ -36,8 +36,12 @@
this.value = value;
}
@Override
@JsonValue
public {{{dataType}}} getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}

View File

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

View File

@ -2,9 +2,10 @@
{{#vars}}
{
"name": "{{baseName}}",
"type": {{^required}}["null", {{/required}}{{>typeProperty}}{{^required}}]{{/required}},
"doc": "{{{description}}}"{{^required}},
"default": null{{/required}}
"type": {{^defaultValue}}{{^required}}["null", {{/required}}{{>typeProperty}}{{^required}}]{{/required}}{{/defaultValue}}{{#defaultValue}}{{^required}}[{{/required}}{{>typeProperty}}{{^required}}, "null"]{{/required}}{{/defaultValue}},
"doc": "{{{description}}}"{{#defaultValue}},
"default": {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{^required}},
"default": null{{/required}}{{/defaultValue}}
}{{^-last}},{{/-last}}
{{/vars}}
]

View File

@ -13,7 +13,9 @@
#include "{{packageName}}/ApiException.h"
#include "{{packageName}}/IHttpBody.h"
#include "{{packageName}}/HttpContent.h"
{{^hasModelImport}}
#include "{{packageName}}/ModelBase.h"
{{/hasModelImport}}
#if defined (_WIN32) || defined (_WIN64)
#undef U
#endif
@ -52,6 +54,9 @@ public:
static utility::string_t parameterToString(double value);
static utility::string_t parameterToString(const utility::datetime &value);
static utility::string_t parameterToString(bool value);
{{^hasModelImport}}
static utility::string_t parameterToString(const ModelBase& value);
{{/hasModelImport}}
template<class T>
static utility::string_t parameterToString(const std::vector<T>& value);
template<class T>

View File

@ -79,6 +79,13 @@ utility::string_t ApiClient::parameterToString(const utility::datetime &value)
return utility::conversions::to_string_t(value.to_string(utility::datetime::ISO_8601));
}
{{^hasModelImport}}
utility::string_t ApiClient::parameterToString(const ModelBase& value)
{
return value.toJson().serialize();
}
{{/hasModelImport}}
utility::string_t ApiClient::parameterToString(bool value)
{
std::stringstream valueAsStringStream;

View File

@ -8,7 +8,7 @@
#
# NOTE: Auto generated by OpenAPI Generator (https://openapi-generator.tech).
cmake_minimum_required (VERSION 3.5)
cmake_minimum_required (VERSION 3.10)
project({{{packageName}}} CXX)
@ -36,6 +36,7 @@ if(NOT CMAKE_BUILD_TYPE)
endif()
find_package(cpprestsdk REQUIRED)
target_compile_definitions(cpprestsdk::cpprest INTERFACE _TURN_OFF_PLATFORM_STRING)
find_package(Boost REQUIRED)
include(GNUInstallDirs)
@ -63,14 +64,16 @@ if (UNIX)
if (BUILD_SHARED_LIBS)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest)
else()
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest crypto)
find_library(CRYPTO_LIB crypto REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest ${CRYPTO_LIB})
endif()
else()
message(STATUS "Building client library for Windows")
if (BUILD_SHARED_LIBS)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest)
else()
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest bcrypt)
find_library(BCRYPT_LIB bcrypt REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::headers cpprestsdk::cpprest ${BCRYPT_LIB})
endif()
endif()

View File

@ -92,6 +92,15 @@ class {{declspec}} {{classname}}
{
public:
{{classname}}();
{{classname}}(utility::string_t str);
operator utility::string_t() const {
return enumToStrMap.at(getValue());
}
{{! operator std::string() const {
return enumToStrMap.at(getValue());
} }}
virtual ~{{classname}}();
/////////////////////////////////////////////
@ -124,6 +133,21 @@ public:
protected:
e{{classname}} m_value;
std::map<e{{classname}},utility::string_t> enumToStrMap = {
{{#allowableValues}}
{{#enumVars}}
{ e{{classname}}::{{classname}}_{{{name}}}, "{{{name}}}" }{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
std::map<utility::string_t,e{{classname}}> strToEnumMap = {
{{#allowableValues}}
{{#enumVars}}
{ "{{{name}}}", e{{classname}}::{{classname}}_{{{name}}} }{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
};
{{/isEnum}}
{{^isEnum}}

View File

@ -82,7 +82,7 @@ using EnumUnderlyingType = {{#isNumeric}}int64_t{{/isNumeric}}{{^isNumeric}}util
{{/isNumeric}}
{{^isNumeric}}
{{#enumVars}}
if (val == utility::conversions::to_string_t(U("{{{value}}}")))
if (val == utility::conversions::to_string_t(_XPLATSTR("{{{value}}}")))
return {{classname}}::e{{classname}}::{{classname}}_{{name}};
{{/enumVars}}
{{/isNumeric}}
@ -97,7 +97,7 @@ EnumUnderlyingType fromEnum({{classname}}::e{{classname}} e)
{
{{#enumVars}}
case {{classname}}::e{{classname}}::{{classname}}_{{name}}:
return {{#isNumeric}}{{value}}{{/isNumeric}}{{^isNumeric}}U("{{value}}"){{/isNumeric}};
return {{#isNumeric}}{{value}}{{/isNumeric}}{{^isNumeric}}_XPLATSTR("{{value}}"){{/isNumeric}};
{{#-last}}
default:
break;
@ -137,9 +137,9 @@ bool {{classname}}::fromJson(const web::json::value& val)
void {{classname}}::toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix) const
{
utility::string_t namePrefix = prefix;
if (!namePrefix.empty() && namePrefix.back() != U('.'))
if (!namePrefix.empty() && namePrefix.back() != _XPLATSTR('.'))
{
namePrefix.push_back(U('.'));
namePrefix.push_back(_XPLATSTR('.'));
}
auto e = fromEnum(m_value);
@ -150,9 +150,9 @@ bool {{classname}}::fromMultiPart(std::shared_ptr<MultipartFormData> multipart,
{
bool ok = true;
utility::string_t namePrefix = prefix;
if (!namePrefix.empty() && namePrefix.back() != U('.'))
if (!namePrefix.empty() && namePrefix.back() != _XPLATSTR('.'))
{
namePrefix.push_back(U('.'));
namePrefix.push_back(_XPLATSTR('.'));
}
{
EnumUnderlyingType e;
@ -176,6 +176,10 @@ void {{classname}}::setValue({{classname}}::e{{classname}} const value)
m_value = value;
}
{{classname}}::{{classname}}(utility::string_t str){
setValue( strToEnumMap[str] );
}
{{/isEnum}}
{{^isEnum}}
@ -227,13 +231,13 @@ web::json::value {{classname}}::toJson() const
{{#isEnum}}{{#isContainer}}{{#isArray}}
{{{dataType}}} refVal = from{{{enumName}}}(m_{{name}});
{{/isArray}}{{#isMap}}
val[utility::conversions::to_string_t(U("{{baseName}}"))] = ModelBase::toJson(m_{{name}});
val[utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))] = ModelBase::toJson(m_{{name}});
{{/isMap}}{{/isContainer}}{{^isContainer}}
utility::string_t refVal = from{{{datatypeWithEnum}}}(m_{{name}});
{{/isContainer}}{{^isMap}}val[utility::conversions::to_string_t(U("{{baseName}}"))] = ModelBase::toJson(refVal);
{{/isContainer}}{{^isMap}}val[utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))] = ModelBase::toJson(refVal);
{{/isMap}}{{/isEnum}}
{{^isEnum}}
val[utility::conversions::to_string_t(U("{{baseName}}"))] = ModelBase::toJson(m_{{name}});
val[utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))] = ModelBase::toJson(m_{{name}});
{{/isEnum}}
}
{{/isInherited}}
@ -250,9 +254,9 @@ bool {{classname}}::fromJson(const web::json::value& val)
{{/parent}}
{{#vars}}
{{^isInherited}}
if(val.has_field(utility::conversions::to_string_t(U("{{baseName}}"))))
if(val.has_field(utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))))
{
const web::json::value& fieldValue = val.at(utility::conversions::to_string_t(U("{{baseName}}")));
const web::json::value& fieldValue = val.at(utility::conversions::to_string_t(_XPLATSTR("{{baseName}}")));
if(!fieldValue.is_null())
{
{{{dataType}}} refVal_{{setter}};
@ -277,26 +281,26 @@ bool {{classname}}::fromJson(const web::json::value& val)
void {{classname}}::toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix) const
{
utility::string_t namePrefix = prefix;
if(namePrefix.size() > 0 && namePrefix.substr(namePrefix.size() - 1) != utility::conversions::to_string_t(U(".")))
if(namePrefix.size() > 0 && namePrefix.substr(namePrefix.size() - 1) != utility::conversions::to_string_t(_XPLATSTR(".")))
{
namePrefix += utility::conversions::to_string_t(U("."));
namePrefix += utility::conversions::to_string_t(_XPLATSTR("."));
}
{{#vars}}
if(m_{{name}}IsSet)
{
{{^isEnum}}
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(U("{{baseName}}")), m_{{name}}));
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(_XPLATSTR("{{baseName}}")), m_{{name}}));
{{/isEnum}}
{{#isEnum}}
{{#isContainer}}
{{#isArray}}
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(U("{{baseName}}")), from{{{enumName}}}(m_{{name}})));
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(_XPLATSTR("{{baseName}}")), from{{{enumName}}}(m_{{name}})));
{{/isArray}}{{#isMap}}
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(U("{{baseName}}")), m_{{name}}));
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(_XPLATSTR("{{baseName}}")), m_{{name}}));
{{/isMap}}
{{/isContainer}}
{{^isContainer}}
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(U("{{baseName}}")), from{{{datatypeWithEnum}}}(m_{{name}})));
multipart->add(ModelBase::toHttpContent(namePrefix + utility::conversions::to_string_t(_XPLATSTR("{{baseName}}")), from{{{datatypeWithEnum}}}(m_{{name}})));
{{/isContainer}}
{{/isEnum}}
}
@ -307,16 +311,16 @@ bool {{classname}}::fromMultiPart(std::shared_ptr<MultipartFormData> multipart,
{
bool ok = true;
utility::string_t namePrefix = prefix;
if(namePrefix.size() > 0 && namePrefix.substr(namePrefix.size() - 1) != utility::conversions::to_string_t(U(".")))
if(namePrefix.size() > 0 && namePrefix.substr(namePrefix.size() - 1) != utility::conversions::to_string_t(_XPLATSTR(".")))
{
namePrefix += utility::conversions::to_string_t(U("."));
namePrefix += utility::conversions::to_string_t(_XPLATSTR("."));
}
{{#vars}}
if(multipart->hasContent(utility::conversions::to_string_t(U("{{baseName}}"))))
if(multipart->hasContent(utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))))
{
{{{dataType}}} refVal_{{setter}};
ok &= ModelBase::fromHttpContent(multipart->getContent(utility::conversions::to_string_t(U("{{baseName}}"))), refVal_{{setter}} );
ok &= ModelBase::fromHttpContent(multipart->getContent(utility::conversions::to_string_t(_XPLATSTR("{{baseName}}"))), refVal_{{setter}} );
{{^isEnum}}
{{setter}}(refVal_{{setter}});
{{/isEnum}}

View File

@ -128,12 +128,12 @@ namespace {{packageName}}.Client
{ // array
foreach (var value in parameter.Value)
{
httpValues.Add(HttpUtility.UrlEncode(parameter.Key) + "[]", value);
httpValues.Add({{#net90OrLater}}HttpUtility.UrlEncode({{/net90OrLater}}parameter.Key{{#net90OrLater}}){{/net90OrLater}} + "[]", value);
}
}
else
{
httpValues.Add(HttpUtility.UrlEncode(parameter.Key), parameter.Value[0]);
httpValues.Add({{#net90OrLater}}HttpUtility.UrlEncode({{/net90OrLater}}parameter.Key{{#net90OrLater}}){{/net90OrLater}}, parameter.Value[0]);
}
#else
if (parameter.Value.Count > 1)

View File

@ -493,7 +493,7 @@ namespace {{packageName}}.Client
{
InterceptRequest(request);
RestResponse<T> response = await getResponse(client);
RestResponse<T> response = await getResponse(client).ConfigureAwait(false);
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
@ -562,7 +562,7 @@ namespace {{packageName}}.Client
{
if (policyResult.Outcome == OutcomeType.Successful)
{
return await client.Deserialize<T>(policyResult.Result, cancellationToken);
return await client.Deserialize<T>(policyResult.Result, cancellationToken).ConfigureAwait(false);
}
else
{
@ -621,7 +621,7 @@ namespace {{packageName}}.Client
{
var policy = RetryConfiguration.AsyncRetryPolicy;
var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false);
return await DeserializeRestResponseFromPolicyAsync<T>(client, request, policyResult, cancellationToken);
return await DeserializeRestResponseFromPolicyAsync<T>(client, request, policyResult, cancellationToken).ConfigureAwait(false);
}
else
{

View File

@ -134,7 +134,7 @@ namespace {{packageName}}.Client
{
#if (NETCOREAPP)
string framework = RuntimeInformation.FrameworkDescription;
string key = framework.StartsWith(".NET 9")?parameter.Key:HttpUtility.UrlEncode(parameter.Key);
string key = framework.StartsWith(".NET 9") ? parameter.Key : {{#net90OrLater}}HttpUtility.UrlEncode({{/net90OrLater}}parameter.Key{{#net90OrLater}}){{/net90OrLater}};
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)

View File

@ -60,6 +60,9 @@
{{#vars}}
{{#hasValidation}}
{{^isEnum}}
{{^isDateTime}}
{{^isDate}}
{{^isTime}}
{{#maxLength}}
// {{{name}}} ({{{dataType}}}) maxLength
if (this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}})
@ -76,6 +79,9 @@
}
{{/minLength}}
{{/isTime}}
{{/isDate}}
{{/isDateTime}}
{{#maximum}}
// {{{name}}} ({{{dataType}}}) maximum
if ({{#useGenericHost}}{{^required}}this.{{{name}}}Option.IsSet && {{/required}}{{/useGenericHost}}this.{{{name}}}{{#useGenericHost}}{{^required}}Option.Value{{/required}}{{/useGenericHost}} {{#exclusiveMaximum}}<={{/exclusiveMaximum}}{{^exclusiveMaximum}}>{{/exclusiveMaximum}} ({{{dataType}}}){{maximum}})

View File

@ -77,137 +77,23 @@ defmodule {{moduleName}}.Connection do
defdelegate request(client, options), to: Tesla
@doc """
Configure a client with no authentication.
### Returns
Tesla.Env.client
"""
@spec new() :: Tesla.Env.client()
def new do
Tesla.client(middleware(), adapter())
end
@doc """
Configure a client that may have authentication.
Configure a {{moduleName}} client.
### Parameters
{{#hasOAuthMethods}}
The first parameter *may* be a `token` (a string, a token fetcher class,
or a module/function tuple) or a keyword list of `options`. They are
documented separately, but only *one* of them will be passed.
- `token`: a String or a function of arity one. This value, or the result
of the function call, will be set as a bearer token in the
`authorization` header.
{{/hasOAuthMethods}}
- `options`: a keyword list of {{moduleName}}.Connection.options.
- `options`: an optional keyword list of {{moduleName}}.Connection.options.
### Returns
Tesla.Env.client
"""
{{#hasOAuthMethods}}
@spec new(String.t() | token_fetcher | options) :: Tesla.Env.client()
{{/hasOAuthMethods}}
{{^hasOAuthMethods}}
@spec new(options) :: Tesla.Env.client()
{{/hasOAuthMethods}}
{{#hasOAuthMethods}}
def new(token) when is_binary(token) or is_function(token, 1) or is_tuple(token) do
new(token: token)
end
{{/hasOAuthMethods}}
def new(options) when is_list(options) do
def new(options \\ []) do
options
|> middleware()
|> Tesla.client(adapter())
end
{{#hasOAuthMethods}}
{{#hasHttpBasicMethods}}
@doc """
Configure a client using bearer authentication with scopes, or with
username and password for basic authentication.
### Parameters
- `token_or_username`: a String representing a bearer token or a username,
depending on the type of the next parameter, or a function arity one
that returns a bearer token.
- `scopes_or_password`: a list of Strings represenging OAuth2 scopes, or
a single string that is the password for the username provided.
- `options`: a keyword list of {{moduleName}}.Connection.options.
### Returns
Tesla.Env.client
"""
@spec new(
token_or_username :: String.t() | token_fetcher,
scopes_or_password :: list(String.t()) | String.t(),
options
) :: Tesla.Env.client()
{{/hasHttpBasicMethods}}
{{^hasHttpBasicMethods}}
@doc """
Configure a client using bearer authentication with scopes.
### Parameters
- `token`: a String or a function of arity one. This value, or the result
of the function call, will be set as a bearer token in the
`authorization` header.
- `scopes`: a list of Strings represenging OAuth2 scopes.
- `options`: a keyword list of {{moduleName}}.Connection.options.
### Returns
Tesla.Env.client
"""
@spec new(String.t() | token_fetcher, list(String.t()), options) :: Tesla.Env.client()
{{/hasHttpBasicMethods}}
{{/hasOAuthMethods}}
{{^hasOAuthMethods}}
{{#hasHttpBasicMethods}}
@doc """
Configure a client using username and password for basic authentication.
### Parameters
- `username`: a String representing a username.
- `password`: a String representing a password.
- `options`: a keyword list of {{moduleName}}.Connection.options.
### Returns
Tesla.Env.client
"""
@spec new(String.t(), String.t()), options) :: Tesla.Env.client()
{{/hasHttpBasicMethods}}
{{/hasOAuthMethods}}
{{#hasOAuthMethods}}
def new(token_or_username, scopes_or_password, options \\ [])
def new(token, scopes, options)
when (is_binary(token) or is_function(token, 1) or is_tuple(token)) and is_list(scopes) do
options
|> Keyword.merge(token: token, token_scopes: scopes)
|> new()
end
{{/hasOAuthMethods}}
{{#hasHttpBasicMethods}}
def new(username, password, options) when is_binary(username) and is_binary(password) do
options
|> Keyword.merge(username: username, password: password)
|> new()
end
{{/hasHttpBasicMethods}}
@doc """
Returns fully configured middleware for passing to Tesla.client/2.
"""

View File

@ -202,14 +202,14 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{#-first}}
// a set of all properties/fields (JSON key names)
{{/-first}}
openapiFields.add("{{baseName}}")
openapiFields.add("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
{{/allVars}}
{{#requiredVars}}
{{#-first}}
// a set of required properties/fields (JSON key names)
{{/-first}}
openapiRequiredFields.add("{{baseName}}")
openapiRequiredFields.add("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
{{/requiredVars}}
}
@ -248,26 +248,26 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{#items.isModel}}
{{#required}}
// ensure the json data is an array
if (!jsonObj.get("{{{baseName}}}").isJsonArray) {
throw IllegalArgumentException(String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString()))
if (!jsonObj.get("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").isJsonArray) {
throw IllegalArgumentException(String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be an array in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString()))
}
// validate the required field `{{{baseName}}}` (array)
for (i in 0 until jsonObj.getAsJsonArray("{{{baseName}}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{{baseName}}}").get(i))
for (i in 0 until jsonObj.getAsJsonArray("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").get(i))
}
{{/required}}
{{^required}}
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
if (jsonObj.getAsJsonArray("{{{baseName}}}") != null) {
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
if (jsonObj.getAsJsonArray("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}") != null) {
// ensure the json data is an array
require(jsonObj["{{{baseName}}}"].isJsonArray) {
String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
require(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonArray) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be an array in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
// validate the optional field `{{{baseName}}}` (array)
for (i in 0 until jsonObj.getAsJsonArray("{{{baseName}}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{{baseName}}}").get(i))
for (i in 0 until jsonObj.getAsJsonArray("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").get(i))
}
}
}
@ -276,19 +276,19 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{^items.isModel}}
{{^required}}
// ensure the optional json data is an array if present
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
require(jsonObj["{{{baseName}}}"].isJsonArray()) {
String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
require(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonArray()) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be an array in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
}
{{/required}}
{{#required}}
// ensure the required json array is present
requireNotNull(jsonObj["{{{baseName}}}"]) {
"Expected the field `{{{baseName}}}` to be an array in the JSON string but got `null`"
requireNotNull(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"]) {
"Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be an array in the JSON string but got `null`"
}
require(jsonObj["{{{baseName}}}"].isJsonArray()) {
String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
require(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonArray()) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be an array in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
{{/required}}
{{/items.isModel}}
@ -296,42 +296,42 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{^isContainer}}
{{#isString}}
{{#notRequiredOrIsNullable}}
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
require(jsonObj.get("{{{baseName}}}").isJsonPrimitive) {
String.format("Expected the field `{{{baseName}}}` to be a primitive type in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
require(jsonObj.get("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}").isJsonPrimitive) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be a primitive type in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
}
{{/notRequiredOrIsNullable}}
{{^notRequiredOrIsNullable}}
require(jsonObj["{{{baseName}}}"].isJsonPrimitive) {
String.format("Expected the field `{{{baseName}}}` to be a primitive type in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
require(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonPrimitive) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be a primitive type in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
{{/notRequiredOrIsNullable}}
{{/isString}}
{{#isModel}}
{{#required}}
// validate the required field `{{{baseName}}}`
{{{dataType}}}.validateJsonElement(jsonObj["{{{baseName}}}"])
{{{dataType}}}.validateJsonElement(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"])
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
{{{dataType}}}.validateJsonElement(jsonObj["{{{baseName}}}"])
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
{{{dataType}}}.validateJsonElement(jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"])
}
{{/required}}
{{/isModel}}
{{#isEnum}}
{{#required}}
// validate the required field `{{{baseName}}}`
require({{{datatypeWithEnum}}}.values().any { it.value == jsonObj["{{{baseName}}}"].asString }) {
String.format("Expected the field `{{{baseName}}}` to be valid `{{{datatypeWithEnum}}}` enum value in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
require({{{datatypeWithEnum}}}.values().any { it.value == jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].asString }) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be valid `{{{datatypeWithEnum}}}` enum value in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
require({{{datatypeWithEnum}}}.values().any { it.value == jsonObj["{{{baseName}}}"].asString }) {
String.format("Expected the field `{{{baseName}}}` to be valid `{{{datatypeWithEnum}}}` enum value in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
require({{{datatypeWithEnum}}}.values().any { it.value == jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].asString }) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be valid `{{{datatypeWithEnum}}}` enum value in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
}
{{/required}}
@ -339,15 +339,15 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{#isEnumRef}}
{{#required}}
// validate the required field `{{{baseName}}}`
require({{{dataType}}}.values().any { it.value == jsonObj["{{{baseName}}}"].asString }) {
String.format("Expected the field `{{{baseName}}}` to be valid `{{{dataType}}}` enum value in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
require({{{dataType}}}.values().any { it.value == jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].asString }) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be valid `{{{dataType}}}` enum value in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
require({{{dataType}}}.values().any { it.value == jsonObj["{{{baseName}}}"].asString }) {
String.format("Expected the field `{{{baseName}}}` to be valid `{{{dataType}}}` enum value in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
if (jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"] != null && !jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].isJsonNull) {
require({{{dataType}}}.values().any { it.value == jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].asString }) {
String.format("Expected the field `{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}` to be valid `{{{dataType}}}` enum value in the JSON string but got `%s`", jsonObj["{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}"].toString())
}
}
{{/required}}

View File

@ -43,7 +43,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
{{#operation}}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}} * @param {{{paramName}}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}

View File

@ -123,7 +123,7 @@ import {{packageName}}.infrastructure.toMultiValue
{{/isEnum}}
{{/allParams}}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}
@ -161,7 +161,7 @@ import {{packageName}}.infrastructure.toMultiValue
}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}

View File

@ -131,7 +131,7 @@ import okhttp3.MultipartBody
{{/isEnum}}
{{/allParams}}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
* Responses:{{#responses}}

View File

@ -88,7 +88,7 @@ import {{packageName}}.infrastructure.*
{{/isEnum}}
{{/allParams}}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}
@ -123,7 +123,7 @@ import {{packageName}}.infrastructure.*
}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}

View File

@ -37,7 +37,7 @@ import {{packageName}}.infrastructure.CollectionFormats.*
{{#operation}}
/**
* {{{httpMethod}}} {{{path}}}
* {{{httpMethod}}} {{#sanitizePathComment}}{{{path}}}{{/sanitizePathComment}}
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}

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