Compare commits

..

38 Commits

Author SHA1 Message Date
William Cheng
a022b904e8 update 2026-02-10 20:48:37 +08:00
William Cheng
7c7555cd82 update 2026-02-10 19:02:11 +08:00
William Cheng
e01fd74265 update 2026-02-10 18:59:11 +08:00
William Cheng
c0bf4fa2dd improve api_client in python client 2026-02-10 18:38:41 +08:00
William Cheng
2ee50ce900 Update axios to newer versions (#22937)
* update axios to newer versions

* update
2026-02-10 18:30:52 +08:00
William Cheng
c18015cccd Add petstore tests in groovy workflow (#22936)
* add petstore testsin groovy workflow

* use localhost

* update samples

* update tests

* import

* fix ignore

* update tests

* update tests

* update

* update

* comment out
2026-02-10 17:26:20 +08:00
William Cheng
7eeab03a57 remove coding: utf-8 as thats the default already (#22934) 2026-02-10 16:42:05 +08:00
Miklós Márton
59042aa647 [cpp-qt-client]Prefix signal argument types with namespace (#22921)
For reason see: https://github.com/KDE/clazy/blob/master/docs/checks/README-fully-qualified-moc-types.md

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-09 21:22:37 +08:00
Timon
d81b0524af feat(python): enhance retry configuration in REST client (#22867)
* feat(python): enhance retry configuration in REST client

Updated the retry parameter in the Configuration class to support different types based on the library used (urllib3 or asyncio). Adjusted the RESTClientObject to handle the new retry configuration, allowing for more flexible retry options. This change improves the handling of retries in API requests, ensuring compatibility with various retry strategies.

* add samples

* use async context for retry doc string
2026-02-07 16:38:34 +08:00
Marcel Jacek
54fe232d67 [BUG] [JAVA] validateJsonElement fails for required nullable fields (#22912)
* [Java] add missing nullable judgement when required property is true

* [Java] add okhttp template test and regenerate sample

* [Java] add tests when field is nullable and required

* [Java] regenerate samples to fix pipeline error

* [Java] add JSONTest fro RequiredNullableBody class

* run generate-samples after rebase

* review feedback

* review feedback

* fix test

* update hash of test file

---------

Co-authored-by: weirdo0314 <2019215183@stu.cqupt.edu.cn>
2026-02-07 15:05:12 +08:00
Sri Sushma Karra
459f359bf4 [JAVA][FEIGN] Put back hardcoded HTTP Client but without the performance issue created in 8484. This is fix for 21187 (#22905)
* BUG:21187 put back hardcoded client without the issue created in 8484

* BUG:21187 put back hardcoded client without the issue created in 8484

---------

Co-authored-by: Sri Sushma Karra <srisushmakarra@Sris-MacBook-Air.local>
2026-02-07 00:48:00 +08:00
dependabot[bot]
07d60e010a build(deps): bump webpack from 5.75.0 to 5.105.0 in /website (#22913)
Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.105.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack/compare/v5.75.0...v5.105.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.105.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-07 00:45:54 +08:00
William Cheng
38f0796759 Update jackson-databind-nullable to v0.2.9 (#22901)
* update jackson databind nullable to v0.2.9

* update samples
2026-02-05 16:55:15 +08:00
Alex Humphreys
561e5bf9ab [kotlin][jvm-okhttp4] Fix multipart/form-data with JSON content-type (#22856)
* [kotlin][jvm-okhttp4] Fix multipart/form-data with JSON content-type

Fixes #16457

Fixes two critical bugs in multipart/form-data handling when parts
have Content-Type application/json:

1. IllegalArgumentException: OkHttp throws "Unexpected header: Content-Type"
   because Content-Type was passed in headers map instead of via
   asRequestBody(mediaType)/toRequestBody(mediaType) parameter.

2. Invalid JSON serialization: Non-file parts with application/json
   Content-Type were serialized using toString() instead of proper
   JSON serialization, producing invalid output like:
   "MyObject(field1=value, field2=123)" instead of
   '{"field1":"value","field2":123}'

Changes:
- Filter Content-Type from headers before passing to OkHttp
- Check part Content-Type and use appropriate serializer (JSON vs toString)
- Add integration tests with echo server to verify fix
- Support all serialization libraries (gson, moshi, jackson, kotlinx)

Fixes issues with multipart endpoints that mix file uploads with
JSON metadata, common in REST APIs for document/image uploads.

* Run mvn clean/package, and regenerate samples

* Add fix for kotlinx serialisation issue

* Refactor multipart helpers for reified type parameter support

* Fix kotlinx.serialization multipart by adding serializer lambda to PartConfig

* Fix internal Ktor API usage in multipart forms
2026-02-04 19:44:39 +08:00
Dennis Ameling
9547ebdc98 [typescript] make TypeScript version configurable (#20064) 2026-02-04 19:01:22 +08:00
Dennis Ameling
48b7c85cd4 [kotlin-server] Add polymorphism, oneOf and allOf support (#22610)
* [kotlin-server] Add polymorphism support

* Fix CI triggers

* Fix FILES

* Fix samples and related triggers

* Fix FILES

* Add discriminator property to sealed class

* Fix double nullability issue

* Update samples
2026-02-04 17:02:02 +08:00
Jachym Metlicka
3ecb49060e [JAVA-SPRING;KOTLIN-SPRING] - add possibility to override x-implements and x-kotlin-implements via config options. (#22839)
* feature/add-skip-x-implements

* feature/add-skip-x-implements

* feature/add-x-implements-overrides support in tooling

* add basic unit test for x-implements and x-implements-overrides

* add implementation and unit test for schemaImplements

* add "java.io.Serializable" directly via x-kotlin-implements

* add schemaImplements and schemaImplementsFields support to kotlin-spring

* add xImplementsSkip additional property

* add xKotlinImplementsSkip and xKotlinImplementsFieldsSkip additional properties

* add unit tests

* add documentation

* commit changes and add missing interface

* add documentation

* add output to samples

* change logs

* fix issue #22756

* revert unrelated formatting changes

* nudge test rerun

* implement feedback from CR

* check compilation success

* fix interfaces
2026-02-04 15:57:00 +08:00
William Cheng
40a0f6f83d add dennisameling to TypeScript, Kotlin technical committee (#22894) 2026-02-04 15:37:44 +08:00
Jachym Metlicka
a973d91560 [BUG] [KOTLIN-SPRING] @HttpExchange in declarative interface does not support property placeholders (#22882)
* fix kotlin-spring declarative http interface

* fix kotlin-spring declarative http interface

* fix kotlin-spring declarative http interface
2026-02-04 15:15:16 +08:00
dependabot[bot]
b07f28604e build(deps): bump bytes in /samples/client/others/rust (#22893)
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.5.0 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.5.0...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-04 13:04:51 +08:00
NeedmeFordev
d284a9aef1 fix(spring): Add Nullable import for array-type models (#22788) (#22844)
* fix(spring): Add Nullable import for array-type models (#22788)

* refactor(spring): Extract helper methods for Nullable import logic (DRY)

* chore: Regenerate Spring samples after Nullable import fix

* Update sample files after regeneration

* Fix phpunit.xml.dist: replace literal backslashes with forward slashes in directory paths

* Add JavaDoc comment for addSpringNullableImportForOperation method

* Fix line endings: replace CRLF (\r\n) with LF (\n) in exampleJson string literals

* Remove unused Nullable imports from PR-related Spring sample files

* Revert date/time example value changes (regeneration artifacts)

* Fix: Skip Nullable import for enum models
2026-02-04 13:04:15 +08:00
dependabot[bot]
de3bbd5e4e build(deps): bump eslint and rewire (#22889)
Bumps [eslint](https://github.com/eslint/eslint) to 9.39.2 and updates ancestor dependency [rewire](https://github.com/jhnns/rewire). These dependencies need to be updated together.


Updates `eslint` from 4.19.1 to 9.39.2
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v4.19.1...v9.39.2)

Updates `rewire` from 4.0.1 to 9.0.1
- [Release notes](https://github.com/jhnns/rewire/releases)
- [Changelog](https://github.com/jhnns/rewire/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jhnns/rewire/compare/v4.0.1...v9.0.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.2
  dependency-type: indirect
- dependency-name: rewire
  dependency-version: 9.0.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 23:10:03 +08:00
Kengo Seki
a25bed78cd [BUG] [java-camel] Align pom.xml generation with the documentation (#22888) 2026-02-03 20:48:26 +08:00
William Cheng
aaa3500419 Fix HTML entity encoding in plugins documentation (#22883) 2026-02-03 13:38:03 +08:00
dersvenhesse
7c5f7cf4e5 docs: update useSpringBoot3 note (#22881)
* docs: update useSpringBoot3 note

* chore: moved changes to code classes

* docs: add generated docs

* docs: update java-camel

* docs: ecape ≥
2026-02-03 13:08:48 +08:00
Rens Groothuijsen
2ab70fa46b fix(typescript-axios): Ignore unused parameter on JSON serializer replacer function (#22858) 2026-02-03 13:08:08 +08:00
Pierre Segalen
95911180f6 Fixed TypeScript code generation for oneOf using arrays (#22780) 2026-02-02 13:20:48 +01:00
George Holderness
1cafc1673a fix: apply integer type fitting for Rust params (#22853)
We already have logic in postProcessModelProperty to fit integer
parameters into the correct Rust primitives. However, this doesn't apply
to other kinds of parameters so integer-typed parameters which end up in
function calls for Api traits in lib.rs are always i32, even when this
is improper.

This commit refactors integer type fitting so that we can run it on both
processParam and model post-processing.
2026-02-02 19:53:10 +08:00
dsteeley
268213004e feat: Support selective ssl/tls backend in rust-server to optionally remove openssl (#22825)
* feat: Support selective ssl/tls backend in rust-server to avoid always requiring openssl

* feat: Switch default features so a user must select SSL backend

* Further tweaks to rust-server HTTPS feature flagging
2026-02-02 17:58:32 +08:00
William Cheng
ad2044c581 minor fix using jackson check (#22877) 2026-02-02 17:40:07 +08:00
William Cheng
f3a21a8bba update samples 2026-02-02 16:33:22 +08:00
Luís Cabral
811529cb66 Fix Jackson Serialization of additionalProperties on java and jaxrs-spec (#22366) 2026-02-02 15:47:11 +08:00
dependabot[bot]
883bd56ea9 build(deps): bump diff and mocha (#22875)
Bumps [diff](https://github.com/kpdecker/jsdiff) to 3.5.1 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `diff` from 3.5.0 to 3.5.1
- [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md)
- [Commits](https://github.com/kpdecker/jsdiff/compare/v3.5.0...v3.5.1)

Updates `mocha` from 5.2.0 to 11.7.5
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/v11.7.5/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v5.2.0...v11.7.5)

---
updated-dependencies:
- dependency-name: diff
  dependency-version: 3.5.1
  dependency-type: indirect
- dependency-name: mocha
  dependency-version: 11.7.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-02 15:38:31 +08:00
William Cheng
897590ae6a update undici to newer version in typescript generator (#22874) 2026-02-02 15:26:17 +08:00
dependabot[bot]
3c052d8b64 build(deps): bump eslint and rewire (#22872)
Bumps [eslint](https://github.com/eslint/eslint) to 9.39.2 and updates ancestor dependency [rewire](https://github.com/jhnns/rewire). These dependencies need to be updated together.


Updates `eslint` from 4.19.1 to 9.39.2
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v4.19.1...v9.39.2)

Updates `rewire` from 4.0.1 to 9.0.1
- [Release notes](https://github.com/jhnns/rewire/releases)
- [Changelog](https://github.com/jhnns/rewire/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jhnns/rewire/compare/v4.0.1...v9.0.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.2
  dependency-type: indirect
- dependency-name: rewire
  dependency-version: 9.0.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-02 14:49:58 +08:00
dependabot[bot]
34dc09b676 build(deps-dev): bump tar (#22873)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.6 to 7.5.7.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.6...v7.5.7)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-02 14:49:08 +08:00
dependabot[bot]
f8e1fadf4e build(deps): bump diff and mocha (#22857)
Bumps [diff](https://github.com/kpdecker/jsdiff) to 3.5.1 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `diff` from 3.2.0 to 3.5.1
- [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md)
- [Commits](https://github.com/kpdecker/jsdiff/compare/v3.2.0...v3.5.1)

Updates `mocha` from 3.5.3 to 11.7.5
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/v11.7.5/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v3.5.3...v11.7.5)

---
updated-dependencies:
- dependency-name: diff
  dependency-version: 3.5.1
  dependency-type: indirect
- dependency-name: mocha
  dependency-version: 11.7.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-02 14:48:45 +08:00
William Cheng
41a8573437 remove compiler option from ts fetch test (#22871) 2026-02-02 13:44:35 +08:00
1578 changed files with 35721 additions and 7448 deletions

View File

@@ -20,6 +20,14 @@ jobs:
matrix:
sample:
- samples/client/petstore/groovy
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
- uses: actions/setup-java@v5
@@ -41,6 +49,6 @@ jobs:
gradle-version: ${{ env.GRADLE_VERSION }}
build-root-directory: ${{ matrix.sample }}
arguments: wrapper
- name: Build
- name: Build & Test
working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test
run: ./gradlew build

View File

@@ -14,6 +14,7 @@ on:
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
# servers
- samples/openapi3/server/petstore/springboot-3/**
- samples/server/petstore/springboot-x-implements-skip/**
- samples/server/petstore/java-camel/**
- samples/server/petstore/java-helidon-server/v3/mp/**
- samples/server/petstore/java-helidon-server/v3/se/**
@@ -31,6 +32,7 @@ on:
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
# servers
- samples/openapi3/server/petstore/springboot-3/**
- samples/server/petstore/springboot-x-implements-skip/**
- samples/server/petstore/java-camel/**
- samples/server/petstore/java-helidon-server/v3/mp/**
- samples/server/petstore/java-helidon-server/v3/se/**
@@ -54,6 +56,7 @@ jobs:
- samples/client/petstore/java/microprofile-rest-client-outer-enum
# servers
- samples/openapi3/server/petstore/springboot-3
- samples/server/petstore/springboot-x-implements-skip
- samples/server/petstore/java-camel/
- samples/server/petstore/java-helidon-server/v3/mp/
- samples/server/petstore/java-helidon-server/v3/se

View File

@@ -20,6 +20,7 @@ jobs:
- samples/client/echo_api/kotlin-jvm-spring-3-restclient
- samples/client/echo_api/kotlin-model-prefix-type-mappings
- samples/client/echo_api/kotlin-jvm-okhttp
- samples/client/echo_api/kotlin-jvm-okhttp-multipart-json
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5

View File

@@ -3,6 +3,7 @@ name: Samples Kotlin server (jdk17)
on:
push:
paths:
- 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-springboot-3*/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-modelMutable/**'
@@ -13,6 +14,7 @@ on:
# - samples/server/petstore/kotlin-spring-default/**
pull_request:
paths:
- 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-springboot-3*/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-modelMutable/**'
@@ -34,6 +36,10 @@ jobs:
matrix:
sample:
# server
- samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
- samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
- samples/server/others/kotlin-server/polymorphism-and-discriminator
- samples/server/others/kotlin-server/polymorphism
- samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-3-no-response-entity

View File

@@ -3,10 +3,12 @@ name: Samples Kotlin server (jdk21)
on:
push:
paths:
- 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**'
pull_request:
paths:
- 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**'
@@ -21,6 +23,10 @@ jobs:
fail-fast: false
matrix:
sample:
- samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
- samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
- samples/server/others/kotlin-server/polymorphism-and-discriminator
- samples/server/others/kotlin-server/polymorphism
- samples/server/petstore/kotlin-server/javalin-6
- samples/server/petstore/kotlin-server/ktor
- samples/server/petstore/kotlin-server/ktor2

View File

@@ -64,6 +64,15 @@ jobs:
if cargo read-manifest | grep -q '"validate"'; then
cargo build --features validate --all-targets
fi
# Test TLS features if they exist
if cargo read-manifest | grep -q '"client-tls"'; then
# Client without TLS (HTTP-only)
cargo build --no-default-features --features=client --lib
# Client with TLS (using native-tls)
cargo build --no-default-features --features=client,client-tls --lib
# Server without TLS
cargo build --no-default-features --features=server --lib
fi
cargo fmt
cargo test
cargo clippy

2
.gitignore vendored
View File

@@ -229,7 +229,9 @@ samples/client/petstore/kotlin*/src/main/kotlin/test/
samples/client/petstore/kotlin*/build/
samples/server/others/kotlin-server/jaxrs-spec/build/
samples/client/echo_api/kotlin-jvm-spring-3-restclient/build/
samples/client/echo_api/kotlin-jvm-spring-3-webclient/build/
samples/client/echo_api/kotlin-jvm-okhttp/build/
samples/client/echo_api/kotlin-jvm-okhttp-multipart-json/build/
# haskell
.stack-work

View File

@@ -1260,7 +1260,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| JMeter | @kannkyo (2021/01) |
| Jetbrains HTTP Client | @jlengrand (2023/01) |
| Julia | @tanmaykm (2023/01) |
| Kotlin | @karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) @stefankoppier (2022/06) @e5l (2024/10) |
| Kotlin | @karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) @stefankoppier (2022/06) @e5l (2024/10) @dennisameling (2026/02) |
| Lua | @daurnimator (2017/08) |
| N4JS | @mmews-n4 (2023/03) |
| Nim | |
@@ -1276,7 +1276,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Rust | @frol (2017/07) @farcaller (2017/08) @richardwhiuk (2019/07) @paladinzh (2020/05) @jacob-pro (2022/10) @dsteeley (2025/07) |
| Scala | @clasnake (2017/07), @shijinkui (2018/01), @ramzimaalej (2018/03), @chameleon82 (2020/03), @Bouillie (2020/04) @fish86 (2023/06) |
| Swift | @jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) @4brunu (2019/11) @dydus0x14 (2023/06) |
| TypeScript | @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02) @davidgamero (2022/03) @mkusaka (2022/04) @joscha (2024/10) |
| TypeScript | @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02) @davidgamero (2022/03) @mkusaka (2022/04) @joscha (2024/10) @dennisameling (2026/02) |
| Xojo | @Topheee (2023/04) |

View File

@@ -1,6 +1,6 @@
generatorName: groovy
outputDir: samples/client/petstore/groovy
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/groovy/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/Groovy
additionalProperties:
hideGenerationTimestamp: "true"

View File

@@ -3,13 +3,11 @@ outputDir: samples/server/petstore/java-camel
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/java-camel-server
additionalProperties:
oas3: "true"
hideGenerationTimestamp: true
camelRestBindingMode: "auto"
performBeanValidation: true
#dateLibrary: "java8-localdatetime"
camelDataformatProperties: "json.out.disableFeatures=WRITE_DATES_AS_TIMESTAMPS"
library: "spring-boot"
withXml: true
jackson: true
camelUseDefaultValidationErrorProcessor: true

View File

@@ -0,0 +1,7 @@
generatorName: kotlin-server
outputDir: samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-server
additionalProperties:
artifactId: kotlin-server-polymorphism-allof-and-discriminator
library: javalin6

View File

@@ -0,0 +1,10 @@
generatorName: kotlin-server
outputDir: samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-server
additionalProperties:
artifactId: kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix
library: javalin6
# This is set to "true" by default, but we also want to test the case where it's set to false.
# See KotlinServerCodegen.java for more details about this property.
fixJacksonJsonTypeInfoInheritance: false

View File

@@ -0,0 +1,8 @@
generatorName: kotlin-server
outputDir: samples/server/others/kotlin-server/polymorphism-and-discriminator
inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-server
additionalProperties:
artifactId: kotlin-server-polymorphism-and-discriminator
library: javalin6
fixJacksonJsonTypeInfoInheritance: true

View File

@@ -0,0 +1,7 @@
generatorName: kotlin-server
outputDir: samples/server/others/kotlin-server/polymorphism
inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-server
additionalProperties:
artifactId: kotlin-server-polymorphism
library: javalin6

View File

@@ -13,3 +13,14 @@ additionalProperties:
serializableModel: true
beanValidations: true
includeHttpRequestContext: true
schemaImplements:
Pet: com.some.pack.WithId
Category: [ com.some.pack.CategoryInterface ]
Dog: [ com.some.pack.Canine ]
schemaImplementsFields:
Pet: id
Category: [ name, id ]
Dog: [ bark, breed ]
xKotlinImplementsSkip: [ com.some.pack.WithPhotoUrls ]
xKotlinImplementsFieldsSkip:
Pet: [ photoUrls ]

View File

@@ -13,3 +13,4 @@ additionalProperties:
reactive: false
useResponseEntity: true
useFlowForArrayReturnType: false
requestMappingMode: "api_interface"

View File

@@ -0,0 +1,15 @@
generatorName: spring
outputDir: samples/server/petstore/springboot-x-implements-skip
inputSpec: modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-fake-endpoints-models-for-testing-x-implements.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
documentationProvider: springfox
artifactId: springboot
snapshotVersion: "true"
hideGenerationTimestamp: "true"
camelCaseDollarSign: "true"
modelNameSuffix: 'Dto'
xImplementsSkip: [ com.custompackage.InterfaceToSkip ]
schemaImplements:
Foo: [ com.custompackage.WithBar, com.custompackage.WithDefaultMethod ]
Animal: com.custompackage.WithColor

View File

@@ -2,9 +2,3 @@ generatorName: typescript-fetch
outputDir: samples/client/petstore/typescript-fetch/builds/oneOf
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/oneOf.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
additionalProperties:
npmVersion: 1.0.0
npmName: '@openapitools/typescript-fetch-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -10,7 +10,7 @@
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/ClientTest.java"
sha256: 325fdd5d7e2c97790c0fb44f712ab7b2ba022d7e1a5b0056f47b07f342682b6d
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java"
sha256: 67941355a0a27ed9ff9318b1caa103e78b81b9aff61b594b18be5cd2bb9f6591
sha256: b1b1d31e0df17f0b68cf2747a4a53879f12acb1bf2860e45385c679c1efe9894
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/api/PetApiTest.java"
sha256: 8b1b8f2a2ad00ccb090873a94a5f73e328b98317d2ec715f53bd7a1accb2a023
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java"

View File

@@ -87,6 +87,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|resourceFolder|resource folder for generated resources| |src/main/resources|
|responseWrapper|wrap the responses in given type (Future, Callable, CompletableFuture,ListenableFuture, DeferredResult, RxObservable, RxSingle or fully qualified type)| |null|
|returnSuccessCode|Generated server returns 2xx code| |false|
|schemaImplements|Ability to supply interfaces per schema that should be implemented (serves similar purpose as vendor extension `x-implements`, but is fully decoupled from the api spec). Example: yaml `schemaImplements: {Pet: com.some.pack.WithId, Category: [com.some.pack.CategoryInterface], Dog: [com.some.pack.Canine, com.some.pack.OtherInterface]}` implements interfaces in schemas `Pet` (interface `com.some.pack.WithId`), `Category` (interface `com.some.pack.CategoryInterface`), `Dog`(interfaces `com.some.pack.Canine`, `com.some.pack.OtherInterface`)| |empty map|
|scmConnection|SCM connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmDeveloperConnection|SCM developer connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
@@ -111,13 +112,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useOptional|Use Optional container for optional parameters| |false|
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
|useSealed|Whether to generate sealed model interfaces and classes| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot &ge; 3 (use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringBuiltInValidation|Disable `@Validated` at the class level when using built-in validation.| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|virtualService|Generates the virtual service. For more details refer - https://github.com/virtualansoftware/virtualan/wiki| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|xImplementsSkip|Ability to choose interfaces that should NOT be implemented in the models despite their presence in vendor extension `x-implements`. Takes a list of fully qualified interface names. Example: yaml `xImplementsSkip: [com.some.pack.WithPhotoUrls]` skips implementing the interface `com.some.pack.WithPhotoUrls` in any schema| |empty list|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -30,6 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true|
|featureMetrics|Enables metrics feature.| |true|
|featureResources|Generates routes in a typed way, for both: constructing URLs and reading the parameters.| |true|
|fixJacksonJsonTypeInfoInheritance|When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property.| |true|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|interfaceOnly|Whether to generate only API interface stubs without the server files. This option is currently supported only when using jaxrs-spec library.| |false|
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd><dt>**ktor2**</dt><dd>ktor (2.x) framework</dd><dt>**jaxrs-spec**</dt><dd>JAX-RS spec only</dd><dt>**javalin5**</dt><dd>Javalin 5</dd><dt>**javalin6**</dt><dd>Javalin 6</dd></dl>|ktor|
@@ -262,11 +263,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism||OAS2,OAS3
|Polymorphism||OAS2,OAS3
|Union|✗|OAS3
|allOf||OAS2,OAS3
|allOf||OAS2,OAS3
|anyOf|✗|OAS3
|oneOf||OAS3
|oneOf||OAS3
|not|✗|OAS3
### Security Feature

View File

@@ -43,6 +43,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|reactive|use coroutines for reactive behavior| |false|
|requestMappingMode|Where to generate the class level @RequestMapping annotation.|<dl><dt>**api_interface**</dt><dd>Generate the @RequestMapping annotation on the generated Api Interface.</dd><dt>**controller**</dt><dd>Generate the @RequestMapping annotation on the generated Api Controller Implementation.</dd><dt>**none**</dt><dd>Do not add a class level @RequestMapping annotation.</dd></dl>|controller|
|schemaImplements|A map of single interface or a list of interfaces per schema name that should be implemented (serves similar purpose as `x-kotlin-implements`, but is fully decoupled from the api spec). Example: yaml `schemaImplements: {Pet: com.some.pack.WithId, Category: [com.some.pack.CategoryInterface], Dog: [com.some.pack.Canine, com.some.pack.OtherInterface]}` implements interfaces in schemas `Pet` (interface `com.some.pack.WithId`), `Category` (interface `com.some.pack.CategoryInterface`), `Dog`(interfaces `com.some.pack.Canine`, `com.some.pack.OtherInterface`)| |empty map|
|schemaImplementsFields|A map of single field or a list of fields per schema name that should be prepended with `override` (serves similar purpose as `x-kotlin-implements-fields`, but is fully decoupled from the api spec). Example: yaml `schemaImplementsFields: {Pet: id, Category: [name, id], Dog: [bark, breed]}` marks fields to be prepended with `override` in schemas `Pet` (field `id`), `Category` (fields `name`, `id`) and `Dog` (fields `bark`, `breed`)| |empty map|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |null|
|serverPort|configuration the port in which the sever is to run on| |8080|
|serviceImplementation|generate stub service implementations that extends service interfaces. If this is set to true service interfaces will also be generated| |false|
@@ -56,9 +58,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useFlowForArrayReturnType|Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.| |true|
|useResponseEntity|Whether (when false) to return actual type (e.g. List&lt;Fruit&gt;) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity&lt;List&lt;Fruit&gt;&gt;). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot &ge; 3 (use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|Whether to use tags for creating interface and controller class names| |false|
|xKotlinImplementsFieldsSkip|A list of fields per schema name that should NOT be created with `override` keyword despite their presence in vendor extension `x-kotlin-implements-fields` for the schema. Example: yaml `xKotlinImplementsFieldsSkip: Pet: [photoUrls]` skips `override` for `photoUrls` in schema `Pet`| |empty map|
|xKotlinImplementsSkip|A list of fully qualified interfaces that should NOT be implemented despite their presence in vendor extension `x-kotlin-implements`. Example: yaml `xKotlinImplementsSkip: [com.some.pack.WithPhotoUrls]` skips implementing the interface in any schema| |empty list|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -80,6 +80,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|resourceFolder|resource folder for generated resources| |src/main/resources|
|responseWrapper|wrap the responses in given type (Future, Callable, CompletableFuture,ListenableFuture, DeferredResult, RxObservable, RxSingle or fully qualified type)| |null|
|returnSuccessCode|Generated server returns 2xx code| |false|
|schemaImplements|Ability to supply interfaces per schema that should be implemented (serves similar purpose as vendor extension `x-implements`, but is fully decoupled from the api spec). Example: yaml `schemaImplements: {Pet: com.some.pack.WithId, Category: [com.some.pack.CategoryInterface], Dog: [com.some.pack.Canine, com.some.pack.OtherInterface]}` implements interfaces in schemas `Pet` (interface `com.some.pack.WithId`), `Category` (interface `com.some.pack.CategoryInterface`), `Dog`(interfaces `com.some.pack.Canine`, `com.some.pack.OtherInterface`)| |empty map|
|scmConnection|SCM connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmDeveloperConnection|SCM developer connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
@@ -104,13 +105,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useOptional|Use Optional container for optional parameters| |false|
|useResponseEntity|Use the `ResponseEntity` type to wrap return values of generated API methods. If disabled, method are annotated using a `@ResponseStatus` annotation, which has the status of the first response declared in the Api definition| |true|
|useSealed|Whether to generate sealed model interfaces and classes| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot &ge; 3 (use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringBuiltInValidation|Disable `@Validated` at the class level when using built-in validation.| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|virtualService|Generates the virtual service. For more details refer - https://github.com/virtualansoftware/virtualan/wiki| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|xImplementsSkip|Ability to choose interfaces that should NOT be implemented in the models despite their presence in vendor extension `x-implements`. Takes a list of fully qualified interface names. Example: yaml `xImplementsSkip: [com.some.pack.WithPhotoUrls]` skips implementing the interface `com.some.pack.WithPhotoUrls` in any schema| |empty list|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -20,7 +20,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|apiPackage|package for generated api classes| |null|
|axiosVersion|Use this property to override the axios version in package.json| |^1.6.1|
|axiosVersion|Use this property to override the axios version in package.json| |^1.13.5|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumNameSuffix|Suffix that will be appended to all enum names.| |Enum|

View File

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

View File

@@ -162,8 +162,8 @@ This gives access to the following tasks:
| Task | Description |
|---------------------------|---------------------------------------------------------------------------------------------|
| <configName>.generate | Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents. |
| <configName>.validateSpec | Validates the configured spec |
| &lt;configName&gt;.generate | Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents. |
| &lt;configName&gt;.validateSpec | Validates the configured spec |
and a command

View File

@@ -112,6 +112,10 @@ public class CliOption {
return new CliOption(opt, description, SchemaTypeUtil.STRING_TYPE);
}
public static CliOption newString(String opt, String description, String defaultValue) {
return new CliOption(opt, description, SchemaTypeUtil.STRING_TYPE).defaultValue(String.valueOf(defaultValue));
}
@JsonIgnore
public String getOptionHelp() {
StringBuilder sb = new StringBuilder(description);

View File

@@ -94,8 +94,11 @@ import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*;
public class DefaultCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
public static final Pattern SPLIT_ON_SEMICOLON_OR_NEWLINE_REGEX = Pattern.compile("\\s*(;|\\r?\\n)\\s*"); // Splits on semicolon or new line, ignoring surrounding whitespace
public static FeatureSet DefaultFeatureSet;
// A cache of sanitized words. The sanitizeName() method is invoked many times with the same
@@ -190,15 +193,20 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> operationIdNameMapping = new HashMap<>();
// a map to store the rules in OpenAPI Normalizer
protected Map<String, String> openapiNormalizer = new HashMap<>();
@Setter protected String modelPackage = "", apiPackage = "";
@Setter
protected String modelPackage = "", apiPackage = "";
protected String fileSuffix;
@Getter @Setter
@Getter
@Setter
protected String modelNamePrefix = "", modelNameSuffix = "";
@Getter @Setter
@Getter
@Setter
protected String apiNamePrefix = "", apiNameSuffix = "Api";
protected String testPackage = "";
@Setter protected String filesMetadataFilename = "FILES";
@Setter protected String versionMetadataFilename = "VERSION";
@Setter
protected String filesMetadataFilename = "FILES";
@Setter
protected String versionMetadataFilename = "VERSION";
/*
apiTemplateFiles are for API outputs only (controllers/handlers).
API templates may be written multiple times; APIs are grouped by tag and the file is written once per tag group.
@@ -210,7 +218,8 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> apiDocTemplateFiles = new HashMap<>();
protected Map<String, String> modelDocTemplateFiles = new HashMap<>();
protected Map<String, String> reservedWordsMappings = new HashMap<>();
@Setter protected String templateDir;
@Setter
protected String templateDir;
protected String embeddedTemplateDir;
protected Map<String, Object> additionalProperties = new HashMap<>();
protected Map<String, String> serverVariables = new HashMap<>();
@@ -225,9 +234,11 @@ public class DefaultCodegen implements CodegenConfig {
protected List<CliOption> cliOptions = new ArrayList<>();
protected boolean skipOverwrite;
protected boolean removeOperationIdPrefix;
@Getter @Setter
@Getter
@Setter
protected String removeOperationIdPrefixDelimiter = "_";
@Getter @Setter
@Getter
@Setter
protected int removeOperationIdPrefixCount = 1;
protected boolean skipOperationExample;
// sort operations by default
@@ -262,13 +273,17 @@ public class DefaultCodegen implements CodegenConfig {
protected boolean supportsMixins;
protected Map<String, String> supportedLibraries = new LinkedHashMap<>();
protected String library;
@Getter @Setter
@Getter
@Setter
protected Boolean sortParamsByRequiredFlag = true;
@Getter @Setter
@Getter
@Setter
protected Boolean sortModelPropertiesByRequiredFlag = false;
@Getter @Setter
@Getter
@Setter
protected Boolean ensureUniqueParams = true;
@Getter @Setter
@Getter
@Setter
protected Boolean allowUnicodeIdentifiers = false;
protected String gitHost, gitUserId, gitRepoId, releaseNote;
protected String httpUserAgent;
@@ -279,7 +294,8 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> specialCharReplacements = new LinkedHashMap<>();
// When a model is an alias for a simple type
protected Map<String, String> typeAliases = Collections.emptyMap();
@Getter @Setter
@Getter
@Setter
protected Boolean prependFormOrBodyParameters = false;
// The extension of the generated documentation files (defaults to markdown .md)
protected String docExtension;
@@ -302,15 +318,18 @@ public class DefaultCodegen implements CodegenConfig {
protected boolean removeEnumValuePrefix = false;
// Support legacy logic for evaluating discriminators
@Setter protected boolean legacyDiscriminatorBehavior = true;
@Setter
protected boolean legacyDiscriminatorBehavior = true;
// Specify what to do if the 'additionalProperties' keyword is not present in a schema.
// See CodegenConstants.java for more details.
@Setter protected boolean disallowAdditionalPropertiesIfNotPresent = true;
@Setter
protected boolean disallowAdditionalPropertiesIfNotPresent = true;
// If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.
// With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.
@Setter protected boolean enumUnknownDefaultCase = false;
@Setter
protected boolean enumUnknownDefaultCase = false;
protected String enumUnknownDefaultCaseName = "unknown_default_open_api";
// make openapi available to all methods
@@ -333,11 +352,18 @@ public class DefaultCodegen implements CodegenConfig {
protected boolean addSuffixToDuplicateOperationNicknames = true;
// Whether to automatically hardcode params that are considered Constants by OpenAPI Spec
@Setter protected boolean autosetConstants = false;
@Setter
protected boolean autosetConstants = false;
@Setter @Getter boolean arrayDefaultToEmpty, arrayNullableDefaultToEmpty, arrayOptionalNullableDefaultToEmpty, arrayOptionalDefaultToEmpty;
@Setter @Getter boolean mapDefaultToEmpty, mapNullableDefaultToEmpty, mapOptionalNullableDefaultToEmpty, mapOptionalDefaultToEmpty;
@Setter @Getter protected boolean defaultToEmptyContainer;
@Setter
@Getter
boolean arrayDefaultToEmpty, arrayNullableDefaultToEmpty, arrayOptionalNullableDefaultToEmpty, arrayOptionalDefaultToEmpty;
@Setter
@Getter
boolean mapDefaultToEmpty, mapNullableDefaultToEmpty, mapOptionalNullableDefaultToEmpty, mapOptionalDefaultToEmpty;
@Setter
@Getter
protected boolean defaultToEmptyContainer;
final List EMPTY_LIST = new ArrayList();
@@ -572,7 +598,7 @@ public class DefaultCodegen implements CodegenConfig {
? false
: model.parentModel.allVars.stream().anyMatch(p ->
p.name.equals(property.name) &&
(p.dataType.equals(property.dataType) == false || p.datatypeWithEnum.equals(property.datatypeWithEnum) == false));
(p.dataType.equals(property.dataType) == false || p.datatypeWithEnum.equals(property.datatypeWithEnum) == false));
}
/**
@@ -716,7 +742,7 @@ public class DefaultCodegen implements CodegenConfig {
for (CodegenProperty cp : model.allVars) {
// detect self import
if (cp.dataType.equalsIgnoreCase(model.classname) ||
(cp.isContainer && cp.items != null && cp.items.dataType.equalsIgnoreCase(model.classname))) {
(cp.isContainer && cp.items != null && cp.items.dataType.equalsIgnoreCase(model.classname))) {
model.imports.remove(model.classname); // remove self import
cp.isSelfReference = true;
}
@@ -758,7 +784,7 @@ public class DefaultCodegen implements CodegenConfig {
}
private void setCircularReferencesOnProperties(final String root,
final Map<String, List<CodegenProperty>> dependencyMap) {
final Map<String, List<CodegenProperty>> dependencyMap) {
dependencyMap.getOrDefault(root, new ArrayList<>())
.forEach(prop -> {
final List<String> unvisited =
@@ -771,9 +797,9 @@ public class DefaultCodegen implements CodegenConfig {
}
private boolean isCircularReference(final String root,
final Set<String> visited,
final List<String> unvisited,
final Map<String, List<CodegenProperty>> dependencyMap) {
final Set<String> visited,
final List<String> unvisited,
final Map<String, List<CodegenProperty>> dependencyMap) {
for (int i = 0; i < unvisited.size(); i++) {
final String next = unvisited.get(i);
if (!visited.contains(next)) {
@@ -1162,7 +1188,6 @@ public class DefaultCodegen implements CodegenConfig {
return escapeText(input).replace("'", "\\'");
}
/**
* Escape characters while allowing new lines
*
@@ -1206,7 +1231,7 @@ public class DefaultCodegen implements CodegenConfig {
@Override
public String escapeUnsafeCharacters(String input) {
LOGGER.warn("escapeUnsafeCharacters should be overridden in the code generator with proper logic to escape " +
"unsafe characters");
"unsafe characters");
// doing nothing by default and code generator should implement
// the logic to prevent code injection
// later we'll make this method abstract to make sure
@@ -1223,7 +1248,7 @@ public class DefaultCodegen implements CodegenConfig {
@Override
public String escapeQuotationMark(String input) {
LOGGER.warn("escapeQuotationMark should be overridden in the code generator with proper logic to escape " +
"single/double quote");
"single/double quote");
return input.replace("\"", "\\\"");
}
@@ -1801,7 +1826,8 @@ public class DefaultCodegen implements CodegenConfig {
CliOption legacyDiscriminatorBehaviorOpt = CliOption.newBoolean(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR, CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR_DESC).defaultValue(Boolean.TRUE.toString());
Map<String, String> legacyDiscriminatorBehaviorOpts = new HashMap<>();
legacyDiscriminatorBehaviorOpts.put("true", "The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.");
legacyDiscriminatorBehaviorOpts.put("false", "The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.");
legacyDiscriminatorBehaviorOpts.put("false",
"The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.");
legacyDiscriminatorBehaviorOpt.setEnum(legacyDiscriminatorBehaviorOpts);
cliOptions.add(legacyDiscriminatorBehaviorOpt);
@@ -2285,7 +2311,6 @@ public class DefaultCodegen implements CodegenConfig {
}
protected Schema<?> getSchemaAdditionalProperties(Schema schema) {
Schema<?> inner = ModelUtils.getAdditionalProperties(schema);
if (inner == null) {
@@ -2359,7 +2384,7 @@ public class DefaultCodegen implements CodegenConfig {
return ModelUtils.unaliasSchema(this.openAPI, schema, schemaMapping);
}
private List<Map<String, Object>> unaliasExamples(Map<String, Example> examples){
private List<Map<String, Object>> unaliasExamples(Map<String, Example> examples) {
return ExamplesUtils.unaliasExamples(this.openAPI, examples);
}
@@ -2631,6 +2656,7 @@ public class DefaultCodegen implements CodegenConfig {
}
private static class NamedSchema {
private NamedSchema(String name, Schema s, boolean required, boolean schemaIsFromAdditionalProperties) {
this.name = name;
this.schema = s;
@@ -2645,13 +2671,15 @@ public class DefaultCodegen implements CodegenConfig {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
NamedSchema that = (NamedSchema) o;
return Objects.equals(required, that.required) &&
Objects.equals(name, that.name) &&
Objects.equals(schema, that.schema) &&
Objects.equals(schemaIsFromAdditionalProperties, that.schemaIsFromAdditionalProperties);
Objects.equals(name, that.name) &&
Objects.equals(schema, that.schema) &&
Objects.equals(schemaIsFromAdditionalProperties, that.schemaIsFromAdditionalProperties);
}
@Override
@@ -2673,7 +2701,7 @@ public class DefaultCodegen implements CodegenConfig {
if (composed.getProperties() != null && !composed.getProperties().isEmpty()) {
if (composed.getOneOf() != null && !composed.getOneOf().isEmpty()) {
LOGGER.warn("'oneOf' is intended to include only the additional optional OAS extension discriminator object. " +
"For more details, see https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 and the OAS section on 'Composition and Inheritance'.");
"For more details, see https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 and the OAS section on 'Composition and Inheritance'.");
}
addVars(m, unaliasPropertySchema(composed.getProperties()), composed.getRequired(), null, null);
}
@@ -3068,7 +3096,7 @@ public class DefaultCodegen implements CodegenConfig {
m.getVendorExtensions().putAll(schema.getExtensions());
}
m.isAlias = (typeAliases.containsKey(name)
|| isAliasOfSimpleTypes(schema)); // check if the unaliased schema is an alias of simple OAS types
|| isAliasOfSimpleTypes(schema)); // check if the unaliased schema is an alias of simple OAS types
m.setDiscriminator(createDiscriminator(name, schema));
if (schema.getDeprecated() != null) {
@@ -3439,7 +3467,7 @@ public class DefaultCodegen implements CodegenConfig {
}
if (discriminatorsPropNames.size() > 1) {
once(LOGGER).warn("The oneOf schemas have conflicting discriminator property names. " +
"oneOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
"oneOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
}
if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getOneOf().size() && discriminatorsPropNames.size() == 1) {
disc.setPropertyName(foundDisc.getPropertyName());
@@ -3468,7 +3496,7 @@ public class DefaultCodegen implements CodegenConfig {
}
if (discriminatorsPropNames.size() > 1) {
once(LOGGER).warn("The anyOf schemas have conflicting discriminator property names. " +
"anyOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
"anyOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
}
if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getAnyOf().size() && discriminatorsPropNames.size() == 1) {
disc.setPropertyName(foundDisc.getPropertyName());
@@ -3667,7 +3695,7 @@ public class DefaultCodegen implements CodegenConfig {
boolean matched = false;
for (MappedModel uniqueDescendant : uniqueDescendants) {
if (uniqueDescendant.getMappingName().equals(otherDescendant.getMappingName())
|| (uniqueDescendant.getModelName().equals(otherDescendant.getModelName()))) {
|| (uniqueDescendant.getModelName().equals(otherDescendant.getModelName()))) {
matched = true;
break;
}
@@ -3865,9 +3893,9 @@ public class DefaultCodegen implements CodegenConfig {
}
property.isNullable = property.isNullable ||
!(ModelUtils.isComposedSchema(p)) ||
p.getAllOf() == null ||
p.getAllOf().size() == 0;
!(ModelUtils.isComposedSchema(p)) ||
p.getAllOf() == null ||
p.getAllOf().size() == 0;
if (languageSpecificPrimitives.contains(property.dataType)) {
property.isPrimitiveType = true;
}
@@ -3943,7 +3971,6 @@ public class DefaultCodegen implements CodegenConfig {
return fromProperty(name, p, required, false);
}
/**
* TODO remove this in 7.0.0 as a breaking change
* This method was kept when required was added to the fromProperty signature
@@ -4124,7 +4151,7 @@ public class DefaultCodegen implements CodegenConfig {
if (referencedSchema.getNullable() != null) {
property.isNullable = referencedSchema.getNullable();
} else if (referencedSchema.getExtensions() != null &&
referencedSchema.getExtensions().containsKey(X_NULLABLE)) {
referencedSchema.getExtensions().containsKey(X_NULLABLE)) {
property.isNullable = (Boolean) referencedSchema.getExtensions().get(X_NULLABLE);
}
@@ -4208,9 +4235,9 @@ public class DefaultCodegen implements CodegenConfig {
}
boolean isAnyTypeWithNothingElseSet = (ModelUtils.isAnyType(p) &&
(p.getProperties() == null || p.getProperties().isEmpty()) &&
!ModelUtils.isComposedSchema(p) &&
p.getAdditionalProperties() == null && p.getNot() == null && p.getEnum() == null);
(p.getProperties() == null || p.getProperties().isEmpty()) &&
!ModelUtils.isComposedSchema(p) &&
p.getAdditionalProperties() == null && p.getNot() == null && p.getEnum() == null);
if (!ModelUtils.isArraySchema(p) && !ModelUtils.isMapSchema(p) && !ModelUtils.isFreeFormObject(p, openAPI) && !isAnyTypeWithNothingElseSet) {
/* schemas that are not Array, not ModelUtils.isMapSchema, not isFreeFormObject, not AnyType with nothing else set
@@ -4289,7 +4316,7 @@ public class DefaultCodegen implements CodegenConfig {
* update container's default to empty container according rules provided by the user.
*
* @param cp codegen property
* @param p schema
* @param p schema
*/
void updateDefaultToEmptyContainer(CodegenProperty cp, Schema p) {
if (cp.isArray) {
@@ -4331,7 +4358,7 @@ public class DefaultCodegen implements CodegenConfig {
void parseDefaultToEmptyContainer(String input) {
String[] inputs = ((String) input).split("[|]");
String containerType;
for (String rule: inputs) {
for (String rule : inputs) {
if (StringUtils.isEmpty(rule)) {
LOGGER.error("updateDefaultToEmptyContainer: Skipped empty input in `{}`.", input);
continue;
@@ -4356,7 +4383,7 @@ public class DefaultCodegen implements CodegenConfig {
LOGGER.error("Skipped invalid container type `{}` in `{}`.", containerType, input);
}
} else if (rule.endsWith("?")) { // optional
containerType = rule.substring(0, rule.length()-1);
containerType = rule.substring(0, rule.length() - 1);
if ("array".equalsIgnoreCase(containerType)) {
arrayOptionalDefaultToEmpty = true;
} else if ("map".equalsIgnoreCase(containerType)) {
@@ -4466,7 +4493,7 @@ public class DefaultCodegen implements CodegenConfig {
protected CodegenProperty getMostInnerItems(CodegenProperty property) {
CodegenProperty currentProperty = property;
while (currentProperty != null && (Boolean.TRUE.equals(currentProperty.isMap)
|| Boolean.TRUE.equals(currentProperty.isArray)) && currentProperty.items != null) {
|| Boolean.TRUE.equals(currentProperty.isArray)) && currentProperty.items != null) {
currentProperty = currentProperty.items;
}
return currentProperty;
@@ -4486,7 +4513,7 @@ public class DefaultCodegen implements CodegenConfig {
protected void updateDataTypeWithEnumForArray(CodegenProperty property) {
CodegenProperty baseItem = property.items;
while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap)
|| Boolean.TRUE.equals(baseItem.isArray))) {
|| Boolean.TRUE.equals(baseItem.isArray))) {
baseItem = baseItem.items;
}
if (baseItem != null) {
@@ -4514,7 +4541,7 @@ public class DefaultCodegen implements CodegenConfig {
protected void updateDataTypeWithEnumForMap(CodegenProperty property) {
CodegenProperty baseItem = property.items;
while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap)
|| Boolean.TRUE.equals(baseItem.isArray))) {
|| Boolean.TRUE.equals(baseItem.isArray))) {
baseItem = baseItem.items;
}
@@ -4575,9 +4602,9 @@ public class DefaultCodegen implements CodegenConfig {
* @param methodResponse the default ApiResponse for the endpoint
*/
protected void handleMethodResponse(Operation operation,
Map<String, Schema> schemas,
CodegenOperation op,
ApiResponse methodResponse) {
Map<String, Schema> schemas,
CodegenOperation op,
ApiResponse methodResponse) {
handleMethodResponse(operation, schemas, op, methodResponse, Collections.emptyMap());
}
@@ -4591,10 +4618,10 @@ public class DefaultCodegen implements CodegenConfig {
* @param schemaMappings mappings of external types to be omitted by unaliasing
*/
protected void handleMethodResponse(Operation operation,
Map<String, Schema> schemas,
CodegenOperation op,
ApiResponse methodResponse,
Map<String, String> schemaMappings) {
Map<String, Schema> schemas,
CodegenOperation op,
ApiResponse methodResponse,
Map<String, String> schemaMappings) {
ApiResponse response = ModelUtils.getReferencedApiResponse(openAPI, methodResponse);
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, response));
@@ -4663,9 +4690,9 @@ public class DefaultCodegen implements CodegenConfig {
*/
@Override
public CodegenOperation fromOperation(String path,
String httpMethod,
Operation operation,
List<Server> servers) {
String httpMethod,
Operation operation,
List<Server> servers) {
LOGGER.debug("fromOperation => operation: {}", operation);
if (operation == null)
throw new RuntimeException("operation cannot be null in fromOperation");
@@ -4733,8 +4760,8 @@ public class DefaultCodegen implements CodegenConfig {
r.setContent(getContent(response.getContent(), imports, mediaTypeSchemaSuffix));
if (r.baseType != null &&
!defaultIncludes.contains(r.baseType) &&
!languageSpecificPrimitives.contains(r.baseType)) {
!defaultIncludes.contains(r.baseType) &&
!languageSpecificPrimitives.contains(r.baseType)) {
imports.add(r.baseType);
}
@@ -4756,14 +4783,14 @@ public class DefaultCodegen implements CodegenConfig {
// check if any 4xx or 5xx response has an error response object defined
if ((Boolean.TRUE.equals(r.is4xx) || Boolean.TRUE.equals(r.is5xx)) &&
Boolean.FALSE.equals(r.primitiveType) && Boolean.FALSE.equals(r.simpleType)) {
Boolean.FALSE.equals(r.primitiveType) && Boolean.FALSE.equals(r.simpleType)) {
op.hasErrorResponseObject = Boolean.TRUE;
}
}
// check if the operation can both return a 2xx response with a body and without
if (op.responses.stream().anyMatch(response -> response.is2xx && response.dataType != null) &&
op.responses.stream().anyMatch(response -> response.is2xx && response.dataType == null)) {
op.responses.stream().anyMatch(response -> response.is2xx && response.dataType == null)) {
op.isResponseOptional = Boolean.TRUE;
}
@@ -4836,8 +4863,8 @@ public class DefaultCodegen implements CodegenConfig {
contentType = contentType.toLowerCase(Locale.ROOT);
}
if (contentType != null &&
((!(this instanceof RustAxumServerCodegen) && contentType.startsWith("application/x-www-form-urlencoded")) ||
contentType.startsWith("multipart"))) {
((!(this instanceof RustAxumServerCodegen) && contentType.startsWith("application/x-www-form-urlencoded")) ||
contentType.startsWith("multipart"))) {
// process form parameters
formParams = fromRequestBodyToFormParameters(requestBody, imports);
op.isMultipart = contentType.startsWith("multipart");
@@ -5027,23 +5054,23 @@ public class DefaultCodegen implements CodegenConfig {
r.code = responseCode;
switch (r.code.charAt(0)) {
case '1':
r.is1xx = true;
break;
case '2':
r.is2xx = true;
break;
case '3':
r.is3xx = true;
break;
case '4':
r.is4xx = true;
break;
case '5':
r.is5xx = true;
break;
default:
throw new RuntimeException("Invalid response code " + responseCode);
case '1':
r.is1xx = true;
break;
case '2':
r.is2xx = true;
break;
case '3':
r.is3xx = true;
break;
case '4':
r.is4xx = true;
break;
case '5':
r.is5xx = true;
break;
default:
throw new RuntimeException("Invalid response code " + responseCode);
}
}
@@ -5273,7 +5300,6 @@ public class DefaultCodegen implements CodegenConfig {
LOGGER.debug("debugging codegenParameter return: {}", codegenParameter);
}
private void updateParameterForMap(CodegenParameter codegenParameter, Schema parameterSchema, Set<String> imports) {
CodegenProperty codegenProperty = fromProperty("inner", ModelUtils.getAdditionalProperties(parameterSchema), false);
codegenParameter.items = codegenProperty;
@@ -5853,7 +5879,7 @@ public class DefaultCodegen implements CodegenConfig {
*/
protected boolean needToImport(String type) {
return StringUtils.isNotBlank(type) && !defaultIncludes.contains(type)
&& !languageSpecificPrimitives.contains(type);
&& !languageSpecificPrimitives.contains(type);
}
@SuppressWarnings("static-method")
@@ -6062,7 +6088,7 @@ public class DefaultCodegen implements CodegenConfig {
}
protected void addVars(CodegenModel m, Map<String, Schema> properties, List<String> required,
Map<String, Schema> allProperties, List<String> allRequired) {
Map<String, Schema> allProperties, List<String> allRequired) {
m.hasRequired = false;
m.hasReadOnly = false;
@@ -6265,7 +6291,7 @@ public class DefaultCodegen implements CodegenConfig {
// allOf with a single item
if (schema.getAllOf() != null && schema.getAllOf().size() == 1
&& schema.getAllOf().get(0) instanceof Schema) {
&& schema.getAllOf().get(0) instanceof Schema) {
schema = unaliasSchema((Schema) schema.getAllOf().get(0));
schema = ModelUtils.getReferencedSchema(this.openAPI, schema);
}
@@ -7040,7 +7066,6 @@ public class DefaultCodegen implements CodegenConfig {
return result;
}
/**
* reads propertyKey from additionalProperties, converts it to a boolean and
* writes it back to additionalProperties to be usable as a boolean in
@@ -7115,6 +7140,69 @@ public class DefaultCodegen implements CodegenConfig {
this.ignoreFilePathOverride = ignoreFileOverride;
}
public List<String> getPropertyAsStringList(String propertyKey) {
final Object value = additionalProperties.get(propertyKey);
return getObjectAsStringList(value);
}
public static List<String> getObjectAsStringList(Object value) {
if (value instanceof List) {
List<?> list = (List<?>) value;
List<String> stringList = new ArrayList<>();
for (Object item : list) {
if (item != null) {
stringList.add(item.toString());
}
}
return stringList;
} else if (value instanceof String) {
return Collections.singletonList((String) value);
}
return Collections.emptyList();
}
public Map<String, String> getPropertyAsStringMap(String propertyKey) {
final Object value = additionalProperties.get(propertyKey);
return getObjectAsStringMap(value);
}
public static Map<String, String> getObjectAsStringMap(Object value) {
if (value instanceof Map) {
Map<?, ?> rawMap = (Map<?, ?>) value;
Map<String, String> stringMap = new HashMap<>();
for (Entry<?, ?> entry : rawMap.entrySet()) {
stringMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
}
return stringMap;
}
return Collections.emptyMap();
}
public Map<String, List<String>> getPropertyAsStringListMap(String propertyKey) {
final Object value = additionalProperties.get(propertyKey);
return getObjectAsStringListMap(value);
}
public static Map<String, List<String>> getObjectAsStringListMap(Object value) {
if (value instanceof Map) {
Map<?, ?> rawMap = (Map<?, ?>) value;
Map<String, List<String>> stringMap = new HashMap<>();
for (Entry<?, ?> entry : rawMap.entrySet()) {
Object entryValue = entry.getValue();
if (entryValue instanceof List) {
List<String> stringList = ((List<?>) entryValue).stream()
.map(String::valueOf)
.collect(Collectors.toList());
stringMap.put(String.valueOf(entry.getKey()), stringList);
} else {
stringMap.put(String.valueOf(entry.getKey()), Collections.singletonList(String.valueOf(entryValue)));
}
}
return stringMap;
}
return Collections.emptyMap();
}
public boolean convertPropertyToBoolean(String propertyKey) {
final Object booleanValue = additionalProperties.get(propertyKey);
boolean result = Boolean.FALSE;
@@ -7218,8 +7306,8 @@ public class DefaultCodegen implements CodegenConfig {
for (String consume : consumesInfo) {
if (consume != null &&
(consume.toLowerCase(Locale.ROOT).startsWith("application/x-www-form-urlencoded") ||
consume.toLowerCase(Locale.ROOT).startsWith("multipart"))) {
(consume.toLowerCase(Locale.ROOT).startsWith("application/x-www-form-urlencoded") ||
consume.toLowerCase(Locale.ROOT).startsWith("multipart"))) {
return true;
}
}
@@ -7338,7 +7426,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema original = null;
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
if (schema.getAllOf().get(0) instanceof Schema) {
original = schema;
schema = (Schema) schema.getAllOf().get(0);
@@ -7630,9 +7718,9 @@ public class DefaultCodegen implements CodegenConfig {
codegenModelDescription = codegenModel.description;
} else {
LOGGER.warn("The following schema has undefined (null) baseType. " +
"It could be due to form parameter defined in OpenAPI v2 spec with incorrect consumes. " +
"A correct 'consumes' for form parameters should be " +
"'application/x-www-form-urlencoded' or 'multipart/?'");
"It could be due to form parameter defined in OpenAPI v2 spec with incorrect consumes. " +
"A correct 'consumes' for form parameters should be " +
"'application/x-www-form-urlencoded' or 'multipart/?'");
LOGGER.warn("schema: {}", schema);
LOGGER.warn("codegenModel is null. Default to UNKNOWN_BASE_TYPE");
codegenModelName = "UNKNOWN_BASE_TYPE";
@@ -7696,7 +7784,6 @@ public class DefaultCodegen implements CodegenConfig {
innerCp = innerCp.items;
}
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "request_body";
} else {
@@ -7991,7 +8078,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema original = null;
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
if (schema.getAllOf().get(0) instanceof Schema) {
original = schema;
schema = (Schema) schema.getAllOf().get(0);
@@ -8379,7 +8466,7 @@ public class DefaultCodegen implements CodegenConfig {
int exitValue = p.exitValue();
if (exitValue != 0) {
try (InputStreamReader inputStreamReader = new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(inputStreamReader)) {
BufferedReader br = new BufferedReader(inputStreamReader)) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
@@ -8548,6 +8635,7 @@ public class DefaultCodegen implements CodegenConfig {
*/
@Getter
private static class SanitizeNameOptions {
public SanitizeNameOptions(String name, String removeCharRegEx, List<String> exceptions) {
this.name = name;
this.removeCharRegEx = removeCharRegEx;
@@ -8564,12 +8652,14 @@ public class DefaultCodegen implements CodegenConfig {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
SanitizeNameOptions that = (SanitizeNameOptions) o;
return Objects.equals(getName(), that.getName()) &&
Objects.equals(getRemoveCharRegEx(), that.getRemoveCharRegEx()) &&
Objects.equals(getExceptions(), that.getExceptions());
Objects.equals(getRemoveCharRegEx(), that.getRemoveCharRegEx()) &&
Objects.equals(getExceptions(), that.getExceptions());
}
@Override
@@ -8675,7 +8765,7 @@ public class DefaultCodegen implements CodegenConfig {
i += 1;
if (dataTypeSet.contains(cp.dataType)
|| (isTypeErasedGenerics() && dataTypeSet.contains(cp.baseType))) {
|| (isTypeErasedGenerics() && dataTypeSet.contains(cp.baseType))) {
// add "x-duplicated-data-type" to indicate if the (base) dataType already occurs before
// in other sub-schemas of allOf/anyOf/oneOf
cp.vendorExtensions.putIfAbsent("x-duplicated-data-type", true);

View File

@@ -56,6 +56,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.SourceVersion;
import java.io.File;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -63,6 +64,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -90,6 +92,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public static final String BOOLEAN_GETTER_PREFIX = "booleanGetterPrefix";
public static final String IGNORE_ANYOF_IN_ENUM = "ignoreAnyOfInEnum";
public static final String ADDITIONAL_MODEL_TYPE_ANNOTATIONS = "additionalModelTypeAnnotations";
public static final String X_IMPLEMENTS_SKIP = "xImplementsSkip";
public static final String SCHEMA_IMPLEMENTS = "schemaImplements";
public static final String ADDITIONAL_ONE_OF_TYPE_ANNOTATIONS = "additionalOneOfTypeAnnotations";
public static final String ADDITIONAL_ENUM_TYPE_ANNOTATIONS = "additionalEnumTypeAnnotations";
public static final String DISCRIMINATOR_CASE_SENSITIVE = "discriminatorCaseSensitive";
@@ -178,6 +182,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Setter protected boolean parentOverridden = false;
@Getter @Setter
protected List<String> additionalModelTypeAnnotations = new LinkedList<>();
@Getter
@Setter
protected List<String> xImplementsSkip = new ArrayList<>();
@Getter
@Setter
protected Map<String, List<String>> schemaImplements = new HashMap<>();
protected Map<String, Boolean> lombokAnnotations = null;
@Getter @Setter
protected List<String> additionalOneOfTypeAnnotations = new LinkedList<>();
@@ -450,6 +460,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
convertPropertyToTypeAndWriteBack(ADDITIONAL_ENUM_TYPE_ANNOTATIONS,
annotations -> Arrays.asList(annotations.split(";")),
this::setAdditionalEnumTypeAnnotations);
if (additionalProperties.containsKey(X_IMPLEMENTS_SKIP)) {
this.setXImplementsSkip(getPropertyAsStringList(X_IMPLEMENTS_SKIP));
}
if (additionalProperties.containsKey(SCHEMA_IMPLEMENTS)) {
this.setSchemaImplements(getPropertyAsStringListMap(SCHEMA_IMPLEMENTS));
}
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
@@ -1998,13 +2014,63 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
listIterator.add(newImportMap);
}
}
// add x-implements for serializable to all models
// make sure the x-implements is always a List and always at least empty
for (ModelMap mo : objs.getModels()) {
CodegenModel cm = mo.getModel();
if (this.serializableModel) {
cm.getVendorExtensions().putIfAbsent(X_IMPLEMENTS, new ArrayList<String>());
((ArrayList<String>) cm.getVendorExtensions().get(X_IMPLEMENTS)).add("Serializable");
if (cm.getVendorExtensions().containsKey(X_IMPLEMENTS)) {
List<String> xImplements = getObjectAsStringList(cm.getVendorExtensions().get(X_IMPLEMENTS));
cm.getVendorExtensions().replace(X_IMPLEMENTS, xImplements);
} else {
cm.getVendorExtensions().put(X_IMPLEMENTS, new ArrayList<String>());
}
}
// skip interfaces predefined in open api spec in x-implements via additional property xImplementsSkip
if (!this.xImplementsSkip.isEmpty()) {
for (ModelMap mo : objs.getModels()) {
CodegenModel cm = mo.getModel();
if (!getObjectAsStringList(cm.getVendorExtensions().get(X_IMPLEMENTS)).isEmpty()) {
List<String> xImplementsInModelOriginal = getObjectAsStringList(cm.getVendorExtensions().get(X_IMPLEMENTS));
List<String> xImplementsInModelSkipped = xImplementsInModelOriginal
.stream()
.filter(o -> this.xImplementsSkip.contains(o))
.collect(Collectors.toList());
if (!xImplementsInModelSkipped.isEmpty()) {
LOGGER.info("Following interfaces configured via config option '{}' will be skipped for model {}: {}", X_IMPLEMENTS_SKIP, cm.classname, xImplementsInModelSkipped);
}
List<String> xImplementsInModelProcessed = xImplementsInModelOriginal.stream()
.filter(Predicate.not(xImplementsInModelSkipped::contains))
.collect(Collectors.toList());
// implement only the non-skipped interfaces
cm.getVendorExtensions().replace(X_IMPLEMENTS, xImplementsInModelProcessed);
}
}
}
// add interfaces defined outside of open api spec
if (!this.schemaImplements.isEmpty()) {
for (ModelMap mo : objs.getModels()) {
CodegenModel cm = mo.getModel();
if (this.schemaImplements.containsKey(cm.getSchemaName())) {
LOGGER.info("Adding interface(s) {} configured via config option '{}' to model {}", this.schemaImplements.get(cm.getSchemaName()), SCHEMA_IMPLEMENTS, cm.classname);
List<String> xImplementsInModel = getObjectAsStringList(cm.getVendorExtensions().get(X_IMPLEMENTS));
List<String> schemaImplements = this.schemaImplements.get(cm.getSchemaName());
List<String> combinedSchemaImplements = Stream.concat(xImplementsInModel.stream(), schemaImplements.stream())
.collect(Collectors.toList());
// Add all the interfaces combined
cm.getVendorExtensions().replace(X_IMPLEMENTS, combinedSchemaImplements);
}
}
}
// add Serializable to x-implements to all models if configured
if (this.serializableModel) {
for (ModelMap mo : objs.getModels()) {
CodegenModel cm = mo.getModel();
List<String> xImplements = new ArrayList<>(getObjectAsStringList(cm.getVendorExtensions().get(X_IMPLEMENTS)));
if (!xImplements.contains("Serializable")) {
xImplements.add("Serializable");
}
cm.getVendorExtensions().replace(X_IMPLEMENTS, xImplements);
}
}

View File

@@ -56,6 +56,10 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
public static final String JAVAX_PACKAGE = "javaxPackage";
public static final String USE_JAKARTA_EE = "useJakartaEe";
public static final String SCHEMA_IMPLEMENTS = "schemaImplements";
public static final String SCHEMA_IMPLEMENTS_FIELDS = "schemaImplementsFields";
public static final String X_KOTLIN_IMPLEMENTS_SKIP = "xKotlinImplementsSkip";
public static final String X_KOTLIN_IMPLEMENTS_FIELDS_SKIP = "xKotlinImplementsFieldsSkip";
private final Logger LOGGER = LoggerFactory.getLogger(AbstractKotlinCodegen.class);
@@ -88,6 +92,18 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
private final Map<String, String> schemaKeyToModelNameCache = new HashMap<>();
@Getter @Setter
protected List<String> additionalModelTypeAnnotations = new LinkedList<>();
@Getter
@Setter
protected Map<String, List<String>> schemaImplements = new HashMap<>();
@Getter
@Setter
protected Map<String, List<String>> schemaImplementsFields = new HashMap<>();
@Getter
@Setter
protected List<String> xKotlinImplementsSkip = new ArrayList<>();
@Getter
@Setter
protected Map<String, List<String>> xKotlinImplementsFieldsSkip = new HashMap<>();
public AbstractKotlinCodegen() {
super();
@@ -513,7 +529,19 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
if (additionalProperties.containsKey(ADDITIONAL_MODEL_TYPE_ANNOTATIONS)) {
String additionalAnnotationsList = additionalProperties.get(ADDITIONAL_MODEL_TYPE_ANNOTATIONS).toString();
this.setAdditionalModelTypeAnnotations(Arrays.asList(additionalAnnotationsList.trim().split("\\s*(;|\\r?\\n)\\s*")));
this.setAdditionalModelTypeAnnotations(Arrays.asList(SPLIT_ON_SEMICOLON_OR_NEWLINE_REGEX.split(additionalAnnotationsList.trim())));
}
if (additionalProperties.containsKey(SCHEMA_IMPLEMENTS)) {
this.setSchemaImplements(getPropertyAsStringListMap(SCHEMA_IMPLEMENTS));
}
if (additionalProperties.containsKey(SCHEMA_IMPLEMENTS_FIELDS)) {
this.setSchemaImplementsFields(getPropertyAsStringListMap(SCHEMA_IMPLEMENTS_FIELDS));
}
if (additionalProperties.containsKey(X_KOTLIN_IMPLEMENTS_SKIP)) {
this.setXKotlinImplementsSkip(getPropertyAsStringList(X_KOTLIN_IMPLEMENTS_SKIP));
}
if (additionalProperties.containsKey(X_KOTLIN_IMPLEMENTS_FIELDS_SKIP)) {
this.setXKotlinImplementsFieldsSkip(getPropertyAsStringListMap(X_KOTLIN_IMPLEMENTS_FIELDS_SKIP));
}
additionalProperties.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, getSortParamsByRequiredFlag());
@@ -839,16 +867,52 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
@Override
public CodegenModel fromModel(String name, Schema schema) {
CodegenModel m = super.fromModel(name, schema);
List<String> implementedInterfacesClasses = (List<String>) m.getVendorExtensions().getOrDefault(VendorExtension.X_KOTLIN_IMPLEMENTS.getName(), List.of());
List<String> implementedInterfacesFields = Optional.ofNullable((List<String>) m.getVendorExtensions().get(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS.getName()))
m.getVendorExtensions().putIfAbsent(VendorExtension.X_KOTLIN_IMPLEMENTS.getName(), List.of());
List<String> schemaImplementedInterfacesClasses = this.getSchemaImplements().getOrDefault(m.getSchemaName(), List.of());
List<String> schemaImplementedInterfacesFields = this.getSchemaImplementsFields().getOrDefault(m.getSchemaName(), List.of());
List<String> vendorExtensionImplementedInterfacesClasses = (List<String>) m.getVendorExtensions().get(VendorExtension.X_KOTLIN_IMPLEMENTS.getName());
List<String> interfacesToSkip = this.getXKotlinImplementsSkip().stream()
.filter(vendorExtensionImplementedInterfacesClasses::contains)
.collect(Collectors.toList());
if (!interfacesToSkip.isEmpty()) {
LOGGER.info("Interface(s) {} in model {} are skipped from being marked as implemented via config option '{}'.",
interfacesToSkip, name, X_KOTLIN_IMPLEMENTS_SKIP);
}
List<String> vendorExtensionImplementedInterfacesClassesFiltered = vendorExtensionImplementedInterfacesClasses.stream()
.filter(interfaceName -> !interfacesToSkip.contains(interfaceName))
.collect(Collectors.toList());
List<String> vendorExtensionImplementedInterfacesFields = Optional.ofNullable((List<String>) m.getVendorExtensions().get(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS.getName()))
.map(xKotlinImplementsFields -> {
if (implementedInterfacesClasses.isEmpty() && !xKotlinImplementsFields.isEmpty()) {
if (vendorExtensionImplementedInterfacesClassesFiltered.isEmpty() && !xKotlinImplementsFields.isEmpty()) {
LOGGER.warn("Annotating {} with {} without {} is not supported. {} will be ignored.",
name, VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS.getName(), VendorExtension.X_KOTLIN_IMPLEMENTS.getName(),
VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS.getName());
}
return xKotlinImplementsFields;
}).orElse(List.of());
List<String> fieldsToSkip = this.getXKotlinImplementsFieldsSkip().getOrDefault(m.getSchemaName(), List.of())
.stream()
.filter(vendorExtensionImplementedInterfacesFields::contains)
.collect(Collectors.toList());
if (!fieldsToSkip.isEmpty()) {
LOGGER.info("Field(s) {} in model {} are skipped from being marked as inherited via config option '{}'.",
fieldsToSkip, name, X_KOTLIN_IMPLEMENTS_FIELDS_SKIP);
}
List<String> vendorExtensionImplementedInterfacesFieldsFiltered = vendorExtensionImplementedInterfacesFields.stream()
.filter(interfaceName -> !fieldsToSkip.contains(interfaceName))
.collect(Collectors.toList());
List<String> combinedImplementedInterfacesClasses = Stream.concat(vendorExtensionImplementedInterfacesClassesFiltered.stream(), schemaImplementedInterfacesClasses.stream())
.distinct()
.sorted()
.collect(Collectors.toList());
List<String> combinedImplementedInterfacesFields = Stream.concat(vendorExtensionImplementedInterfacesFieldsFiltered.stream(), schemaImplementedInterfacesFields.stream())
.distinct()
.collect(Collectors.toList());
if (serializableModel && !combinedImplementedInterfacesClasses.contains("java.io.Serializable")) {
combinedImplementedInterfacesClasses.add("java.io.Serializable");
}
m.getVendorExtensions().replace(VendorExtension.X_KOTLIN_IMPLEMENTS.getName(), combinedImplementedInterfacesClasses);
LOGGER.info("Model {} implements interface(s): {}", name, combinedImplementedInterfacesClasses);
m.optionalVars = m.optionalVars.stream().distinct().collect(Collectors.toList());
// Update allVars/requiredVars/optionalVars with isInherited
// Each of these lists contains elements that are similar, but they are all cloned
@@ -865,7 +929,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
Stream.of(m.requiredVars, m.optionalVars)
.flatMap(List::stream)
.filter(p -> allVarsMap.containsKey(p.baseName)
|| implementedInterfacesFields.contains(p.baseName)
|| combinedImplementedInterfacesFields.contains(p.baseName)
)
.forEach(p -> p.isInherited = true);
return m;

View File

@@ -72,7 +72,7 @@ public class JavaCamelServerCodegen extends SpringCodegen implements BeanValidat
templateDir = "java-camel-server";
addCliOptions();
artifactId = "openapi-camel";
super.library = "";
annotationLibrary = AnnotationLibrary.SWAGGER2;
}
@Override

View File

@@ -25,6 +25,7 @@ import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.CamelCaseLambda;
@@ -68,6 +69,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
private boolean returnResponse = false;
@Setter
private boolean omitGradleWrapper = false;
@Getter
@Setter
private boolean fixJacksonJsonTypeInfoInheritance = true;
// This is here to potentially warn the user when an option is not supported by the target framework.
private Map<String, List<String>> optionsSupportedPerFramework = new ImmutableMap.Builder<String, List<String>>()
@@ -106,6 +110,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
public KotlinServerCodegen() {
super();
// Enable proper oneOf/anyOf discriminator handling for polymorphism
legacyDiscriminatorBehavior = false;
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
@@ -120,7 +127,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
.includeSchemaSupportFeatures(
SchemaSupportFeature.allOf,
SchemaSupportFeature.oneOf,
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
@@ -166,6 +175,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
addSwitch(Constants.RETURN_RESPONSE, Constants.RETURN_RESPONSE_DESC, returnResponse);
addSwitch(Constants.OMIT_GRADLE_WRAPPER, Constants.OMIT_GRADLE_WRAPPER_DESC, omitGradleWrapper);
addSwitch(USE_JAKARTA_EE, Constants.USE_JAKARTA_EE_DESC, useJakartaEe);
addSwitch(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE, Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC, fixJacksonJsonTypeInfoInheritance);
}
@Override
@@ -235,6 +245,11 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
setOmitGradleWrapper(Boolean.parseBoolean(additionalProperties.get(Constants.OMIT_GRADLE_WRAPPER).toString()));
}
if (additionalProperties.containsKey(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE)) {
setFixJacksonJsonTypeInfoInheritance(Boolean.parseBoolean(additionalProperties.get(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE).toString()));
}
additionalProperties.put(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE, fixJacksonJsonTypeInfoInheritance);
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
// set default library to "ktor"
@@ -381,6 +396,291 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
public static final String OMIT_GRADLE_WRAPPER = "omitGradleWrapper";
public static final String OMIT_GRADLE_WRAPPER_DESC = "Whether to omit Gradle wrapper for creating a sub project.";
public static final String IS_KTOR = "isKtor";
public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE = "fixJacksonJsonTypeInfoInheritance";
public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC = "When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property.";
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
objs = super.postProcessAllModels(objs);
// For libraries that use Jackson, set up parent-child relationships for discriminator children
// This enables proper polymorphism support with @JsonTypeInfo and @JsonSubTypes annotations
if (usesJacksonSerialization()) {
// Build a map of model name -> model for easy lookup
Map<String, CodegenModel> allModelsMap = new HashMap<>();
for (ModelsMap modelsMap : objs.values()) {
for (ModelMap modelMap : modelsMap.getModels()) {
CodegenModel model = modelMap.getModel();
allModelsMap.put(model.getClassname(), model);
}
}
// First pass: collect all discriminator parent -> children mappings
// Also identify the "true" discriminator owners (not inherited via allOf)
Map<String, String> childToParentMap = new HashMap<>();
Set<String> trueDiscriminatorOwners = new HashSet<>();
for (ModelsMap modelsMap : objs.values()) {
for (ModelMap modelMap : modelsMap.getModels()) {
CodegenModel model = modelMap.getModel();
if (model.getDiscriminator() != null && model.getDiscriminator().getMappedModels() != null
&& !model.getDiscriminator().getMappedModels().isEmpty()) {
String discriminatorPropBaseName = model.getDiscriminator().getPropertyBaseName();
for (CodegenDiscriminator.MappedModel mappedModel : model.getDiscriminator().getMappedModels()) {
childToParentMap.put(mappedModel.getModelName(), model.getClassname());
// If the mapping name equals the model name, check if we can derive
// a better mapping name from the child's discriminator property enum value
if (mappedModel.getMappingName().equals(mappedModel.getModelName())) {
CodegenModel childModel = allModelsMap.get(mappedModel.getModelName());
if (childModel != null) {
// Find the discriminator property in the child model
for (CodegenProperty prop : childModel.getAllVars()) {
if (prop.getBaseName().equals(discriminatorPropBaseName) && prop.isEnum) {
// If it's an enum with exactly one value, use that as the mapping name
Map<String, Object> allowableValues = prop.getAllowableValues();
if (allowableValues != null && allowableValues.containsKey("values")) {
@SuppressWarnings("unchecked")
List<Object> values = (List<Object>) allowableValues.get("values");
if (values != null && values.size() == 1) {
mappedModel.setMappingName(String.valueOf(values.get(0)));
}
}
}
}
}
}
}
// This model owns its discriminator (has mapped models)
trueDiscriminatorOwners.add(model.getClassname());
}
}
}
// Second pass: process child models
for (ModelsMap modelsMap : objs.values()) {
for (ModelMap modelMap : modelsMap.getModels()) {
CodegenModel model = modelMap.getModel();
String parentName = childToParentMap.get(model.getClassname());
if (parentName != null) {
// This model is a child of a discriminator parent
CodegenModel parentModel = allModelsMap.get(parentName);
// Set parent if not already set
if (model.getParent() == null) {
model.setParent(parentName);
}
// If this child has a discriminator but it's inherited (not a true owner),
// remove it - only the parent should have the discriminator annotations
if (model.getDiscriminator() != null && !trueDiscriminatorOwners.contains(model.getClassname())) {
model.setDiscriminator(null);
}
// For allOf pattern: if parent has properties, mark child's inherited properties
// Skip this for oneOf/anyOf patterns where parent properties are merged from children
boolean parentIsOneOfOrAnyOf = parentModel != null
&& ((parentModel.oneOf != null && !parentModel.oneOf.isEmpty())
|| (parentModel.anyOf != null && !parentModel.anyOf.isEmpty()));
if (parentModel != null && parentModel.getHasVars() && !parentIsOneOfOrAnyOf) {
Set<String> parentPropNames = new HashSet<>();
List<String> inheritedPropNamesList = new ArrayList<>();
for (CodegenProperty parentProp : parentModel.getAllVars()) {
parentPropNames.add(parentProp.getBaseName());
inheritedPropNamesList.add(parentProp.getName());
}
// Mark properties inherited from parent
for (CodegenProperty prop : model.getAllVars()) {
if (parentPropNames.contains(prop.getBaseName())) {
prop.isInherited = true;
}
}
for (CodegenProperty prop : model.getVars()) {
if (parentPropNames.contains(prop.getBaseName())) {
prop.isInherited = true;
}
}
for (CodegenProperty prop : model.getRequiredVars()) {
if (parentPropNames.contains(prop.getBaseName())) {
prop.isInherited = true;
}
}
for (CodegenProperty prop : model.getOptionalVars()) {
if (parentPropNames.contains(prop.getBaseName())) {
prop.isInherited = true;
}
}
// Set vendor extension for parent constructor call with inherited properties
if (!inheritedPropNamesList.isEmpty()) {
String parentCtorArgs = String.join(", ", inheritedPropNamesList.stream()
.map(name -> name + " = " + name)
.toArray(String[]::new));
model.getVendorExtensions().put("x-parent-ctor-args", parentCtorArgs);
}
}
}
}
}
// Third pass: set vendor extension for discriminator style and handle fixJacksonJsonTypeInfoInheritance
for (String ownerName : trueDiscriminatorOwners) {
CodegenModel owner = allModelsMap.get(ownerName);
if (owner != null && owner.getDiscriminator() != null) {
String discriminatorPropBaseName = owner.getDiscriminator().getPropertyBaseName();
boolean isOneOfOrAnyOfPattern = (owner.oneOf != null && !owner.oneOf.isEmpty())
|| (owner.anyOf != null && !owner.anyOf.isEmpty());
// hasParentProperties controls whether the sealed class has properties in its constructor
// This should be false for oneOf/anyOf patterns (parent is a type union, no direct properties)
// and true for allOf patterns (parent has properties that children inherit)
boolean hasParentProperties = !isOneOfOrAnyOfPattern;
// visibleTrue controls whether visible=true is set on @JsonTypeInfo
// When fixJacksonJsonTypeInfoInheritance is true, we always set visible=true
// When false, we only set visible=true if the parent has properties (allOf pattern)
boolean visibleTrue;
if (fixJacksonJsonTypeInfoInheritance) {
// When fixJacksonJsonTypeInfoInheritance is true:
// 1. Always set visible=true so Jackson can read the discriminator
// 2. For oneOf/anyOf patterns: add discriminator property to parent and children
visibleTrue = true;
// For oneOf/anyOf patterns, add the discriminator property to the parent sealed class
// This allows accessing the discriminator value from the parent type directly
if (isOneOfOrAnyOfPattern) {
String discriminatorVarName = toVarName(discriminatorPropBaseName);
// Clear all merged properties from the oneOf parent - they belong to children only
// We'll add back just the discriminator property
owner.getVars().clear();
owner.getRequiredVars().clear();
owner.getOptionalVars().clear();
owner.getAllVars().clear();
// Add discriminator property to parent
CodegenProperty parentDiscriminatorProp = new CodegenProperty();
parentDiscriminatorProp.baseName = discriminatorPropBaseName;
parentDiscriminatorProp.name = discriminatorVarName;
parentDiscriminatorProp.dataType = "kotlin.String";
parentDiscriminatorProp.datatypeWithEnum = "kotlin.String";
parentDiscriminatorProp.required = true;
parentDiscriminatorProp.isNullable = false;
parentDiscriminatorProp.isReadOnly = false;
owner.getVars().add(parentDiscriminatorProp);
owner.getRequiredVars().add(parentDiscriminatorProp);
owner.getAllVars().add(parentDiscriminatorProp);
// Parent now has properties (just the discriminator)
hasParentProperties = true;
// Process children: mark discriminator as inherited and set default values
for (CodegenDiscriminator.MappedModel mappedModel : owner.getDiscriminator().getMappedModels()) {
CodegenModel childModel = allModelsMap.get(mappedModel.getModelName());
if (childModel != null) {
boolean hasDiscriminatorProp = false;
String discriminatorDefault = "\"" + mappedModel.getMappingName() + "\"";
// Update existing discriminator property in all lists - mark as inherited
for (CodegenProperty prop : childModel.getVars()) {
if (prop.getBaseName().equals(discriminatorPropBaseName)) {
hasDiscriminatorProp = true;
prop.defaultValue = discriminatorDefault;
prop.dataType = "kotlin.String";
prop.datatypeWithEnum = "kotlin.String";
prop.required = true;
prop.isNullable = false;
prop.isInherited = true;
}
}
for (CodegenProperty prop : childModel.getAllVars()) {
if (prop.getBaseName().equals(discriminatorPropBaseName)) {
prop.defaultValue = discriminatorDefault;
prop.dataType = "kotlin.String";
prop.datatypeWithEnum = "kotlin.String";
prop.required = true;
prop.isNullable = false;
prop.isInherited = true;
}
}
// Move discriminator from optionalVars to requiredVars if needed
CodegenProperty propToMove = null;
for (CodegenProperty prop : childModel.getOptionalVars()) {
if (prop.getBaseName().equals(discriminatorPropBaseName)) {
prop.defaultValue = discriminatorDefault;
prop.dataType = "kotlin.String";
prop.datatypeWithEnum = "kotlin.String";
prop.required = true;
prop.isNullable = false;
prop.isInherited = true;
propToMove = prop;
break;
}
}
if (propToMove != null) {
childModel.getOptionalVars().remove(propToMove);
childModel.getRequiredVars().add(propToMove);
}
// Also update if it's already in requiredVars
for (CodegenProperty prop : childModel.getRequiredVars()) {
if (prop.getBaseName().equals(discriminatorPropBaseName)) {
prop.defaultValue = discriminatorDefault;
prop.dataType = "kotlin.String";
prop.datatypeWithEnum = "kotlin.String";
prop.isNullable = false;
prop.isInherited = true;
}
}
// If child doesn't have the discriminator property, add it as required and inherited
if (!hasDiscriminatorProp) {
CodegenProperty discriminatorProp = new CodegenProperty();
discriminatorProp.baseName = discriminatorPropBaseName;
discriminatorProp.name = discriminatorVarName;
discriminatorProp.dataType = "kotlin.String";
discriminatorProp.datatypeWithEnum = "kotlin.String";
discriminatorProp.defaultValue = discriminatorDefault;
discriminatorProp.required = true;
discriminatorProp.isNullable = false;
discriminatorProp.isReadOnly = false;
discriminatorProp.isInherited = true;
childModel.getVars().add(discriminatorProp);
childModel.getRequiredVars().add(discriminatorProp);
childModel.getAllVars().add(discriminatorProp);
}
// Set parent constructor args for the discriminator property
childModel.getVendorExtensions().put("x-parent-ctor-args",
discriminatorVarName + " = " + discriminatorVarName);
}
}
}
} else {
// When fixJacksonJsonTypeInfoInheritance is false:
// visible=true only for allOf pattern (parent has properties)
visibleTrue = hasParentProperties;
}
// Set on both model and discriminator so it's accessible in different template contexts
owner.getVendorExtensions().put("x-discriminator-has-parent-properties", hasParentProperties);
owner.getDiscriminator().getVendorExtensions().put("x-discriminator-has-parent-properties", hasParentProperties);
owner.getVendorExtensions().put("x-discriminator-visible-true", visibleTrue);
owner.getDiscriminator().getVendorExtensions().put("x-discriminator-visible-true", visibleTrue);
}
}
}
return objs;
}
@Override
@@ -462,6 +762,16 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
return Constants.JAVALIN5.equals(library) || Constants.JAVALIN6.equals(library);
}
/**
* Returns true if the current library uses Jackson for JSON serialization.
* This is used to determine if Jackson-specific features like polymorphism annotations should be enabled.
*/
private boolean usesJacksonSerialization() {
return Constants.JAVALIN5.equals(library) ||
Constants.JAVALIN6.equals(library) ||
Constants.JAXRS_SPEC.equals(library);
}
private boolean isKtor2Or3() {
return Constants.KTOR.equals(library) || Constants.KTOR2.equals(library);
}

View File

@@ -241,12 +241,16 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
addSwitch(BEAN_QUALIFIERS, "Whether to add fully-qualifier class names as bean qualifiers in @Component and " +
"@RestController annotations. May be used to prevent bean names clash if multiple generated libraries" +
" (contexts) added to single project.", beanQualifiers);
addSwitch(USE_SPRING_BOOT3, "Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.", useSpringBoot3);
addSwitch(USE_SPRING_BOOT3, "Generate code and provide dependencies for use with Spring Boot ≥ 3 (use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.", useSpringBoot3);
addSwitch(USE_FLOW_FOR_ARRAY_RETURN_TYPE, "Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.", useFlowForArrayReturnType);
addSwitch(INCLUDE_HTTP_REQUEST_CONTEXT, "Whether to include HttpServletRequest (blocking) or ServerWebExchange (reactive) as additional parameter in generated methods.", includeHttpRequestContext);
addSwitch(USE_RESPONSE_ENTITY,
"Whether (when false) to return actual type (e.g. List<Fruit>) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity<List<Fruit>>). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition",
useResponseEntity);
addOption(X_KOTLIN_IMPLEMENTS_SKIP, "A list of fully qualified interfaces that should NOT be implemented despite their presence in vendor extension `x-kotlin-implements`. Example: yaml `xKotlinImplementsSkip: [com.some.pack.WithPhotoUrls]` skips implementing the interface in any schema", "empty list");
addOption(X_KOTLIN_IMPLEMENTS_FIELDS_SKIP, "A list of fields per schema name that should NOT be created with `override` keyword despite their presence in vendor extension `x-kotlin-implements-fields` for the schema. Example: yaml `xKotlinImplementsFieldsSkip: Pet: [photoUrls]` skips `override` for `photoUrls` in schema `Pet`", "empty map");
addOption(SCHEMA_IMPLEMENTS, "A map of single interface or a list of interfaces per schema name that should be implemented (serves similar purpose as `x-kotlin-implements`, but is fully decoupled from the api spec). Example: yaml `schemaImplements: {Pet: com.some.pack.WithId, Category: [com.some.pack.CategoryInterface], Dog: [com.some.pack.Canine, com.some.pack.OtherInterface]}` implements interfaces in schemas `Pet` (interface `com.some.pack.WithId`), `Category` (interface `com.some.pack.CategoryInterface`), `Dog`(interfaces `com.some.pack.Canine`, `com.some.pack.OtherInterface`)", "empty map");
addOption(SCHEMA_IMPLEMENTS_FIELDS, "A map of single field or a list of fields per schema name that should be prepended with `override` (serves similar purpose as `x-kotlin-implements-fields`, but is fully decoupled from the api spec). Example: yaml `schemaImplementsFields: {Pet: id, Category: [name, id], Dog: [bark, breed]}` marks fields to be prepended with `override` in schemas `Pet` (field `id`), `Category` (fields `name`, `id`) and `Dog` (fields `bark`, `breed`)", "empty map");
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");

View File

@@ -610,6 +610,10 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
processParam(param, op);
}
for (CodegenParameter param : op.pathParams) {
processParam(param, op);
}
// We keep track of the 'default' model type for this API. If there are
// *any* XML responses, then we set the default to XML, otherwise we
// let the default be JSON. It would be odd for an API to want to use
@@ -1459,6 +1463,45 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
return null;
}
/**
* Determine the appropriate Rust integer type based on format and min/max constraints.
* Returns the fitted data type, or null if the baseType is not an integer.
*
* @param dataFormat The data format (e.g., "int32", "int64", "uint32", "uint64")
* @param minimum The minimum value constraint
* @param maximum The maximum value constraint
* @param exclusiveMinimum Whether the minimum is exclusive
* @param exclusiveMaximum Whether the maximum is exclusive
* @return The fitted Rust integer type.
*/
private String applyIntegerTypeFitting(String dataFormat,
String minimum, String maximum,
boolean exclusiveMinimum, boolean exclusiveMaximum) {
BigInteger min = Optional.ofNullable(minimum).filter(s -> !s.isEmpty()).map(BigInteger::new).orElse(null);
BigInteger max = Optional.ofNullable(maximum).filter(s -> !s.isEmpty()).map(BigInteger::new).orElse(null);
boolean unsigned = canFitIntoUnsigned(min, exclusiveMinimum);
if (Strings.isNullOrEmpty(dataFormat)) {
return bestFittingIntegerType(min, exclusiveMinimum, max, exclusiveMaximum, true);
} else {
switch (dataFormat) {
// custom integer formats (legacy)
case "uint32":
return "u32";
case "uint64":
return "u64";
case "int32":
return unsigned ? "u32" : "i32";
case "int64":
return unsigned ? "u64" : "i64";
default:
LOGGER.warn("The integer format '{}' is not recognized and will be ignored.", dataFormat);
return bestFittingIntegerType(min, exclusiveMinimum, max, exclusiveMaximum, true);
}
}
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
@@ -1492,41 +1535,12 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
// Integer type fitting
if (Objects.equals(property.baseType, "integer")) {
BigInteger minimum = Optional.ofNullable(property.getMinimum()).map(BigInteger::new).orElse(null);
BigInteger maximum = Optional.ofNullable(property.getMaximum()).map(BigInteger::new).orElse(null);
boolean unsigned = canFitIntoUnsigned(minimum, property.getExclusiveMinimum());
if (Strings.isNullOrEmpty(property.dataFormat)) {
property.dataType = bestFittingIntegerType(minimum,
property.getExclusiveMinimum(),
maximum,
property.getExclusiveMaximum(),
true);
} else {
switch (property.dataFormat) {
// custom integer formats (legacy)
case "uint32":
property.dataType = "u32";
break;
case "uint64":
property.dataType = "u64";
break;
case "int32":
property.dataType = unsigned ? "u32" : "i32";
break;
case "int64":
property.dataType = unsigned ? "u64" : "i64";
break;
default:
LOGGER.warn("The integer format '{}' is not recognized and will be ignored.", property.dataFormat);
property.dataType = bestFittingIntegerType(minimum,
property.getExclusiveMinimum(),
maximum,
property.getExclusiveMaximum(),
true);
}
}
property.dataType = applyIntegerTypeFitting(
property.dataFormat,
property.getMinimum(),
property.getMaximum(),
property.getExclusiveMinimum(),
property.getExclusiveMaximum());
}
property.name = underscore(property.name);
@@ -1580,6 +1594,17 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
private void processParam(CodegenParameter param, CodegenOperation op) {
String example = null;
// If a parameter is an integer, fit it into the right type.
// Note: For CodegenParameter, baseType may be null, so we check isInteger/isLong/isShort flags instead.
if (param.isInteger || param.isLong || param.isShort) {
param.dataType = applyIntegerTypeFitting(
param.dataFormat,
param.minimum,
param.maximum,
param.exclusiveMinimum,
param.exclusiveMaximum);
}
// If a parameter uses UUIDs, we need to import the UUID package.
if (uuidType.equals(param.dataType)) {
additionalProperties.put("apiUsesUuid", true);

View File

@@ -249,6 +249,9 @@ public class SpringCodegen extends AbstractJavaCodegen
cliOptions
.add(CliOption.newBoolean(RETURN_SUCCESS_CODE, "Generated server returns 2xx code", returnSuccessCode));
cliOptions.add(CliOption.newBoolean(SPRING_CONTROLLER, "Annotate the generated API as a Spring Controller", useSpringController));
cliOptions.add(CliOption.newString(X_IMPLEMENTS_SKIP, "Ability to choose interfaces that should NOT be implemented in the models despite their presence in vendor extension `x-implements`. Takes a list of fully qualified interface names. Example: yaml `xImplementsSkip: [com.some.pack.WithPhotoUrls]` skips implementing the interface `com.some.pack.WithPhotoUrls` in any schema", "empty list"));
cliOptions.add(CliOption.newString(SCHEMA_IMPLEMENTS, "Ability to supply interfaces per schema that should be implemented (serves similar purpose as vendor extension `x-implements`, but is fully decoupled from the api spec). Example: yaml `schemaImplements: {Pet: com.some.pack.WithId, Category: [com.some.pack.CategoryInterface], Dog: [com.some.pack.Canine, com.some.pack.OtherInterface]}` implements interfaces in schemas `Pet` (interface `com.some.pack.WithId`), `Category` (interface `com.some.pack.CategoryInterface`), `Dog`(interfaces `com.some.pack.Canine`, `com.some.pack.OtherInterface`)", "empty map"));
CliOption requestMappingOpt = new CliOption(REQUEST_MAPPING_OPTION,
"Where to generate the class level @RequestMapping annotation.")
@@ -276,7 +279,7 @@ public class SpringCodegen extends AbstractJavaCodegen
"Use `equalsIgnoreCase` when String for enum comparison",
useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(USE_SPRING_BOOT3,
"Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.",
"Generate code and provide dependencies for use with Spring Boot ≥ 3 (use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.",
useSpringBoot3));
cliOptions.add(CliOption.newBoolean(GENERATE_CONSTRUCTOR_WITH_REQUIRED_ARGS,
"Whether to generate constructors with required args for models",
@@ -968,11 +971,6 @@ public class SpringCodegen extends AbstractJavaCodegen
if (model.getVendorExtensions().containsKey("x-jackson-optional-nullable-helpers")) {
model.imports.add("Arrays");
}
// to prevent inheritors (JavaCamelServerCodegen etc.) mistakenly use it
if (getName().contains("spring")) {
model.imports.add("Nullable");
}
}
@Override
@@ -989,6 +987,11 @@ public class SpringCodegen extends AbstractJavaCodegen
codegenModel.imports.remove("Schema");
}
// Only add Nullable import for non-enum models that may have nullable fields
if (!Boolean.TRUE.equals(codegenModel.isEnum)) {
addSpringNullableImport(codegenModel.imports);
}
return codegenModel;
}
@@ -1052,11 +1055,7 @@ public class SpringCodegen extends AbstractJavaCodegen
codegenOperation.imports.addAll(provideArgsClassSet);
}
// to prevent inheritors (JavaCamelServerCodegen etc.) mistakenly use it
if (getName().contains("spring")) {
codegenOperation.allParams.stream().filter(CodegenParameter::notRequiredOrIsNullable).findAny()
.ifPresent(p -> codegenOperation.imports.add("Nullable"));
}
addSpringNullableImportForOperation(codegenOperation);
if (reactive) {
if (DocumentationProvider.SPRINGFOX.equals(getDocumentationProvider())) {
@@ -1219,4 +1218,26 @@ public class SpringCodegen extends AbstractJavaCodegen
extensions.add(VendorExtension.X_SPRING_API_VERSION);
return extensions;
}
private boolean isSpringCodegen() {
return getName().contains("spring");
}
private void addSpringNullableImport(Set<String> imports) {
if (isSpringCodegen()) {
imports.add("Nullable");
}
}
/**
* Adds Spring Nullable import if any parameter is nullable or optional.
*/
private void addSpringNullableImportForOperation(CodegenOperation codegenOperation) {
if (isSpringCodegen()) {
codegenOperation.allParams.stream()
.filter(CodegenParameter::notRequiredOrIsNullable)
.findAny()
.ifPresent(param -> codegenOperation.imports.add("Nullable"));
}
}
}

View File

@@ -51,7 +51,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
public static final String IMPORT_FILE_EXTENSION_SWITCH_DESC = "File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html).";
public static final String USE_SQUARE_BRACKETS_IN_ARRAY_NAMES = "useSquareBracketsInArrayNames";
public static final String AXIOS_VERSION = "axiosVersion";
public static final String DEFAULT_AXIOS_VERSION = "^1.6.1";
public static final String DEFAULT_AXIOS_VERSION = "^1.13.5";
public static final String WITH_AWSV4_SIGNATURE = "withAWSV4Signature";
@Getter @Setter

View File

@@ -78,6 +78,9 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
private static final String USE_OBJECT_PARAMS_SWITCH = "useObjectParameters";
private static final String USE_OBJECT_PARAMS_DESC = "Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.";
protected static final String TYPESCRIPT_MAJOR_VERSION_SWTICH = "typescriptMajorVersion";
private static final String TYPESCRIPT_MAJOR_VERSION_DESC = "Specify the major version of TypeScript to use in the client code. Default is 5.";
public static final String USE_ERASABLE_SYNTAX = "useErasableSyntax";
public static final String USE_ERASABLE_SYNTAX_DESC = "Use erasable syntax for the generated code. This is a temporary feature and will be removed in the future.";
@@ -97,6 +100,9 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
protected String snapshot = null;
protected ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = ENUM_PROPERTY_NAMING_TYPE.PascalCase;
@Getter @Setter
protected String typescriptMajorVersion = "5";
private final DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
private final DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
@@ -131,6 +137,7 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_INVERSIFY_SWITCH, TypeScriptClientCodegen.USE_INVERSIFY_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.TYPESCRIPT_MAJOR_VERSION_SWTICH, TypeScriptClientCodegen.TYPESCRIPT_MAJOR_VERSION_DESC).defaultValue(this.getTypescriptMajorVersion()));
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_ERASABLE_SYNTAX, TypeScriptClientCodegen.USE_ERASABLE_SYNTAX_DESC).defaultValue("false"));
@@ -495,6 +502,8 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
if (additionalProperties.containsKey(NPM_REPOSITORY)) {
setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}
additionalProperties.put(TYPESCRIPT_MAJOR_VERSION_SWTICH, typescriptMajorVersion);
}
private String getHttpLibForFramework(String object) {

View File

@@ -0,0 +1,34 @@
{{#jackson}}
{{#additionalPropertiesType}}
/**
* Set the additional (undeclared) property with the specified name and value.
* Creates the property if it does not already exist, otherwise replaces it.
* @param key the name of the property
* @param value the value of the property
* @return self reference
*/
@JsonAnySetter
public {{classname}} putAdditionalProperty(String key, {{{.}}} value) {
this.put(key, value);
return this;
}
/**
* Return the additional (undeclared) properties.
* @return the additional (undeclared) properties
*/
@JsonAnyGetter
public Map<String, {{{.}}}> getAdditionalProperties() {
return this;
}
/**
* Return the additional (undeclared) property with the specified name.
* @param key the name of the property
* @return the additional (undeclared) property with the specified name
*/
public {{{.}}} getAdditionalProperty(String key) {
return this.get(key);
}
{{/additionalPropertiesType}}
{{/jackson}}

View File

@@ -117,7 +117,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
{{#useBeanValidation}}

View File

@@ -117,7 +117,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
httpclient_version = "5.1.3"

View File

@@ -354,7 +354,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>

View File

@@ -34,6 +34,12 @@ import feign.jackson.JacksonEncoder;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
{{/gson}}
{{#feign-okhttp}}
import feign.okhttp.OkHttpClient;
{{/feign-okhttp}}
{{#feign-hc5}}
import feign.hc5.ApacheHttp5Client;
{{/feign-hc5}}
import feign.slf4j.Slf4jLogger;
import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.HttpBearerAuth;
@@ -65,12 +71,24 @@ public class ApiClient {
protected String basePath = "{{{basePath}}}";
protected Map<String, RequestInterceptor> apiAuthorizations;
protected Feign.Builder feignBuilder;
{{#feign-okhttp}}
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();
{{/feign-okhttp}}
{{#feign-hc5}}
private static final ApacheHttp5Client APACHE_HTTP5_CLIENT = new ApacheHttp5Client();
{{/feign-hc5}}
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, RequestInterceptor>();
{{#jackson}}
objectMapper = createObjectMapper();
feignBuilder = Feign.builder()
{{#feign-okhttp}}
.client(OK_HTTP_CLIENT)
{{/feign-okhttp}}
{{#feign-hc5}}
.client(APACHE_HTTP5_CLIENT)
{{/feign-hc5}}
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
.decoder(new ApiResponseDecoder(objectMapper))
{{#hasOAuthMethods}}
@@ -81,6 +99,12 @@ public class ApiClient {
{{/jackson}}
{{#gson}}
feignBuilder = Feign.builder()
{{#feign-okhttp}}
.client(OK_HTTP_CLIENT)
{{/feign-okhttp}}
{{#feign-hc5}}
.client(APACHE_HTTP5_CLIENT)
{{/feign-hc5}}
.encoder(new FormEncoder(new GsonEncoder()))
.decoder(new GsonDecoder())
{{#hasOAuthMethods}}

View File

@@ -107,7 +107,7 @@ ext {
jackson_databind_version = "2.19.2"
{{/jackson}}
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
feign_version = "13.5"

View File

@@ -416,7 +416,7 @@
<gson-version>2.10.1</gson-version>
{{/gson}}
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>

View File

@@ -101,7 +101,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
google_api_client_version = "1.32.2"

View File

@@ -313,7 +313,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#joda}}
<jodatime-version>2.9.9</jodatime-version>

View File

@@ -107,7 +107,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
{{#useBeanValidation}}

View File

@@ -24,7 +24,7 @@ lazy val root = (project in file(".")).
{{/joda}}
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.19.2" % "compile",
{{#openApiNullable}}
"org.openapitools" % "jackson-databind-nullable" % "0.2.8" % "compile",
"org.openapitools" % "jackson-databind-nullable" % "0.2.9" % "compile",
{{/openApiNullable}}
{{#hasOAuthMethods}}
"com.github.scribejava" % "scribejava-apis" % "8.3.1" % "compile",

View File

@@ -407,7 +407,7 @@
<jersey-version>2.37</jersey-version>
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>

View File

@@ -102,7 +102,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "2.1.0"
{{#useBeanValidation}}

View File

@@ -24,7 +24,7 @@ lazy val root = (project in file(".")).
{{/joda}}
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.19.2" % "compile",
{{#openApiNullable}}
"org.openapitools" % "jackson-databind-nullable" % "0.2.8" % "compile",
"org.openapitools" % "jackson-databind-nullable" % "0.2.9" % "compile",
{{/openApiNullable}}
{{#hasOAuthMethods}}
"com.github.scribejava" % "scribejava-apis" % "8.3.1" % "compile",

View File

@@ -407,7 +407,7 @@
<jersey-version>3.1.11</jersey-version>
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>

View File

@@ -102,7 +102,7 @@ dependencies {
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
implementation "org.openapitools:jackson-databind-nullable:0.2.8"
implementation "org.openapitools:jackson-databind-nullable:0.2.9"
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
{{#useBeanValidation}}
implementation "jakarta.validation:jakarta.validation-api:$beanvalidation_version"

View File

@@ -300,7 +300,7 @@
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<jackson-version>2.19.2</jackson-version>
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>

View File

@@ -132,7 +132,7 @@ dependencies {
implementation 'io.gsonfire:gson-fire:1.9.0'
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:2.1.6'
{{#openApiNullable}}
implementation 'org.openapitools:jackson-databind-nullable:0.2.8'
implementation 'org.openapitools:jackson-databind-nullable:0.2.9'
{{/openApiNullable}}
{{#withAWSV4Signature}}
implementation 'software.amazon.awssdk:auth:2.20.157'

View File

@@ -16,7 +16,7 @@ lazy val root = (project in file(".")).
"org.apache.commons" % "commons-lang3" % "3.18.0",
"jakarta.ws.rs" % "jakarta.ws.rs-api" % "2.1.6",
{{#openApiNullable}}
"org.openapitools" % "jackson-databind-nullable" % "0.2.8",
"org.openapitools" % "jackson-databind-nullable" % "0.2.9",
{{/openApiNullable}}
{{#withAWSV4Signature}}
"software.amazon.awssdk" % "auth" % "2.20.157",

View File

@@ -385,16 +385,16 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{#isArray}}
{{#items.isModel}}
{{#required}}
// ensure the json data is an array
if (!jsonObj.get("{{{baseName}}}").isJsonArray()) {
throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj.get("{{{baseName}}}").toString()));
if (jsonObj.get("{{{baseName}}}") != null{{#isNullable}} && !jsonObj.get("{{{baseName}}}").isJsonNull(){{/isNullable}}) {
if (!jsonObj.get("{{{baseName}}}").isJsonArray()) {
throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj.get("{{{baseName}}}").toString()));
}
JsonArray jsonArray{{name}} = jsonObj.getAsJsonArray("{{{baseName}}}");
// validate the required field `{{{baseName}}}` (array)
for (int i = 0; i < jsonArray{{name}}.size(); i++) {
{{{items.dataType}}}.validateJsonElement(jsonArray{{name}}.get(i));
}
}
JsonArray jsonArray{{name}} = jsonObj.getAsJsonArray("{{{baseName}}}");
// validate the required field `{{{baseName}}}` (array)
for (int i = 0; i < jsonArray{{name}}.size(); i++) {
{{{items.dataType}}}.validateJsonElement(jsonArray{{name}}.get(i));
};
{{/required}}
{{^required}}
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
@@ -424,7 +424,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
// ensure the required json array is present
if (jsonObj.get("{{{baseName}}}") == null) {
throw new IllegalArgumentException("Expected the field `linkedContent` to be an array in the JSON string but got `null`");
} else if (!jsonObj.get("{{{baseName}}}").isJsonArray()) {
} else if (!jsonObj.get("{{{baseName}}}").isJsonArray(){{#isNullable}} && !jsonObj.get("{{baseName}}").isJsonNull(){{/isNullable}}) {
throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj.get("{{{baseName}}}").toString()));
}
{{/required}}
@@ -438,8 +438,14 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{/isString}}
{{#isModel}}
{{#required}}
{{#isNullable}}
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
{{/isNullable}}
// validate the required field `{{{baseName}}}`
{{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
{{#isNullable}}
}
{{/isNullable}}
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
@@ -450,8 +456,14 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{/isModel}}
{{#isEnum}}
{{#required}}
{{#isNullable}}
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
{{/isNullable}}
// validate the required field `{{{baseName}}}`
{{{datatypeWithEnum}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
{{#isNullable}}
}
{{/isNullable}}
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
@@ -462,8 +474,14 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{/isEnum}}
{{#isEnumRef}}
{{#required}}
{{#isNullable}}
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
{{/isNullable}}
// validate the required field `{{{baseName}}}`
{{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
{{#isNullable}}
}
{{/isNullable}}
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`

View File

@@ -416,7 +416,7 @@
<gson-version>2.10.1</gson-version>
<commons-lang3-version>3.18.0</commons-lang3-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#joda}}
<jodatime-version>2.12.0</jodatime-version>

View File

@@ -109,7 +109,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
{{/jackson}}
{{#gson}}

View File

@@ -18,7 +18,7 @@ lazy val root = (project in file(".")).
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.19.2",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.19.2",
{{#openApiNullable}}
"org.openapitools" % "jackson-databind-nullable" % "0.2.8",
"org.openapitools" % "jackson-databind-nullable" % "0.2.9",
{{/openApiNullable}}
{{#withXml}}
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % "2.13.4.1",

View File

@@ -354,7 +354,7 @@
{{#jackson}}
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/jackson}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>

View File

@@ -106,7 +106,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
spring_web_version = "6.1.21"
jakarta_annotation_version = "2.1.1"

View File

@@ -350,7 +350,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{#joda}}

View File

@@ -101,7 +101,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
threetenbp_version = "2.9.10"

View File

@@ -301,7 +301,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>

View File

@@ -118,7 +118,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
{{#useJakartaEe}}
spring_web_version = "6.2.8"

View File

@@ -364,7 +364,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<spring-web-version>6.2.8</spring-web-version>

View File

@@ -104,7 +104,7 @@ ext {
jackson_databind_version = "2.19.2"
javax_ws_rs_api_version = "2.1.1"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
{{/jackson}}
{{#usePlayWS}}

View File

@@ -386,7 +386,7 @@
<jackson-databind-version>2.19.2</jackson-databind-version>
<jackson-version>2.19.2</jackson-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
<javax.ws.rs-api-version>2.1.1</javax.ws.rs-api-version>
{{/jackson}}

View File

@@ -35,7 +35,7 @@ ext {
vertx_version = "{{#supportVertxFuture}}4.0.0{{/supportVertxFuture}}{{^supportVertxFuture}}3.5.2{{/supportVertxFuture}}"
junit_version = "5.10.3"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
jakarta_annotation_version = "1.3.5"
}

View File

@@ -308,7 +308,7 @@
{{/swagger2AnnotationLibrary}}
<jackson-version>2.19.2</jackson-version>
<jackson-databind>2.19.2</jackson-databind>
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{/useJakartaEe}}

View File

@@ -147,7 +147,7 @@ ext {
jackson_version = "2.19.2"
jackson_databind_version = "2.19.2"
{{#openApiNullable}}
jackson_databind_nullable_version = "0.2.8"
jackson_databind_nullable_version = "0.2.9"
{{/openApiNullable}}
{{#joda}}
jodatime_version = "2.9.9"

View File

@@ -170,7 +170,7 @@
<jackson-version>2.19.2</jackson-version>
<jackson-databind-version>2.19.2</jackson-databind-version>
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<spring-boot-version>3.2.12</spring-boot-version>

View File

@@ -17,6 +17,17 @@ import java.io.Serializable;
{{#jackson}}
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeName;
{{#models}}
{{#model}}
{{#additionalPropertiesType}}
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonFormat;
{{/additionalPropertiesType}}
{{/model}}
{{/models}}
{{#withXml}}
import com.fasterxml.jackson.dataformat.xml.annotation.*;
{{/withXml}}

View File

@@ -24,6 +24,9 @@
@JsonTypeName("{{name}}")
{{/hasDiscriminatorWithNonEmptyMapping}}
{{/isClassnameSanitized}}
{{#additionalPropertiesType}}
@JsonFormat(shape=JsonFormat.Shape.OBJECT)
{{/additionalPropertiesType}}
{{/jackson}}
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}
{{#vendorExtensions.x-class-extra-annotation}}
@@ -281,6 +284,8 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
{{/isReadOnly}}
{{/vars}}
{{>additional_properties}}
{{#parent}}
{{#readWriteVars}}
{{#isOverridden}}

View File

@@ -0,0 +1,32 @@
{{#additionalProperties}}
/**
* Set the additional (undeclared) property with the specified name and value.
* Creates the property if it does not already exist, otherwise replaces it.
* @param key the name of the property
* @param value the value of the property
* @return self reference
*/
@JsonAnySetter
public {{classname}} putAdditionalProperty(String key, {{{datatypeWithEnum}}} value) {
this.put(key, value);
return this;
}
/**
* Return the additional (undeclared) properties.
* @return the additional (undeclared) properties
*/
@JsonAnyGetter
public Map<String, {{{datatypeWithEnum}}}> getAdditionalProperties() {
return this;
}
/**
* Return the additional (undeclared) property with the specified name.
* @param key the name of the property
* @return the additional (undeclared) property with the specified name
*/
public {{{datatypeWithEnum}}} getAdditionalProperty(String key) {
return this.get(key);
}
{{/additionalProperties}}

View File

@@ -51,7 +51,7 @@
<smallrye.rest.client.version>1.2.1</smallrye.rest.client.version>
{{/useMutiny}}
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
</properties>
<dependencyManagement>

View File

@@ -10,6 +10,13 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.annotation.JsonTypeName;
{{#additionalProperties}}
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonFormat;
{{/additionalProperties}}
{{/jackson}}
{{#openApiNullable}}
import org.openapitools.jackson.nullable.JsonNullable;
@@ -30,7 +37,12 @@ import {{javaxPackage}}.xml.bind.annotation.XmlEnumValue;
{{#useSwaggerAnnotations}}{{#description}}@ApiModel(description = "{{{.}}}"){{/description}}{{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
@Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}}
@org.eclipse.microprofile.openapi.annotations.media.Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useMicroProfileOpenAPIAnnotations}}
{{#jackson}}@JsonTypeName("{{name}}"){{/jackson}}
{{#jackson}}
@JsonTypeName("{{name}}")
{{#additionalProperties}}
@JsonFormat(shape=JsonFormat.Shape.OBJECT)
{{/additionalProperties}}
{{/jackson}}
{{>generatedAnnotation}}{{>additionalModelTypeAnnotations}}{{>xmlPojoAnnotation}}
{{#vendorExtensions.x-class-extra-annotation}}
{{{vendorExtensions.x-class-extra-annotation}}}
@@ -196,6 +208,7 @@ public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}} {{#vendorExtens
}
{{/isMap}}
{{/vars}}
{{>additional_properties}}
@Override
public boolean equals(Object o) {

View File

@@ -208,7 +208,7 @@
<jakarta.ws.rs-version>2.1.6</jakarta.ws.rs-version>
{{/useJakartaEe}}
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
<jackson-databind-nullable-version>0.2.9</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useSwaggerV3Annotations}}
<io.swagger.v3.annotations.version>2.2.21</io.swagger.v3.annotations.version>

View File

@@ -208,7 +208,7 @@
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.8</version>
<version>0.2.9</version>
</dependency>
{{/openApiNullable}}
{{#useBeanValidation}}

View File

@@ -139,7 +139,7 @@
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
{{^parentOverridden}}
<version>0.2.8</version>
<version>0.2.9</version>
{{/parentOverridden}}
</dependency>
{{/openApiNullable}}

View File

@@ -86,7 +86,7 @@
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.8</version>
<version>0.2.9</version>
</dependency>
{{/openApiNullable}}
{{#lombok}}

View File

@@ -71,7 +71,7 @@ public:
int getHttpResponseCode() const;
Q_SIGNALS:
void on_execution_finished({{prefix}}HttpRequestWorker *worker);
void on_execution_finished({{#cppNamespaceDeclarations}}{{this}}::{{/cppNamespaceDeclarations}}{{prefix}}HttpRequestWorker *worker);
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
private:

View File

@@ -116,20 +116,22 @@ Do not edit the class manually.
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.8</version>
<version>0.2.9</version>
</dependency>
{{#swagger1AnnotationLibrary}}
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.3</version>
</dependency>
{{#oas3}}
{{/swagger1AnnotationLibrary}}
{{#swagger2AnnotationLibrary}}
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.8</version>
</dependency>
{{/oas3}}
{{/swagger2AnnotationLibrary}}
{{#jackson}}
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>

View File

@@ -18,7 +18,7 @@
<properties>
{{#openApiNullable}}
<version.jackson.databind.nullable>0.2.8</version.jackson.databind.nullable>
<version.jackson.databind.nullable>0.2.9</version.jackson.databind.nullable>
{{/openApiNullable}}
</properties>

View File

@@ -19,7 +19,7 @@
<properties>
{{#openApiNullable}}
<version.jackson.databind.nullable>0.2.8</version.jackson.databind.nullable>
<version.jackson.databind.nullable>0.2.9</version.jackson.databind.nullable>
{{/openApiNullable}}
</properties>

View File

@@ -19,7 +19,7 @@
<properties>
{{#openApiNullable}}
<version.jackson.databind.nullable>0.2.7</version.jackson.databind.nullable>
<version.jackson.databind.nullable>0.2.9</version.jackson.databind.nullable>
{{/openApiNullable}}
</properties>

View File

@@ -20,7 +20,7 @@
<properties>
<mainClass>{{{invokerPackage}}}.Main</mainClass>
{{#openApiNullable}}
<version.jackson.databind.nullable>0.2.8</version.jackson.databind.nullable>
<version.jackson.databind.nullable>0.2.9</version.jackson.databind.nullable>
{{/openApiNullable}}
</properties>

View File

@@ -4,8 +4,16 @@ package {{packageName}}.infrastructure
* Defines a config object for a given part of a multi-part request.
* NOTE: Headers is a Map<String,String> because rfc2616 defines
* multi-valued headers as csv-only.
*
* @property headers The headers for this part
* @property body The body content for this part
* @property serializer Optional custom serializer for JSON content. When provided, this will be
* used instead of the default serialization for parts with application/json
* content-type. This allows capturing type information at the call site to
* avoid issues with type erasure in kotlinx.serialization.
*/
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}data class PartConfig<T>(
val headers: MutableMap<String, String> = mutableMapOf(),
val body: T? = null
val body: T? = null,
val serializer: ((Any?) -> String)? = null
)

View File

@@ -46,6 +46,9 @@ import {{packageName}}.infrastructure.RequestMethod
import {{packageName}}.infrastructure.ResponseType
import {{packageName}}.infrastructure.Success
import {{packageName}}.infrastructure.toMultiValue
{{#kotlinx_serialization}}
import {{packageName}}.infrastructure.Serializer
{{/kotlinx_serialization}}
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}}(basePath: kotlin.String = defaultBasePath, client: Call.Factory = ApiClient.defaultClient) : ApiClient(basePath, client) {
@@ -199,7 +202,7 @@ import {{packageName}}.infrastructure.toMultiValue
}}{{#bodyParams}}{{{paramName}}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{!
}}{{^hasFormParams}}null{{/hasFormParams}}{{!
}}{{#hasFormParams}}mapOf({{#formParams}}
"{{#lambda.escapeDollar}}{{{baseName}}}{{/lambda.escapeDollar}}" to PartConfig(body = {{{paramName}}}{{#isEnum}}{{^required}}?{{/required}}.value{{/isEnum}}, headers = mutableMapOf({{#contentType}}"Content-Type" to "{{contentType}}"{{/contentType}})),{{!
"{{#lambda.escapeDollar}}{{{baseName}}}{{/lambda.escapeDollar}}" to PartConfig(body = {{{paramName}}}{{#isEnum}}{{^required}}?{{/required}}.value{{/isEnum}}, headers = mutableMapOf({{#contentType}}"Content-Type" to "{{contentType}}"{{/contentType}}){{#contentType}}{{^isFile}}, serializer = {{#kotlinx_serialization}}{ obj -> Serializer.kotlinxSerializationJson.encodeToString<{{{dataType}}}>(obj as {{{dataType}}}) }{{/kotlinx_serialization}}{{^kotlinx_serialization}}null{{/kotlinx_serialization}}{{/isFile}}{{/contentType}}),{{!
}}{{/formParams}}){{/hasFormParams}}{{!
}}{{/hasBodyParam}}
val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mutableMapOf()

View File

@@ -115,6 +115,25 @@ import com.squareup.moshi.adapter
return contentType ?: "application/octet-stream"
}
/**
* Builds headers for a multipart form-data part.
* OkHttp requires Content-Type to be passed via the RequestBody parameter, not in headers.
* This function filters out Content-Type and builds the appropriate Content-Disposition header.
*
* @param name The field name
* @param headers The headers from the PartConfig (may include Content-Type)
* @param filename Optional filename for file uploads
* @return Headers object ready for addPart()
*/
protected fun buildPartHeaders(name: String, headers: Map<String, String>, filename: String? = null): Headers {
val disposition = if (filename != null) {
"form-data; name=\"$name\"; filename=\"$filename\""
} else {
"form-data; name=\"$name\""
}
return (headers.filterKeys { it != "Content-Type" } + ("Content-Disposition" to disposition)).toHeaders()
}
/**
* Adds a File to a MultipartBody.Builder
* Defined a helper in the requestBody method to not duplicate code
@@ -127,15 +146,48 @@ import com.squareup.moshi.adapter
* @see requestBody
*/
protected fun MultipartBody.Builder.addPartToMultiPart(name: String, headers: Map<String, String>, file: File) {
val partHeaders = headers.toMutableMap() +
("Content-Disposition" to "form-data; name=\"$name\"; filename=\"${file.name}\"")
val fileMediaType = guessContentTypeFromFile(file).toMediaTypeOrNull()
addPart(
partHeaders.toHeaders(),
buildPartHeaders(name, headers, file.name),
file.asRequestBody(fileMediaType)
)
}
/**
* Serializes a multipart body part based on its content type.
* Uses JSON serialization for application/json content types, otherwise converts to string.
*
* @param obj The object to serialize
* @param contentType The Content-Type header value, if any
* @param serializer Optional custom serializer (used for kotlinx.serialization to preserve type info)
* @return The serialized string representation
*/
protected fun serializePartBody(obj: Any?, contentType: String?, serializer: ((Any?) -> String)?): String {
// Use custom serializer if provided (for kotlinx.serialization with captured type info)
if (serializer != null) {
return serializer(obj)
}
return if (contentType?.contains("json") == true) {
{{#moshi}}
Serializer.moshi.adapter(Any::class.java).toJson(obj)
{{/moshi}}
{{#gson}}
Serializer.gson.toJson(obj)
{{/gson}}
{{#jackson}}
Serializer.jacksonObjectMapper.writeValueAsString(obj)
{{/jackson}}
{{#kotlinx_serialization}}
// Note: Without a custom serializer, kotlinx.serialization cannot serialize Any?
// The custom serializer should be provided at PartConfig creation to capture type info
parameterToString(obj)
{{/kotlinx_serialization}}
} else {
parameterToString(obj)
}
}
/**
* Adds any type to a MultipartBody.Builder
* Defined a helper in the requestBody method to not duplicate code
@@ -144,15 +196,17 @@ import com.squareup.moshi.adapter
* @param name The field name to add in the request
* @param headers The headers that are in the PartConfig
* @param obj The field name to add in the request
* @param serializer Optional custom serializer for this part
* @return The method returns Unit but the new Part is added to the Builder that the extension function is applying on
* @see requestBody
*/
protected fun <T> MultipartBody.Builder.addPartToMultiPart(name: String, headers: Map<String, String>, obj: T?) {
val partHeaders = headers.toMutableMap() +
("Content-Disposition" to "form-data; name=\"$name\"")
protected fun MultipartBody.Builder.addPartToMultiPart(name: String, headers: Map<String, String>, obj: Any?, serializer: ((Any?) -> String)? = null) {
val partContentType = headers["Content-Type"]
val partMediaType = partContentType?.toMediaTypeOrNull()
val partBody = serializePartBody(obj, partContentType, serializer)
addPart(
partHeaders.toHeaders(),
parameterToString(obj).toRequestBody(null)
buildPartHeaders(name, headers),
partBody.toRequestBody(partMediaType)
)
}
@@ -174,11 +228,11 @@ import com.squareup.moshi.adapter
if (it is File) {
addPartToMultiPart(name, part.headers, it)
} else {
addPartToMultiPart(name, part.headers, it)
addPartToMultiPart(name, part.headers, it, part.serializer)
}
}
}
else -> addPartToMultiPart(name, part.headers, part.body)
else -> addPartToMultiPart(name, part.headers, part.body, part.serializer)
}
}
}.build()

View File

@@ -11,6 +11,10 @@ import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import kotlinx.serialization.json.Json
import io.ktor.http.ParametersBuilder
import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
import io.ktor.http.ContentType
import io.ktor.http.content.PartData
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
@@ -76,11 +80,31 @@ import kotlinx.serialization.encoding.*
{{#formParams}}
{{#isArray}}
{{{paramName}}}?.onEach {
{{#isFile}}append(it){{/isFile}}{{^isFile}}append("{{{baseName}}}", it){{/isFile}}
{{#isFile}}append(it){{/isFile}}{{^isFile}}append("{{{baseName}}}", it.toString()){{/isFile}}
}
{{/isArray}}
{{^isArray}}
{{{paramName}}}?.apply { {{#isFile}}append({{{baseName}}}){{/isFile}}{{^isFile}}append("{{{baseName}}}", {{^isEnumOrRef}}{{{paramName}}}{{/isEnumOrRef}}{{#isEnumOrRef}}{{{paramName}}}.value{{/isEnumOrRef}}){{/isFile}} }
{{#isFile}}
{{{paramName}}}?.apply { append({{{baseName}}}) }
{{/isFile}}
{{^isFile}}
{{#isPrimitiveType}}
{{#isString}}
{{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
{{/isString}}
{{^isString}}
{{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}.toString()) }
{{/isString}}
{{/isPrimitiveType}}
{{^isPrimitiveType}}
{{#isEnumOrRef}}
{{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}.value.toString()) }
{{/isEnumOrRef}}
{{^isEnumOrRef}}
{{{paramName}}}?.apply { append("{{{baseName}}}", ApiClient.JSON_DEFAULT.encodeToString({{{dataType}}}.serializer(), {{{paramName}}})) }
{{/isEnumOrRef}}
{{/isPrimitiveType}}
{{/isFile}}
{{/isArray}}
{{/formParams}}
}

View File

@@ -12,23 +12,38 @@ import java.io.Serializable
{{/isKtor}}
/**
* {{{description}}}
{{#isKtor}}
{{#vars}}
* @param {{{name}}} {{{description}}}
{{/vars}}
{{/isKtor}}
{{^isKtor}}
{{^discriminator}}
{{#vars}}
* @param {{{name}}} {{{description}}}
{{/vars}}
{{/discriminator}}
{{#discriminator}}
{{#vendorExtensions.x-discriminator-has-parent-properties}}
{{#vars}}
* @param {{{name}}} {{{description}}}
{{/vars}}
{{/vendorExtensions.x-discriminator-has-parent-properties}}
{{/discriminator}}
{{/isKtor}}
*/
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
{{#isKtor}}
@Serializable
{{/isKtor}}
{{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
){{^isKtor}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/isKtor}}
)
{{#vendorExtensions.x-has-data-class-body}}
{
{{/vendorExtensions.x-has-data-class-body}}
@@ -52,3 +67,53 @@ import java.io.Serializable
{{#vendorExtensions.x-has-data-class-body}}
}
{{/vendorExtensions.x-has-data-class-body}}
{{/isKtor}}
{{^isKtor}}
{{#discriminator}}
{{>typeInfoAnnotation}}
{{#vendorExtensions.x-discriminator-has-parent-properties}}
sealed class {{classname}}(
{{#requiredVars}}
{{>data_class_sealed_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_sealed_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
)
{{/vendorExtensions.x-discriminator-has-parent-properties}}
{{^vendorExtensions.x-discriminator-has-parent-properties}}
sealed class {{classname}}
{{/vendorExtensions.x-discriminator-has-parent-properties}}
{{/discriminator}}
{{^discriminator}}
{{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
){{#parent}} : {{{.}}}({{#vendorExtensions.x-parent-ctor-args}}{{{.}}}{{/vendorExtensions.x-parent-ctor-args}}){{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/parent}}
{{#vendorExtensions.x-has-data-class-body}}
{
{{/vendorExtensions.x-has-data-class-body}}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
/**
* {{{description}}}
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
*/
enum class {{{nameInPascalCase}}}(val value: {{{dataType}}}){
{{#allowableValues}}
{{#enumVars}}
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{#vendorExtensions.x-has-data-class-body}}
}
{{/vendorExtensions.x-has-data-class-body}}
{{/discriminator}}
{{/isKtor}}

View File

@@ -0,0 +1,4 @@
{{#description}}
/* {{{.}}} */
{{/description}}
open val {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}?{{/required}}{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}

View File

@@ -0,0 +1,6 @@
{{#description}}
/* {{{.}}} */
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
open {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}

View File

@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}

View File

@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}

View File

@@ -0,0 +1,6 @@
{{#description}}
/* {{{.}}} */
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
open {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}

View File

@@ -0,0 +1,5 @@
{{#description}}
/* {{{.}}} */
{{/description}}
@get:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
open val {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}?{{/required}}{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}

View File

@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}

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