Compare commits

...

43 Commits

Author SHA1 Message Date
devhl
da9ef216a0 version bump 2024-09-06 19:08:32 -04:00
David Omid
2bc0e5f745 [typescript-fetch] Fixed issue where unique arrays (sets) of primitive values aren't initialized properly (#19521)
* Fix for https://github.com/OpenAPITools/openapi-generator/issues/19520

* Removed redundant Array<any> cast

* Fixed modelGeneric.mustache

* Updated samples
2024-09-05 15:43:34 +02:00
Tero Hagström
2f54a2fb11 Fix for #15736 [TYPESCRIPT-FETCH] Subclassing components using discri… (#19524)
* Fix for #15736 [TYPESCRIPT-FETCH] Subclassing components using discriminators fails to convert subclasses to JSON.
Added similar discriminator handling to ToJSON as was already in place for FromJSON.
The actual files changed are typescript-fetch/modelGeneric.mustache and typescript-fetch/apis.mustache.
Also, adjusted FromJSON a bit in an attempt to support multiple hierarchical levels of discriminators.
And fixed an issue with calling FromJSON from the map() function, which caused the index parameter getting inadvertently passed as the ignoreDiscriminator parameter.
Additionally, fixed failing "mvn integration-test -f samples/client/petstore/typescript-fetch/builds/prefix-parameter-interfaces/pom.xml"
Moreover, added forceConsistentCasingInFileNames:false into tsconfig.json to make tests compile on OsX.

