Compare commits

..

115 Commits

Author SHA1 Message Date
William Cheng
5c7b8b64b7 update samples 2025-10-29 18:22:37 +08:00
William Cheng
044bd9c63e Merge branch 'bugfix/fix-formparams-defaultvalue' of https://github.com/JoseLora/openapi-generator into JoseLora-bugfix/fix-formparams-defaultvalue 2025-10-29 18:19:47 +08:00
William Cheng
3d4f29eac7 [PYTHON-FASTAPI] update starlette to newer version 0.49.1 (#22243)
* update starlette to newer version 0.49.1

* update fastapi to newer version
2025-10-29 15:18:27 +08:00
William Cheng
351b601368 openapi-normalizer: Add REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT normalize option (#22236)
* fix bug 21680: Introduce REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT normalize option

* Advise to use REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT

* update doc

---------

Co-authored-by: Guillaume ALAMOME <guillaume.alamome@gmail.com>
2025-10-28 13:54:49 +08:00
Jason Frey
2c248e6c93 [ruby] Introduce ApiModelBase (#22052)
The Ruby code that is generated copies numerous methods into every
model. This creates bloat both in file size and run-time memory usage.
This commit introduces a base class for all models to store common
methods. This commit's focus is only on static methods that do not
change between models.
2025-10-28 12:42:51 +08:00
Eddie Sholl
68b0dfe6d1 Expose mtls certificate config params in python and php configuration templates (#22229)
* Expose mtls config params in python template

* Expose certFile and keyFile configuration items to support mtls in php generated client

* Regenerate of examples
2025-10-28 12:33:05 +08:00
Leon Linhart
31e462dc3e Make Gradle properties non-nullable (#22050)
They were never really intended to support null values, so this is kind of a bug. However, this is technically also breaking for users that set these properties to `null` explicitly (instead of leaving them unset).
2025-10-27 15:18:08 +08:00
Elliott Kember
74488fa3c3 Update modelOneOf.mustache (#22220)
Adds booleans to modelOneOf
2025-10-27 15:15:57 +08:00
William Cheng
8c54f18f7c remove BACKTICK_PLAN.md 2025-10-27 14:56:13 +08:00
Anshul Singhvi
57d12811ef [Julia] Fix docstring parameter formatting with backticks (#22190)
* [Julia] Fix docstring parameter formatting with backticks

Wrap parameter names in backticks in generated Julia client docstrings
to prevent markdown from misinterpreting underscores as italic formatting.

This fixes an issue where parameter names like `pet_id`, `api_key`, and
`additional_metadata` would render incorrectly in documentation, with
underscores being treated as markdown italic markers instead of literal
characters.

Related issue: JuliaComputing/OpenAPI.jl#72

* Also wrap data types and return types in backticks

* Regenerate Julia client samples with backticked docstrings

* [Julia] Add backticks to all markdown documentation templates

Extend backtick formatting to markdown documentation templates for
both Julia client and server generators. This ensures consistent
markdown rendering of identifiers with underscores.

Changes:
- julia-client/api_doc.mustache: Add backticks to function signatures,
  parameter names, types, and return types in markdown API docs
- julia-server/api_doc.mustache: Same changes for server API docs
- julia-client/model_doc.mustache: Add backticks to property names and
  types in markdown model documentation
- julia-server/model_doc.mustache: Same changes for server model docs

All generated markdown files now properly display identifiers like
`pet_id`, `Custom_Type`, `update_pet_with_form` with literal
underscores instead of broken italic formatting.

Related to JuliaComputing/OpenAPI.jl#72
2025-10-27 14:55:35 +08:00
lbilger
676efae183 [Java] Add import for java.util.Arrays if there is a set property in a model. Arrays.asList is used when initializing the property if it has a default value. (#22207) 2025-10-27 14:55:10 +08:00
Rens Groothuijsen
a4d05b38f5 [go] Correctly set default array value on query parameters (#22060) 2025-10-27 10:30:08 +08:00
Mattias Sehlstedt
75ae04ecfd Fix so that the x-field-extra-annotation properly split any array items (#22226)
* Fix so that the x-field-extra-annotation properly split any array items

* Add a unit test to show that the annotations are generated as expected
2025-10-27 09:56:38 +08:00
rignicat
808d106e0c [jaxrs] Support jackson option (true by default) (#22169)
* allow configuring jackson, remove jackson import if disabled

* do not generate root resource or application file if generating interface

* change template files to remove jackson if disabled

* updated samples and docs as required by PR checklist
2025-10-27 09:56:07 +08:00
William Cheng
9d810e0fbb update jackson databind nullable to v0.2.8 (#22230) 2025-10-27 00:35:51 +08:00
Kevin Liddle
91a499b8c6 [rust-axum] Fix polymorphic type discriminators (#22222)
* [rust-axum] Make discriminator field name camelCase

* [rust-axum] Give polymorphic enum values a serde alias using the mapping keys if available

* update samples

* update test file checksum
2025-10-25 22:43:56 +08:00
dependabot[bot]
eda2e67b94 Bump actions/download-artifact from 5 to 6 (#22225)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-25 17:31:18 +08:00
Rens Groothuijsen
8643bc1d66 [python-fastapi] Remove additional slashes in query regex (#22223) 2025-10-25 17:16:17 +08:00
dependabot[bot]
2b22d172da Bump actions/upload-artifact from 4 to 5 (#22224)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-25 17:14:59 +08:00
William Cheng
d605afeef5 update vertx-web to 4.x 2025-10-23 10:32:20 +08:00
William Cheng
6eff628139 update logback to newer versions (#22204) 2025-10-22 18:51:38 +08:00
William Cheng
1d071288f8 use path from spec in ts angular documentation (#22194) 2025-10-21 15:40:48 +08:00
dependabot[bot]
816befc466 Bump vite and @angular-devkit/build-angular (#22192)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) to 6.4.1 and updates ancestor dependency [@angular-devkit/build-angular](https://github.com/angular/angular-cli). These dependencies need to be updated together.


Updates `vite` from 6.3.6 to 6.4.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@6.4.1/packages/vite)

Updates `@angular-devkit/build-angular` from 19.2.17 to 19.2.17
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/19.2.17...19.2.17)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.4.1
  dependency-type: indirect
- dependency-name: "@angular-devkit/build-angular"
  dependency-version: 19.2.17
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-21 15:08:27 +08:00
William Cheng
3d00fd2adc update C# samples 2025-10-21 11:40:43 +08:00
Fabian Buchenberger
00d16496c8 [csharp] do not use deprecated HttpRequestMessage.Properties (#20737) 2025-10-21 10:58:47 +08:00
William Cheng
57752d190c add cache: gradle to java setup workflow (#22183) 2025-10-20 17:15:36 +08:00
William Cheng
6572d5d9a6 Use JDK11 for kotlin-server projects (#22182)
* use jdk11 for kotlin server projects

* test with jdk11 by default
2025-10-20 16:54:50 +08:00
William Cheng
c15ba67fc9 update kotlin-spring projects to use jdk11 (#22181) 2025-10-20 15:48:10 +08:00
William Cheng
63ddce0c1b default REFACTOR_ALLOF_WITH_PROPERTIES_ONLY to true (#22180) 2025-10-20 11:39:09 +08:00
Kevin Liddle
01139e6963 [rust-axum] don't include quotes in output string from Display trait for string types (#22161)
* [rust-axum] don't include quotes in output string from Display trait for string types

* [rust-axum] update samples
2025-10-20 10:35:18 +08:00
Sven Allers
e7dae1a81e Custom error messages for size, length, min & max validations in Spring & Spring-Kotlin (#22090)
* Custom error messages for size, length, min & max validations in Spring & Spring-Kotlin

* Run scripts
2025-10-19 21:25:03 +08:00
Ilia
4e7bba659b [dart] Fix compile error in inline enum properties with "default" values(#22120) (#22165) 2025-10-19 20:47:20 +08:00
jpfinne
88bba259e9 OpenApiNormalizer FILTER improvements. Multi filters + filter on path (#22128)
* Use Filter Parser and allow multiple filters

* OpenAPINormalizer fails for invalid FILTER syntax

* Fix typo

* Use constants for filter keys.
Improve exception handling and tests.

* Fix format missing Locale.ROOT

* Make Filter extensible

* Additional unit test for invalid filter
2025-10-18 22:39:44 +08:00
William Cheng
8c85e3cedc [typescript-axios] Add support for AWSv4 Signature (#22174)
* [typescript-axios] Add support for AWSv4 Signature

* update typescript-axios.md file

* update doc

---------

Co-authored-by: qasim <qasim@calo.app>
2025-10-18 16:52:24 +08:00
Jérémy Reynard
d840c495c4 [FEAT] Support nullable Array<org.springframework.web.multipart.MultipartFile> in Kotlin-Spring generator (#21994)
* Support nullable `org.springframework.web.multipart.MultipartFile` in Kotlin Spring generator

- nullable is only supported for MultipartFile. However, Array<MultipartFile> could be also nullable

* Support nullable `org.springframework.web.multipart.MultipartFile` in Kotlin Spring generator

* Support nullable `org.springframework.web.multipart.MultipartFile` in Kotlin Spring generator

Update kotlin-spring-additionalproperties samples
2025-10-18 16:44:19 +08:00
Martin Tomašovič
7c000687e4 [csharp][generichost] Fix DateOnly parsing (#22099)
* Fix DateOnly parsing

* update samples
2025-10-18 14:58:36 +08:00
Mattias Sehlstedt
23a2aafe91 [CSHARP] Fix how the array type is set when using NULLABLE_REFERENCE_TYPES (#22071)
* Fix how the type is calculated for deep inline arrays

* Add list alias objects to petstore specification and regenerate samples
2025-10-18 14:58:08 +08:00
daberni
2afe7d29cd [Spring] Remove unnecessary modifiers from API interface templates (#22132)
* public static final String PATH_

* regenerate samples
2025-10-18 14:56:59 +08:00
William Cheng
6ede03d546 remove includeEndpointUrl (#22173) 2025-10-18 14:52:51 +08:00
Rostislav Svoboda
ee85775afd chore: Misc cleanup related to deprecations (#22172)
* Replace deprecated StringUtils.startsWith methods

* Add missing @Deprecated annotations
2025-10-18 14:52:19 +08:00
Robin Csutorás
94e8997cc7 [typescript-angular] Add includeEndpointUrl option to include endpoint URLs in generated service comments (#22152)
Adds a new boolean option 'includeEndpointUrl' that, when enabled, includes endpoint URL information as JSDoc comments in generated service methods and interfaces. This helps developers quickly identify the HTTP method and path for each API operation.

Co-authored-by: Robin Csutoras <robin.csutoras@Robins-Laptop.local>
2025-10-18 14:35:58 +08:00
jheyens
552ab4c6d5 Java-wiremock: Correctly handle multiple MIME-types in HTTP-Accept-headers (#22133)
* Java-wiremock: Allow matching multiple Accept-header values

* Wiremock: Ignore casing when matching requests' Content-Type headers

* Java-wiremock: Regenerate samples
2025-10-18 14:27:03 +08:00
daberni
2b00bab60a [Spring] Optimize and omit unnecessary imports on Api in ApiController templates (#22164)
* Optimize imports

* remove unnecessary blank line

* revert unintended indentation
2025-10-18 14:19:35 +08:00
Zach Hornback
ccd43a5ce4 [python-fastapi] Fix: Skip sorting of path operations (#22163) (#22166)
* [python-fastapi] Fix: Skip sorting of path operations (#22163)

Make use of helpful code added in
243f501aef to skip sorting of path
parameters.  In FastAPI, order matters, see link for details:
https://fastapi.tiangolo.com/tutorial/path-params/?h=path#order-matters

Issue: https://github.com/OpenAPITools/openapi-generator/issues/22163

* Update samples after previous commit

Reading comprehension is hard.  I missed the part of step 3 where
samples would be updated in response to the change I had previous
submitted.

Via this commit, update samples to match expectations.  The order of
various endpoint implementations is now changed in the sample, matchcing
the order in the yaml files that created them.
2025-10-18 14:18:15 +08:00
Rens Groothuijsen
592c262277 Set default value for isOauth field (#22162) 2025-10-17 15:49:26 +08:00
Bradford Hovinen
40b9d69d5a Support deprecated API endpoints in reqwest-based Rust clients (#22131)
Previously, if an API endpoint was marked deprecated, this fact was not
reflected in the generated Rust clients using the reqwest library. We
want to know exactly when our client code is using a deprecated endpoint,
so marking the corresponding functions with the `#[deprecatd]` attribute
would be very helpful. Uses of the endpoint would then be picked up by
linters so that we can react.

This adds a line to the template which marks functions generated from
deprecated endpoints with the `#[deprecated]` attribute.

This does not touch any of the other client generators for Rust or any
other language, since they are out of scope for our needs.

Co-authored-by: Bradford Hovinen <bho@qwello.eu>
2025-10-16 19:41:28 +08:00
CG
323f978674 fix(kotlin-spring): the generated RequestHeader defaultValue for String parameters contains duplicated double quotes (#22123) 2025-10-16 18:34:33 +08:00
William Cheng
4fe1c4ac73 feat(typescript-fetch): add docs support (#22110)
* feat(typescript-fetch): add docs support

fixes #18276

* chore: regenerate

- generate-samples.sh
- export_docs_generators.sh

* chore: address PR feedback

* update samples

* update samples

* clean up unused files

---------

Co-authored-by: Aaron Heckmann <aaron@plane.so>
2025-10-16 18:21:41 +08:00
monksy
ecaf3ea48a Removed a duplicate binding for an address for rust-server (#22116)
* Removed a duplicate binding for an address for rust-server. The address binding happens higher up in the method.

* Updated samples.
2025-10-16 17:04:41 +08:00
jheyens
ce1e9e0866 Jersey2/3: Fixes a bug in OAuth token renewal, where the previous HTTP 401 code is reused even after the retry succeeds (#22134)
* Jersey2/3: Fix a bug where, when using OAuth, the HTTP 401 status code persisted even if the second request after renewing the Bearer access token succeeded

* Jersey2/3: Regenerate samples
2025-10-16 16:32:05 +08:00
Adnan
fc12a1b63a feat(rust-axum): make the Object value public (#22144)
* feat(rust-axum): make the Object value public

* feat(rust-axum): regenerate samples
2025-10-16 15:01:19 +08:00
William Cheng
bce0ea65fe CircleCI: clean up unused tests/setup (#22158)
* clean up circleci tests

* ignore .angular

* trigger build failure

* Revert "trigger build failure"

This reverts commit ee228266b1.
2025-10-16 14:50:41 +08:00
Linh Tran Tuan
117042aa44 [Rust-Axum] Fix wrong validation for non-model Body (#22155)
* Fix Issue 21143

* Update
2025-10-16 14:25:01 +08:00
William Cheng
c680f39ad7 Fix TypeScript Angular v20 tests with correct versions (#22156)
* fix ts angular v20 tetss with correct versions

* restore old version

* fix pom.xml
2025-10-16 14:14:11 +08:00
William Cheng
211f51702d Update package.json manually in angular v19 tests (#22151)
* update package.json manually in angular v19 tests

* fix angular v19 tests

* remove declarations
2025-10-15 21:25:01 +08:00
sermler
a4a24a8168 [typescript-fetch] Rework fix infinite recursion with self-referencing discriminator mappings (#22149)
* Prevent ConcurrentModificationException

* Update typescript-fetch samples

* Add fixture sample

* Update samples
2025-10-15 19:25:45 +08:00
William Cheng
cbb27163a0 Add samples to test jaxrs spec (withXml option enabled) (#22148)
* add samples to test jaxrs spec with xml option enabled

* add new files
2025-10-15 18:11:19 +08:00
William Cheng
fdbabee87e Add tests for typescript angular v17, v18, v20 (#22145)
* add tests for angular v17, v18, v20

* trigger build failure

* Revert "trigger build failure"

This reverts commit bab6448ed1.

* update samples
2025-10-15 18:08:52 +08:00
William Cheng
cdd120d976 update samples 2025-10-15 17:53:01 +08:00
maushomu
9d110fcb6b [Java][jaxrs-spec] withXml support (#22140)
* withXml support in pojo.mustache

* Create xmlPojoAnnotation.mustache

* withXml support in enumClass.mustache
2025-10-15 17:43:15 +08:00
Robert Marsal
57324efd48 fix: typescript docs not being put in a docs directory (#22124)
* fix: typescript docs not being put in a docs directory

* fix: platform agnostic path separator
2025-10-15 17:13:51 +08:00
William Cheng
21d29dacc2 Add tests for TypeScript Angular v19 (#22139)
* add tests for ts angular v19

* fix transfer cache
2025-10-15 16:36:03 +08:00
dependabot[bot]
c27f9c3ebc Bump actions/setup-java from 4 to 5 (#22137)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 16:30:14 +08:00
William Cheng
486e0c5e61 Test TypeScript Angular v16 in Github workflow (#22138)
* test ts angular v16 in github workflow

* trigger build failure

* Revert "trigger build failure"

This reverts commit c7987599a9.
2025-10-15 14:51:40 +08:00
sermler
4bedcb754b [typescript-fetch] Fix infinite recursion with self-referencing discriminator mappings (#21956)
* Add selfReferencingDiscriminatorMapping to ExtendedCodegenModel

* Add selfReferencingDiscriminatorMapping to template
2025-10-14 13:39:58 +02:00
William Cheng
89b0bc48fa Add workflow to test TypeScript clients (#22126)
* add workflow to test ts clients

* update

* update

* run petstore

* update

* trigger build
2025-10-14 16:33:29 +08:00
Ivan Leb
0b9172ef5c add cache to efficiently lookup CodegenModel in csharp codegen (#22094)
Co-authored-by: ivan_leb <ivan_leb@mail.ru>
2025-10-14 15:13:26 +08:00
Raymond Carino
b199901aab [fix] Apply REMOVE_X_INTERNAL normalizer to nested inline properties (#22097)
* fix: Apply REMOVE_X_INTERNAL normalizer to nested inline properties

When REMOVE_X_INTERNAL=true is set, the normalizer removes the x-internal
extension from top-level schemas in components/schemas but fails to remove
it from inline object properties within those schemas.

This causes issues when:
1. A schema is imported cross-file (e.g., admin.yaml imports from chat.yaml)
2. That schema has an inline object property with x-internal: true
3. The inline property has type: object with nested properties

Result: TypeScript generator creates a type reference but no interface
definition, causing compilation errors.

This fix applies the same x-internal removal logic to normalizeProperties()
that already exists in normalizeComponentsSchemas(), ensuring inline
properties are handled consistently.

Fixes behavior for inline schemas with x-internal in cross-file imports.

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

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* test: Add test case for REMOVE_X_INTERNAL with inline properties

Adds test to verify that REMOVE_X_INTERNAL normalizer correctly removes
x-internal extension from inline object properties, not just top-level schemas.

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert "Apply suggestion from @Copilot"

This reverts commit c899e9ec96.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-14 14:44:59 +08:00
William Cheng
941a5ccf13 Add workflow to test TypeScript server (#22125)
* add workflow to test TS servers

* fix path

* trigger build failure

* Revert "trigger build failure"

This reverts commit a0bf0199d3.

* remove ts server tests in circleci
2025-10-14 13:50:59 +08:00
Simon Podlipsky
5f13c53825 fix(php,php-nextgen): remove useless string cast from ObjectSerializer.mustache (#22121) 2025-10-14 13:14:02 +08:00
Beppe Catanese
1240d103ff [Typescript]: add deprecated tags for attributes (#22108)
* Add deprecated annotation when attribute is deprecated

* Generate samples
2025-10-13 08:44:35 +02:00
Mattias Sehlstedt
42af4f9529 Move all vendor extension definitions within AbstractCSharpCodegen to CodegenConstants. Then adjust other usages of those same vendor extension definitions to the created constants. (#22112) 2025-10-12 23:21:17 +08:00
Sarvesh Mungurwadi
81a3488556 fixed Bean Validation pattern (#19748) 2025-10-12 09:27:15 +08:00
William Cheng
08da0abfca remove unused files in java samples (#22105) 2025-10-11 00:51:11 +08:00
Artem Shubovych
fb277f82d5 [java] [spring] Fix annotationLibrary option being ignored in spring generator (#22046)
* Fix annotationLibrary option being ignored in spring generator

* Generate sample code

* Sample generator weirdness

* Revert "Sample generator weirdness"
2025-10-11 00:15:04 +08:00
Amaury Graillat
6b1b5cc4c5 Update c curl generator to support float (#21103)
* [C-Curl] Client generator does not handle float properly (#21092)

- Change function signature to float*
- Change generator to convert float to string
- Similar change for double and long

* [C-Curl] Client generator does not handle float properly (#21092)

- Generate samples
- Fix generator for headers and path params

* Revert "[C-Curl] Client generator does not handle float properly (#21092)"

This reverts commit ba044a65d5.

* Revert "[C-Curl] Client generator does not handle float properly (#21092)"

This reverts commit f99c5b0382.

* [C-Curl] Client generator does not handle float properly (#21092)

- Convert float, double and long to string
- Generate samples

* [C-Curl] Client generator does not handle float properly (#21092)

- Add missing yaml example file

* [C-Curl] Client generator does not handle float properly (#21092)

- Transfer float and double in scientific notation with resp. 7 and 16 decimals
- Adapt string size to number of required characters

* [C-Curl] Client generator does not handle float properly (#21092)

- Fix unused variable.
- Fix snprintf string

* * [C-Curl] Client generator does not handle float properly (#21092)

- Generating samples

* * [C-Curl] Client generator does not handle float properly (#21092)

- Always allocate the exact string size
2025-10-08 14:23:45 +08:00
dependabot[bot]
fd84c8fbd6 Bump s4u/setup-maven-action from 1.18.0 to 1.19.0 (#22085)
Bumps [s4u/setup-maven-action](https://github.com/s4u/setup-maven-action) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/s4u/setup-maven-action/releases)
- [Commits](https://github.com/s4u/setup-maven-action/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: s4u/setup-maven-action
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 10:46:42 +08:00
dependabot[bot]
f092f72cc5 Bump actions/setup-node from 4 to 5 (#22086)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 10:46:23 +08:00
Antoine Reilles
37cac71f87 [java-cxf-cdi] @Api description is deprecated (#22083)
@Api(description=...) is deprecated.
Remove its usage: it is not used by swagger-ui, and generated warnings
at build
2025-10-07 02:10:20 +08:00
José María Lora
3cf4994ba2 Merge branch 'master' into bugfix/fix-formparams-defaultvalue 2025-10-06 19:40:07 +02:00
Timo Schwarz
b8d805980a Spring 7 WebClient Compatibility (#22030)
* Update Spring Boot dependency for WebClient

* Adapt WebClient ApiClient to change in HttpHeaders with Spring 7

---------

Co-authored-by: Timo Schwarz <timo.schwarz@bredex.de>
2025-10-06 21:07:57 +08:00
William Cheng
b49ec6e033 [fix][elixir] missing type mapping for AnyType (#22081)
* fix: unmapped anytype

* add tests for any type in elixir client

---------

Co-authored-by: Enrique Fernandez <enrique@bluelabs.eu>
2025-10-06 15:10:10 +08:00
Mattias Sehlstedt
4352a2fcd0 [Test] [Java] Add test example of how to handle x-parent without REF_AS_PARENT_IN_ALLOF normalization (#22058)
* Add test to illustrate example of how to handle x-parent without REF_AS_PARENT_IN_ALLOF normalization

* Minor change to retrigger build
2025-10-06 13:07:50 +08:00
William Cheng
6f3dacafc4 update ts samples 2025-10-06 01:45:35 +08:00
Sebastien Dionne
2d2e1c41c4 Fix typos and linguistic errors in documentation (#22078) 2025-10-06 01:32:00 +08:00
William Cheng
a955bead08 Migrate JS tests to Github workflows (#22077)
* update samples

* fix name

* update

* remove

* clean up test
2025-10-06 01:11:49 +08:00
jpfinne
d7b79a26c6 [Spring] add support for api versioning. Fix #22027 (#22028)
* Add spring api versioning support

* Do not add version if not requested

* Fix duplicate VendorExtensions

* Improve description

* Fix removal of RequestMapping version attribute if x-spring-api-version: '' is set at the operation level
2025-10-03 19:59:38 +08:00
William Cheng
1d7d399ec2 fix additional properties handling in 3.1 spec (#22056) 2025-10-03 11:06:39 +08:00
William Cheng
4121803442 update php samples 2025-10-03 10:02:59 +08:00
benkarrer-lab
602549cb36 php: render tag description in Api docs (api_doc.mustache) via operationTagDescription (#14395) (#22064)
Co-authored-by: benkarrer-lab <benkarrer-lab@users.noreply.github.com>
2025-10-03 09:57:32 +08:00
dependabot[bot]
1c082c7287 Bump gradle/actions from 4 to 5 (#22061)
Bumps [gradle/actions](https://github.com/gradle/actions) from 4 to 5.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/v4...v5)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 15:27:53 +08:00
Jean-Marc Le Roux
7ab9364094 [Rust] Configurable default features from reqwest dependency (#22041)
* fix(rust): Remove default features from reqwest dependency

This change removes the default features (specifically native-tls) from the reqwest
dependency in the Rust client generator. This allows users to explicitly choose
their TLS backend without automatically including openssl-sys as a transitive dependency.

Users can now explicitly enable TLS backends using feature flags:
- native-tls
- rustls-tls
- default-tls

Fixes #21933

* feat(rust): Add reqwestDefaultFeatures option with backward-compatible default

This change adds a new generator option `reqwestDefaultFeatures` that allows
users to configure the default Cargo features for the reqwest dependency.

The option accepts:
- An array of strings in YAML config: reqwestDefaultFeatures: ["native-tls"]
- A comma-separated string via CLI: --additional-properties=reqwestDefaultFeatures=native-tls
- An empty value for no defaults: reqwestDefaultFeatures: []

Default value: ["native-tls"] (maintains backward compatibility)

This addresses the feedback in #21933 to make the change opt-in rather than
breaking existing users.

Users can now:
- Keep the current behavior (default)
- Opt-out: reqwestDefaultFeatures: []
- Use alternative TLS: reqwestDefaultFeatures: ["rustls-tls"]
- Combine features: reqwestDefaultFeatures: ["native-tls", "cookies"]

Fixes #21933
2025-10-02 01:47:08 +08:00
Ilia
28e7e7f2eb [kotlin] Add AnyOf/oneOf to multiplatform (#22035) 2025-10-02 01:44:54 +08:00
Mattias Sehlstedt
e8a688a724 Define codegen vendor extensions in CodegenConstants (#22054)
* Add an enum to centralize common internal vendor extensions used for Codegen processing

* Extend the normalizer tests to illustrate that an AllOfs with several refs have all of them marked as parents

* Add x-internal to the Codegen vendor extensions

* Move the Codegen vendor extensions into CodegenConstants

* Add assertion to JavaClient CodegenTest
2025-10-02 01:44:11 +08:00
Beppe Catanese
ddb15d4b9d Delete docs/generators/postman.md (#22044) 2025-09-29 19:01:36 +08:00
William Cheng
885ea07b17 Prepare 7.17.0 (#22040)
* Revert "v7.16.0 release"

This reverts commit 31299af0fc.

* prepare 7.17.0-SNAPSHOT

* update doc, samples
2025-09-28 17:25:13 +08:00
William Cheng
c0b72ee970 update readme with 7.16.0 2025-09-28 16:23:38 +08:00
William Cheng
ee76a05def v7.16.0 release (#22039) 2025-09-28 16:01:01 +08:00
William Cheng
30096d63b7 Revert "fix(rust): Add anyOf support to Rust client generator (#21896)" (#22038)
This reverts commit ee40887d47.
2025-09-28 12:23:50 +08:00
Yonatan Karp-Rudin
44a3be170f fix(kotlin-spring): add missing constructor parentheses for hashmap models (#22029)
* fix(kotlin-spring): add missing constructor parentheses for hashmap models

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

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

The existing samples have been regenerated to reflect this change.

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

* Update

* Fix

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

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

* update docs

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

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

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

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

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

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

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

---------

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

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

* revert
2025-09-24 17:15:08 +08:00
José María Lora
df2a8d6d46 Merge branch 'master' into bugfix/fix-formparams-defaultvalue 2025-05-16 12:28:47 +02:00
José María Lora
ade1e5838e Merge branch 'master' into bugfix/fix-formparams-defaultvalue 2025-04-10 17:39:55 +02:00
José María Lora
8ecdb15528 Merge branch 'master' into bugfix/fix-formparams-defaultvalue 2025-01-29 14:04:42 +01:00
José María Lora
ce89695bb6 chore: remove unwanted formatting changes 2024-12-13 12:22:00 +01:00
José María Lora
a424b5af8e fix: add support for default values in formParams template 2024-12-13 12:12:16 +01:00
9920 changed files with 206289 additions and 35008 deletions

View File

@@ -1,6 +1,6 @@
<!--
Please follow the issue template below for bug reports and feature requests.
Also please indicate in the issue title which language/library is concerned. Eg: [JAVA] Bug generating foo with bar
Also please indicate in the issue title which language/library is concerned. E.g.: [JAVA] Bug generating foo with bar
-->
##### Description

View File

@@ -18,7 +18,7 @@ assignees: ''
<!--
Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. Eg: [BUG][JAVA] Bug generating foo with bar
Also please indicate in the issue title which language/library is concerned. E.g.: [BUG][JAVA] Bug generating foo with bar
-->
##### Description

View File

@@ -19,6 +19,7 @@ jobs:
with:
java-version: 11
distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -37,6 +37,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 11
cache: gradle
# Cache Gradle Dependencies
- name: Setup Gradle Dependencies Cache
uses: actions/cache@v4

View File

@@ -27,6 +27,7 @@ jobs:
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
cache: gradle
- uses: actions/cache@v4
with:
@@ -44,12 +45,12 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- uses: gradle/actions/setup-gradle@v4
- uses: gradle/actions/setup-gradle@v5
with:
gradle-version: '8.14.3'
- name: Setup Maven
uses: s4u/setup-maven-action@v1.18.0
uses: s4u/setup-maven-action@v1.19.0
with:
java-version: ${{ matrix.java }}
maven-version: 3.8.8
@@ -61,7 +62,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Upload Maven build artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
if: matrix.java == '11' && matrix.os == 'ubuntu-latest'
with:
name: artifact
@@ -91,12 +92,13 @@ jobs:
- name: Check out code
uses: actions/checkout@v5
- name: Setup Maven
uses: s4u/setup-maven-action@v1.18.0
uses: s4u/setup-maven-action@v1.19.0
with:
java-version: 11
maven-version: 3.8.8
cache: gradle
- name: Download build artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: artifact
- name: Run Ensures Script

View File

@@ -21,6 +21,7 @@ jobs:
with:
java-version: 11
distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:
@@ -41,7 +42,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- run: ls -la modules/openapi-generator-cli/target
- name: Upload openapi-generator-cli.jar artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target/openapi-generator-cli.jar
@@ -59,6 +60,7 @@ jobs:
with:
java-version: 11
distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:
@@ -79,7 +81,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Publish unit test reports
if: ${{ always() }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: surefire-test-results
path: '**/surefire-reports/TEST-*.xml'
@@ -97,7 +99,7 @@ jobs:
java-version: 11
distribution: 'temurin'
- name: Download openapi-generator-cli.jar artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target
@@ -136,7 +138,7 @@ jobs:
java-version: 11
distribution: 'temurin'
- name: Download openapi-generator-cli.jar artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target

View File

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

View File

@@ -26,6 +26,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 8
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -5,6 +5,7 @@ on:
paths:
- 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -27,6 +28,7 @@ on:
paths:
- 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -54,6 +56,7 @@ jobs:
matrix:
sample:
# clients
- samples/client/petstore/jaxrs-cxf-client-swagger2
- samples/client/petstore/jaxrs-cxf-client
- samples/client/petstore/java/native
- samples/client/petstore/java/native-async
@@ -115,6 +118,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 11
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -42,6 +42,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 17
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -0,0 +1,51 @@
name: Samples JS clients
on:
push:
paths:
#- samples/client/petstore/javascript-flowtyped/**
- samples/client/petstore/javascript-es6/**
- samples/client/petstore/javascript-promise-es6/**
pull_request:
paths:
#- samples/client/petstore/javascript-flowtyped/**
- samples/client/petstore/javascript-es6/**
- samples/client/petstore/javascript-promise-es6/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node:
- "18.x"
- "20.x"
sample:
# clients
- samples/client/petstore/javascript-es6/
- samples/client/petstore/javascript-promise-es6/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v5
- name: Add hosts to /etc/hosts
run: |
sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts
- name: Use Node.js 20.x
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: npm install
working-directory: ${{ matrix.sample }}
run: npm install
- name: npm test
working-directory: ${{ matrix.sample }}
run: npm test

View File

@@ -20,10 +20,7 @@ jobs:
- samples/server/petstore/jaxrs/jersey2-useTags
- samples/server/petstore/jaxrs-jersey
- samples/server/petstore/jaxrs-spec
- samples/server/petstore/jaxrs-spec-interface
- samples/server/petstore/jaxrs-spec-interface-response
- samples/server/petstore/jaxrs-jersey
- samples/server/petstore/jaxrs-spec
- samples/server/petstore/jaxrs-spec-withxml
- samples/server/petstore/jaxrs-spec-interface
- samples/server/petstore/jaxrs-spec-interface-response
- samples/server/petstore/jaxrs-datelib-j8

View File

@@ -77,6 +77,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 11
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -26,6 +26,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 17
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -34,6 +34,7 @@ jobs:
# server
- samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-additionalproperties
- samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request-cookie
- samples/server/petstore/kotlin-server/jaxrs-spec
@@ -51,6 +52,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 17
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:
@@ -67,4 +69,4 @@ jobs:
arguments: wrapper
- name: Build
working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test
run: ./gradlew build -x test

View File

@@ -32,6 +32,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 21
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:

View File

@@ -59,7 +59,8 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 8
java-version: 11
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:
@@ -76,4 +77,4 @@ jobs:
arguments: wrapper
- name: Build
working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test
run: ./gradlew build -x test

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,142 @@
name: Samples TS clients
on:
push:
paths:
- samples/client/others/typescript-angular/**
# comment out angular released before Nov 2023
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
#- samples/client/petstore/typescript-angular-v14-provided-in-root/**
#- samples/client/petstore/typescript-angular-v15-provided-in-root/**
- samples/client/petstore/typescript-angular-v16-provided-in-root/**
- samples/client/petstore/typescript-angular-v17-provided-in-root/**
- samples/client/petstore/typescript-angular-v18-provided-in-root/**
- samples/client/petstore/typescript-angular-v19-provided-in-root/**
- samples/client/petstore/typescript-angular-v20-provided-in-root/**
- samples/openapi3/client/petstore/typescript/builds/default/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/default/**
- samples/openapi3/client/petstore/typescript/builds/jquery/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/jquery/**
- samples/openapi3/client/petstore/typescript/builds/object_params/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/object_params/**
#- samples/openapi3/client/petstore/typescript/builds/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/deno/**
- samples/openapi3/client/petstore/typescript/builds/browser/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/browser/**
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/**
- samples/client/petstore/typescript-fetch/builds/default/**
- samples/client/petstore/typescript-fetch/builds/es6-target/**
- samples/client/petstore/typescript-fetch/builds/with-npm-version/**
- samples/client/petstore/typescript-fetch/tests/default/**
# comment out due to build failure
#- samples/client/petstore/typescript-node/npm/**
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/**
- samples/client/petstore/typescript-axios/builds/with-npm-version/**
# comment out due to build failure
#- samples/client/petstore/typescript-axios/tests/default/**
pull_request:
paths:
- samples/client/others/typescript-angular/**
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
#- samples/client/petstore/typescript-angular-v14-provided-in-root/**
#- samples/client/petstore/typescript-angular-v15-provided-in-root/**
- samples/client/petstore/typescript-angular-v16-provided-in-root/**
- samples/client/petstore/typescript-angular-v17-provided-in-root/**
- samples/client/petstore/typescript-angular-v18-provided-in-root/**
- samples/client/petstore/typescript-angular-v19-provided-in-root/**
- samples/client/petstore/typescript-angular-v20-provided-in-root/**
- samples/openapi3/client/petstore/typescript/builds/default/**
#- samples/openapi3/client/petstore/typescript/tests/default/**
- samples/openapi3/client/petstore/typescript/builds/jquery/**
#- samples/openapi3/client/petstore/typescript/tests/jquery/**
- samples/openapi3/client/petstore/typescript/builds/object_params/**
#- samples/openapi3/client/petstore/typescript/tests/object_params/**
#- samples/openapi3/client/petstore/typescript/builds/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/deno/**
- samples/openapi3/client/petstore/typescript/builds/browser/**
#- samples/openapi3/client/petstore/typescript/tests/browser/**
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/**
- samples/client/petstore/typescript-fetch/builds/default/**
- samples/client/petstore/typescript-fetch/builds/es6-target/**
- samples/client/petstore/typescript-fetch/builds/with-npm-version/**
- samples/client/petstore/typescript-fetch/tests/default/**
#- samples/client/petstore/typescript-node/npm/**
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/**
- samples/client/petstore/typescript-axios/builds/with-npm-version/**
#- samples/client/petstore/typescript-axios/tests/default/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
strategy:
fail-fast: false
matrix:
node:
#- "18.x"
- "20.x"
sample:
- samples/client/others/typescript-angular/
#- samples/client/petstore/typescript-angular-v12-provided-in-root/
#- samples/client/petstore/typescript-angular-v13-provided-in-root/
#- samples/client/petstore/typescript-angular-v14-provided-in-root/
#- samples/client/petstore/typescript-angular-v15-provided-in-root/
- samples/client/petstore/typescript-angular-v16-provided-in-root/
- samples/client/petstore/typescript-angular-v17-provided-in-root/
- samples/client/petstore/typescript-angular-v18-provided-in-root/
- samples/client/petstore/typescript-angular-v19-provided-in-root/
- samples/client/petstore/typescript-angular-v20-provided-in-root/
- samples/openapi3/client/petstore/typescript/builds/default/
#- samples/openapi3/client/petstore/typescript/tests/default/
- samples/openapi3/client/petstore/typescript/builds/jquery/
#- samples/openapi3/client/petstore/typescript/tests/jquery/
- samples/openapi3/client/petstore/typescript/builds/object_params/
#- samples/openapi3/client/petstore/typescript/tests/object_params/
#- samples/openapi3/client/petstore/typescript/builds/inversify/
#- samples/openapi3/client/petstore/typescript/tests/inversify/
#- samples/openapi3/client/petstore/typescript/tests/deno/
- samples/openapi3/client/petstore/typescript/builds/browser/
#- samples/openapi3/client/petstore/typescript/tests/browser/
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/
- samples/client/petstore/typescript-fetch/builds/default/
- samples/client/petstore/typescript-fetch/builds/es6-target/
- samples/client/petstore/typescript-fetch/builds/with-npm-version/
- samples/client/petstore/typescript-fetch/tests/default/
#- samples/client/petstore/typescript-node/npm/
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/
- samples/client/petstore/typescript-axios/builds/with-npm-version/
#- samples/client/petstore/typescript-axios/tests/default/
steps:
- uses: actions/checkout@v5
- name: Add hosts to /etc/hosts
run: |
sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17' # Specify your desired Java version
distribution: 'temurin' # Or 'adopt', 'oracle', etc.
cache: maven # Cache Maven dependencies for faster builds
- name: Use Node.js
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: mvn integration-test
working-directory: ${{ matrix.sample }}
run: mvn integration-test

View File

@@ -0,0 +1,34 @@
name: Samples TS servers
on:
push:
paths:
- samples/server/petstore/typescript-nestjs-server/**
pull_request:
paths:
- samples/server/petstore/typescript-nestjs-server/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node:
- "18.x"
- "20.x"
sample:
- samples/server/petstore/typescript-nestjs-server/
steps:
- uses: actions/checkout@v5
- name: Use Node.js 20.x
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: npm install
working-directory: ${{ matrix.sample }}
run: npm install
- name: npm test
working-directory: ${{ matrix.sample }}
run: npm test

View File

@@ -24,6 +24,7 @@ jobs:
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies
uses: actions/cache@v4
env:
@@ -39,7 +40,7 @@ jobs:
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
- name: Setup Maven
uses: s4u/setup-maven-action@v1.18.0
uses: s4u/setup-maven-action@v1.19.0
with:
java-version: ${{ matrix.java }}
maven-version: 3.8.8

2
.gitignore vendored
View File

@@ -49,6 +49,8 @@ nb-configuration.xml
*.xml~
*.t~
**/.angular
/target
/generated-files
test-output/

View File

@@ -11,43 +11,15 @@ export NODE_ENV=test
if [ "$NODE_INDEX" = "1" ]; then
echo "Running node $NODE_INDEX ..."
java -version
sudo apt-get -y install cpanminus
# install rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
echo "Testing perl"
(cd samples/client/petstore/perl && /bin/bash ./test.bash)
echo "Testing ruby"
(cd samples/client/petstore/ruby && mvn integration-test)
(cd samples/client/petstore/ruby-faraday && mvn integration-test)
(cd samples/client/petstore/ruby-httpx && mvn integration-test)
(cd samples/client/petstore/ruby-autoload && mvn integration-test)
echo "Testing rust"
(cd samples/server/petstore/rust-axum && mvn integration-test)
elif [ "$NODE_INDEX" = "2" ]; then
echo "Running node $NODE_INDEX to test Go"
# install haskell
#curl -sSLk https://get.haskellstack.org/ | sh
#stack upgrade
#stack --version
# install curl
#sudo apt-get -y build-dep libcurl4-gnutls-dev
#sudo apt-get -y install libcurl4-gnutls-dev
# Install golang version 1.18
go version
sudo mkdir /usr/local/go1.18
wget -c https://dl.google.com/go/go1.18.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local/go1.18
export PATH="/usr/local/go1.18/go/bin:$PATH"
go version
echo "Running node $NODE_INDEX to test cpp-restsdk"
# install cpprestsdk
sudo apt-get install libcpprest-dev
@@ -62,58 +34,15 @@ elif [ "$NODE_INDEX" = "3" ]; then
echo "Running node $NODE_INDEX ... "
# Install node@stable (for angular 6)
set +e
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
#nvm install stable
# install v16 instead of the latest stable version
nvm install 18
nvm alias default 18
node --version
# Each step uses the same `$BASH_ENV`, so need to modify it
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
(cd samples/client/others/typescript-angular && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v12-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v13-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v14-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v15-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v16-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v17-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v18-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v19-provided-in-root && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/default && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/default && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/jquery && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/jquery && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/object_params && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/object_params && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/inversify && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/inversify && mvn integration-test)
#(cd samples/openapi3/client/petstore/typescript/tests/deno && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/browser && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/browser && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/nullable-enum && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/default && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/es6-target && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/tests/default && mvn integration-test)
(cd samples/client/petstore/typescript-node/npm && mvn integration-test)
(cd samples/client/petstore/typescript-rxjs/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-axios/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-axios/tests/default && mvn integration-test)
(cd samples/client/petstore/typescript-axios/tests/with-complex-headers && mvn integration-test)
(cd samples/client/petstore/javascript-flowtyped && mvn integration-test)
(cd samples/client/petstore/javascript-es6 && mvn integration-test)
(cd samples/client/petstore/javascript-promise-es6 && mvn integration-test)
(cd samples/server/petstore/typescript-nestjs-server && mvn integration-test)
echo "Testing ruby"
(cd samples/client/petstore/ruby && mvn integration-test)
(cd samples/client/petstore/ruby-faraday && mvn integration-test)
(cd samples/client/petstore/ruby-httpx && mvn integration-test)
(cd samples/client/petstore/ruby-autoload && mvn integration-test)
else
echo "Running node $NODE_INDEX ..."
java -version
./mvnw clean install
fi

View File

@@ -15,7 +15,7 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.16.0`):
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.17.0`):
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
@@ -148,8 +148,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.16.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.16.0-SNAPSHOT/) | 22.09.2025 | Minor release with breaking changes (with fallback) |
| [7.15.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.15.0) (latest stable release) | 22.08.2025 | Minor release with breaking changes (with fallback) |
| 7.17.0 (upcoming minor release) [SNAPSHOT](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) | 24.10.2025 | Minor release with breaking changes (with fallback) |
| [7.16.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.16.0) (latest stable release) | 28.09.2025 | Minor release with breaking changes (with fallback) |
| [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | Minor release with breaking changes (with fallback) |
| [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) |
@@ -212,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.15.0/openapi-generator-cli-7.15.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -456,7 +456,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 7.15.0
openapi-generator-cli version-manager set 7.16.0
```
Or install it as dev-dependency:
@@ -480,7 +480,7 @@ pip install openapi-generator-cli
To install a specific version
```
pip install openapi-generator-cli==7.15.0
pip install openapi-generator-cli==7.16.0
```
You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required)
@@ -506,7 +506,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
<!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar)
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar)
<!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`

View File

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

View File

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

View File

@@ -0,0 +1,10 @@
generatorName: jaxrs-spec
outputDir: samples/server/petstore/jaxrs-spec-withxml/
inputSpec: modules/openapi-generator/src/test/resources/3_0/jaxrs-spec/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/spec
additionalProperties:
artifactId: jaxrs-spec-withxml-petstore-server
serializableModel: "true"
hideGenerationTimestamp: "true"
generateBuilders: "true"
withXml: true

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 19.0.0
supportsES6: true
enumNameMappings:
delivered: SHIPPED

View File

@@ -0,0 +1,9 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 20.0.0
supportsES6: true
enumNameMappings:
delivered: SHIPPED

View File

@@ -0,0 +1,7 @@
generatorName: typescript-fetch
outputDir: samples/client/others/typescript-fetch/infinite-recursion-issue
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/infinite-recursion-issue.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
additionalProperties:
enumPropertyNaming: "original"
enumUnknownDefaultCase: true

View File

@@ -5,11 +5,11 @@ Running `./save_dart_keywords.sh` from this directory will generate `dart-keywor
## When should the keywords be generated?
`save_dart_keywords.sh` should be run when a new version of Dart is release to update the keywords file.
`save_dart_keywords.sh` should be run when a new version of Dart is released to update the keywords file.
The last Dart version that was used to generate the keywords can be found in `dart-version.txt`.
## What does the shellscript do?
## What does the shell script do?
1. run the dart app
- `dart run save-dart-keywords.dart`

View File

@@ -59,6 +59,6 @@
sha256: 45cdaba3d2adc212cd4f0184ad475419a95e2326254c2ef84175e210c922b2f3
# rust axum test files
- filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs"
sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600
sha256: b2093528aac971193f2863a70f46eea45cf8bda79120b133a614599e80d8b46d
- filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs"
sha256: e72fbf81a9849dc7abb7e2169f2fc355c8b1cf991c0e2ffc083126abd9e966e7
sha256: 1d3fb01f65e98290b1d3eece28014c7d3e3f2fdf18e7110249d3c591cc4642ab

View File

@@ -538,6 +538,7 @@ OpenAPI Normalizer transforms the input OpenAPI doc/spec (which may not perfectl
- SIMPLIFY_ONEOF_ANYOF
- SIMPLIFY_BOOLEAN_ENUM
- REFACTOR_ALLOF_WITH_PROPERTIES_ONLY
(One can use `DISABLE_ALL=true` to disable all the rules)
@@ -643,9 +644,16 @@ Example:
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer NORMALIZER_CLASS=org.openapitools.codegen.OpenAPINormalizerTest$RemoveRequiredNormalizer
```
- `REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT`: When set to true, remove the "properties" of a schema with type other than "object".
Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true
```
- `FILTER`
The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated.
The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated. Multiple filters can be separated by a semicolon.
### Available Filters
@@ -658,6 +666,9 @@ The `FILTER` parameter allows selective inclusion of API operations based on spe
- **`tag`**
When set to `tag:person|basic`, operations **not** tagged with `person` or `basic` will be marked as internal (`x-internal: true`), and will not be generated.
- **`path`**
When set to `path:/v1|/v2`, operations on paths **not** starting with `/v1` or with `/v2` will be marked as internal (`x-internal: true`), and will not be generated.
### Example Usage
```sh
@@ -665,7 +676,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
-g java \
-i modules/openapi-generator/src/test/resources/3_0/petstore.yaml \
-o /tmp/java-okhttp/ \
--openapi-normalizer FILTER="operationId:addPet|getPetById"
--openapi-normalizer FILTER="operationId:addPet|getPetById ; tag:store"
```
- `SET_CONTAINER_TO_NULLABLE`: When set to `array|set|map` (or just `array`) for example, it will set `nullable` in array, set and map to true.

View File

@@ -5,7 +5,7 @@ title: Debugging
## Generation
As a user there may be times when generated outputs don't match your expectations it's unclear why. The CLI supports a `--dry-run` option which may be used to inspect the anticipated file operations without making changes to the file system.
As a user there may be times when generated outputs don't match your expectations and it's unclear why. The CLI supports a `--dry-run` option which may be used to inspect the anticipated file operations without making changes to the file system.
Suppose you generate using the `--minimal-update` option, and you notice on subsequent generations of a client that no files have changed. This is by design.

View File

@@ -3,6 +3,7 @@ id: generators
title: Generators List
---
[main] INFO o.o.c.l.PythonFastAPIServerCodegen - Skipping sorting of path operations, order matters, let the developer decide via their specification file.
The following generators are available:
## CLIENT generators

View File

@@ -95,6 +95,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|springApiVersion|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
@@ -132,6 +133,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
## IMPORT MAPPING

View File

@@ -67,6 +67,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL|
|x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-kotlin-implements|Ability to specify interfaces that model must implement|MODEL|empty array
|x-kotlin-implements-fields|Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`|MODEL|empty array

View File

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

View File

@@ -25,7 +25,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|lazyImports|Enable lazy imports.| |false|
|library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3| |urllib3|
|library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx| |urllib3|
|mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]|
|packageName|python package name (convention: snake_case).| |openapi_client|
|packageUrl|python package URL.| |null|

View File

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

View File

@@ -27,6 +27,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|packageName|Rust package name (convention: lowercase).| |openapi|
|packageVersion|Rust package version.| |1.0.0|
|preferUnsignedInt|Prefer unsigned integers where minimum value is &gt;= 0| |false|
|reqwestDefaultFeatures|Default features for the reqwest dependency (comma-separated). Use empty for no defaults. This option is for 'reqwest' and 'reqwest-trait' library only.| |native-tls|
|supportAsync|If set, generate async function call instead. This option is for 'reqwest' library only| |true|
|supportMiddleware|If set, add support for reqwest-middleware. This option is for 'reqwest' and 'reqwest-trait' library only| |false|
|supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' and 'reqwest-trait' library only| |false|

View File

@@ -88,6 +88,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|springApiVersion|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
@@ -125,6 +126,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
## IMPORT MAPPING

View File

@@ -44,6 +44,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|supportsES6|Generate code that conforms to ES6.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|
|useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false|
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|withNodeImports|Setting this property to true adds imports for NodeJS| |false|
|withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes. This requires in addition a value for 'apiPackage' and 'modelPackage'| |false|
@@ -291,7 +292,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|SignatureAuth|✗|OAS3
|AWSV4Signature||ToolingExtension
|AWSV4Signature||ToolingExtension
### Wire Format Feature
| Name | Supported | Defined By |

View File

@@ -22,7 +22,7 @@ npm install @openapitools/openapi-generator-cli -g
To install a specific version of the tool, pass the version during installation:
<!-- RELEASE_VERSION -->
```bash
openapi-generator-cli version-manager set 7.15.0
openapi-generator-cli version-manager set 7.16.0
```
<!-- /RELEASE_VERSION -->
To install the tool as a dev dependency in your current project:
@@ -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.15.0/openapi-generator-cli-7.15.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar`
For **Mac/Linux** users:
```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar
```
<!-- /RELEASE_VERSION -->

View File

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

View File

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

View File

@@ -29,6 +29,7 @@ import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConfig;
@@ -248,7 +249,7 @@ public class GenerateBatch extends OpenApiGeneratorCommand {
Path filesMeta = Paths.get(outDir.toAbsolutePath().toString(), ".openapi-generator", "FILES");
if (filesMeta.toFile().exists()) {
FileUtils.readLines(filesMeta.toFile(), StandardCharsets.UTF_8).forEach(relativePath -> {
if (!StringUtils.startsWith(relativePath, ".")) {
if (!Strings.CS.startsWith(relativePath, ".")) {
Path file = outDir.resolve(relativePath).toAbsolutePath();
// hack: disallow directory traversal outside of output directory. we don't want to delete wrong files.
if (file.toString().startsWith(outDir.toAbsolutePath().toString())) {

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.16.0-SNAPSHOT
openApiGeneratorVersion=7.17.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.16.0-SNAPSHOT</version>
<version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath>
</parent>

View File

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

View File

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

View File

@@ -81,12 +81,12 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* The template directory holding a custom template.
*/
val templateDir = project.objects.property<String?>()
val templateDir = project.objects.property<String>()
/**
* The template location (which may be a directory or a classpath location) holding custom templates.
*/
val templateResourcePath = project.objects.property<String?>()
val templateResourcePath = project.objects.property<String>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
@@ -109,7 +109,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* Specifies if the existing files should be overwritten during the generation.
*/
val skipOverwrite = project.objects.property<Boolean?>()
val skipOverwrite = project.objects.property<Boolean>()
/**
* Package for generated classes (where supported)
@@ -244,32 +244,32 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* Reference the library template (sub-template) of a generator.
*/
val library = project.objects.property<String?>()
val library = project.objects.property<String>()
/**
* Git host, e.g. gitlab.com.
*/
val gitHost = project.objects.property<String?>()
val gitHost = project.objects.property<String>()
/**
* Git user ID, e.g. openapitools.
*/
val gitUserId = project.objects.property<String?>()
val gitUserId = project.objects.property<String>()
/**
* Git repo ID, e.g. openapi-generator.
*/
val gitRepoId = project.objects.property<String?>()
val gitRepoId = project.objects.property<String>()
/**
* Release note, default to 'Minor update'.
*/
val releaseNote = project.objects.property<String?>()
val releaseNote = project.objects.property<String>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}'
*/
val httpUserAgent = project.objects.property<String?>()
val httpUserAgent = project.objects.property<String>()
/**
* Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.
@@ -279,17 +279,17 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/
val ignoreFileOverride = project.objects.property<String?>()
val ignoreFileOverride = project.objects.property<String>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
val removeOperationIdPrefix = project.objects.property<Boolean?>()
val removeOperationIdPrefix = project.objects.property<Boolean>()
/**
* Skip examples defined in the operation
*/
val skipOperationExample = project.objects.property<Boolean?>()
val skipOperationExample = project.objects.property<Boolean>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
@@ -394,7 +394,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* Templating engine: "mustache" (default) or "handlebars" (beta)
*/
val engine = project.objects.property<String?>()
val engine = project.objects.property<String>()
/**
* Defines whether the output dir should be cleaned up before generating the output.

View File

@@ -55,7 +55,6 @@ import org.openapitools.codegen.config.MergedSpecBuilder
*
* @author Jim Schubert
*/
@Suppress("UnstableApiUsage")
@CacheableTask
open class GenerateTask @Inject constructor(private val objectFactory: ObjectFactory) : DefaultTask() {
@@ -154,14 +153,14 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Optional
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
val templateDir = project.objects.property<String?>()
val templateDir = project.objects.property<String>()
/**
* Resource path containing template files.
*/
@get:Optional
@get:Input
val templateResourcePath = project.objects.property<String?>()
val templateResourcePath = project.objects.property<String>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
@@ -193,7 +192,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/
@get:Optional
@get:Input
val skipOverwrite = project.objects.property<Boolean?>()
val skipOverwrite = project.objects.property<Boolean>()
/**
* Package for generated classes (where supported)
@@ -384,42 +383,42 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/
@get:Optional
@get:Input
val library = project.objects.property<String?>()
val library = project.objects.property<String>()
/**
* Git host, e.g. gitlab.com.
*/
@get:Optional
@get:Input
val gitHost = project.objects.property<String?>()
val gitHost = project.objects.property<String>()
/**
* Git user ID, e.g. openapitools.
*/
@get:Optional
@get:Input
val gitUserId = project.objects.property<String?>()
val gitUserId = project.objects.property<String>()
/**
* Git repo ID, e.g. openapi-generator.
*/
@get:Optional
@get:Input
val gitRepoId = project.objects.property<String?>()
val gitRepoId = project.objects.property<String>()
/**
* Release note, default to 'Minor update'.
*/
@get:Optional
@get:Input
val releaseNote = project.objects.property<String?>()
val releaseNote = project.objects.property<String>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}'
*/
@get:Optional
@get:Input
val httpUserAgent = project.objects.property<String?>()
val httpUserAgent = project.objects.property<String>()
/**
* Specifies how a reserved name should be escaped to.
@@ -434,21 +433,21 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Optional
@get:InputFile
@get:PathSensitive(PathSensitivity.RELATIVE)
val ignoreFileOverride = project.objects.property<String?>()
val ignoreFileOverride = project.objects.property<String>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
@get:Optional
@get:Input
val removeOperationIdPrefix = project.objects.property<Boolean?>()
val removeOperationIdPrefix = project.objects.property<Boolean>()
/**
* Remove examples defined in the operation
*/
@get:Optional
@get:Input
val skipOperationExample = project.objects.property<Boolean?>()
val skipOperationExample = project.objects.property<Boolean>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
@@ -581,7 +580,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/
@get:Optional
@get:Input
val engine = project.objects.property<String?>()
val engine = project.objects.property<String>()
/**
* Defines whether the output dir should be cleaned up before generating the output.
@@ -598,19 +597,11 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Input
val dryRun = project.objects.property<Boolean>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
private fun <T> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
val item: T? = get()
if (item != null) {
when (get()) {
is String -> if ((get() as String).isNotEmpty()) {
block(get())
}
is String? -> if (true == (get() as String?)?.isNotEmpty()) {
block(get())
}
else -> block(get())
}
when (val value = get()) {
is String -> if (value.isNotEmpty()) block(value)
else -> block(value)
}
}
}
@@ -725,7 +716,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
}
skipOverwrite.ifNotEmpty { value ->
configurator.setSkipOverwrite(value ?: false)
configurator.setSkipOverwrite(value)
}
generatorName.ifNotEmpty { value ->
@@ -820,11 +811,11 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
}
removeOperationIdPrefix.ifNotEmpty { value ->
configurator.setRemoveOperationIdPrefix(value!!)
configurator.setRemoveOperationIdPrefix(value)
}
skipOperationExample.ifNotEmpty { value ->
configurator.setSkipOperationExample(value!!)
configurator.setSkipOperationExample(value)
}
logToStderr.ifNotEmpty { value ->

View File

@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.15.0</version>
<version>7.16.0</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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.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.16.0-SNAPSHOT</version>
<version>7.17.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@@ -456,4 +456,31 @@ public class CodegenConstants {
public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars";
public static final String DEFAULT_TO_EMPTY_CONTAINER = "defaultToEmptyContainer";
// Vendor extensions
public static final String X_INTERNAL = "x-internal";
public static final String X_PARENT = "x-parent";
public static final String X_COMPOSED_DATA_TYPE = "x-composed-data-type";
public static final String X_BASE_NAME = "x-base-name";
public static final String X_IS_VALUE_TYPE = "x-is-value-type";
public static final String X_IS_REFERENCE_TYPE = "x-is-reference-type";
public static final String X_IS_NULLABLE_TYPE = "x-is-nullable-type";
public static final String X_IS_BASE_OR_NEW_DISCRIMINATOR = "x-is-base-or-new-discriminator";
public static final String X_ENUM_BYTE = "x-enum-byte";
public static final String X_HTTP_STATUS = "x-http-status";
public static final String X_HTTP_STATUSES_WITH_RETURN = "x-http-statuses-with-return";
public static final String X_SET_COOKIE = "x-set-cookie";
public static final String X_DUPLICATES = "x-duplicates";
public static final String X_HTTP_STATUS_IS_DEFAULT = "x-http-status-is-default";
public static final String X_ONLY_DEFAULT = "x-only-default";
public static final String X_HTTP_STATUS_RANGE = "x-http-status-range";
public static final String X_NOT_NULLABLE_REFERENCE_TYPES = "x-not-nullable-reference-types";
public static final String X_HAS_NOT_NULLABLE_REFERENCE_TYPES = "x-has-not-nullable-reference-types";
public static final String X_NULLABLE_VALUE_TYPE = "x-nullable-value-type";
public static final String X_NULLABLE_TYPE = "x-nullable-type";
public static final String X_CSHARP_VALUE_TYPE = "x-csharp-value-type";
public static final String X_REGEX = "x-regex";
public static final String X_MODIFIERS = "x-modifiers";
public static final String X_MODIFIER_PREFIX = "x-modifier-";
public static final String X_MODEL_IS_MUTABLE = "x-model-is-mutable";
}

View File

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

View File

@@ -88,8 +88,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.openapitools.codegen.CodegenConstants.DEFAULT_TO_EMPTY_CONTAINER;
import static org.openapitools.codegen.CodegenConstants.UNSUPPORTED_V310_SPEC_MSG;
import static org.openapitools.codegen.CodegenConstants.*;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*;
@@ -5197,7 +5196,7 @@ public class DefaultCodegen implements CodegenConfig {
String method = p.getKey();
Operation op = p.getValue();
if (op.getExtensions() != null && Boolean.TRUE.equals(op.getExtensions().get("x-internal"))) {
if (op.getExtensions() != null && Boolean.TRUE.equals(op.getExtensions().get(X_INTERNAL))) {
// skip operation if x-internal sets to true
LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true",
method, expression, op.getOperationId());
@@ -5735,7 +5734,7 @@ public class DefaultCodegen implements CodegenConfig {
cs.name = key;
cs.description = securityScheme.getDescription();
cs.type = securityScheme.getType().toString();
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = false;
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = cs.isOAuth = false;
cs.isHttpSignature = false;
cs.isBasicBasic = cs.isBasicBearer = false;
cs.scheme = securityScheme.getScheme();

View File

@@ -61,6 +61,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.removeStart;
import static org.openapitools.codegen.CodegenConstants.X_INTERNAL;
import static org.openapitools.codegen.utils.OnceLogger.once;
@SuppressWarnings("rawtypes")
@@ -486,7 +487,7 @@ public class DefaultGenerator implements Generator {
Schema schema = ModelUtils.getSchemas(this.openAPI).get(name);
if (schema.getExtensions() != null && Boolean.TRUE.equals(schema.getExtensions().get("x-internal"))) {
if (schema.getExtensions() != null && Boolean.TRUE.equals(schema.getExtensions().get(X_INTERNAL))) {
LOGGER.info("Model {} not generated since x-internal is set to true", name);
continue;
} else if (ModelUtils.isFreeFormObject(schema, openAPI)) { // check to see if it's a free-form object
@@ -1564,7 +1565,7 @@ public class DefaultGenerator implements Generator {
final List<SecurityRequirement> globalSecurities = openAPI.getSecurity();
for (Tag tag : tags) {
try {
if (operation.getExtensions() != null && Boolean.TRUE.equals(operation.getExtensions().get("x-internal"))) {
if (operation.getExtensions() != null && Boolean.TRUE.equals(operation.getExtensions().get(X_INTERNAL))) {
// skip operation if x-internal sets to true
LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true",
httpMethod, resourcePath, operation.getOperationId());

View File

@@ -356,7 +356,9 @@ public class InlineModelResolver {
} else if (schema.getProperties() != null) {
// If non-object type is specified but also properties
LOGGER.error("Illegal schema found with non-object type combined with properties," +
" no properties should be defined:\n " + schema.toString());
" no properties should be defined:" +
" consider using --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true\n " +
schema.toString());
return;
} else if (schema.getAdditionalProperties() != null) {
// If non-object type is specified but also additionalProperties

View File

@@ -37,6 +37,8 @@ import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_INTERNAL;
import static org.openapitools.codegen.CodegenConstants.X_PARENT;
import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema;
import static org.openapitools.codegen.utils.StringUtils.getUniqueString;
@@ -47,7 +49,7 @@ public class OpenAPINormalizer {
private TreeSet<String> anyTypeTreeSet = new TreeSet<>();
protected final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
protected static final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
Set<String> ruleNames = new TreeSet<>();
Set<String> rulesDefaultToTrue = new TreeSet<>();
@@ -122,20 +124,18 @@ public class OpenAPINormalizer {
// the allOf contains a new schema containing the properties in the top level
final String REFACTOR_ALLOF_WITH_PROPERTIES_ONLY = "REFACTOR_ALLOF_WITH_PROPERTIES_ONLY";
// when set to true, remove the "properties" of a schema with type other than "object"
final String REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT = "REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT";
// when set to true, normalize OpenAPI 3.1 spec to make it work with the generator
final String NORMALIZE_31SPEC = "NORMALIZE_31SPEC";
// when set to true, remove x-internal: true from models, operations
final String REMOVE_X_INTERNAL = "REMOVE_X_INTERNAL";
final String X_INTERNAL = "x-internal";
boolean removeXInternal;
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
final String FILTER = "FILTER";
HashSet<String> operationIdFilters = new HashSet<>();
HashSet<String> methodFilters = new HashSet<>();
HashSet<String> tagFilters = new HashSet<>();
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
final String SET_CONTAINER_TO_NULLABLE = "SET_CONTAINER_TO_NULLABLE";
@@ -209,11 +209,13 @@ public class OpenAPINormalizer {
ruleNames.add(SET_CONTAINER_TO_NULLABLE);
ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE);
ruleNames.add(SIMPLIFY_ONEOF_ANYOF_ENUM);
ruleNames.add(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT);
// rules that are default to true
rules.put(SIMPLIFY_ONEOF_ANYOF, true);
rules.put(SIMPLIFY_BOOLEAN_ENUM, true);
rules.put(SIMPLIFY_ONEOF_ANYOF_ENUM, true);
rules.put(REFACTOR_ALLOF_WITH_PROPERTIES_ONLY, true);
processRules(inputRules);
@@ -274,30 +276,7 @@ public class OpenAPINormalizer {
if (inputRules.get(FILTER) != null) {
rules.put(FILTER, true);
String[] filterStrs = inputRules.get(FILTER).split(":");
if (filterStrs.length != 2) { // only support operationId with : at the moment
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
} else {
if ("operationId".equals(filterStrs[0])) {
operationIdFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else if ("method".equals(filterStrs[0])) {
methodFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else if ("tag".equals(filterStrs[0])) {
tagFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else {
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
}
}
// actual parsing is delayed to allow customization of the Filter processing
}
if (inputRules.get(SET_CONTAINER_TO_NULLABLE) != null) {
@@ -343,6 +322,19 @@ public class OpenAPINormalizer {
}
}
/**
* Create the filter to process the FILTER normalizer.
* Override this to create a custom filter normalizer.
*
* @param openApi Contract used in the filtering (could be used for customization).
* @param filters full FILTER value
*
* @return a Filter containing the parsed filters.
*/
protected Filter createFilter(OpenAPI openApi, String filters) {
return new Filter(filters);
}
/**
* Normalizes the OpenAPI input, which may not perfectly conform to
* the specification.
@@ -404,15 +396,15 @@ public class OpenAPINormalizer {
"trace", PathItem::getTrace
);
// Iterates over each HTTP method in methodMap, retrieves the corresponding Operation from the PathItem,
// and marks it as internal (`x-internal`) if the method is not in methodFilters.
methodMap.forEach((method, getter) -> {
Operation operation = getter.apply(path);
if (operation != null && !methodFilters.isEmpty()) {
LOGGER.info("operation `{}` marked internal only (x-internal: `{}`) by the method FILTER", operation.getOperationId(), !methodFilters.contains(method));
operation.addExtension("x-internal", !methodFilters.contains(method));
if (Boolean.TRUE.equals(getRule(FILTER))) {
String filters = inputRules.get(FILTER);
Filter filter = createFilter(this.openAPI, filters);
if (filter.parse()) {
// Iterates over each HTTP method in methodMap, retrieves the corresponding Operations from the PathItem,
// and marks it as internal (`x-internal=true`) if the method/operationId/tag/path is not in the filters.
filter.apply(pathsEntry.getKey(), path, methodMap);
}
});
}
// Include callback operation as well
for (Operation operation : path.readOperations()) {
@@ -429,22 +421,6 @@ public class OpenAPINormalizer {
normalizeParameters(path.getParameters());
for (Operation operation : operations) {
if (operationIdFilters.size() > 0) {
if (operationIdFilters.contains(operation.getOperationId())) {
operation.addExtension("x-internal", false);
} else {
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the operationId FILTER", operation.getOperationId());
operation.addExtension("x-internal", true);
}
} else if (!tagFilters.isEmpty()) {
if (operation.getTags().stream().anyMatch(tagFilters::contains)) {
operation.addExtension("x-internal", false);
} else {
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the tag FILTER", operation.getOperationId());
operation.addExtension("x-internal", true);
}
}
normalizeOperation(operation);
normalizeRequestBody(operation);
normalizeParameters(operation.getParameters());
@@ -723,15 +699,19 @@ public class OpenAPINormalizer {
if (skipNormalization(schema, visitedSchemas)) {
return schema;
}
if (ModelUtils.isNullTypeSchema(openAPI, schema)) {
return schema;
}
markSchemaAsVisited(schema, visitedSchemas);
processNormalizeOtherThanObjectWithProperties(schema);
if (ModelUtils.isArraySchema(schema)) { // array
Schema result = normalizeArraySchema(schema);
normalizeSchema(result.getItems(), visitedSchemas);
return result;
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeMapSchema(schema);
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (ModelUtils.isOneOf(schema)) { // oneOf
return normalizeOneOf(schema, visitedSchemas);
} else if (ModelUtils.isAnyOf(schema)) { // anyOf
@@ -768,6 +748,9 @@ public class OpenAPINormalizer {
return schema;
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
normalizeProperties(schema.getProperties(), visitedSchemas);
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeMapSchema(schema);
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (schema instanceof BooleanSchema) {
normalizeBooleanSchema(schema, visitedSchemas);
} else if (schema instanceof IntegerSchema) {
@@ -849,6 +832,20 @@ public class OpenAPINormalizer {
}
for (Map.Entry<String, Schema> propertiesEntry : properties.entrySet()) {
Schema property = propertiesEntry.getValue();
// remove x-internal if needed (same logic as normalizeComponentsSchemas)
if (property.getExtensions() != null && getRule(REMOVE_X_INTERNAL)) {
Object xInternalValue = property.getExtensions().get(X_INTERNAL);
boolean isInternal = false;
if (xInternalValue instanceof Boolean) {
isInternal = (Boolean) xInternalValue;
} else if (xInternalValue instanceof String) {
isInternal = Boolean.parseBoolean((String) xInternalValue);
}
if (isInternal) {
property.getExtensions().remove(X_INTERNAL);
}
}
Schema newProperty = normalizeSchema(property, new HashSet<>());
propertiesEntry.setValue(newProperty);
}
@@ -1011,6 +1008,7 @@ public class OpenAPINormalizer {
if (schema.getAnyOf() == null) {
return schema;
}
for (int i = 0; i < schema.getAnyOf().size(); i++) {
// normalize anyOf sub schemas one by one
Object item = schema.getAnyOf().get(i);
@@ -1083,10 +1081,10 @@ public class OpenAPINormalizer {
refSchema.setExtensions(new HashMap<>());
}
if (refSchema.getExtensions().containsKey("x-parent")) {
if (refSchema.getExtensions().containsKey(X_PARENT)) {
// doing nothing as x-parent already exists
} else {
refSchema.getExtensions().put("x-parent", true);
refSchema.getExtensions().put(X_PARENT, true);
}
LOGGER.debug("processUseAllOfRefAsParent added `x-parent: true` to {}", refSchema);
@@ -1108,7 +1106,7 @@ public class OpenAPINormalizer {
return;
}
if (Boolean.parseBoolean(String.valueOf(operation.getExtensions().get("x-internal")))) {
if (Boolean.parseBoolean(String.valueOf(operation.getExtensions().get(X_INTERNAL)))) {
operation.getExtensions().remove(X_INTERNAL);
}
}
@@ -1342,7 +1340,7 @@ public class OpenAPINormalizer {
*
* @param schema Schema to modify
* @param subSchemas List of sub-schemas to check
* @param schemaType Type of composed schema ("oneOf" or "anyOf")
* @param composedType Type of composed schema ("oneOf" or "anyOf")
* @return Simplified schema
*/
protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) {
@@ -1811,4 +1809,181 @@ public class OpenAPINormalizer {
}
// ===================== end of rules =====================
protected static class Filter {
public static final String OPERATION_ID = "operationId";
public static final String METHOD = "method";
public static final String TAG = "tag";
public static final String PATH = "path";
private final String filters;
protected Set<String> operationIdFilters = Collections.emptySet();
protected Set<String> methodFilters = Collections.emptySet();
protected Set<String> tagFilters = Collections.emptySet();
protected Set<String> pathStartingWithFilters = Collections.emptySet();
private boolean hasFilter;
protected Filter(String filters) {
this.filters = filters.trim();
}
/**
* Perform the parsing of the filter string.
*
* @return true if filters need to be processed
*/
public boolean parse() {
if (StringUtils.isEmpty(filters)) {
return false;
}
try {
doParse();
return hasFilter();
} catch (RuntimeException e) {
String message = String.format(Locale.ROOT, "FILTER rule [%s] must be in the form of `%s:name1|name2|name3` or `%s:get|post|put` or `%s:tag1|tag2|tag3` or `%s:/v1|/v2`. Error: %s",
filters, Filter.OPERATION_ID, Filter.METHOD, Filter.TAG, Filter.PATH, e.getMessage());
// throw an exception. This is a breaking change compared to pre 7.16.0
// Workaround: fix the syntax!
throw new IllegalArgumentException(message);
}
}
private void doParse() {
for (String filter : filters.split(";")) {
filter = filter.trim();
String[] filterStrs = filter.split(":");
if (filterStrs.length != 2) { // only support filter with : at the moment
throw new IllegalArgumentException("filter with no value not supported :[" + filter + "]");
} else {
String filterKey = filterStrs[0].trim();
String filterValue = filterStrs[1];
Set<String> parsedFilters = splitByPipe(filterValue);
hasFilter = true;
if (OPERATION_ID.equals(filterKey)) {
operationIdFilters = parsedFilters;
} else if (METHOD.equals(filterKey)) {
methodFilters = parsedFilters;
} else if (TAG.equals(filterKey)) {
tagFilters = parsedFilters;
} else if (PATH.equals(filterKey)) {
pathStartingWithFilters = parsedFilters;
} else {
parse(filterKey, filterValue);
}
}
}
}
/**
* Split the filterValue by pipe.
*
* @return the split values.
*/
protected Set<String> splitByPipe(String filterValue) {
return Arrays.stream(filterValue.split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
}
/**
* Parse non default filters.
*
* Override this method to add custom parsing logic.
*
* By default throws IllegalArgumentException.
*
* @param filterName name of the filter
* @param filterValue value of the filter
*/
protected void parse(String filterName, String filterValue) {
parseFails(filterName, filterValue);
}
protected void parseFails(String filterName, String filterValue) {
throw new IllegalArgumentException("filter not supported :[" + filterName + ":" + filterValue + "]");
}
/**
* Test if the OpenAPI contract match an extra filter.
*
* Override this method to add custom logic.
*
* @param operation Openapi Operation
* @param path Path of the operation
*
* @return true if the operation of path match the filter
*/
protected boolean hasCustomFilterMatch(String path, Operation operation) {
return false;
}
public boolean hasFilter() {
return hasFilter;
}
public void apply(String path, PathItem pathItem, Map<String, Function<PathItem, Operation>> methodMap) {
methodMap.forEach((method, getter) -> {
Operation operation = getter.apply(pathItem);
if (operation != null) {
boolean found = false;
found |= logIfMatch(PATH, operation, hasPathStarting(path));
found |= logIfMatch(TAG, operation, hasTag(operation));
found |= logIfMatch(OPERATION_ID, operation, hasOperationId(operation));
found |= logIfMatch(METHOD, operation, hasMethod(method));
found |= hasCustomFilterMatch(path, operation);
operation.addExtension(X_INTERNAL, !found);
}
});
}
protected boolean logIfMatch(String filterName, Operation operation, boolean filterMatched) {
if (filterMatched) {
logMatch(filterName, operation);
}
return filterMatched;
}
protected void logMatch(String filterName, Operation operation) {
getLogger().info("operation `{}` marked as internal only (x-internal: true) by the {} FILTER", operation.getOperationId(), filterName);
}
protected Logger getLogger() {
return OpenAPINormalizer.LOGGER;
}
private boolean hasPathStarting(String path) {
return pathStartingWithFilters.stream().anyMatch(filter -> path.startsWith(filter));
}
private boolean hasTag( Operation operation) {
return operation.getTags() != null && operation.getTags().stream().anyMatch(tagFilters::contains);
}
private boolean hasOperationId(Operation operation) {
return operationIdFilters.contains(operation.getOperationId());
}
private boolean hasMethod(String method) {
return methodFilters.contains(method);
}
}
/**
* When set to true, remove "properties" attribute on schema other than "object"
* since it should be ignored and may result in odd generated code
*
* @param schema Schema
* @return Schema
*/
protected void processNormalizeOtherThanObjectWithProperties(Schema schema) {
if (getRule(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT)) {
// Check object models / any type models / composed models for properties,
// if the schema has a type defined that is not "object" it should not define
// any properties
if (schema.getType() != null && !"object".equals(schema.getType())) {
schema.setProperties(null);
}
}
}
}

View File

@@ -13,6 +13,7 @@ public enum VendorExtension {
X_KOTLIN_IMPLEMENTS("x-kotlin-implements", ExtensionLevel.MODEL, "Ability to specify interfaces that model must implement", "empty array"),
X_KOTLIN_IMPLEMENTS_FIELDS("x-kotlin-implements-fields", ExtensionLevel.MODEL, "Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`", "empty array"),
X_SPRING_PAGINATED("x-spring-paginated", ExtensionLevel.OPERATION, "Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.", "false"),
X_SPRING_API_VERSION("x-spring-api-version", ExtensionLevel.OPERATION, "Value for 'version' attribute in @RequestMapping (for Spring 7 and above).", null),
X_SPRING_PROVIDE_ARGS("x-spring-provide-args", ExtensionLevel.OPERATION, "Allows adding additional hidden parameters in the API specification to allow access to content such as header values or properties", "empty array"),
X_DISCRIMINATOR_VALUE("x-discriminator-value", ExtensionLevel.MODEL, "Used with model inheritance to specify value for discriminator that identifies current model", ""),
X_SETTER_EXTRA_ANNOTATION("x-setter-extra-annotation", ExtensionLevel.FIELD, "Custom annotation that can be specified over java setter for specific field", "When field is array & uniqueItems, then this extension is used to add `@JsonDeserialize(as = LinkedHashSet.class)` over setter, otherwise no value"),
@@ -26,8 +27,10 @@ public enum VendorExtension {
X_OPERATION_EXTRA_ANNOTATION("x-operation-extra-annotation", ExtensionLevel.OPERATION, "List of custom annotations to be added to operation", null),
X_VERSION_PARAM("x-version-param", ExtensionLevel.OPERATION_PARAMETER, "Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false", null),
X_PATTERN_MESSAGE("x-pattern-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null),
X_ZERO_BASED_ENUM("x-zero-based-enum", ExtensionLevel.MODEL, "When used on an enum, the index will not be generated and the default numbering will be used, zero-based", "false"),
;
X_SIZE_MESSAGE("x-size-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the size or length of a variable", null),
X_MINIMUM_MESSAGE("x-minimum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the minimum value of a variable", null),
X_MAXIMUM_MESSAGE("x-maximum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the maximum value of a variable", null),
X_ZERO_BASED_ENUM("x-zero-based-enum", ExtensionLevel.MODEL, "When used on an enum, the index will not be generated and the default numbering will be used, zero-based", "false");
private final String name;
private final List<ExtensionLevel> levels;

View File

@@ -46,6 +46,7 @@ import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.*;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.ModelUtils.getSchemaItems;
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -116,6 +117,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
// A cache to efficiently lookup schema `toModelName()` based on the schema Key
private final Map<String, String> schemaKeyToModelNameCache = new HashMap<>();
// A cache to efficiently lookup CodegenModel `fromModel(codegenModelName, parentModelSchema)` based on the pair of model name and schema
private final Map<Map.Entry<String, Schema>, CodegenModel> codegenModelNameAndSchemaKeyToCodegenModelCache = new HashMap<>();
public AbstractCSharpCodegen() {
super();
@@ -543,7 +547,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (dataTypeSet.contains(oneOfProperty.dataType)) {
// add "x-duplicated-data-type" to indicate if the dataType already occurs before
// in other sub-schemas of allOf/anyOf/oneOf
oneOfProperty.vendorExtensions.putIfAbsent("x-composed-data-type", true);
oneOfProperty.vendorExtensions.putIfAbsent(X_COMPOSED_DATA_TYPE, true);
} else {
dataTypeSet.add(oneOfProperty.dataType);
}
@@ -557,7 +561,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (dataTypeSet.contains(anyOfProperty.dataType)) {
// add "x-duplicated-data-type" to indicate if the dataType already occurs before
// in other sub-schemas of allOf/anyOf/oneOf
anyOfProperty.vendorExtensions.putIfAbsent("x-composed-data-type", true);
anyOfProperty.vendorExtensions.putIfAbsent(X_COMPOSED_DATA_TYPE, true);
} else {
dataTypeSet.add(anyOfProperty.dataType);
}
@@ -619,7 +623,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
continue;
}
model.vendorExtensions.put("x-model-is-mutable", modelIsMutable(model, null));
model.vendorExtensions.put(X_MODEL_IS_MUTABLE, modelIsMutable(model, null));
CodegenComposedSchemas composedSchemas = model.getComposedSchemas();
if (composedSchemas != null) {
@@ -639,7 +643,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchProperty(enumRefs, model, property);
property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames);
property.isNullable = true;
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
property.vendorExtensions.put(X_BASE_NAME, model.name.substring(model.name.lastIndexOf('_') + 1));
}
}
@@ -650,7 +654,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchProperty(enumRefs, model, property);
property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames);
property.isNullable = true;
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
property.vendorExtensions.put(X_BASE_NAME, model.name.substring(model.name.lastIndexOf('_') + 1));
}
}
}
@@ -784,10 +788,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
private void patchPropertyVendorExtensions(CodegenProperty property) {
boolean isValueType = isValueType(property);
property.vendorExtensions.put("x-is-value-type", isValueType);
property.vendorExtensions.put("x-is-reference-type", !isValueType);
property.vendorExtensions.put("x-is-nullable-type", this.getNullableReferencesTypes() || isValueType);
property.vendorExtensions.put("x-is-base-or-new-discriminator", (property.isDiscriminator && !property.isInherited) || (property.isDiscriminator && property.isNew));
property.vendorExtensions.put(X_IS_VALUE_TYPE, isValueType);
property.vendorExtensions.put(X_IS_REFERENCE_TYPE, !isValueType);
property.vendorExtensions.put(X_IS_NULLABLE_TYPE, this.getNullableReferencesTypes() || isValueType);
property.vendorExtensions.put(X_IS_BASE_OR_NEW_DISCRIMINATOR, (property.isDiscriminator && !property.isInherited) || (property.isDiscriminator && property.isNew));
}
protected void patchPropertyIsInherited(CodegenModel model, CodegenProperty property) {
@@ -888,7 +892,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
// Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here.
if (var.isEnum) {
if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums.
var.vendorExtensions.put("x-enum-byte", true);
var.vendorExtensions.put(X_ENUM_BYTE, true);
var.isString = false;
var.isLong = false;
var.isInteger = false;
@@ -909,7 +913,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
}
private void postProcessResponseCode(CodegenResponse response, String status, Set<String> httpStatusesWithReturn) {
response.vendorExtensions.put("x-http-status", status);
response.vendorExtensions.put(X_HTTP_STATUS, status);
if (response.dataType != null) {
httpStatusesWithReturn.add(status);
}
@@ -942,11 +946,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
}
private void postProcessOperations(OperationMap operations, List<ModelMap> allModels) {
Set<String> httpStatusesWithReturn = additionalProperties.get("x-http-statuses-with-return") instanceof Set<?>
? (Set<String>) additionalProperties.get("x-http-statuses-with-return")
Set<String> httpStatusesWithReturn = additionalProperties.get(X_HTTP_STATUSES_WITH_RETURN) instanceof Set<?>
? (Set<String>) additionalProperties.get(X_HTTP_STATUSES_WITH_RETURN)
: new HashSet<String>();
additionalProperties.put("x-http-statuses-with-return", httpStatusesWithReturn);
additionalProperties.put(X_HTTP_STATUSES_WITH_RETURN, httpStatusesWithReturn);
HashMap<String, CodegenModel> modelMaps = ModelMap.toCodegenModelMap(allModels);
@@ -955,7 +959,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
for (CodegenOperation operation : ops) {
String duplicates = duplicateOf.get(operation.operationId);
if (duplicates != null) {
operation.vendorExtensions.put("x-duplicates", duplicates);
operation.vendorExtensions.put(X_DUPLICATES, duplicates);
} else {
duplicateOf.put(operation.operationId, operations.getClassname());
}
@@ -964,13 +968,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (response.returnProperty != null) {
Boolean isValueType = isValueType(response.returnProperty);
response.vendorExtensions.put("x-is-value-type", isValueType);
response.vendorExtensions.put("x-is-reference-type", !isValueType);
response.vendorExtensions.put(X_IS_VALUE_TYPE, isValueType);
response.vendorExtensions.put(X_IS_REFERENCE_TYPE, !isValueType);
}
if (response.headers != null && response.headers.stream().anyMatch(h -> h.baseName.equals("Set-Cookie"))) {
response.vendorExtensions.put("x-set-cookie", true);
operation.vendorExtensions.put("x-set-cookie", true);
response.vendorExtensions.put(X_SET_COOKIE, true);
operation.vendorExtensions.put(X_SET_COOKIE, true);
}
String code = response.code.toLowerCase(Locale.ROOT);
@@ -978,9 +982,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
case "default":
case "0":
postProcessResponseCode(response, "Default", httpStatusesWithReturn);
response.vendorExtensions.put("x-http-status-is-default", true);
response.vendorExtensions.put(X_HTTP_STATUS_IS_DEFAULT, true);
if ((long) operation.responses.size() == 1) {
response.vendorExtensions.put("x-only-default", true);
response.vendorExtensions.put(X_ONLY_DEFAULT, true);
}
break;
case "100":
@@ -1161,23 +1165,23 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
postProcessResponseCode(response, "NetworkAuthenticationRequired", httpStatusesWithReturn);
break;
case "1xx":
response.vendorExtensions.put("x-http-status-range", 1);
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 1);
postProcessResponseCode(response, "HttpStatusCode1XX", httpStatusesWithReturn);
break;
case "2xx":
response.vendorExtensions.put("x-http-status-range", 2);
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 2);
postProcessResponseCode(response, "HttpStatusCode2XX", httpStatusesWithReturn);
break;
case "3xx":
response.vendorExtensions.put("x-http-status-range", 3);
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 3);
postProcessResponseCode(response, "HttpStatusCode3XX", httpStatusesWithReturn);
break;
case "4xx":
response.vendorExtensions.put("x-http-status-range", 4);
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 4);
postProcessResponseCode(response, "HttpStatusCode4XX", httpStatusesWithReturn);
break;
case "5xx":
response.vendorExtensions.put("x-http-status-range", 5);
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 5);
postProcessResponseCode(response, "HttpStatusCode5XX", httpStatusesWithReturn);
break;
default:
@@ -1278,9 +1282,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchParameter(model, parameter);
}
List<CodegenParameter> referenceTypes = operation.allParams.stream().filter(p -> p.vendorExtensions.get("x-is-value-type") == null && !p.isNullable).collect(Collectors.toList());
operation.vendorExtensions.put("x-not-nullable-reference-types", referenceTypes);
operation.vendorExtensions.put("x-has-not-nullable-reference-types", referenceTypes.size() > 0);
List<CodegenParameter> referenceTypes = operation.allParams.stream().filter(p -> p.vendorExtensions.get(X_IS_VALUE_TYPE) == null && !p.isNullable).collect(Collectors.toList());
operation.vendorExtensions.put(X_NOT_NULLABLE_REFERENCE_TYPES, referenceTypes);
operation.vendorExtensions.put(X_HAS_NOT_NULLABLE_REFERENCE_TYPES, referenceTypes.size() > 0);
processOperation(operation);
// Remove constant params from allParams list and add to constantParams
@@ -1291,7 +1295,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
protected void patchVendorExtensionNullableValueType(CodegenParameter parameter) {
if (parameter.isNullable && !parameter.isContainer && (this.getValueTypes().contains(parameter.dataType) || parameter.isEnum)) {
parameter.vendorExtensions.put("x-nullable-value-type", true);
parameter.vendorExtensions.put(X_NULLABLE_VALUE_TYPE, true);
}
}
@@ -1307,15 +1311,15 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
*/
protected void patchVendorExtensionNullableValueTypeLegacy(CodegenParameter parameter) {
if (parameter.isNullable && !parameter.isContainer && (this.getNullableTypes().contains(parameter.dataType) || parameter.isEnum)) {
parameter.vendorExtensions.put("x-nullable-value-type", true);
parameter.vendorExtensions.put(X_NULLABLE_VALUE_TYPE, true);
}
}
private void patchParameter(CodegenModel model, CodegenParameter parameter) {
patchVendorExtensionNullableValueType(parameter);
if (this.getNullableReferencesTypes() || (parameter.vendorExtensions.get("x-nullable-value-type") != null)) {
parameter.vendorExtensions.put("x-nullable-type", true);
if (this.getNullableReferencesTypes() || (parameter.vendorExtensions.get(X_NULLABLE_VALUE_TYPE) != null)) {
parameter.vendorExtensions.put(X_NULLABLE_TYPE, true);
}
if (!isSupportNullable()) {
@@ -1362,12 +1366,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.vendorExtensions.put("x-csharp-value-type", true);
parameter.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}
if (!parameter.isContainer && this.getNullableTypes().contains(parameter.dataType)) {
parameter.vendorExtensions.put("x-csharp-value-type", true);
parameter.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}
@@ -1377,12 +1381,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.vendorExtensions.put("x-is-value-type", true);
parameter.vendorExtensions.put(X_IS_VALUE_TYPE, true);
}
}
if (!parameter.isContainer && this.getValueTypes().contains(parameter.dataType)) {
parameter.vendorExtensions.put("x-is-value-type", true);
parameter.vendorExtensions.put(X_IS_VALUE_TYPE, true);
}
}
@@ -1624,7 +1628,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems(schema);
return getSchemaType(target) + "<" + getTypeDeclarationForArray(items) + ">";
return typeMapping.get("array") + "<" + getTypeDeclarationForArray(items) + ">";
} else if (ModelUtils.isMapSchema(p)) {
// Should we also support maps of maps?
Schema<?> inner = ModelUtils.getAdditionalProperties(p);
@@ -1703,6 +1707,17 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
return toModelName(name) + "Tests";
}
protected CodegenModel getCodegenModel(String codegenModelName, Schema schema){
var key = new AbstractMap.SimpleEntry<>(codegenModelName, schema);
if(codegenModelNameAndSchemaKeyToCodegenModelCache.containsKey(key)){
return codegenModelNameAndSchemaKeyToCodegenModelCache.get(key);
}
CodegenModel model = super.fromModel(codegenModelName, schema);
codegenModelNameAndSchemaKeyToCodegenModelCache.put(key, model);
return model;
}
public void setNullableReferenceTypes(final Boolean nullReferenceTypesFlag) {
this.nullReferenceTypesFlag = nullReferenceTypesFlag;
additionalProperties.put("nullableReferenceTypes", nullReferenceTypesFlag);
@@ -2050,13 +2065,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
} else if (c == 'l') {
modifiers.remove("CultureInvariant");
} else {
vendorExtensions.put("x-modifier-" + c, c);
vendorExtensions.put(X_MODIFIER_PREFIX + c, c);
}
}
String regex = pattern.substring(start, end).replace("\"", "\"\"");
vendorExtensions.put("x-regex", regex);
vendorExtensions.put("x-modifiers", modifiers);
vendorExtensions.put(X_REGEX, regex);
vendorExtensions.put(X_MODIFIERS, modifiers);
}
}

View File

@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import static org.openapitools.codegen.CodegenConstants.X_ENUM_BYTE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -433,7 +434,7 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
if (model.dataType.startsWith("byte")) {
// F# Actually supports byte and short enums, swagger spec only supports byte.
isByte = true;
model.vendorExtensions.put("x-enum-byte", true);
model.vendorExtensions.put(X_ENUM_BYTE, true);
} else if (model.dataType.startsWith("int32")) {
isInteger = true;
model.vendorExtensions.put("x-enum-integer", true);
@@ -487,7 +488,7 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
// Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here.
if (var.isEnum) {
if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums.
var.vendorExtensions.put("x-enum-byte", true);
var.vendorExtensions.put(X_ENUM_BYTE, true);
var.isString = false;
var.isLong = false;
var.isInteger = false;

View File

@@ -1891,6 +1891,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
model.imports.add("Arrays");
} else if ("set".equals(property.containerType)) {
model.imports.add("LinkedHashSet");
model.imports.add("Arrays");
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
model.imports.add("JsonDeserialize");
property.vendorExtensions.put("x-setter-extra-annotation", "@JsonDeserialize(as = LinkedHashSet.class)");

View File

@@ -119,6 +119,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
convertPropertyToStringAndWriteBack(CodegenConstants.IMPL_FOLDER, this::setImplFolder);
convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION, this::setUseBeanValidation);
convertPropertyToBooleanAndWriteBack(USE_TAGS, this::setUseTags);
convertPropertyToBooleanAndWriteBack(JACKSON, this::setJackson);
}
@Override

View File

@@ -40,6 +40,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.*;
@@ -1353,9 +1355,9 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
}
}
vendorExtensions.put("x-regex", regex.replace("\"", "\\\""));
vendorExtensions.put(X_REGEX, regex.replace("\"", "\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\""));
vendorExtensions.put("x-modifiers", modifiers);
vendorExtensions.put(X_MODIFIERS, modifiers);
}
}

View File

@@ -34,6 +34,7 @@ import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.DocumentationFeature;
@@ -46,6 +47,8 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.camelize;
public abstract class AbstractPythonConnexionServerCodegen extends AbstractPythonCodegen implements CodegenConfig {
@@ -599,7 +602,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name, "import", "from")) {
if (Strings.CS.startsWithAny(name, "import", "from")) {
modelImport = name;
} else {
modelImport = "from ";
@@ -743,8 +746,8 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
}
}
vendorExtensions.put("x-regex", regex);
vendorExtensions.put("x-modifiers", modifiers);
vendorExtensions.put(X_REGEX, regex);
vendorExtensions.put(X_MODIFIERS, modifiers);
}
}
}

View File

@@ -39,6 +39,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractPythonPydanticV1Codegen extends DefaultCodegen implements CodegenConfig {
@@ -1915,9 +1917,9 @@ public abstract class AbstractPythonPydanticV1Codegen extends DefaultCodegen imp
}
}
vendorExtensions.put("x-regex", regex.replace("\"", "\\\""));
vendorExtensions.put(X_REGEX, regex.replace("\"", "\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\""));
vendorExtensions.put("x-modifiers", modifiers);
vendorExtensions.put(X_MODIFIERS, modifiers);
}
}

View File

@@ -37,6 +37,7 @@ import java.net.URL;
import java.util.*;
import static java.util.UUID.randomUUID;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
public class AspNetServerCodegen extends AbstractCSharpCodegen {
@@ -347,7 +348,7 @@ public class AspNetServerCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional
parameter.dataType = parameter.dataType + "?";
}
}
@@ -627,7 +628,7 @@ public class AspNetServerCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put("x-csharp-value-type", true);
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}

View File

@@ -39,6 +39,7 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -409,7 +410,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional
parameter.dataType = parameter.dataType + "?";
}
}
@@ -436,7 +437,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
final Schema<?> parentModel = allDefinitions.get(toModelName(codegenModel.parent));
if (parentModel != null) {
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
final CodegenModel parentCodegenModel = getCodegenModel(codegenModel.parent, parentModel);
if (codegenModel.hasEnums) {
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
}
@@ -1626,7 +1627,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (!GENERICHOST.equals(getLibrary())) {
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put("x-csharp-value-type", true);
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}
}

View File

@@ -36,6 +36,7 @@ import java.net.URL;
import java.util.*;
import static java.util.UUID.randomUUID;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
@@ -287,7 +288,7 @@ public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put("x-csharp-value-type", true);
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}
@@ -295,7 +296,7 @@ public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional
parameter.dataType = parameter.dataType + "?";
}
}

View File

@@ -37,6 +37,7 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -350,7 +351,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put("x-csharp-value-type", true);
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true);
}
}
@@ -358,7 +359,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional
parameter.dataType = parameter.dataType + "?";
}
}
@@ -380,7 +381,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
final Schema parentModel = allDefinitions.get(toModelName(codegenModel.parent));
if (parentModel != null) {
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
final CodegenModel parentCodegenModel = getCodegenModel(codegenModel.parent, parentModel);
if (codegenModel.hasEnums) {
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
}

View File

@@ -226,6 +226,7 @@ public class ElixirClientCodegen extends DefaultCodegen {
typeMapping.put("date", "Date.t");
typeMapping.put("date-time", "DateTime.t");
// other
typeMapping.put("AnyType", "any()");
typeMapping.put("ByteArray", "binary()");
typeMapping.put("DateTime", "DateTime.t");
typeMapping.put("UUID", "String.t");

View File

@@ -17,6 +17,7 @@
package org.openapitools.codegen.languages;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.Iterables;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.Schema;
@@ -440,6 +441,17 @@ public class GoClientCodegen extends AbstractGoCodegen {
return null;
}
if (ModelUtils.isArraySchema(p)) {
StringJoiner joinedDefaultValues = new StringJoiner(", ");
Object defaultValues = p.getDefault();
if (defaultValues instanceof ArrayNode) {
for (var value : (ArrayNode) defaultValues) {
joinedDefaultValues.add(value.toString());
}
return "{" + joinedDefaultValues + "}";
}
}
return super.toDefaultValue(p);
}

View File

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

View File

@@ -187,19 +187,22 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());
supportingFiles.add(new SupportingFile("RestResourceRoot.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestResourceRoot.java")
.doNotOverwrite());
if (!interfaceOnly) {
supportingFiles.add(new SupportingFile("RestResourceRoot.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestResourceRoot.java")
.doNotOverwrite());
supportingFiles.add(new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java")
.doNotOverwrite());
}
if (generatePom) {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")
.doNotOverwrite());
}
supportingFiles.add(new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java")
.doNotOverwrite());
if (StringUtils.isNotEmpty(openApiSpecFileLocation)) {
int index = openApiSpecFileLocation.lastIndexOf('/');
String fileFolder;
@@ -276,6 +279,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
if (!jackson) {
codegenModel.imports.remove("JsonValue");
codegenModel.imports.remove("JsonProperty");
codegenModel.imports.remove("JsonTypeName");
}
return codegenModel;
}

View File

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

View File

@@ -1012,6 +1012,9 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
extensions.add(VendorExtension.X_DISCRIMINATOR_VALUE);
extensions.add(VendorExtension.X_FIELD_EXTRA_ANNOTATION);
extensions.add(VendorExtension.X_PATTERN_MESSAGE);
extensions.add(VendorExtension.X_SIZE_MESSAGE);
extensions.add(VendorExtension.X_MINIMUM_MESSAGE);
extensions.add(VendorExtension.X_MAXIMUM_MESSAGE);
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS);
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS);
return extensions;

View File

@@ -20,7 +20,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
@@ -157,7 +157,8 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
supportedLibraries.put("urllib3", "urllib3-based client");
supportedLibraries.put("asyncio", "asyncio-based client");
supportedLibraries.put("tornado", "tornado-based client (deprecated)");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3");
supportedLibraries.put("httpx", "httpx-based client");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx");
libraryOption.setDefault(DEFAULT_LIBRARY);
cliOptions.add(libraryOption);
setLibrary(DEFAULT_LIBRARY);
@@ -330,10 +331,15 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
if ("asyncio".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("asyncio", "true");
} else if ("tornado".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("tornado", "true");
} else if ("httpx".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("httpx/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("httpx", "true");
} else {
supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py"));
}
@@ -349,7 +355,7 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name, "import", "from")) {
if (Strings.CS.startsWithAny(name, "import", "from")) {
modelImport = name;
} else {
modelImport = "from ";

View File

@@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -89,6 +90,11 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
public PythonFastAPIServerCodegen() {
super();
// Skip sorting of operations to preserve the order found in the OpenAPI spec file. See
// https://fastapi.tiangolo.com/tutorial/path-params/?h=path#order-matters for details on why order matters.
LOGGER.info("Skipping sorting of path operations, order matters, let the developer decide via their specification file.");
setSkipSortingOperations(true);
modifyFeatureSet(features -> features.includeSecurityFeatures(
SecurityFeature.OAuth2_AuthorizationCode,
SecurityFeature.OAuth2_Password
@@ -198,7 +204,7 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name, "import", "from")) {
if (Strings.CS.startsWithAny(name, "import", "from")) {
modelImport = name;
} else {
modelImport = "from ";

View File

@@ -20,6 +20,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Setter;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -353,7 +354,7 @@ public class PythonPydanticV1ClientCodegen extends AbstractPythonPydanticV1Codeg
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name, "import", "from")) {
if (Strings.CS.startsWithAny(name, "import", "from")) {
modelImport = name;
} else {
modelImport = "from ";

View File

@@ -271,6 +271,7 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile("gem.mustache", libFolder, gemName + ".rb"));
String gemFolder = libFolder + File.separator + gemName;
supportingFiles.add(new SupportingFile("api_error.mustache", gemFolder, "api_error.rb"));
supportingFiles.add(new SupportingFile("api_model_base.mustache", gemFolder, "api_model_base.rb"));
supportingFiles.add(new SupportingFile("version.mustache", gemFolder, "version.rb"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));

View File

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

View File

@@ -58,6 +58,7 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
@Setter private boolean preferUnsignedInt = false;
@Setter private boolean bestFitInt = false;
@Setter private boolean avoidBoxedModels = false;
private List<String> reqwestDefaultFeatures = Arrays.asList("native-tls");
public static final String PACKAGE_NAME = "packageName";
public static final String EXTERN_CRATE_NAME = "externCrateName";
@@ -77,6 +78,7 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
public static final String TOP_LEVEL_API_CLIENT = "topLevelApiClient";
public static final String MOCKALL = "mockall";
public static final String BON_BUILDER = "useBonBuilder";
public static final String REQWEST_DEFAULT_FEATURES = "reqwestDefaultFeatures";
@Setter protected String packageName = "openapi";
@Setter protected String packageVersion = "1.0.0";
@@ -227,6 +229,8 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(BON_BUILDER, "Use the bon crate for building parameter types. This option is for the 'reqwest-trait' library only", SchemaTypeUtil.BOOLEAN_TYPE)
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(REQWEST_DEFAULT_FEATURES, "Default features for the reqwest dependency (comma-separated). Use empty for no defaults. This option is for 'reqwest' and 'reqwest-trait' library only.")
.defaultValue("native-tls"));
supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper (v1.x).");
supportedLibraries.put(HYPER0X_LIBRARY, "HTTP client: Hyper (v0.x).");
@@ -307,69 +311,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
mdl.getComposedSchemas().setOneOf(newOneOfs);
}
// Handle anyOf schemas similarly to oneOf
// This is pragmatic since Rust's untagged enum will deserialize to the first matching variant
if (mdl.getComposedSchemas() != null && mdl.getComposedSchemas().getAnyOf() != null
&& !mdl.getComposedSchemas().getAnyOf().isEmpty()) {
List<CodegenProperty> newAnyOfs = mdl.getComposedSchemas().getAnyOf().stream()
.map(CodegenProperty::clone)
.collect(Collectors.toList());
List<Schema> schemas = ModelUtils.getInterfaces(model);
if (newAnyOfs.size() != schemas.size()) {
// For safety reasons, this should never happen unless there is an error in the code
throw new RuntimeException("anyOf size does not match the model");
}
Map<String, String> refsMapping = Optional.ofNullable(model.getDiscriminator())
.map(Discriminator::getMapping).orElse(Collections.emptyMap());
// Reverse mapped references to use as baseName for anyOf, but different keys may point to the same $ref.
// Thus, we group them by the value
Map<String, List<String>> mappedNamesByRef = refsMapping.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
));
for (int i = 0; i < newAnyOfs.size(); i++) {
CodegenProperty anyOf = newAnyOfs.get(i);
Schema schema = schemas.get(i);
if (mappedNamesByRef.containsKey(schema.get$ref())) {
// prefer mapped names if present
// remove mapping not in order not to reuse for the next occurrence of the ref
List<String> names = mappedNamesByRef.get(schema.get$ref());
String mappedName = names.remove(0);
anyOf.setBaseName(mappedName);
anyOf.setName(toModelName(mappedName));
} else if (!org.apache.commons.lang3.StringUtils.isEmpty(schema.get$ref())) {
// use $ref if it's reference
String refName = ModelUtils.getSimpleRef(schema.get$ref());
if (refName != null) {
String modelName = toModelName(refName);
anyOf.setName(modelName);
anyOf.setBaseName(refName);
}
} else if (anyOf.isArray) {
// If the type is an array, extend the name with the inner type to prevent name collisions
// in case multiple arrays with different types are defined. If the user has manually specified
// a name, use that name instead.
String collectionWithTypeName = toModelName(schema.getType()) + anyOf.containerTypeMapped + anyOf.items.dataType;
String anyOfName = Optional.ofNullable(schema.getTitle()).orElse(collectionWithTypeName);
anyOf.setName(anyOfName);
}
else {
// In-placed type (primitive), because there is no mapping or ref for it.
// use camelized `title` if present, otherwise use `type`
String anyOfName = Optional.ofNullable(schema.getTitle()).orElseGet(schema::getType);
anyOf.setName(toModelName(anyOfName));
}
}
// Set anyOf as oneOf for template processing since we want the same output
mdl.getComposedSchemas().setOneOf(newAnyOfs);
}
return mdl;
}
@@ -494,6 +435,21 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
}
writePropertyBack(AVOID_BOXED_MODELS, getAvoidBoxedModels());
if (additionalProperties.containsKey(REQWEST_DEFAULT_FEATURES)) {
Object value = additionalProperties.get(REQWEST_DEFAULT_FEATURES);
if (value instanceof List) {
reqwestDefaultFeatures = (List<String>) value;
} else if (value instanceof String) {
String str = (String) value;
if (str.isEmpty()) {
reqwestDefaultFeatures = new ArrayList<>();
} else {
reqwestDefaultFeatures = Arrays.asList(str.split(",\\s*"));
}
}
}
additionalProperties.put(REQWEST_DEFAULT_FEATURES, reqwestDefaultFeatures);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
additionalProperties.put(EXTERN_CRATE_NAME, getExternCrateName());

View File

@@ -1408,6 +1408,7 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
*
* @deprecated Avoid using this - use a different mechanism instead.
*/
@Deprecated
private static String stripNullable(String type) {
if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) {
return type.substring("swagger::Nullable<".length(), type.length() - 1);

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