* Rolled back the changes related to the map() function calls in favor of using ToJSONTyped instead, as that is in line with how FromJSON is already implemented.
2024-09-05 15:29:44 +02:00
William Cheng
e914c4098b update samples 2024-09-04 16:42:41 +08:00
Nicklas Wiegandt
e4112c5aca feat (JAVA SPRING RESTCLIENT) 19406: Add single request parameter for Spring RestClient (#19430)
* feat (JAVA SPRING RESTCLIENT) 19406: Add single request parameter for Spring RestClient

Closes #19406

* chore (JAVA SPRING RESTCLIENT) 19406: Add new sample to jdk 17 tests

* fix (JAVA SPRING RESTCLIENT) 19406: Fix sample build
2024-09-04 16:17:13 +08:00
Rugal Bernstein
f54b0e25a4 Remove appendRequestToHandler (#19500) 2024-09-04 16:03:31 +08:00
Horace Li
42d98e2526 [Java Libraries] Jakarta Validation API support useJakartaEe flag (#19469)
* Jakarta Validation API support useJakartaEe flag

* Jakarta Validation API support useJakartaEe flag
2024-09-04 15:57:55 +08:00
Joscha Feth
f40f72cea8 [typescript] fix: explode: true should yield appended query params (#19519)
* [typescript] fix: `explode: true` should yield appended `query` params

* fix: object keys should be `set`
2024-09-04 08:16:21 +02:00
Dan Goslen
8678ee8a1f [Typescript:Axios] Fix withInterfaces and usSingleRequestObjectParam (#19467)
* Support withSingleRequestParameter along with withInterfaces

* Add sample and config for combination

* Re-generate samples
2024-09-03 17:22:11 +02:00
Matteo Molinari
fb1c2f3483 [Bugfix][Java] Fixed jersey clients for multiple file upload (#19476)
* Fixed jersey3 client for multiple file upload

* Updated sample

* Fixed typo

* Fix

* Fix for jersey2
2024-09-02 17:25:54 +08:00
William Cheng
c733bb69a2 [typescript-angular] fix: when model property name is sanitized, use instead original property name within quotes in mustache template (#19508)
* fix: typescript-angular -> when model property name is sanitized, use instead original property name within quotes in mustache template

* fix: updated samples

* chore: added comment for hasSanitizedName

* add original tag, add dummy model for test

* update samples

---------

Co-authored-by: Davide Diaconu <davidediak@gmail.com>
2024-09-02 17:15:58 +08:00
jpfinne
b228133a20 [java] Fix issue #17472 when using schemaMapping for models in collections, not compilable code with @Valid is generated (#19093)
* Fix issue 17472

* Avoid cast exception
2024-09-02 17:03:08 +08:00
William Cheng
1776c000ed update C# restsharp to 112.0.0 (#19507) 2024-09-02 16:52:54 +08:00
Sobhan Sharifi
0643f526af Fix ObjectSerializer::isEmptyValue to not consider "0" as "" (#19472) 2024-09-02 16:03:36 +08:00
Chris McEvoy
5b96e85fd5 bugfix: use the correct key when generating auth example in readme (#19492) 2024-09-02 15:38:57 +08:00
Beppe Catanese
4ed8c70a92 Remove unused go-server-required (#19505) 2024-09-02 15:36:42 +08:00
Brenton Bostick
abd19dd253 fix typo woking -> working (#19498) 2024-09-02 15:34:42 +08:00
Joscha Feth
be618ec168 docs: add hints about how to use snapshot version of generator-cli (#19497)
* docs: add hints about how to use snapshot version of `generator-cli`

* docs: simplify

* style: indentation
2024-08-30 16:26:00 +02:00
Joscha Feth
7510e6bbf8 [Typescript] Generate oneOf schemas as type unions (#19494)
* Add oneOf model for Typescript generator

* Update import procces: For oneOfs only import $refs within the oneOf

* Remove new line after description

* Update samples

* Typescript: Update model.mustache

* Typescript: Remove emun from oneOf models

* Update samples

* Typescript oneOf: add discriminator and update deserialize procces

* Typescript: update tests

* Typescript oneOf: move type mapping to models

* Typescript: Update samples

* Typescript: Update type of mappig

* Typescript: Update type of mappig

* Typescript oneOf: update deserializing logic

* Typescript: Update samples

* Revert "[typescript] fix: `enum` can not receive stringified class name (#19481)"

This reverts commit 4238f17322.

* [typescript] chore: update fixtures

---------

Co-authored-by: ksvirkou-hubspot <ksvirkou@hubspot.com>
2024-08-30 16:20:18 +02:00
Joscha Feth
1518237c25 [typescript] fix: deno: type exports for isolatedModules (#19484) 2024-08-29 13:56:02 +02:00
Joscha Feth
4238f17322 [typescript] fix: enum can not receive stringified class name (#19481)
* fix: `enum` can not receive stringified class name

* chore: update generated code samples
2024-08-29 13:54:57 +02:00
Eric
dfc381c22f [Java] Add a new additional property to configure Jackson's failOnUnknownProperties (#19271)
* [Java] Add a new additional property to configure Jackson's `failOnUnknownProperties`

* Move `FAIL_ON_UNKNOWN_PROPERTIES` property to JavaClientCodegen

* Template `FAIL_ON_UNKNOWN_PROPERTIES` for other libraries beside retrofit2

* Default `failOnUnknownProperties` to false for all Java Client libraries

* Fix integration tests

Add the `failOnUnknownProperties: true` additional properties to generate the
expected mapper
2024-08-29 13:25:25 +08:00
Joscha Feth
082382cc1e [typescript] use const for middleware symbol (#19478)
* style: use const for `middleware`

* chore: update generated code samples
2024-08-28 17:52:26 +02:00
Anderson de Borba
85763cdb08 [java] Use @JsonFormat instead of @JsonSerialize for bigDecimalAsString property (#19322)
* [java] Use @JsonFormat instead of @JsonSerialize so that JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN is respected and generates a String using BigDecimal#toPlainString instead of BigDecimal#toString

* Only add Jackson @JsonFormat if properties serializeBigDecimalAsString and jackson are enabled

* Do not verify if jackson is available when mapping imports as the property is not evaluated yet

* Removed unused JsonSerialize and ToStringSerializer
2024-08-28 16:22:13 +08:00
William Cheng
e69fb86957 remove unused file 2024-08-28 15:46:06 +08:00
William Cheng
9579122945 Better handling of parameters in inline model resolver (#19460)
* add tests for parameter ref of oneOf

* update samples

* better handlding of parameters in inline model resolver
2024-08-28 15:31:04 +08:00
JP Moresmau
d6780e7d43 Remove extra bracket to fix compilation (#19464) 2024-08-28 15:30:15 +08:00
Matthias Schwarz
4330b2f46d [typescript-fetch] Add option to generate validation attributes of model properties (#19448) 2024-08-27 14:13:59 +02:00
dependabot[bot]
aae3ab3154 Bump micromatch from 4.0.5 to 4.0.8 in /website (#19444)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/4.0.8/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-27 17:19:11 +08:00
condorcorde
fe381e2199 Support multiple files (#19449) 2024-08-26 15:39:15 +08:00
aakash-dev-maersk
f13a11b53c Add support for global token based auth for k6 script generation (#19348)
* Add global token based auth support (basic, bearer) for k6

* config files and generated code files after the changes

* Handle empty or null auth at path level

* files changed after update with master and run build
2024-08-25 23:40:38 +08:00
Richard Whitehouse
2b40a2c058 [Rust Server] Add auto-generated CLI Client (#19392)
* [Rust Server] Add auto-generated CLI tool

* [Rust Server] Test multiple path parameters

* [Rust Server] Test boolean parameters and apostrophes

* [Rust Server] Test operation with two boolean parameters with same first letter

* [Rust Server] Test apostrophes in operation summary

* Update samples

* [Rust Server] Fix build errors with OpenSSL

* Update samples

* Update samples
2024-08-24 23:57:03 +08:00
ふぁ
69cce249f6 [python] fix content_type deserialize (#19317)
* [Python] fix: #19285

* [python] update sample

* [python] add test

* [python] remove test
2024-08-24 23:40:15 +08:00
Victor Mosin
7a7c8c19ab [Kotlin][okhttp] replace okhttpclient with callfactory (#19422) 2024-08-22 21:19:32 +01:00
William Cheng
0f294a5129 use gitHost in python pyproject template (#19421) 2024-08-22 16:09:53 +08:00
Martin Boos
ae069e6840 [Python] Update python-pydantic-v1 generator to respect the --git-host argument (#19404)
* Update pyproject.mustache

chore(pyproject): replace static `github.com` with variable `{{{gitHost}}}`

* chore: follow contribution guidelines
2024-08-22 15:52:36 +08:00
mohamuni
deb007b976 fix regex breakage in unmarshaljson function (#19410) 2024-08-22 15:12:54 +08:00
julianladisch
87704b28c0 Upgrade commons-io dependency to latest 2.16.1 (#19414) 2024-08-22 14:59:20 +08:00
Bruno Coelho
b3f74c7c4f [typescript][angular] move app description from license info to readme (#19397)
* [typescript][angular] move app description from header license info to readme

* [typescript][angular] move app description from header license info to readme
2024-08-21 13:51:39 +02:00
Richard Whitehouse
eda4547f15 [Rust Server] Fix up model generation (#19363)
* [Rust Server] Fix up model generation

- Correctly generate anyOf/oneOf models
- Fix up ToString / FromStr support
- Disable PartialOrd generation for anyOf/oneOf models
- Generate models for inline enums
- Support enums in headers, and vectors of models in headers

* [Rust Server] Add test for anyOf with additional properties

* Update samples

* [Rust Server] Tidy up logging
2024-08-21 15:14:52 +08:00
Rory Schadler
cc98333d87 feat(python): handle multiple file parameters (#19329)
* test: fix broken python test

* fix: handle multiple file parameters

Previously an array of files was not handled correctly, despite the type
annotation implying it was.

* feat: handle filename,filedata tuples in file param

This allows for users to pass filenames with their data in file params,
which is useful for multipart formdata requests. Without this, the list
of files added in the previous commit would have the same filename for
all files (the parameter name).
2024-08-21 15:09:10 +08:00
William Cheng
c2472b03b6 update doc to v7.8.0 2024-08-19 16:19:49 +08:00
William Cheng
91da2fd240 Prepare 7.9.0 snapshot (#19386)
* Revert "v7.8.0 release (#19385)"

This reverts commit 6bdc452f92.

* update samples for v7.9.0-snapshot
2024-08-19 16:14:51 +08:00
8010 changed files with 79302 additions and 14634 deletions

View File

@@ -10,7 +10,7 @@ on:
paths:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/restclient-*/**
- samples/client/petstore/java/restclient-*/**
jobs:
build:
name: Build Java Client JDK17
@@ -25,6 +25,7 @@ jobs:
- samples/client/petstore/java/restclient
- samples/client/petstore/java/restclient-nullable-arrays
- samples/client/petstore/java/restclient-swagger2
- samples/client/petstore/java/restclient-useSingleRequestParameter
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4

View File

@@ -30,7 +30,6 @@ jobs:
# server
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request
- samples/server/petstore/kotlin-springboot-request-cookie
- samples/server/petstore/kotlin-server/javalin
- samples/server/petstore/kotlin-server/javalin-6

View File

@@ -15,7 +15,7 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.8.0`):
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.9.0`):
[![Build Status](https://api.travis-ci.com/OpenAPITools/openapi-generator.svg?branch=master&status=passed)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
@@ -128,8 +128,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.8.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.8.0-SNAPSHOT/) | 09.08.2024 | Minor release with breaking changes (with fallback) |
| [7.7.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.7.0) (latest stable release) | 02.07.2024 | Minor release with breaking changes (with fallback) |
| 7.9.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.9.0-SNAPSHOT/) | 23.09.2024 | Minor release with breaking changes (with fallback) |
| [7.8.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.8.0) (latest stable release) | 19.08.2024 | Minor release with breaking changes (with fallback) |
| [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | Minor release with breaking changes (with fallback) |
| [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) |
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
@@ -192,16 +192,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -436,7 +436,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 7.7.0
openapi-generator-cli version-manager set 7.8.0
```
Or install it as dev-dependency:
@@ -445,6 +445,43 @@ Or install it as dev-dependency:
npm install @openapitools/openapi-generator-cli -D
```
<!-- /RELEASE_VERSION -->
#### Use locally built JAR
In order to use a locally built jar of the generator CLI, you can copy the jar from your local build (i.e. if you were to `build` this repository it would be in `~/openapi-generator/modules/openapi-generator-cli/target/openapi-generator-cli.jar`) into `./node_modules/@openapitools/openapi-generator-cli/versions/` and change the `version` in the `openapitools.json` file to the base name of the jar file.
E.g.:
```sh
cd openapi-generator
./mvnw clean package
cp ./modules/openapi-generator-cli/target/openapi-generator-cli.jar /your/project/node_modules/@openapitools/openapi-generator-cli/versions/my-local-snapshot.jar
```
and then:
```json
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "my-local-snapshot",
}
}
```
#### Use nightly `SNAPSHOT` build
Change your `openapitools.json` to:
```json
{
"$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "7.9.0-20240829.123431-22",
"repository": {
"downloadUrl": "https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.9.0-SNAPSHOT/openapi-generator-cli-${versionName}.jar"
}
}
}
```
(example is with a snapshot of `7.9.0`, please change the `version` and `downloadUrl` accordingly)
## [2 - Getting Started](#table-of-contents)
To generate a PHP client for [petstore.yaml](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml), please run the following
@@ -460,7 +497,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
<!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar)
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar)
<!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`

View File

@@ -11,3 +11,4 @@ additionalProperties:
useOneOfDiscriminatorLookup: true
disallowAdditionalPropertiesIfNotPresent: false
gradleProperties: "\n# JVM arguments\norg.gradle.jvmargs=-Xmx2024m -XX:MaxPermSize=512m\n# set timeout\norg.gradle.daemon.idletimeout=3600000\n# show all warnings\norg.gradle.warning.mode=all"
failOnUnknownProperties: true

View File

@@ -12,3 +12,4 @@ additionalProperties:
useOneOfDiscriminatorLookup: true
disallowAdditionalPropertiesIfNotPresent: false
gradleProperties: "\n# JVM arguments\norg.gradle.jvmargs=-Xmx2024m -XX:MaxPermSize=512m\n# set timeout\norg.gradle.daemon.idletimeout=3600000\n# show all warnings\norg.gradle.warning.mode=all"
failOnUnknownProperties: true

View File

@@ -0,0 +1,9 @@
generatorName: java
outputDir: samples/client/petstore/java/restclient-useSingleRequestParameter
library: restclient
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: singleparam-restclient
hideGenerationTimestamp: "true"
useSingleRequestParameter: true

View File

@@ -0,0 +1,4 @@
generatorName: k6
outputDir: samples/client/others/k6/basicAuth
inputSpec: modules/openapi-generator/src/test/resources/3_0/k6/basic_auth.yaml
templateDir: modules/openapi-generator/src/main/resources/k6

View File

@@ -0,0 +1,4 @@
generatorName: k6
outputDir: samples/client/others/k6/bearerAuth
inputSpec: modules/openapi-generator/src/test/resources/3_0/k6/bearer_auth.yaml
templateDir: modules/openapi-generator/src/main/resources/k6

View File

@@ -1,9 +0,0 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-request
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
appendRequestToHandler: true
interfaceOnly: true
useSpringBoot3: true

View File

@@ -2,6 +2,9 @@ generatorName: python-pydantic-v1
outputDir: samples/openapi3/client/petstore/python-pydantic-v1
inputSpec: modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/python-pydantic-v1
gitHost: GIT_HOST
gitUserId: GIT_USER_ID
gitRepoId: GIT_REPO_ID
additionalProperties:
packageName: petstore_api
useOneOfDiscriminatorLookup: "true"

View File

@@ -0,0 +1,7 @@
generatorName: typescript-axios
outputDir: samples/client/petstore/typescript-axios/builds/with-interfaces-and-with-single-request-param
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-axios
additionalProperties:
withInterfaces: "true"
useSingleRequestParameter: "true"

View File

@@ -0,0 +1,10 @@
generatorName: typescript
outputDir: samples/openapi3/client/petstore/typescript/builds/deno_object_params
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript
additionalProperties:
platform: deno
npmName: ts-petstore-client
useObjectParameters: true
projectName: ts-petstore-client
moduleName: petstore

View File

@@ -0,0 +1,9 @@
generatorName: typescript
outputDir: samples/openapi3/client/petstore/typescript/builds/explode-query
inputSpec: modules/openapi-generator/src/test/resources/3_0/snakecase-discriminator.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript
additionalProperties:
platform: node
npmName: ts-petstore-client
projectName: ts-petstore-client
moduleName: petstore

View File

@@ -0,0 +1,6 @@
generatorName: typescript-fetch
outputDir: samples/client/petstore/typescript-fetch/builds/validation-attributes
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/validation-attributes.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
additionalProperties:
validationAttributes: true

View File

@@ -49,6 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|errorObjectType|Error Object type. (This option is for okhttp-gson only)| |null|
|failOnUnknownProperties|Fail Jackson de-serialization on unknown properties| |false|
|generateBuilders|Whether to generate builders for models| |false|
|generateClientAsBean|For resttemplate, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
@@ -98,7 +99,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile support this option.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -49,6 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|errorObjectType|Error Object type. (This option is for okhttp-gson only)| |null|
|failOnUnknownProperties|Fail Jackson de-serialization on unknown properties| |false|
|generateBuilders|Whether to generate builders for models| |false|
|generateClientAsBean|For resttemplate, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
@@ -98,7 +99,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile support this option.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -22,7 +22,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|annotationLibrary|Select the complementary documentation annotation library.|<dl><dt>**none**</dt><dd>Do not annotate Model and Api with complementary annotations.</dd><dt>**swagger1**</dt><dd>Annotate Model and Api using the Swagger Annotations 1.x library.</dd><dt>**swagger2**</dt><dd>Annotate Model and Api using the Swagger Annotations 2.x library.</dd></dl>|swagger2|
|apiPackage|api package for generated code| |org.openapitools.api|
|apiSuffix|suffix for api classes| |Api|
|appendRequestToHandler|Append ServerHttpRequest to handler method for getting request stuff| |false|
|artifactId|Generated artifact id (name of jar).| |openapi-spring|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|basePackage|base package (invokerPackage) for generated code| |org.openapitools|

View File

@@ -44,6 +44,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|supportsES6|Generate code that conforms to ES6.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |true|
|useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false|
|validationAttributes|Setting this property to true will generate the validation attributes of model properties.| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|withoutRuntimeChecks|Setting this property to true will remove any runtime checks on the request and response payloads. Payloads will be casted to their expected types.| |false|

View File

@@ -22,7 +22,7 @@ npm install @openapitools/openapi-generator-cli -g
To install a specific version of the tool, pass the version during installation:
<!-- RELEASE_VERSION -->
```bash
openapi-generator-cli version-manager set 7.7.0
openapi-generator-cli version-manager set 7.8.0
```
<!-- /RELEASE_VERSION -->
To install the tool as a dev dependency in your current project:
@@ -103,18 +103,18 @@ docker run --rm \
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar`
For **Mac/Linux** users:
```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar
```
<!-- /RELEASE_VERSION -->

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.8.0
openApiGeneratorVersion=7.9.0-SNAPSHOT
# /RELEASE_VERSION
# BEGIN placeholders

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.8.0
openApiGeneratorVersion=7.9.0-SNAPSHOT
# /RELEASE_VERSION

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -410,7 +410,7 @@ public class CodegenConstants {
public static final String UNSUPPORTED_V310_SPEC_MSG =
"Generation using 3.1.0 specs is in development and is not officially supported yet. " +
"If you would like to expedite development, please consider woking on the open issues in the 3.1.0 project: https://github.com/orgs/OpenAPITools/projects/4/views/1 " +
"If you would like to expedite development, please consider working on the open issues in the 3.1.0 project: https://github.com/orgs/OpenAPITools/projects/4/views/1 " +
"and reach out to our team on Slack at https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g";
public static final String ENUM_UNKNOWN_DEFAULT_CASE = "enumUnknownDefaultCase";

View File

@@ -31,7 +31,8 @@ public class CodegenOperation {
isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, defaultReturnType = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, hasConstantParams = false,
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
hasErrorResponseObject, // if 4xx, 5xx responses have at least one error object defined
hasSingleParam = false; // if the operation has only one parameter;
public CodegenProperty returnProperty;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
@@ -351,6 +352,7 @@ public class CodegenOperation {
sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
sb.append(", hasSingleParam=").append(hasSingleParam);
sb.append(", isRestfulIndex=").append(isRestfulIndex);
sb.append(", isRestfulShow=").append(isRestfulShow);
sb.append(", isRestfulCreate=").append(isRestfulCreate);
@@ -431,6 +433,7 @@ public class CodegenOperation {
hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse &&
hasErrorResponseObject == that.hasErrorResponseObject &&
hasSingleParam == that.hasSingleParam &&
isRestfulIndex == that.isRestfulIndex &&
isRestfulShow == that.isRestfulShow &&
isRestfulCreate == that.isRestfulCreate &&
@@ -500,6 +503,6 @@ public class CodegenOperation {
pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
vendorExtensions, nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase,
operationIdSnakeCase, hasErrorResponseObject, requiredAndNotNullableParams, notNullableParams, constantParams);
operationIdSnakeCase, hasErrorResponseObject, hasSingleParam, requiredAndNotNullableParams, notNullableParams, constantParams);
}
}

View File

@@ -243,6 +243,8 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
private boolean hasDiscriminatorWithNonEmptyMapping;
private CodegenComposedSchemas composedSchemas = null;
private boolean hasMultipleTypes = false;
/** true if the property's baseName != name, e.g. baseName = '_prop.value', name = 'propValue' after sanitization */
private boolean hasSanitizedName = false;
private Map<String, CodegenProperty> requiredVarsMap;
private String ref;
private boolean schemaIsFromAdditionalProperties;
@@ -843,6 +845,12 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
this.hasMultipleTypes = hasMultipleTypes;
}
public boolean getHasSanitizedName() {
return hasSanitizedName;
}
public void setHasSanitizedName(boolean hasSanitizedName) { this.hasSanitizedName = hasSanitizedName; }
@Override
public boolean getIsUuid() {
return isUuid;
@@ -1061,6 +1069,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
sb.append(", getHasDiscriminatorWithNonEmptyMapping=").append(hasDiscriminatorWithNonEmptyMapping);
sb.append(", composedSchemas=").append(composedSchemas);
sb.append(", hasMultipleTypes=").append(hasMultipleTypes);
sb.append(", hasSanitizedName=").append(hasSanitizedName);
sb.append(", requiredVarsMap=").append(requiredVarsMap);
sb.append(", ref=").append(ref);
sb.append(", schemaIsFromAdditionalProperties=").append(schemaIsFromAdditionalProperties);
@@ -1129,6 +1138,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
isNull == that.isNull &&
isVoid == that.isVoid &&
hasMultipleTypes == that.getHasMultipleTypes() &&
hasSanitizedName == that.getHasSanitizedName() &&
hasDiscriminatorWithNonEmptyMapping == that.hasDiscriminatorWithNonEmptyMapping &&
isBooleanSchemaTrue == that.getIsBooleanSchemaTrue() &&
isBooleanSchemaFalse == that.getIsBooleanSchemaFalse() &&
@@ -1207,7 +1217,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
vendorExtensions, hasValidation, isInherited, discriminatorValue, nameInPascalCase, nameInCamelCase,
nameInSnakeCase, enumName, maxItems, minItems, isXmlAttribute, xmlPrefix, xmlName,
xmlNamespace, isXmlWrapped, isNull, isVoid, additionalPropertiesIsAnyType, hasVars, hasRequired,
hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes, requiredVarsMap,
hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes, hasSanitizedName, requiredVarsMap,
ref, uniqueItemsBoolean, schemaIsFromAdditionalProperties, isBooleanSchemaTrue, isBooleanSchemaFalse,
format, dependentRequired, contains);
}

View File

@@ -3884,6 +3884,7 @@ public class DefaultCodegen implements CodegenConfig {
property.name = toVarName(name);
property.baseName = name;
property.setHasSanitizedName(!property.baseName.equals(property.name));
if (ModelUtils.getType(p) == null) {
property.openApiType = getSchemaType(p);
} else {
@@ -4737,6 +4738,9 @@ public class DefaultCodegen implements CodegenConfig {
}
op.hasRequiredParams = op.requiredParams.size() > 0;
// check if the operation has only a single parameter
op.hasSingleParam = op.allParams.size() == 1;
// set Restful Flag
op.isRestfulShow = op.isRestfulShow();
op.isRestfulIndex = op.isRestfulIndex();

View File

@@ -141,11 +141,15 @@ public class InlineModelResolver {
}
}
// flatten path-level parameters
flattenParameters(pathname, path.getParameters(), null);
// flatten parameters for each operation
for (Map.Entry<HttpMethod, Operation> operationEntry : toFlatten) {
Operation operation = operationEntry.getValue();
String inlineSchemaName = this.getInlineSchemaName(operationEntry.getKey(), pathname);
flattenRequestBody(inlineSchemaName, operation);
flattenParameters(inlineSchemaName, operation);
flattenParameters(inlineSchemaName, operation.getParameters(), operation.getOperationId());
flattenResponses(inlineSchemaName, operation);
}
}
@@ -509,15 +513,20 @@ public class InlineModelResolver {
* Flatten inline models in parameters
*
* @param modelName model name
* @param operation target operation
* @param parameters list of parameters
* @param operationId operation Id (optional)
*/
private void flattenParameters(String modelName, Operation operation) {
List<Parameter> parameters = operation.getParameters();
private void flattenParameters(String modelName, List<Parameter> parameters, String operationId) {
//List<Parameter> parameters = operation.getParameters();
if (parameters == null) {
return;
}
for (Parameter parameter : parameters) {
if (StringUtils.isNotEmpty(parameter.get$ref())) {
parameter = ModelUtils.getReferencedParameter(openAPI, parameter);
}
if (parameter.getSchema() == null) {
continue;
}
@@ -528,7 +537,7 @@ public class InlineModelResolver {
continue;
}
String schemaName = resolveModelName(parameterSchema.getTitle(),
(operation.getOperationId() == null ? modelName : operation.getOperationId()) + "_" + parameter.getName() + "_parameter");
(operationId == null ? modelName : operationId) + "_" + parameter.getName() + "_parameter");
// Recursively gather/make inline models within this schema if any
gatherInlineModels(parameterSchema, schemaName);
if (isModelNeeded(parameterSchema)) {

View File

@@ -411,9 +411,7 @@ public class OpenAPINormalizer {
parameter = ModelUtils.getReferencedParameter(openAPI, parameter);
}
if (parameter.getSchema() == null) {
continue;
} else {
if (parameter.getSchema() != null) {
Schema newSchema = normalizeSchema(parameter.getSchema(), new HashSet<>());
parameter.setSchema(newSchema);
}

View File

@@ -63,6 +63,7 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.openapitools.codegen.utils.CamelizeOption.*;
import static org.openapitools.codegen.utils.ModelUtils.getSchemaItems;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*;
@@ -568,15 +569,16 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.sanitizeConfig();
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
importMapping.put("JsonDeserialize", "com.fasterxml.jackson.databind.annotation.JsonDeserialize");
if (serializeBigDecimalAsString) {
importMapping.put("JsonFormat", "com.fasterxml.jackson.annotation.JsonFormat");
}
// imports for pojos
importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty");
importMapping.put("ApiModel", "io.swagger.annotations.ApiModel");
importMapping.put("Schema", "io.swagger.v3.oas.annotations.media.Schema");
importMapping.put("BigDecimal", "java.math.BigDecimal");
importMapping.put("JsonDeserialize", "com.fasterxml.jackson.databind.annotation.JsonDeserialize");
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes");
importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo");
@@ -704,7 +706,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
propertyHash.put(property.name, property);
final CodegenProperty parentVar = property.clone();
parentVar.isInherited = true;
LOGGER.info("adding parent variable {} to {}", property.name, codegenModel.name);
LOGGER.debug("adding parent variable {} to {}", property.name, codegenModel.name);
codegenModel.parentVars.add(parentVar);
Set<String> imports = parentVar.getImports(true, this.importBaseType, generatorMetadata.getFeatureSet()).stream().filter(Objects::nonNull).collect(Collectors.toSet());
for (String imp : imports) {
@@ -1007,8 +1009,9 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = ModelUtils.getSchemaItems(schema);
return getSchemaType(target) + "<" + getBeanValidation(items) + getTypeDeclaration(items) + ">";
Schema<?> items = getSchemaItems(schema);
String typeDeclaration = getTypeDeclarationForArray(items);
return getSchemaType(target) + "<" + typeDeclaration + ">";
} else if (ModelUtils.isMapSchema(target)) {
// Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that also defines
// additionalproperties: true
@@ -1023,6 +1026,29 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return super.getTypeDeclaration(target);
}
private String getTypeDeclarationForArray(Schema<?> items) {
String typeDeclaration = getTypeDeclaration(items);
String beanValidation = getBeanValidation(items);
if (StringUtils.isEmpty(beanValidation)) {
return typeDeclaration;
}
int idxLt = typeDeclaration.indexOf('<');
int idx = idxLt < 0 ?
typeDeclaration.lastIndexOf('.'):
// last dot before the generic like in List<com.mycompany.Container<java.lang.Object>
typeDeclaration.substring(0, idxLt).lastIndexOf('.');
if (idx > 0) {
// fix full qualified name, we need List<java.lang.@Valid String>
// or List<com.mycompany.@Valid Container<java.lang.Object>
return typeDeclaration.substring(0, idx + 1) + beanValidation
+ typeDeclaration.substring(idx + 1);
} else {
return beanValidation + typeDeclaration;
}
}
/**
* This method stand for resolve bean validation for container(array, set).
* Return empty if there's no bean validation for requested type or prop useBeanValidation false or missed.
@@ -1705,11 +1731,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (serializeBigDecimalAsString && jackson) {
if ("decimal".equals(property.baseType) || "bigdecimal".equalsIgnoreCase(property.baseType)) {
// we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("x-extra-annotation", "@JsonSerialize(using = ToStringSerializer.class)");
property.vendorExtensions.put("x-extra-annotation", "@JsonFormat(shape = JsonFormat.Shape.STRING)");
// this requires some more imports to be added for this model...
model.imports.add("ToStringSerializer");
model.imports.add("JsonSerialize");
model.imports.add("JsonFormat");
}
}
@@ -1727,7 +1752,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
model.imports.add("Arrays");
} else if ("set".equals(property.containerType)) {
model.imports.add("LinkedHashSet");
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
model.imports.add("JsonDeserialize");
property.vendorExtensions.put("x-setter-extra-annotation", "@JsonDeserialize(as = LinkedHashSet.class)");
}

View File

@@ -1951,9 +1951,22 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
}
moduleImports.add("typing", "Union");
PythonType pt = new PythonType("Union");
pt.addTypeParam(bytest);
pt.addTypeParam(strt);
if (cp.getIsBinary()) {
moduleImports.add("typing", "Tuple");
PythonType tt = new PythonType("Tuple");
// this string is a filename, not a validated value
tt.addTypeParam(new PythonType("str"));
tt.addTypeParam(bytest);
pt.addTypeParam(tt);
}
return pt;
} else {
// same as above which has validation
@@ -1964,6 +1977,17 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
PythonType pt = new PythonType("Union");
pt.addTypeParam(new PythonType("StrictBytes"));
pt.addTypeParam(new PythonType("StrictStr"));
if (cp.getIsBinary()) {
moduleImports.add("typing", "Tuple");
PythonType tt = new PythonType("Tuple");
tt.addTypeParam(new PythonType("StrictStr"));
tt.addTypeParam(new PythonType("StrictBytes"));
pt.addTypeParam(tt);
}
return pt;
}
}

View File

@@ -856,6 +856,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
private String getNameUsingModelPropertyNaming(String name) {
switch (getModelPropertyNaming()) {
case original:
additionalProperties.put("modelPropertyNamingOriginal", true);
return name;
case camelCase:
return camelize(name, LOWERCASE_FIRST_LETTER);

View File

@@ -132,9 +132,6 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
super.postProcessModelProperty(model, property);
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
if (jackson) {
//Add jackson imports when model has inner enum

View File

@@ -227,8 +227,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
super.postProcessModelProperty(model, property);
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
model.imports.remove("JsonFormat");
//Add imports for Jackson when model has inner enum
if (isJackson()) {

View File

@@ -100,6 +100,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String MICROPROFILE_KUMULUZEE = "kumuluzee";
public static final String WEBCLIENT_BLOCKING_OPERATIONS = "webclientBlockingOperations";
public static final String USE_ENUM_CASE_INSENSITIVE = "useEnumCaseInsensitive";
public static final String FAIL_ON_UNKNOWN_PROPERTIES = "failOnUnknownProperties";
public static final String SERIALIZATION_LIBRARY_GSON = "gson";
public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
@@ -134,6 +135,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Setter protected boolean withAWSV4Signature = false;
@Setter protected String gradleProperties;
@Setter protected String errorObjectType;
@Getter @Setter protected boolean failOnUnknownProperties = false;
protected String authFolder;
/**
* Serialization library.
@@ -235,11 +237,12 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newString(CONFIG_KEY_FROM_CLASS_NAME, "If true, set tag as key in @RegisterRestClient. Default to false. Only `microprofile` supports this option."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC + " Only jersey2, jersey3, native, okhttp-gson support this option."));
cliOptions.add(CliOption.newString(MICROPROFILE_REST_CLIENT_VERSION, "Version of MicroProfile Rest Client API."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile support this option."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option."));
cliOptions.add(CliOption.newBoolean(WEBCLIENT_BLOCKING_OPERATIONS, "Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync", this.webclientBlockingOperations));
cliOptions.add(CliOption.newBoolean(GENERATE_CLIENT_AS_BEAN, "For resttemplate, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).", this.generateClientAsBean));
cliOptions.add(CliOption.newBoolean(SUPPORT_URL_QUERY, "Generate toUrlQueryString in POJO (default to true). Available on `native`, `apache-httpclient` libraries."));
cliOptions.add(CliOption.newBoolean(USE_ENUM_CASE_INSENSITIVE, "Use `equalsIgnoreCase` when String for enum comparison", useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", this.failOnUnknownProperties));
supportedLibraries.put(JERSEY2, "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.17.1");
supportedLibraries.put(JERSEY3, "HTTP client: Jersey client 3.1.1. JSON processing: Jackson 2.17.1");
@@ -390,6 +393,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
convertPropertyToStringAndWriteBack(GRADLE_PROPERTIES, this::setGradleProperties);
convertPropertyToStringAndWriteBack(ERROR_OBJECT_TYPE, this::setErrorObjectType);
convertPropertyToBooleanAndWriteBack(WEBCLIENT_BLOCKING_OPERATIONS, op -> webclientBlockingOperations=op);
convertPropertyToBooleanAndWriteBack(FAIL_ON_UNKNOWN_PROPERTIES, this::setFailOnUnknownProperties);
// add URL query deepObject support to native, apache-httpclient by default
if (!additionalProperties.containsKey(SUPPORT_URL_QUERY)) {
@@ -937,8 +941,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
if (MICROPROFILE.equals(getLibrary())) {
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
}
if (!BooleanUtils.toBoolean(model.isEnum)) {

View File

@@ -371,14 +371,10 @@ public class JavaHelidonClientCodegen extends JavaHelidonCommonCodegen {
if (HELIDON_MP.equals(getLibrary())) {
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
} else if (HELIDON_SE.equals(getLibrary())) {
// TODO check for SE-specifics
model.imports.remove("ApiModelProperty");
model.imports.remove("ApiModel");
model.imports.remove("JsonSerialize");
model.imports.remove("ToStringSerializer");
}
if ("set".equals(property.containerType) && !JACKSON.equals(serializationLibrary)) {

View File

@@ -250,8 +250,6 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
codegenModel.imports.remove("ApiModel");
}
if (!jackson) {
codegenModel.imports.remove("JsonSerialize");
codegenModel.imports.remove("ToStringSerializer");
codegenModel.imports.remove("JsonValue");
codegenModel.imports.remove("JsonProperty");
}

View File

@@ -362,6 +362,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
public static final String PROJECT_DESCRIPTION = "projectDescription";
public static final String PROJECT_VERSION = "projectVersion";
public static final String BASE_URL = "baseURL";
public static final String TOKEN = "authToken";
public static final String PRESERVE_LEADING_PARAM_CHAR = "preserveLeadingParamChar";
static final Collection<String> INVOKER_PKG_SUPPORTING_FILES = Arrays.asList("script.mustache", "README.mustache");
static final String[][] JAVASCRIPT_SUPPORTING_FILES = {
@@ -666,7 +667,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
pathVariables.put(groupName, variables);
// put auth medthods in header or cookie
// put auth methods in header or cookie
for (CodegenSecurity globalAuthMethod : globalAuthMethods) {
if (globalAuthMethod.isKeyInHeader) {
httpParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
@@ -676,6 +677,25 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
cookieParams.add(new Parameter(globalAuthMethod.keyParamName, getTemplateString(toVarName(globalAuthMethod.keyParamName))));
extraParameters.add(new Parameter(toVarName(globalAuthMethod.keyParamName), globalAuthMethod.keyParamName.toUpperCase(Locale.ROOT)));
}
// when security is specifically given empty for an end point, it should not be included
if (operation.getSecurity() != null && operation.getSecurity().isEmpty()) {
continue;
}
if ("bearerAuth".equalsIgnoreCase(globalAuthMethod.name)) {
if (operation.getSecurity() == null ||
operation.getSecurity().stream().anyMatch(securityRequirement -> securityRequirement.containsKey("bearerAuth"))) {
httpParams.add(new Parameter("Authorization", "`Bearer ${TOKEN}`"));
additionalProperties.put(TOKEN, true);
}
}
if ("basicAuth".equalsIgnoreCase(globalAuthMethod.name)) {
if (operation.getSecurity() == null ||
operation.getSecurity().stream().anyMatch(securityRequirement -> securityRequirement.containsKey("basicAuth"))) {
httpParams.add(new Parameter("Authorization", "`Basic ${TOKEN}`"));
additionalProperties.put(TOKEN, true);
}
}
}
final HTTPParameters params = new HTTPParameters(null, cookieParams, httpParams, null, null, null, null, null,

View File

@@ -105,7 +105,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public static final String BEAN_QUALIFIERS = "beanQualifiers";
public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
public static final String APPEND_REQUEST_TO_HANDLER = "appendRequestToHandler";
public static final String REQUEST_MAPPING_OPTION = "requestMappingMode";
public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController";
public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface";
@@ -236,7 +235,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
"@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(APPEND_REQUEST_TO_HANDLER, "Append ServerHttpRequest to handler method for getting request stuff", false);
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
@@ -356,10 +354,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
return this.useBeanValidation;
}
public boolean isAppendRequestToHandler() {
return Boolean.parseBoolean(additionalProperties.getOrDefault(APPEND_REQUEST_TO_HANDLER, false).toString());
}
@Override
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
@@ -435,10 +429,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
typeMapping.put("map", "kotlin.collections.MutableMap");
}
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
// Swagger import mappings
importMapping.put("ApiModel", "io.swagger.annotations.ApiModel");
importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty");
@@ -893,9 +883,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
final List<CodegenParameter> allParams = operation.allParams;
if (allParams != null) {
if (this.isAppendRequestToHandler()) {
allParams.add(new RequestCodegenParameter());
}
allParams.forEach(param ->
// This is necessary in case 'modelMutable' is enabled,
// to prevent Spring Request handlers from being generated with
@@ -987,22 +974,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
return !type.startsWith("org.springframework.") && super.needToImport(type);
}
@AllArgsConstructor
@Data
@EqualsAndHashCode(callSuper = true)
static class RequestCodegenParameter extends CodegenParameter {
boolean isRequestObject = true;
public RequestCodegenParameter() {
this.isOptional = false;
this.required = true;
this.paramName = "serverHttpRequest";
this.dataType = "ServerHttpRequest";
}
}
public RequestMappingMode getRequestMappingMode() {
return requestMappingMode;
}

View File

@@ -22,6 +22,9 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.FileSchema;
import io.swagger.v3.oas.models.media.XML;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
@@ -119,6 +122,9 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
)
);
// We need inline enums to be resolved to a separate model so that
// anyOf/oneOf that contain them work correctly.
inlineSchemaOption.put("RESOLVE_INLINE_ENUMS", "true");
// Show the generation timestamp by default
hideGenerationTimestamp = Boolean.FALSE;
@@ -244,6 +250,7 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
supportingFiles.add(new SupportingFile("example-ca.pem", "examples", "ca.pem"));
supportingFiles.add(new SupportingFile("example-server-chain.pem", "examples", "server-chain.pem"));
supportingFiles.add(new SupportingFile("example-server-key.pem", "examples", "server-key.pem"));
supportingFiles.add(new SupportingFile("bin-cli.mustache", "bin", "cli.rs"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());
}
@@ -580,6 +587,13 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
String vendorExtensionHttpMethod = op.httpMethod.toUpperCase(Locale.ROOT);
op.vendorExtensions.put("x-http-method", vendorExtensionHttpMethod);
boolean isDelete = op.httpMethod.toUpperCase(Locale.ROOT).equals("DELETE");
op.vendorExtensions.put("x-is-delete", isDelete);
if (isDelete) {
additionalProperties.put("apiHasDeleteMethods", true);
}
if (!op.vendorExtensions.containsKey("x-must-use-response")) {
// If there's more than one response, than by default the user must explicitly handle them
op.vendorExtensions.put("x-must-use-response", op.responses.size() > 1);
@@ -852,6 +866,27 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
op.vendorExtensions.put("x-has-request-body", true);
}
// The CLI generates a structopt structure for each operation. This can only have a single
// use of a short option, which comes from the parameter name, so we need to police
// against duplicates
HashMap<Character, CodegenParameter> availableOptions = new HashMap();
for (CodegenParameter p : op.allParams) {
if (p.isBoolean && p.isPrimitiveType) {
char shortOption = p.paramName.charAt(0);
if (shortOption == 'a' || shortOption == 'o' || shortOption == 'f') {
// These are used by serverAddress, output, and force
p.vendorExtensions.put("x-provide-cli-short-opt", false);
} else if (availableOptions.containsKey(shortOption)) {
availableOptions.get(shortOption).vendorExtensions.put("x-provide-cli-short-opt", false);
p.vendorExtensions.put("x-provide-cli-short-opt", false);
} else {
availableOptions.put(shortOption, p);
p.vendorExtensions.put("x-provide-cli-short-opt", true);
}
}
}
String underscoredOperationId = underscore(op.operationId).toUpperCase(Locale.ROOT);
if (op.bodyParam != null) {
@@ -1003,6 +1038,66 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
return codegenParameter;
}
@Override
public String getTypeDeclaration(String name) {
return "models::" + name;
}
private String modelFromSchema(Schema schema) {
String ref = null;
if (schema != null) {
ref = schema.get$ref();
}
if (ref != null && ref.indexOf("#/components/schemas/") == 0) {
ref = toModelName(ref.substring("#/components/schemas/".length()));
} else {
ref = null;
}
return ref;
}
@Override
public String getTypeDeclaration(Schema p) {
LOGGER.trace("Getting type declaration for schema");
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
String innerType = getTypeDeclaration(inner);
return typeMapping.get("array") + "<" + innerType + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
String innerType = getTypeDeclaration(inner);
StringBuilder typeDeclaration = new StringBuilder(typeMapping.get("map")).append("<").append(typeMapping.get("string")).append(", ");
typeDeclaration.append(innerType).append(">");
return typeDeclaration.toString();
} else if (!StringUtils.isEmpty(p.get$ref())) {
String dataType;
try {
dataType = modelFromSchema(p);
if (dataType != null) {
dataType = "models::" + dataType;
LOGGER.debug("Returning " + dataType + " from ref");
}
} catch (Exception e) {
dataType = null;
LOGGER.error("Error obtaining the datatype from schema (model): " + p + ". Error was: " + e.getMessage(), e);
}
LOGGER.debug("Returning " + dataType);
return dataType;
} else if (p instanceof FileSchema) {
return typeMapping.get("File").toString();
}
return super.getTypeDeclaration(p);
}
@Override
public String toInstantiationType(Schema p) {
if (ModelUtils.isArraySchema(p)) {
@@ -1023,6 +1118,17 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
CodegenModel mdl = super.fromModel(name, model);
LOGGER.debug("fromModel (base end): " + mdl);
if (!StringUtils.isEmpty(model.get$ref())) {
String ref = ModelUtils.getSimpleRef(model.get$ref());
String dataType = toModelName(ref);
mdl.dataType = dataType;
mdl.isAlias = false;
LOGGER.debug("Schema for: " + name + " is wrapper for: " + dataType);
}
if (ModelUtils.isArraySchema(model)) {
Schema inner = ModelUtils.getSchemaItems(model);
String xmlName = null;
@@ -1060,49 +1166,84 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
additionalProperties.put("usesXmlNamespaces", true);
}
LOGGER.trace("Created model: {}", mdl);
Schema modelAdditionalProperties = ModelUtils.getAdditionalProperties(model);
return mdl;
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> newObjs = super.postProcessAllModels(objs);
//Index all CodegenModels by model name.
HashMap<String, CodegenModel> allModels = new HashMap<>();
for (Entry<String, ModelsMap> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
List<ModelMap> models = entry.getValue().getModels();
for (ModelMap mo : models) {
allModels.put(modelName, mo.getModel());
}
if (modelAdditionalProperties != null) {
mdl.additionalPropertiesType = getTypeDeclaration(modelAdditionalProperties);
}
for (Entry<String, CodegenModel> entry : allModels.entrySet()) {
CodegenModel model = entry.getValue();
// Does this support partial ordering?
boolean partialOrdSupport = true;
if (uuidType.equals(model.dataType)) {
if (mdl.dataType != null && mdl.dataType.equals("object")) {
// Object isn't a sensible default. Instead, we set it to
// 'null'. This ensures that we treat this model as a struct
// with multiple parameters.
mdl.dataType = null;
} else if ("map".equals(mdl.dataType)) {
if (!mdl.allVars.isEmpty() || mdl.additionalPropertiesType == null) {
// We don't yet support `additionalProperties` that also have
// properties. If we see variables, we ignore the
// `additionalProperties` type ('map') and warn the user. This
// will produce code that compiles, but won't feature the
// `additionalProperties` - but that's likely more useful to
// the user than the alternative.
LOGGER.warn("Ignoring additionalProperties (see https://github.com/OpenAPITools/openapi-generator/issues/318) alongside defined properties");
mdl.dataType = null;
} else {
mdl.dataType = "std::collections::HashMap<String, " + mdl.additionalPropertiesType + ">";
partialOrdSupport = false;
}
} else if (mdl.dataType != null && mdl.isAlias) {
// We need to hack about with single-parameter models to
// get them recognised correctly.
mdl.isAlias = false;
mdl.dataType = typeMapping.get(mdl.dataType);
}
if (uuidType.equals(mdl.dataType)) {
additionalProperties.put("apiUsesUuid", true);
}
for (CodegenProperty prop : mdl.vars) {
if (uuidType.equals(prop.dataType)) {
additionalProperties.put("apiUsesUuid", true);
}
for (CodegenProperty prop : model.vars) {
if (uuidType.equals(prop.dataType)) {
additionalProperties.put("apiUsesUuid", true);
}
String xmlName = modelXmlNames.get(prop.dataType);
if (xmlName != null) {
prop.vendorExtensions.put("x-item-xml-name", xmlName);
}
}
String xmlName = modelXmlNames.get(prop.dataType);
if (xmlName != null) {
prop.vendorExtensions.put("x-item-xml-name", xmlName);
}
// Do we suppport doing ToString/FromStr conversions for query parameters?
boolean toStringSupport = true;
boolean isString = "String".equals(mdl.dataType);
if (uuidType.equals(prop.dataType)) {
additionalProperties.put("apiUsesUuid", true);
if (isString) {
toStringSupport = true;
} else if (mdl.dataType != null
&& (mdl.dataType.startsWith("swagger::OneOf") || mdl.dataType.startsWith("swagger::AnyOf"))) {
toStringSupport = false;
partialOrdSupport = false;
} else if (mdl.getAdditionalPropertiesType() != null) {
toStringSupport = false;
} else if (model instanceof ComposedSchema) {
for (Schema schema : ModelUtils.getInterfaces((ComposedSchema) model)) {
if (additionalProperties != null) {
toStringSupport = false;
}
}
}
return newObjs;
mdl.vendorExtensions.put("x-upper-case-name", name.toUpperCase(Locale.ROOT));
mdl.vendorExtensions.put("x-is-string", isString);
mdl.vendorExtensions.put("x-to-string-support", toStringSupport);
mdl.vendorExtensions.put("x-partial-ord", partialOrdSupport);
LOGGER.trace("Created model: " + name + ": " + mdl + " from schema: " + model);
return mdl;
}
@Override
@@ -1231,6 +1372,14 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
@Override
public String toOneOfName(List<String> names, Schema composedSchema) {
Map<String, Object> exts = null;
if (composedSchema != null) {
exts = composedSchema.getExtensions();
}
if (exts != null && exts.containsKey("x-one-of-name")) {
return (String) exts.get("x-one-of-name");
}
List<Schema> schemas = ModelUtils.getInterfaces(composedSchema);
List<String> types = new ArrayList<>();
@@ -1251,6 +1400,12 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
return "swagger::AnyOf" + types.size() + "<" + String.join(",", types) + ">";
}
@Override
public String toAllOfName(List<String> names, Schema composedSchema) {
// Handle all of objects as freeform
return null;
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
@@ -1327,47 +1482,10 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
for (ModelMap mo : objs.getModels()) {
CodegenModel cm = mo.getModel();
LOGGER.trace("Post processing model: {}", cm);
if ("object".equals(cm.dataType)) {
// Object isn't a sensible default. Instead, we set it to
// 'null'. This ensures that we treat this model as a struct
// with multiple parameters.
cm.dataType = null;
} else if ("map".equals(cm.dataType)) {
if (!cm.allVars.isEmpty() || cm.additionalPropertiesType == null) {
// We don't yet support `additionalProperties` that also have
// properties. If we see variables, we ignore the
// `additionalProperties` type ('map') and warn the user. This
// will produce code that compiles, but won't feature the
// `additionalProperties` - but that's likely more useful to
// the user than the alternative.
LOGGER.warn("Ignoring additionalProperties (see https://github.com/OpenAPITools/openapi-generator/issues/318) alongside defined properties");
cm.dataType = null;
} else {
cm.dataType = "std::collections::HashMap<String, " + cm.additionalPropertiesType + ">";
}
} else if (cm.dataType != null) {
// We need to hack about with single-parameter models to
// get them recognised correctly.
cm.isAlias = false;
cm.dataType = typeMapping.get(cm.dataType);
if (uuidType.equals(cm.dataType)) {
additionalProperties.put("apiUsesUuid", true);
}
}
cm.vendorExtensions.put("x-is-string", "String".equals(cm.dataType));
}
return super.postProcessModelsEnum(objs);
}
private void processParam(CodegenParameter param, CodegenOperation op) {
String example = null;
// If a parameter uses UUIDs, we need to import the UUID package.

View File

@@ -354,6 +354,16 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
}
}
}
if (!cm.oneOf.isEmpty()) {
// For oneOfs only import $refs within the oneOf
TreeSet<String> oneOfRefs = new TreeSet<>();
for (String im : cm.imports) {
if (cm.oneOf.contains(im)) {
oneOfRefs.add(im);
}
}
cm.imports = oneOfRefs;
}
}
for (ModelMap mo : models) {
CodegenModel cm = mo.getModel();

View File

@@ -60,6 +60,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
public static final String CAMEL_CASE = "camelCase";
public static final String PASCAL_CASE = "PascalCase";
public static final String USE_SQUARE_BRACKETS_IN_ARRAY_NAMES = "useSquareBracketsInArrayNames";
public static final String VALIDATION_ATTRIBUTES = "validationAttributes";
@Getter @Setter
protected String npmRepository = null;
@@ -92,7 +93,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
@Getter @Setter
protected String inferEntityFromUniqueIdWithName = null;
@Setter protected boolean packageAsSourceOnlyLibrary = false;
@Getter @Setter
protected Boolean generateValidationAttributes = false;
public TypeScriptFetchClientCodegen() {
super();
@@ -123,6 +125,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
this.cliOptions.add(new CliOption(IMPORT_FILE_EXTENSION_SWITCH, IMPORT_FILE_EXTENSION_SWITCH_DESC).defaultValue(""));
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'PascalCase', 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
this.cliOptions.add(new CliOption(USE_SQUARE_BRACKETS_IN_ARRAY_NAMES, "Setting this property to true will add brackets to array attribute names, e.g. my_values[].", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(VALIDATION_ATTRIBUTES, "Setting this property to true will generate the validation attributes of model properties.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
}
@Override
@@ -308,6 +311,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
}
}
}
setGenerateValidationAttributes(convertPropertyToBooleanAndWriteBack(VALIDATION_ATTRIBUTES));
}
@Override

View File

@@ -4,8 +4,8 @@ package {{invokerPackage}};
import java.util.Set;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ValidationException;
import {{javaxPackage}}.validation.ConstraintViolation;
import {{javaxPackage}}.validation.ValidationException;
public class BeanValidationException extends ValidationException {
/**

View File

@@ -137,7 +137,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public ApiClient(CloseableHttpClient httpClient) {
objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}});
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);

View File

@@ -24,8 +24,8 @@ import java.util.Map;
import java.util.StringJoiner;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
{{>generatedAnnotation}}

View File

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

View File

@@ -358,13 +358,12 @@
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<junit-version>5.10.2</junit-version>
</properties>
</project>

View File

@@ -173,7 +173,12 @@ public class ApiClient {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
{{#failOnUnknownProperties}}
objectMapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
{{/failOnUnknownProperties}}
{{^failOnUnknownProperties}}
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
{{/failOnUnknownProperties}}
objectMapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setDateFormat(new RFC3339DateFormat());

View File

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

View File

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

View File

@@ -147,6 +147,6 @@ dependencies {
testImplementation "org.junit.jupiter:junit-jupiter-params:$junit_version"
testImplementation "com.github.tomakehurst:wiremock-jre8:2.35.1"
testImplementation "org.hamcrest:hamcrest:2.2"
testImplementation "commons-io:commons-io:2.8.0"
testImplementation "commons-io:commons-io:2.16.1"
testImplementation "ch.qos.logback:logback-classic:1.2.3"
}

View File

@@ -32,7 +32,7 @@ lazy val root = (project in file(".")).
"org.junit.jupiter" % "junit-jupiter-params" % "5.7.0" % "test",
"com.github.tomakehurst" % "wiremock-jre8" % "2.35.1" % "test",
"org.hamcrest" % "hamcrest" % "2.2" % "test",
"commons-io" % "commons-io" % "2.8.0" % "test",
"commons-io" % "commons-io" % "2.16.1" % "test",
"com.novocode" % "junit-interface" % "0.10" % "test"
)
)

View File

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

View File

@@ -403,13 +403,12 @@
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<junit-version>5.10.0</junit-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<scribejava-version>8.3.3</scribejava-version>

View File

@@ -34,7 +34,12 @@ public class ApiClient {
// A reasonable default object mapper. Client can pass in a chosen ObjectMapper anyway, this is just for reasonable defaults.
private static ObjectMapper createDefaultObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper()
{{#failOnUnknownProperties}}
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
{{/failOnUnknownProperties}}
{{^failOnUnknownProperties}}
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
{{/failOnUnknownProperties}}
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new RFC3339DateFormat());
{{#joda}}

View File

@@ -988,24 +988,10 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
if (contentType.startsWith("multipart/form-data")) {
MultiPart multiPart = new MultiPart();
for (Entry<String, Object> param: formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
.fileName(file.getName()).size(file.length()).build();
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
if (param.getValue() instanceof Iterable) {
((Iterable)param.getValue()).forEach(v -> addParamToMultipart(v, param.getKey(), multiPart));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));
addParamToMultipart(param.getValue(), param.getKey(), multiPart);
}
}
entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE);
@@ -1034,6 +1020,36 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return entity;
}
/**
* Adds the object with the provided key to the MultiPart.
* Based on the object type sets Content-Disposition and Content-Type.
*
* @param obj Object
* @param key Key of the object
* @param multiPart MultiPart to add the form param to
*/
private void addParamToMultipart(Object value, String key, MultiPart multiPart) {
if (value instanceof File) {
File file = (File) value;
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key)
.fileName(file.getName()).size(file.length()).build();
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(value)));
}
}
/**
* Serialize the given Java object into string according the given
* Content-Type (only JSON, HTTP form is supported for now).

View File

@@ -32,7 +32,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
mapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}})
.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, true)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)

View File

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

View File

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

View File

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

View File

@@ -112,7 +112,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
attemptParsing |= (token == JsonToken.VALUE_NUMBER_FLOAT);
{{/isDecimal}}
{{#isBoolean}}
attemptParsing |= (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE));
attemptParsing |= (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE);
{{/isBoolean}}
{{#isNullable}}
attemptParsing |= (token == JsonToken.VALUE_NULL);

View File

@@ -401,13 +401,12 @@
<jackson-databind-nullable-version>0.2.6</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<junit-version>5.10.0</junit-version>
{{#hasHttpSignatureMethods}}
<http-signature-version>1.8</http-signature-version>

View File

@@ -988,24 +988,10 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
if (contentType.startsWith("multipart/form-data")) {
MultiPart multiPart = new MultiPart();
for (Entry<String, Object> param: formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey())
.fileName(file.getName()).size(file.length()).build();
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
if (param.getValue() instanceof Iterable) {
((Iterable)param.getValue()).forEach(v -> addParamToMultipart(v, param.getKey(), multiPart));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue())));
addParamToMultipart(param.getValue(), param.getKey(), multiPart);
}
}
entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE);
@@ -1034,6 +1020,36 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return entity;
}
/**
* Adds the object with the provided key to the MultiPart.
* Based on the object type sets Content-Disposition and Content-Type.
*
* @param obj Object
* @param key Key of the object
* @param multiPart MultiPart to add the form param to
*/
private void addParamToMultipart(Object value, String key, MultiPart multiPart) {
if (value instanceof File) {
File file = (File) value;
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key)
.fileName(file.getName()).size(file.length()).build();
// Attempt to probe the content type for the file so that the form part is more correctly
// and precisely identified, but fall back to application/octet-stream if that fails.
MediaType type;
try {
type = MediaType.valueOf(Files.probeContentType(file.toPath()));
} catch (IOException | IllegalArgumentException e) {
type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, type));
} else {
FormDataContentDisposition contentDisp = FormDataContentDisposition.name(key).build();
multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(value)));
}
}
/**
* Serialize the given Java object into string according the given
* Content-Type (only JSON, HTTP form is supported for now).

View File

@@ -32,7 +32,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
mapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}})
.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, true)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)

View File

@@ -112,7 +112,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
attemptParsing |= (token == JsonToken.VALUE_NUMBER_FLOAT);
{{/isDecimal}}
{{#isBoolean}}
attemptParsing |= (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE));
attemptParsing |= (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE);
{{/isBoolean}}
{{#isNullable}}
attemptParsing |= (token == JsonToken.VALUE_NULL);

View File

@@ -400,9 +400,7 @@
<jackson-databind-version>2.17.1</jackson-databind-version>
<jackson-databind-nullable-version>0.2.6</jackson-databind-nullable-version>
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<junit-version>5.10.0</junit-version>
{{#hasHttpSignatureMethods}}
<http-signature-version>1.8</http-signature-version>

View File

@@ -30,7 +30,12 @@ public class JSON {
mapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS)
{{#failOnUnknownProperties}}
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
{{/failOnUnknownProperties}}
{{^failOnUnknownProperties}}
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
{{/failOnUnknownProperties}}
.enable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)

View File

@@ -14,8 +14,8 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#hasFormParamsInSpec}}

View File

@@ -19,8 +19,8 @@ import java.util.concurrent.CompletableFuture;
{{/asyncNative}}
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
/**

View File

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

View File

@@ -295,13 +295,12 @@
<jackson-databind-nullable-version>0.2.6</jackson-databind-nullable-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
{{#hasFormParamsInSpec}}
<httpmime-version>4.5.14</httpmime-version>
{{/hasFormParamsInSpec}}

View File

@@ -26,14 +26,14 @@ import io.swagger.v3.oas.models.parameters.Parameter;
import java.io.IOException;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#performBeanValidation}}
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.executable.ExecutableValidator;
import {{javaxPackage}}.validation.ConstraintViolation;
import {{javaxPackage}}.validation.Validation;
import {{javaxPackage}}.validation.ValidatorFactory;
import {{javaxPackage}}.validation.executable.ExecutableValidator;
import java.util.Set;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

View File

@@ -17,8 +17,8 @@ import java.io.InputStream;
{{/supportStreaming}}
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
/**

View File

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

View File

@@ -423,16 +423,15 @@
{{/joda}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#performBeanValidation}}
<jakarta.el-version>3.0.3</jakarta.el-version>
{{/performBeanValidation}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<junit-version>5.10.3</junit-version>
<junit-platform-runner.version>1.10.0</junit-platform-runner.version>
<jakarta.ws.rs-api-version>2.1.6</jakarta.ws.rs-api-version>

View File

@@ -27,7 +27,7 @@ public class JacksonObjectMapper extends Jackson2Mapper {
ObjectMapper mapper = new ObjectMapper();
mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}});
mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);

View File

@@ -33,8 +33,8 @@ import io.swagger.v3.oas.annotations.security.*;
{{/swagger2AnnotationLibrary}}
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import java.lang.reflect.Type;

View File

@@ -20,8 +20,8 @@ import java.util.List;
import java.util.Map;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import static io.restassured.config.ObjectMapperConfig.objectMapperConfig;

View File

@@ -358,13 +358,12 @@
{{/jackson}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
<beanvalidation-version>2.0.2</beanvalidation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
<okio-version>3.6.0</okio-version>
<junit-version>5.10.3</junit-version>
</properties>

View File

@@ -125,7 +125,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
mapper.registerModule(new JavaTimeModule());
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}});
{{#openApiNullable}}
JsonNullableModule jnm = new JsonNullableModule();
mapper.registerModule(jnm);

View File

@@ -11,6 +11,11 @@ import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -47,6 +52,79 @@ public class {{classname}} {
}
{{#operation}}
{{#useSingleRequestParameter}}
{{#hasParams}}
{{#hasSingleParam}}
// It has a single param!
/*
{{#allParams}}
* {{paramName}}
{{/allParams}}
*/
{{/hasSingleParam}}
{{^hasSingleParam}}
// It has NO single param!
/*
{{#allParams}}
* {{paramName}}
{{/allParams}}
*/
{{/hasSingleParam}}
{{^hasSingleParam}}
public record {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}){}
/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
{{#returnType}} * @return {{.}}
{{/returnType}} * @throws RestClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws RestClientResponseException {
{{#returnType}}return {{/returnType}}this.{{operationId}}({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}
/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
{{#returnType}} * @return ResponseEntity&lt;{{.}}&gt;
{{/returnType}} * @throws RestClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public {{#returnType}}ResponseEntity<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>{{/returnType}}{{^returnType}}ResponseEntity<Void>{{/returnType}} {{operationId}}WithHttpInfo({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws RestClientResponseException {
return this.{{operationId}}WithHttpInfo({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}
/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
* @return ResponseSpec
* @throws RestClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public ResponseSpec {{operationId}}WithResponseSpec({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws RestClientResponseException {
return this.{{operationId}}WithResponseSpec({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}
{{/hasSingleParam}}
{{/hasParams}}
{{/useSingleRequestParameter}}
/**
* {{summary}}
* {{notes}}

View File

@@ -4,8 +4,8 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Test;
import org.junit.Ignore;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
@@ -13,10 +13,15 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
/**
* API tests for {{classname}}
*/
@Ignore
@Disabled
public class {{classname}}Test {
private final {{classname}} api = new {{classname}}();

View File

@@ -362,9 +362,7 @@
{{#joda}}
<jodatime-version>2.9.9</jodatime-version>
{{/joda}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
{{#performBeanValidation}}
<hibernate-validator-version>5.4.3.Final</hibernate-validator-version>
{{/performBeanValidation}}

View File

@@ -20,7 +20,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
public JSON() {
mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}});
mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);

View File

@@ -14,8 +14,8 @@ import java.util.Map;
import java.util.stream.Collectors;
{{#useBeanValidation}}
import jakarta.validation.constraints.*;
import jakarta.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import org.springframework.beans.factory.annotation.Autowired;

View File

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

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