Compare commits

..

28 Commits

Author SHA1 Message Date
dependabot[bot]
4f9f14a7d8 Bump express (#22483)
Bumps [express](https://github.com/expressjs/express) from 4.18.0 to 4.22.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.0...v4.22.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 17:57:08 +08:00
William Cheng
da778c46b0 add option to set params_encoder (#22484) 2025-12-02 17:54:44 +08:00
dependabot[bot]
abea33c32a Bump express (#22481)
Bumps [express](https://github.com/expressjs/express) from 4.18.0 to 4.22.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.0...v4.22.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 17:04:35 +08:00
dependabot[bot]
7a431db7ef Bump express from 4.19.2 to 4.22.1 in /website (#22479)
Bumps [express](https://github.com/expressjs/express) from 4.19.2 to 4.22.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...v4.22.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 13:31:43 +08:00
Nicolas Rodriguez
f125e1072f [crystal-lang] Various fixes for Crystal client (#22465)
* [crystal] implement "multi" params

See: https://github.com/mamantoha/crest?tab=readme-ov-file#crestnestedparamsencoder

* [crystal] remove useless templates (imported from ruby)
2025-12-02 11:15:35 +08:00
William Cheng
9a6f14ad47 Add workflow to test Crystal client (#22477)
* add workflow to test crystal client

* update

* shards install

* fix

* use localhost
2025-12-02 11:04:54 +08:00
Julian Ste
2d3082a1b7 Fixes oatpp generator to expose network server on 0.0.0.0 instead of localhost (#22330)
* Change server address from 'localhost' to '0.0.0.0'

* Change server connection to listen on all interfaces
2025-12-02 10:12:24 +08:00
KRJ-RTX
18b359ba17 Add Basic and Bearer Authorization to the CPP Pistache generator (#22337)
* [cpp][pistache-server] Add extraction and forwarding of credentials for HTTP Basic protected endpoints.

* [cpp][pistache-server] Change HTTP Basic credentials to be contained on a struct instead of two std::strings

* [cpp][pistache-server] Add callbacks to authenticate http basic credentials.

* [cpp][pistache-server] Add `void* userdata` to HttpBasicCredentials.

This allows for data ft be passed on from the authenticator to the
handler implementation. For example a userid that has already been
looked up

* [cpp][pistache-server] Add support for HTTP Bearer authentication.

* [cpp][pistache-server] Add new file `api-base-source.mustache`

`api-base-source.mustache` contain implementations of security
related methods and also the empty constructor.

* [cpp][pistache-server] Add re-generated samples.

* Fix PR 19978: Updated indentation levels and fixed test problems

---------

Co-authored-by: Morten Winkler <morten@winkler.dk>
2025-12-02 10:07:47 +08:00
dependabot[bot]
39ea9b6da7 Bump express in /samples/client/others/typescript-angular-v20 (#22475)
Bumps [express](https://github.com/expressjs/express) from 5.1.0 to 5.2.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/v5.1.0...v5.2.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 5.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:07:00 +08:00
dependabot[bot]
fc5ccdf3a5 Bump express (#22473)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.22.0.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.22.0/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.22.0)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:06:49 +08:00
dependabot[bot]
bf5f7b0d6b Bump swift-actions/setup-swift from 2 to 3 (#22476)
Bumps [swift-actions/setup-swift](https://github.com/swift-actions/setup-swift) from 2 to 3.
- [Release notes](https://github.com/swift-actions/setup-swift/releases)
- [Commits](https://github.com/swift-actions/setup-swift/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:06:32 +08:00
dsteeley
41f97d8187 fix: Rust-server bytes response fixed to not attempt string conversion (#22471) 2025-12-01 21:36:50 +08:00
scarf
5a2503dc49 fix(typescript-fetch): fix logic when stringEnums is explicitly set to false (#22466)
Passing `stringEnums=false` was incorrectly treated as `true`. This went unnoticed since the default behavior works as expected. Made the logic consistent with `typescript-axios`.
2025-12-01 09:51:13 +01:00
Linh Tran Tuan
1e7ca08ccc [Rust-Axum] Fix: do not gen Partial Ord/Ord for Any type (#22469) 2025-12-01 16:38:32 +08:00
William Cheng
c0d98864e0 [Java] fix missing header parameters in the generated google-api-client Java client (#22468)
* fix(java): add header parameter handling for google-api-client

  Header parameters defined in OpenAPI specs were being accepted as method
  parameters but never actually added to the HTTP request.

  Fixes #22457

* update samples

* minor enhancement

---------

Co-authored-by: artnan <artn@outlook.com>
2025-12-01 13:09:28 +08:00
William Cheng
788f67dd01 Fix Spring Framework 7 compatibility in jvm-spring-restclient and jvm-spring-webclient (#22467)
* Fix Spring Framework 7 compatibility issues

Fixes #22368

* update samples

---------

Co-authored-by: jwalter <joakim.waltersson@gmail.com>
2025-12-01 12:24:37 +08:00
Piotr Kubowicz
7b83462a83 [kotlin] Make API classes open (non-final) unless nonPublicApi is used (#22461)
* [kotlin] Make API classes open (non-final) unless nonPublicApi is used

By making those classes open, AspectJ can be used to enhance their
behavior.

I'm not changing kotlin-multiplatform templates, where 'open' was
already present before my changes.

Closes #22271

* Fail Kotlin sample compilation if API classes stop to be public

Serves as a 'regression test'.
2025-12-01 00:03:29 +08:00
dsteeley
453997bd16 Ensure rust-server compiles with no-default-features (#22445) 2025-11-30 23:05:25 +08:00
Elric Milon
e9bc44bebe [Rust] Implement support for multipart file uploads for reqwest-async and reqwest-trait (#22454)
* feat(Rust): Add support for multipart file uploads in reqwest generators

* chore: Regen relevant samples affected by the updated multipart support
2025-11-30 23:04:29 +08:00
gonzalad
7a48bd8ef5 [typescript-angular] fix integration tests (#22463)
The expected files where not the correct ones.
2025-11-29 16:46:43 +08:00
William Cheng
1689d7b5b6 Typescript-Angular: Fix several query parameters serialization issues (#22459)
* Generate skeleton for new integration test

* Typescript-angular: Move query param deep-object test

* typescript-angular: Add query param JSON test

* Typescript-angular: Add query param form test

* Test for #20998

* typescript-angular: Reimplement query param serialisation

This notably fixes:
- JSON query param serialisation
- array serialisation with style=form and explode=true

As the class HttpParams from Angular is specially designed for the
mimetype: `application/x-www-form-urlencoded` it does not support
the range of query parameters defined by the OpenAPI specification.
To workaround this issue, this patch introduces a custom
`OpenAPIHttpParams` class which supports a wider range of query param
styles.

Note that as `HttpClient` is used afterwards, the class
`OpenApiHttpParams` has a method to convert it into a `HttpParams` from
Angular with a no-op HttpParameterCodec to avoid double serialisation of
the query parameters.

* update samples

---------

Co-authored-by: Vladimir Svoboda <vsvoboda@forkoder.eu>
2025-11-28 20:59:29 +08:00
David Gamero
08858a91e6 [typescript] migrate node-fetch to undici (#22408)
* migrate typescript generator to undici

* smaples

* missing comma

* upgrade types in encode test

* remove EOL node versions, add new LTS

* fix export issue in encode/decode

* d.js issue and commonjs module in tsconfig for esm dual support

* update samples merge master

* sync samples

* files samples
2025-11-27 16:36:19 +08:00
William Cheng
e9c842f150 fix: do not add dependency on urllib3 if not required (#22453)
* fix: do not add dependency on urllib3 if not required

* update samples

* remove import

---------

Co-authored-by: Sascha Kreutz <saschakreutz@hotmail.de>
2025-11-27 16:03:21 +08:00
dependabot[bot]
41c54e8122 Bump node-forge (#22447)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-27 14:45:57 +08:00
dependabot[bot]
b8df8e7f22 Bump node-forge (#22448)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-27 14:45:47 +08:00
William Cheng
578bdbe679 minor fix documentation for customization (#22440) 2025-11-26 18:00:50 +08:00
Jachym Metlicka
1b557790e6 [kotlin-spring][server] Feat: Return from controllers without ResponseEntity wrapper. (#22377)
* remove "async" and "responseWrapper" from template as these are not supported by kotlin-spring generator

* try to force pipelines rerun

* force pipelines rerun

* fix mustache to keep generated code identical

* Revert "fix mustache to keep generated code identical"

This reverts commit c573b43401.

* Reapply "fix mustache to keep generated code identical"

This reverts commit 2c3b065c5c.

* Add support for 'useResponseEntity' in kotlin-spring. Consolidate with the separate flag 'declarativeInterfaceWrapResponses' as these can now be controlled both by one flag. Default to true.

* fix status annotation and add compile-test samples

* satisfy samples-up-to-date check

* add unit tests covering both reactive and non-reactive

* fix template to avoid unnecessary empty line

* fix template to avoid unnecessary empty line

* put method params (if present) on separate lines to improve readability

* put method params (if present) on separate lines to improve readability; fix double spaces, spaces before comma, incorrect spaces

* fix test

* store PATHs as accesible strings in companion objects.

* fix missing import

* fix incorrect import

* fix fallback to nested placeholders.
2025-11-26 18:00:17 +08:00
William Cheng
3d6e9d5693 better format in build.gradle (kotlin) (#22439) 2025-11-26 17:41:17 +08:00
837 changed files with 38315 additions and 7052 deletions

37
.github/workflows/samples-crystal.yaml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Samples Crystal clients
on:
push:
paths:
- samples/client/petstore/crystal/**
pull_request:
paths:
- samples/client/petstore/crystal/**
jobs:
build:
name: Build Crystal projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/client/petstore/crystal/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v5
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
- name: Shards Install
run: shards install
working-directory: ${{ matrix.sample }}
- name: Run tests
run: crystal spec
working-directory: ${{ matrix.sample }}

View File

@@ -36,6 +36,7 @@ jobs:
# server
- samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-3-no-response-entity
- samples/server/petstore/kotlin-springboot-additionalproperties
- samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request-cookie

View File

@@ -29,6 +29,8 @@ jobs:
sample:
# server
- samples/server/petstore/kotlin-springboot
- samples/server/petstore/kotlin-springboot-no-response-entity
- samples/server/petstore/kotlin-springboot-no-response-entity-delegate
- samples/server/petstore/kotlin-springboot-multipart-request-model
- samples/server/petstore/kotlin-springboot-bigdecimal-default
- samples/server/petstore/kotlin-springboot-delegate

View File

@@ -39,7 +39,10 @@ jobs:
- name: Build
working-directory: ${{ matrix.sample }}
run: cargo build --all-targets --all-features
run: |
set -e
cargo build --all-targets --all-features
cargo build --all-targets --no-default-features
- name: Tests
working-directory: ${{ matrix.sample }}
run: |

View File

@@ -35,7 +35,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v5
- uses: swift-actions/setup-swift@v2
- uses: swift-actions/setup-swift@v3
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
swift-version: '5'

View File

@@ -4,6 +4,7 @@ on:
push:
paths:
- samples/client/others/typescript-angular/**
- samples/client/others/typescript-angular-v20/**
# comment out angular released before Nov 2023
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
@@ -43,6 +44,7 @@ on:
pull_request:
paths:
- samples/client/others/typescript-angular/**
- samples/client/others/typescript-angular-v20/**
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
#- samples/client/petstore/typescript-angular-v14-provided-in-root/**
@@ -92,6 +94,7 @@ jobs:
- "20.x"
sample:
- samples/client/others/typescript-angular/
- samples/client/others/typescript-angular-v20/
#- samples/client/petstore/typescript-angular-v12-provided-in-root/
#- samples/client/petstore/typescript-angular-v13-provided-in-root/
#- samples/client/petstore/typescript-angular-v14-provided-in-root/

View File

@@ -16,9 +16,9 @@ jobs:
# clients
- samples/client/others/typescript/encode-decode/test
node-version:
- 16
- 18
- 20
- 22
- 24
steps:
- uses: actions/checkout@v5

View File

@@ -6,6 +6,7 @@ additionalProperties:
shardVersion: 1.0.0
moduleName: Petstore
shardName: petstore
#paramsEncoder: Crest::EnumeratedFlatParamsEncoder
strictSpecBehavior: false
modelNameMappings:
PropertyNameMapping: AnotherPropertyNameMapping

View File

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

View File

@@ -0,0 +1,15 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-no-response-entity-delegate
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: none
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
useResponseEntity: "false"
delegatePattern: true
requestMappingMode: controller

View File

@@ -0,0 +1,14 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-no-response-entity
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: none
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
useResponseEntity: "false"
requestMappingMode: controller

View File

@@ -11,6 +11,6 @@ additionalProperties:
beanValidations: "true"
interfaceOnly: true
reactive: true
declarativeInterfaceWrapResponses: false
useResponseEntity: false
useFlowForArrayReturnType: false
declarativeInterfaceReactiveMode: "coroutines"

View File

@@ -11,6 +11,6 @@ additionalProperties:
beanValidations: "true"
interfaceOnly: true
reactive: true
declarativeInterfaceWrapResponses: true
useResponseEntity: true
useFlowForArrayReturnType: false
declarativeInterfaceReactiveMode: "reactor"

View File

@@ -11,5 +11,5 @@ additionalProperties:
beanValidations: "true"
interfaceOnly: true
reactive: false
declarativeInterfaceWrapResponses: true
useResponseEntity: true
useFlowForArrayReturnType: false

View File

@@ -11,5 +11,5 @@ additionalProperties:
beanValidations: "true"
interfaceOnly: true
reactive: false
declarativeInterfaceWrapResponses: true
useResponseEntity: true
useFlowForArrayReturnType: false

View File

@@ -5,6 +5,7 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: true
useAsyncFileStream: true
supportMiddleware: true
supportMultipleResponses: true
packageName: petstore-reqwest-async-middleware

View File

@@ -5,6 +5,7 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: true
useAsyncFileStream: true
supportTokenSource: true
supportMultipleResponses: true
packageName: petstore-reqwest-async-tokensource

View File

@@ -5,6 +5,7 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: true
useAsyncFileStream: true
supportMultipleResponses: true
packageName: petstore-reqwest-async
useSingleRequestParameter: true

View File

@@ -5,6 +5,7 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: true
useAsyncFileStream: true
supportMultipleResponses: true
avoidBoxedModels: true
packageName: petstore-reqwest-avoid-box

View File

@@ -5,6 +5,7 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
packageName: petstore-reqwest-serde-path-to-error
useAsyncFileStream: true
useSerdePathToError: true
enumNameMappings:
delivered: shipped

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
generatorName: typescript-angular
outputDir: samples/client/others/typescript-angular-v20/builds/query-param-form
inputSpec: modules/openapi-generator/src/test/resources/3_0/query-param-form.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 20.0.0
npmName: sample-angular-20-0-0-query-param-form
supportsES6: true

View File

@@ -0,0 +1,8 @@
generatorName: typescript-angular
outputDir: samples/client/others/typescript-angular-v20/builds/query-param-json
inputSpec: modules/openapi-generator/src/test/resources/3_0/query-param-json.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 20.0.0
npmName: sample-angular-20-0-0-query-param-json
supportsES6: true

View File

@@ -538,6 +538,7 @@ OpenAPI Normalizer transforms the input OpenAPI doc/spec (which may not perfectl
- SIMPLIFY_ONEOF_ANYOF
- SIMPLIFY_BOOLEAN_ENUM
- SIMPLIFY_ONEOF_ANYOF_ENUM
- REFACTOR_ALLOF_WITH_PROPERTIES_ONLY
(One can use `DISABLE_ALL=true` to disable all the rules)
@@ -565,8 +566,7 @@ Example:
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyAnyOfStringAndEnumString_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING=true
```
- `SIMPLIFY_ONEOF_ANYOF_ENUM`: when set to true, oneOf/anyOf with only enum sub-schemas all containing enum values will be converted to a single enum
This is enabled by default
- `SIMPLIFY_ONEOF_ANYOF_ENUM`: when set to true, oneOf/anyOf with only enum sub-schemas all containing enum values will be converted to a single enum. This is enabled by default.
Example:

View File

@@ -25,6 +25,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|moduleName|module name (e.g. TwitterClient| |OpenAPIClient|
|paramsEncoder|params_encoder setting (e.g. Crest::NestedParamsEncoder, Crest::EnumeratedFlatParamsEncoder, Crest::ZeroEnumeratedFlatParamsEncoder| |Crest::NestedParamsEncoder|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|shardAuthor|shard author (only one is supported).| |null|
|shardAuthorEmail|shard author email (only one is supported).| |null|

View File

@@ -28,7 +28,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|beanQualifiers|Whether to add fully-qualifier class names as bean qualifiers in @Component and @RestController annotations. May be used to prevent bean names clash if multiple generated libraries (contexts) added to single project.| |false|
|configPackage|configuration package for generated code| |org.openapitools.configuration|
|declarativeInterfaceReactiveMode|What type of reactive style to use in Spring Http declarative interface|<dl><dt>**coroutines**</dt><dd>Use kotlin-idiomatic 'suspend' functions</dd><dt>**reactor**</dt><dd>Use reactor return wrappers 'Mono' and 'Flux'</dd></dl>|coroutines|
|declarativeInterfaceWrapResponses|Whether (when false) to return actual type (e.g. List&lt;Fruit&gt;) and handle non 2xx responses via exceptions or (when true) return entire ResponseEntity (e.g. ResponseEntity&lt;List&lt;Fruit&gt;&gt;)| |false|
|delegatePattern|Whether to generate the server files using the delegate pattern| |false|
|documentationProvider|Select the OpenAPI documentation provider.|<dl><dt>**none**</dt><dd>Do not publish an OpenAPI specification.</dd><dt>**source**</dt><dd>Publish the original input OpenAPI specification.</dd><dt>**springfox**</dt><dd>Generate an OpenAPI 2 (fka Swagger RESTful API Documentation Specification) specification using SpringFox 2.x. Deprecated (for removal); use springdoc instead.</dd><dt>**springdoc**</dt><dd>Generate an OpenAPI 3 specification using SpringDoc.</dd></dl>|springdoc|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
@@ -56,6 +55,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations to validate data types| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useFlowForArrayReturnType|Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.| |true|
|useResponseEntity|Whether (when false) to return actual type (e.g. List&lt;Fruit&gt;) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity&lt;List&lt;Fruit&gt;&gt;). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|Whether to use tags for creating interface and controller class names| |false|

View File

@@ -191,6 +191,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
private void setupSupportingFiles() {
supportingFiles.clear();
supportingFiles.add(new SupportingFile("api-base-header.mustache", "api", "ApiBase.h"));
supportingFiles.add(new SupportingFile("api-base-source.mustache", "api", "ApiBase.cpp"));
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("main-api-server.mustache", "", modelNamePrefix + "main-api-server.cpp"));

View File

@@ -57,6 +57,7 @@ public class CrystalClientCodegen extends DefaultCodegen {
@Setter protected String shardDescription = "This shard maps to a REST API";
@Setter protected String shardAuthor = "";
@Setter protected String shardAuthorEmail = "";
@Setter protected String paramsEncoder = "Crest::NestedParamsEncoder";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected List<String> primitiveTypes = new ArrayList<String>();
@@ -70,6 +71,7 @@ public class CrystalClientCodegen extends DefaultCodegen {
public static final String SHARD_DESCRIPTION = "shardDescription";
public static final String SHARD_AUTHOR = "shardAuthor";
public static final String SHARD_AUTHOR_EMAIL = "shardAuthorEmail";
public static final String PARAMS_ENCODER = "paramsEncoder";
public CrystalClientCodegen() {
super();
@@ -197,8 +199,7 @@ public class CrystalClientCodegen extends DefaultCodegen {
cliOptions.add(new CliOption(SHARD_HOMEPAGE, "shard homepage.").defaultValue("http://org.openapitools"));
cliOptions.add(
new CliOption(SHARD_DESCRIPTION, "shard description.").defaultValue("This shard maps to a REST API"));
cliOptions.add(new CliOption(SHARD_DESCRIPTION, "shard description.").defaultValue("This shard maps to a REST API"));
cliOptions.add(new CliOption(SHARD_AUTHOR, "shard author (only one is supported)."));
@@ -206,6 +207,10 @@ public class CrystalClientCodegen extends DefaultCodegen {
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(PARAMS_ENCODER,
"params_encoder setting (e.g. Crest::NestedParamsEncoder, Crest::EnumeratedFlatParamsEncoder, Crest::ZeroEnumeratedFlatParamsEncoder").
defaultValue("Crest::NestedParamsEncoder"));
}
@Override
@@ -260,6 +265,12 @@ public class CrystalClientCodegen extends DefaultCodegen {
setShardAuthorEmail((String) additionalProperties.get(SHARD_AUTHOR_EMAIL));
}
if (additionalProperties.containsKey(PARAMS_ENCODER)) {
setParamsEncoder((String) additionalProperties.get(PARAMS_ENCODER));
} else {
additionalProperties.put(PARAMS_ENCODER, paramsEncoder);
}
// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);

View File

@@ -33,6 +33,7 @@ import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.SpringHttpStatusLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
@@ -85,7 +86,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public static final String DELEGATE_PATTERN = "delegatePattern";
public static final String USE_TAGS = "useTags";
public static final String BEAN_QUALIFIERS = "beanQualifiers";
public static final String DECLARATIVE_INTERFACE_WRAP_RESPONSES = "declarativeInterfaceWrapResponses";
public static final String USE_RESPONSE_ENTITY = "useResponseEntity";
public static final String DECLARATIVE_INTERFACE_REACTIVE_MODE = "declarativeInterfaceReactiveMode";
public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
@@ -109,6 +110,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
}
}
public enum RequestMappingMode {
api_interface("Generate the @RequestMapping annotation on the generated Api Interface."),
controller("Generate the @RequestMapping annotation on the generated Api Controller Implementation."),
@@ -155,7 +157,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
@Setter protected boolean useTags = false;
@Setter private boolean beanQualifiers = false;
@Setter private DeclarativeInterfaceReactiveMode declarativeInterfaceReactiveMode = DeclarativeInterfaceReactiveMode.coroutines;
@Setter private boolean declarativeInterfaceWrapResponses = false;
@Setter private boolean useResponseEntity = true;
@Getter @Setter
protected boolean useSpringBoot3 = false;
@@ -242,9 +244,9 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
addSwitch(USE_SPRING_BOOT3, "Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.", useSpringBoot3);
addSwitch(USE_FLOW_FOR_ARRAY_RETURN_TYPE, "Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.", useFlowForArrayReturnType);
addSwitch(INCLUDE_HTTP_REQUEST_CONTEXT, "Whether to include HttpServletRequest (blocking) or ServerWebExchange (reactive) as additional parameter in generated methods.", includeHttpRequestContext);
addSwitch(DECLARATIVE_INTERFACE_WRAP_RESPONSES,
"Whether (when false) to return actual type (e.g. List<Fruit>) and handle non 2xx responses via exceptions or (when true) return entire ResponseEntity (e.g. ResponseEntity<List<Fruit>>)",
declarativeInterfaceWrapResponses);
addSwitch(USE_RESPONSE_ENTITY,
"Whether (when false) to return actual type (e.g. List<Fruit>) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity<List<Fruit>>). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition",
useResponseEntity);
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
@@ -468,6 +470,12 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
additionalProperties.put(CodegenConstants.LIBRARY, library);
}
if(additionalProperties.containsKey(USE_RESPONSE_ENTITY)) {
this.setUseResponseEntity(Boolean.parseBoolean(additionalProperties.get(USE_RESPONSE_ENTITY).toString()));
}
writePropertyBack(USE_RESPONSE_ENTITY, useResponseEntity);
additionalProperties.put("springHttpStatus", new SpringHttpStatusLambda());
// Set basePackage from invokerPackage
if (!additionalProperties.containsKey(BASE_PACKAGE)
&& additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {

View File

@@ -1233,6 +1233,10 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
additionalProperties.put("apiUsesUuid", true);
}
if (prop.isByteArray) {
additionalProperties.put("apiUsesByteArray", true);
}
String xmlName = modelXmlNames.get(prop.dataType);
if (xmlName != null) {
prop.vendorExtensions.put("x-item-xml-name", xmlName);
@@ -1535,6 +1539,11 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
additionalProperties.put("apiUsesUuid", true);
}
// If a parameter uses byte arrays, we need to set a flag.
if (param.isByteArray) {
additionalProperties.put("apiUsesByteArray", true);
}
if (Boolean.TRUE.equals(param.isFreeFormObject)) {
param.vendorExtensions.put("x-format-string", "{:?}");
example = null;

View File

@@ -1213,6 +1213,10 @@ public class RustServerCodegenDeprecated extends AbstractRustCodegen implements
additionalProperties.put("apiUsesUuid", true);
}
if (prop.isByteArray) {
additionalProperties.put("apiUsesByteArray", true);
}
String xmlName = modelXmlNames.get(prop.dataType);
if (xmlName != null) {
prop.vendorExtensions.put("x-item-xml-name", xmlName);
@@ -1515,6 +1519,11 @@ public class RustServerCodegenDeprecated extends AbstractRustCodegen implements
additionalProperties.put("apiUsesUuid", true);
}
// If a parameter uses byte arrays, we need to set a flag.
if (param.isByteArray) {
additionalProperties.put("apiUsesByteArray", true);
}
if (Boolean.TRUE.equals(param.isFreeFormObject)) {
param.vendorExtensions.put("x-format-string", "{:?}");
example = null;

View File

@@ -204,6 +204,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("param.mustache", getIndexDirectory(), "param.ts"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("queryParams.mustache", getIndexDirectory(), "query.params.ts"));
if(ngVersionAtLeast_17) {
supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md"));

View File

@@ -283,6 +283,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
if (additionalProperties.containsKey(STRING_ENUMS)) {
this.setStringEnums(convertPropertyToBoolean(STRING_ENUMS));
additionalProperties.put("stringEnums", this.stringEnums);
}
if (additionalProperties.containsKey(FILE_NAMING)) {

View File

@@ -123,7 +123,13 @@ public class {{classname}} {
GenericUrl genericUrl = new GenericUrl(localVarUrl);
HttpContent content = {{#isBodyAllowed}}{{#bodyParam}}apiClient.new JacksonJsonHttpContent({{paramName}}){{/bodyParam}}{{^bodyParam}}new EmptyContent(){{/bodyParam}}{{/isBodyAllowed}}{{^isBodyAllowed}}null{{/isBodyAllowed}};
return apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content).execute();
com.google.api.client.http.HttpRequest httpRequest = apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content);
{{#headerParams}}
if ({{paramName}} != null) {
httpRequest.getHeaders().set("{{baseName}}", {{paramName}});
}
{{/headerParams}}
return httpRequest.execute();
}{{#bodyParam}}
{{#isDeprecated}}
@@ -159,7 +165,13 @@ public class {{classname}} {
HttpContent content = {{#bodyParam}}{{paramName}} == null ?
apiClient.new JacksonJsonHttpContent(null) :
new InputStreamContent(mediaType == null ? Json.MEDIA_TYPE : mediaType, {{paramName}}){{/bodyParam}};
return apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content).execute();
com.google.api.client.http.HttpRequest httpRequest = apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content);
{{#headerParams}}
if ({{paramName}} != null) {
httpRequest.getHeaders().set("{{baseName}}", {{paramName}});
}
{{/headerParams}}
return httpRequest.execute();
}{{/bodyParam}}
{{#isDeprecated}}
@@ -201,7 +213,21 @@ public class {{classname}} {
GenericUrl genericUrl = new GenericUrl(localVarUrl);
HttpContent content = {{#isBodyAllowed}}{{#bodyParam}}apiClient.new JacksonJsonHttpContent({{paramName}}){{/bodyParam}}{{^bodyParam}}new EmptyContent(){{/bodyParam}}{{/isBodyAllowed}}{{^isBodyAllowed}}null{{/isBodyAllowed}};
return apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content).execute();
com.google.api.client.http.HttpRequest httpRequest = apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content);
{{#hasHeaderParams}}
// Note: Header params passed via 'params' map are handled below
for (Map.Entry<String, Object> entry: params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Check if this is a header parameter by name
{{#headerParams}}
if ("{{baseName}}".equals(key) && value != null) {
httpRequest.getHeaders().set(key, value);
}
{{/headerParams}}
}
{{/hasHeaderParams}}
return httpRequest.execute();
}

View File

@@ -22,7 +22,7 @@ public:
* Create ConnectionProvider component which listens on the port
*/
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
return oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", {{serverPort}}{{^serverPort}}8080{{/serverPort}}, oatpp::network::Address::IP_4});
return oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", {{serverPort}}{{^serverPort}}8080{{/serverPort}}, oatpp::network::Address::IP_4});
}());
/**

View File

@@ -14,14 +14,47 @@
namespace {{apiNamespace}}
{
{{#authMethods}}{{#isBasicBasic}}
typedef struct
{
std::string user;
std::string password;
std::unique_ptr<void, std::function<void(void*)>> userdata;
} HttpBasicCredentials;
typedef std::function<bool(HttpBasicCredentials &)> BasicCredentialsAuthenticator;
{{/isBasicBasic}}
{{#isBasicBearer}}
typedef struct
{
std::string token;
std::unique_ptr<void, std::function<void(void*)>> userdata;
} HttpBearerToken;
typedef std::function<bool(HttpBearerToken &)> BearerTokenAuthenticator;
{{/isBasicBearer}}
{{/authMethods}}
class ApiBase {
public:
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr) {};
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr);
virtual ~ApiBase() = default;
virtual void init() = 0;
{{#authMethods}}{{#isBasicBasic}}void setBasicCredentialsAuthenticator( const BasicCredentialsAuthenticator &newBasicCredentialsAuthenticator);{{/isBasicBasic}}{{/authMethods}}
{{#authMethods}}{{#isBasicBearer}}void setBearerTokenAuthenticator( const BearerTokenAuthenticator &newbearerTokenAuthenticator);{{/isBasicBearer}}{{/authMethods}}
protected:
const std::shared_ptr<Pistache::Rest::Router> router;
{{#authMethods}}{{#isBasicBasic}}std::optional<BasicCredentialsAuthenticator> basicCredentialsAuthenticator;{{/isBasicBasic}}{{/authMethods}}
{{#authMethods}}{{#isBasicBearer}}std::optional<BearerTokenAuthenticator> bearerTokenAuthenticator;{{/isBasicBearer}}{{/authMethods}}
};
} // namespace {{apiNamespace}}

View File

@@ -0,0 +1,25 @@
{{>licenseInfo}}
#include "ApiBase.h"
namespace {{apiNamespace}}
{
ApiBase::ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr)
{
}
{{#authMethods}}{{#isBasicBasic}}
void ApiBase::setBasicCredentialsAuthenticator( const BasicCredentialsAuthenticator &newBasicCredentialsAuthenticator)
{
basicCredentialsAuthenticator = newBasicCredentialsAuthenticator;
}
{{/isBasicBasic}}
{{#isBasicBearer}}
void ApiBase::setBearerTokenAuthenticator( const BearerTokenAuthenticator &newbearerTokenAuthenticator)
{
bearerTokenAuthenticator = newbearerTokenAuthenticator;
}
{{/isBasicBearer}}
{{/authMethods}}
} // Namespace {{apiNamespace}}

View File

@@ -79,7 +79,7 @@ private:
{{#allParams}}
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}
virtual void {{operationIdSnakeCase}}({{#allParams}}const {{#isModel}}{{^isOptional}}{{modelNamespace}}::{{/isOptional}}{{/isModel}}{{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response) = 0;
virtual void {{operationIdSnakeCase}}({{#authMethods}}{{#isBasicBasic}}const HttpBasicCredentials &credentials, {{/isBasicBasic}}{{#isBasicBearer}}const HttpBearerToken &accessToken, {{/isBasicBearer}}{{/authMethods}} {{#allParams}}const {{#isModel}}{{^isOptional}}{{modelNamespace}}::{{/isOptional}}{{/isModel}}{{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response) = 0;
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{^vendorExtensions.x-codegen-pistache-is-parsing-supported}}
virtual void {{operationIdSnakeCase}}(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response) = 0;

View File

@@ -26,7 +26,8 @@ namespace {{apiNamespace}}
{
{{#hasModelImport}}
using namespace {{modelNamespace}};{{/hasModelImport}}
using namespace {{modelNamespace}};
{{/hasModelImport}}
class {{declspec}} {{classname}}Impl : public {{apiNamespace}}::{{classname}} {
public:
@@ -35,7 +36,7 @@ public:
{{#operation}}
{{#vendorExtensions.x-codegen-pistache-is-parsing-supported}}
void {{operationIdSnakeCase}}({{#allParams}}const {{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response);
void {{operationIdSnakeCase}}({{#authMethods}}{{#isBasicBasic}}const HttpBasicCredentials &credentials,{{/isBasicBasic}}{{#isBasicBearer}}const HttpBearerToken &bearerToken, {{/isBasicBearer}}{{/authMethods}}{{#allParams}}const {{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response);
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{^vendorExtensions.x-codegen-pistache-is-parsing-supported}}
void {{operationIdSnakeCase}}(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response);

View File

@@ -8,21 +8,140 @@ namespace {{this}} {
{{/apiNamespaceDeclarations}}
{{#hasModelImport}}
using namespace {{modelNamespace}};{{/hasModelImport}}
using namespace {{modelNamespace}};
{{/hasModelImport}}
{{classname}}Impl::{{classname}}Impl(const std::shared_ptr<Pistache::Rest::Router>& rtr)
: {{classname}}(rtr)
{
{{#authMethods}}{{#isBasicBasic}}/*
Http Basic Auth
===============
Do this in the individual classes in the constructor
this->setBasicCredentialsAuthenticator(
[](HttpBasicCredentials &credentials)->bool
{
if(credentials.user == "foo" && credentials.password == "bar")
{
const int userIdOfFoo = 66;
credentials.userdata = std::unique_ptr<void, std::function<void(void*)>> (
reinterpret_cast<void*>(new int(userIdOfFoo)),
[&](void* ptr)
{
int * value = reinterpret_cast<int*>(ptr);
delete value;
}
);
return true;
}
return false;
}
);
or in main:
for (auto api : apiImpls) {
api->init();
api->setBasicCredentialsAuthenticator(
[]( HttpBasicCredentials &credentials)->bool
{
if(credentials.user == "foo" && credentials.password == "bar")
{
const int userIdOfFoo = 66;
credentials.userdata = std::unique_ptr<void, std::function<void(void*)>> (
reinterpret_cast<void*>(new int(userIdOfFoo)),
[&](void* ptr)
{
int * value = reinterpret_cast<int*>(ptr);
delete value;
}
);
return true;
}
return false;
}
);
}
or a mix.
Until you do either, protected resources will result in a 401.
*/{{/isBasicBasic}}
{{#isBasicBearer}}/*
Http Basic Bearer
===============
Do this in the individual classes in the constructor
this->setBearerTokenAuthenticator(
[](HttpBearerToken &token)->bool
{
if(token.token == "Zm9vYmFyCg==")
{
const int userIdOfFoo = 99;
token.userdata = std::unique_ptr<void,std::function<void(void*)>>(
reinterpret_cast<void*>(new int(userIdOfFoo)),
[&](void* ptr)
{
int * value = reinterpret_cast<int*>(ptr);
delete value;
}
);
return true;
}
return false;
}
);
or in main:
for (auto api : apiImpls) {
api->init();
api->setBearerTokenAuthenticator(
[](HttpBearerToken &token)->bool
{
if(token.token == "Zm9vYmFyCg==")
{
const int userIdOfFoo = 99;
token.userdata = std::unique_ptr<void,std::function<void(void*)>>(
reinterpret_cast<void*>(new int(userIdOfFoo)),
[&](void* ptr)
{
int * value = reinterpret_cast<int*>(ptr);
delete value;
}
);
return true;
}
return false;
}
);
}
or a mix.
Until you do either, protected resources will result in a 401.
*/{{/isBasicBearer}}
{{/authMethods}}
}
{{#operation}}
{{#vendorExtensions.x-codegen-pistache-is-parsing-supported}}
void {{classname}}Impl::{{operationIdSnakeCase}}({{#allParams}}const {{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response) {
void {{classname}}Impl::{{operationIdSnakeCase}}({{#authMethods}}{{#isBasicBasic}}const HttpBasicCredentials &credentials, {{/isBasicBasic}}{{#isBasicBearer}}const HttpBearerToken &bearerToken, {{/isBasicBearer}}{{/authMethods}}{{#allParams}}const {{{dataType}}} &{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}Pistache::Http::ResponseWriter &response) {
response.send(Pistache::Http::Code::Ok, "Do some magic\n");
}
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{^vendorExtensions.x-codegen-pistache-is-parsing-supported}}
void {{classname}}Impl::{{operationIdSnakeCase}}(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response){
void {{classname}}Impl::{{operationIdSnakeCase}}(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response) {
response.send(Pistache::Http::Code::Ok, "Do some magic\n");
}
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}

View File

@@ -9,14 +9,14 @@ namespace {{apiNamespace}}
using namespace {{helpersNamespace}};
{{#hasModelImport}}
using namespace {{modelNamespace}};{{/hasModelImport}}
using namespace {{modelNamespace}};
{{/hasModelImport}}
const std::string {{classname}}::base = "{{basePathWithoutHost}}";
{{classname}}::{{classname}}(const std::shared_ptr<Pistache::Rest::Router>& rtr)
: ApiBase(rtr)
{
}
{}
void {{classname}}::init() {
setupRoutes();
@@ -33,14 +33,12 @@ void {{classname}}::setupRoutes() {
router->addCustomHandler(Routes::bind(&{{classname}}::{{classnameSnakeLowerCase}}_default_handler, this));
}
void {{classname}}::handleParsingException(const std::exception& ex, Pistache::Http::ResponseWriter &response) const noexcept
{
void {{classname}}::handleParsingException(const std::exception& ex, Pistache::Http::ResponseWriter &response) const noexcept {
std::pair<Pistache::Http::Code, std::string> codeAndError = handleParsingException(ex);
response.send(codeAndError.first, codeAndError.second);
}
std::pair<Pistache::Http::Code, std::string> {{classname}}::handleParsingException(const std::exception& ex) const noexcept
{
std::pair<Pistache::Http::Code, std::string> {{classname}}::handleParsingException(const std::exception& ex) const noexcept {
try {
throw;
} catch (nlohmann::detail::exception &e) {
@@ -52,94 +50,187 @@ std::pair<Pistache::Http::Code, std::string> {{classname}}::handleParsingExcepti
}
}
void {{classname}}::handleOperationException(const std::exception& ex, Pistache::Http::ResponseWriter &response) const noexcept
{
void {{classname}}::handleOperationException(const std::exception& ex, Pistache::Http::ResponseWriter &response) const noexcept {
std::pair<Pistache::Http::Code, std::string> codeAndError = handleOperationException(ex);
response.send(codeAndError.first, codeAndError.second);
}
std::pair<Pistache::Http::Code, std::string> {{classname}}::handleOperationException(const std::exception& ex) const noexcept
{
std::pair<Pistache::Http::Code, std::string> {{classname}}::handleOperationException(const std::exception& ex) const noexcept {
return std::make_pair(Pistache::Http::Code::Internal_Server_Error, ex.what());
}
{{#operation}}
void {{classname}}::{{operationIdSnakeCase}}_handler(const Pistache::Rest::Request &{{#hasParams}}request{{/hasParams}}, Pistache::Http::ResponseWriter response) {
void {{classname}}::{{operationIdSnakeCase}}_handler(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response) {
try {
{{#vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{#vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{#hasPathParams}}
// Getting the path params
{{#pathParams}}
auto {{paramName}} = request.param(":{{paramName}}").as<{{dataType}}>();
{{/pathParams}}
{{/hasPathParams}}{{#hasBodyParam}}
// Getting the body param
{{#bodyParam}}
{{^isPrimitiveType}}{{^isContainer}}
{{baseType}} {{paramName}};{{/isContainer}}{{#isArray}}std::vector<{{items.baseType}}> {{paramName}};{{/isArray}}{{#isMap}}std::map<std::string, {{items.baseType}}> {{paramName}};{{/isMap}}{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{dataType}} {{paramName}};
{{/isPrimitiveType}}
{{/bodyParam}}
{{/hasBodyParam}}{{#hasQueryParams}}
// Getting the query params
{{#queryParams}}
auto {{paramName}}Query = request.query().get("{{baseName}}");
std::optional<{{^isContainer}}{{dataType}}{{/isContainer}}{{#isArray}}std::vector<{{items.baseType}}>{{/isArray}}> {{paramName}};
if({{paramName}}Query.has_value()){
{{^isContainer}}{{dataType}}{{/isContainer}}{{#isArray}}std::vector<{{items.baseType}}>{{/isArray}} valueQuery_instance;
if(fromStringValue({{paramName}}Query.value(), valueQuery_instance)){
{{paramName}} = valueQuery_instance;
{{#hasPathParams}}
// Getting the path params
{{#pathParams}}
auto {{paramName}} = request.param(":{{paramName}}").as<{{dataType}}>();
{{/pathParams}}
{{/hasPathParams}}
{{#hasBodyParam}}
// Getting the body param
{{#bodyParam}}
{{^isPrimitiveType}}{{^isContainer}}
{{baseType}} {{paramName}};
{{/isContainer}}
{{#isArray}}std::vector<{{items.baseType}}> {{paramName}};{{/isArray}}
{{#isMap}}std::map<std::string, {{items.baseType}}> {{paramName}};{{/isMap}}
{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{dataType}} {{paramName}};
{{/isPrimitiveType}}
{{/bodyParam}}
{{/hasBodyParam}}
{{#hasQueryParams}}
// Getting the query params
{{#queryParams}}
auto {{paramName}}Query = request.query().get("{{baseName}}");
std::optional<{{^isContainer}}{{dataType}}{{/isContainer}}{{#isArray}}std::vector<{{items.baseType}}>{{/isArray}}> {{paramName}};
if ({{paramName}}Query.has_value()) {
{{^isContainer}}{{dataType}}{{/isContainer}}{{#isArray}}std::vector<{{items.baseType}}>{{/isArray}} valueQuery_instance;
if (fromStringValue({{paramName}}Query.value(), valueQuery_instance)) {
{{paramName}} = valueQuery_instance;
}
}
}
{{/queryParams}}
{{/hasQueryParams}}{{#hasHeaderParams}}
// Getting the header params
{{#headerParams}}
auto {{paramName}} = request.headers().tryGetRaw("{{baseName}}");
{{/headerParams}}
{{/hasHeaderParams}}
{{/queryParams}}
{{/hasQueryParams}}
{{#hasHeaderParams}}
// Getting the header params
{{#headerParams}}
auto {{paramName}} = request.headers().tryGetRaw("{{baseName}}");
{{/headerParams}}
{{/hasHeaderParams}}
try {
{{#hasBodyParam}}
{{#bodyParam}}
{{^isPrimitiveType}}
nlohmann::json::parse(request.body()).get_to({{paramName}});{{#isArray}}
for (const auto& validationParam : {{paramName}})
validationParam.validate();{{/isArray}}{{^isArray}}
{{paramName}}.validate();{{/isArray}}
{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{paramName}} = request.body();
{{/isPrimitiveType}}
} catch (std::exception &e) {
this->handleParsingException(e, response);
return;
}
{{#hasBodyParam}}
try {
{{#bodyParam}}
{{^isPrimitiveType}}
nlohmann::json::parse(request.body()).get_to({{paramName}});
{{#isArray}}
for (const auto& validationParam : {{paramName}})
validationParam.validate();
{{/isArray}}
{{^isArray}}
{{paramName}}.validate();
{{/isArray}}
{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{paramName}} = request.body();
{{/isPrimitiveType}}
{{/bodyParam}}
} catch (std::exception& e) {
this->handleParsingException(e, response);
return;
}
{{/hasBodyParam}}
try {
{{/bodyParam}}
{{/hasBodyParam}}
this->{{operationIdSnakeCase}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}response);
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{^vendorExtensions.x-codegen-pistache-is-parsing-supported}}
try {
this->{{operationIdSnakeCase}}(request, response);
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
this->handleOperationException(e, response);
return;
}
try {
{{#authMethods}}
#ifndef HTTP_BASIC_AUTH_DEFINED
#define HTTP_BASIC_AUTH_DEFINED 0
#endif
#ifndef HTTP_BEARER_AUTH_DEFINED
#define HTTP_BEARER_AUTH_DEFINED 0
#endif
{{/authMethods}}
{{#authMethods}}{{#isBasicBasic}}
#undef HTTP_BASIC_AUTH_DEFINED
#define HTTP_BASIC_AUTH_DEFINED 1
auto basicAuthHeader = request.headers().tryGet<Pistache::Http::Header::Authorization>();
if(!basicAuthHeader || (basicAuthHeader->getMethod() != Pistache::Http::Header::Authorization::Method::Basic))
{
response.send(Pistache::Http::Code::Unauthorized, "");
return;
}
HttpBasicCredentials credentials{basicAuthHeader->getBasicUser(), basicAuthHeader->getBasicPassword()};
if (!this->basicCredentialsAuthenticator.has_value() || !this->basicCredentialsAuthenticator.value()(credentials))
{
response.send(Pistache::Http::Code::Unauthorized, "");
return;
}
{{/isBasicBasic}}
{{/authMethods}}
{{#authMethods}}
{{#isBasicBearer}}
#undef HTTP_BEARER_AUTH_DEFINED
#define HTTP_BEARER_AUTH_DEFINED 1
auto bearerAuthHeader = request.headers().tryGet<Pistache::Http::Header::Authorization>();
if (!bearerAuthHeader || (bearerAuthHeader->getMethod() != Pistache::Http::Header::Authorization::Method::Bearer))
{
response.send(Pistache::Http::Code::Unauthorized, "");
return;
}
std::string completeHeaderValue = bearerAuthHeader->value();
const std::string tokenAsString(completeHeaderValue.begin() + std::string("Bearer ").length(), completeHeaderValue.end());
HttpBearerToken bearerToken{tokenAsString};
if (!this->bearerTokenAuthenticator.has_value() || !this->bearerTokenAuthenticator.value()(bearerToken))
{
response.send(Pistache::Http::Code::Unauthorized, "");
return;
}
{{/isBasicBearer}}
{{/authMethods}}
this->{{operationIdSnakeCase}}({{#authMethods}}{{#isBasicBasic}}credentials,{{/isBasicBasic}}{{#isBasicBearer}}bearerToken,{{/isBasicBearer}}{{/authMethods}}{{#allParams}}{{paramName}}, {{/allParams}}response);
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
{{^vendorExtensions.x-codegen-pistache-is-parsing-supported}}
try {
this->{{operationIdSnakeCase}}(request, response);
{{/vendorExtensions.x-codegen-pistache-is-parsing-supported}}
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
this->handleOperationException(e, response);
return;
}
} catch (std::exception &e) {
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
}
{{#hasAuthMethods}}
#ifndef HTTP_BASIC_AUTH_DEFINED
#define HTTP_BASIC_AUTH_DEFINED 0
#endif
#ifndef HTTP_BEARER_AUTH_DEFINED
#define HTTP_BEARER_AUTH_DEFINED 0
#endif
#define REST_PATH "{{{vendorExtensions.x-codegen-pistache-path}}}" {{! this is nessecary, because the path does not exist in the authMethods scope.}}
{{! This static assert may be rendered more that once, so the compilation will fail even harder!}}
static_assert(HTTP_BASIC_AUTH_DEFINED + HTTP_BEARER_AUTH_DEFINED < 2, "Path '" REST_PATH "' has more than one security scheme specified, and the Pistache server generator does not support that.");
#undef REST_PATH
#ifdef HTTP_BEARER_AUTH_DEFINED
#undef HTTP_BEARER_AUTH_DEFINED
#endif
#ifdef HTTP_BASIC_AUTH_DEFINED
#undef HTTP_BASIC_AUTH_DEFINED
#endif
{{/hasAuthMethods}}
}
{{/operation}}
void {{classname}}::{{classnameSnakeLowerCase}}_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {

View File

@@ -1,9 +0,0 @@
source 'https://rubygems.org'
gemspec
group :development, :test do
gem 'rake', '~> 13.0.1'
gem 'pry-byebug'
gem 'rubocop', '~> 0.66.0'
end

View File

@@ -1,10 +0,0 @@
require "bundler/gem_tasks"
begin
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task default: :spec
rescue LoadError
# no rspec available
end

View File

@@ -131,7 +131,7 @@ module {{moduleName}}
cookie_params = Hash(String, String).new
# query parameters
query_params = Hash(String, String).new
query_params = Hash(String, String | Array(String)).new
{{#queryParams}}
query_params["{{{baseName}}}"] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}) unless {{{paramName}}}.nil?{{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}.to_s unless {{{paramName}}}.nil?{{/collectionFormat}}
{{/queryParams}}

View File

@@ -109,8 +109,7 @@ module {{moduleName}}
when :pipes
param.join("|")
when :multi
# TODO: Need to fix this
raise "multi is not supported yet"
param
else
raise "unknown collection format: #{collection_format.inspect}"
end
@@ -147,7 +146,8 @@ module {{moduleName}}
cookies: cookie_params,
form: form_or_body,
logging: @config.debugging,
handle_errors: false
handle_errors: false,
params_encoder: {{{paramsEncoder}}}
)
response = request.execute

View File

@@ -1,35 +0,0 @@
=begin
{{> api_info}}
=end
require 'spec_helper'
Spectator.describe {{moduleName}}::Configuration do
let(:config) { {{moduleName}}::Configuration.default }
before(:each) do
# uncomment below to setup host and base_path
# require 'URI'
# uri = URI.parse("{{{basePath}}}")
# {{moduleName}}.configure do |c|
# c.host = uri.host
# c.base_path = uri.path
# end
end
describe '#base_url' do
it 'should have the default value' do
# uncomment below to test default value of the base path
# expect(config.base_url).to eq("{{{basePath}}}")
end
it 'should remove trailing slashes' do
[nil, '', '/', '//'].each do |base_path|
config.base_path = base_path
# uncomment below to test trailing slashes
# expect(config.base_url).to eq("{{{basePath}}}")
end
end
end
end

View File

@@ -1,29 +0,0 @@
### TLS/SSL setting
# Set this to false to skip verifying SSL certificate when calling API from https server.
# Default to true.
#
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
#
# @return [true, false]
#TODO attr_accessor :ssl_verify
### TLS/SSL setting
# Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
#
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
#
#TODO attr_accessor :ssl_verify_mode
### TLS/SSL setting
# Set this to customize the certificate file to verify the peer.
#
# @return [String] the path to the certificate file
#TODO attr_accessor :ssl_ca_file
### TLS/SSL setting
# Client certificate file (for client certificate)
#TODO attr_accessor :ssl_client_cert
### TLS/SSL setting
# Client private key file (for client certificate)
#TODO attr_accessor :ssl_client_key

View File

@@ -1,34 +0,0 @@
### TLS/SSL setting
# Set this to false to skip verifying SSL certificate when calling API from https server.
# Default to true.
#
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
#
# @return [true, false]
#TODO attr_accessor :verify_ssl
### TLS/SSL setting
# Set this to false to skip verifying SSL host name
# Default to true.
#
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
#
# @return [true, false]
# TODO attr_accessor :verify_ssl_host
### TLS/SSL setting
# Set this to customize the certificate file to verify the peer.
#
# @return [String] the path to the certificate file
#
# @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code:
# https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145
# TODO attr_accessor :ssl_ca_cert
### TLS/SSL setting
# Client certificate file (for client certificate)
# TODO attr_accessor :cert_file
### TLS/SSL setting
# Client private key file (for client certificate)
# TODO attr_accessor :key_file

View File

@@ -1,5 +0,0 @@
# {{#lambdaPrefixWithHash}}{{> api_info}}{{/lambdaPrefixWithHash}}
module {{moduleName}}
VERSION = '{{shardVersion}}'
end

View File

@@ -48,7 +48,7 @@ import {{packageName}}.infrastructure.Success
import {{packageName}}.infrastructure.toMultiValue
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}class {{classname}}(basePath: kotlin.String = defaultBasePath, client: Call.Factory = ApiClient.defaultClient) : ApiClient(basePath, client) {
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}}(basePath: kotlin.String = defaultBasePath, client: Call.Factory = ApiClient.defaultClient) : ApiClient(basePath, client) {
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
@JvmStatic
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {

View File

@@ -20,7 +20,7 @@ import org.springframework.http.MediaType
import {{packageName}}.infrastructure.*
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}class {{classname}}(client: RestClient) : ApiClient(client) {
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}}(client: RestClient) : ApiClient(client) {
{{#jackson}}
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}constructor(baseUrl: String) : this(RestClient.builder()

View File

@@ -10,7 +10,7 @@ import org.springframework.util.LinkedMultiValueMap
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient(protected val client: RestClient) {
protected inline fun <reified I : Any, reified T: Any?> request(requestConfig: RequestConfig<I>): ResponseEntity<T> {
protected inline fun <reified I : Any, reified T: Any> request(requestConfig: RequestConfig<I>): ResponseEntity<T> {
return prepare(defaults(requestConfig))
.retrieve()
.toEntity(object : ParameterizedTypeReference<T>() {})

View File

@@ -21,7 +21,7 @@ import org.springframework.util.LinkedMultiValueMap
import {{packageName}}.infrastructure.*
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}class {{classname}}(client: WebClient) : ApiClient(client) {
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}}(client: WebClient) : ApiClient(client) {
{{#jackson}}
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}constructor(baseUrl: String) : this(WebClient.builder()

View File

@@ -12,7 +12,7 @@ import reactor.core.publisher.Mono
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient(protected val client: WebClient) {
protected inline fun <reified I : Any, reified T: Any?> request(requestConfig: RequestConfig<I>): Mono<ResponseEntity<T>> {
protected inline fun <reified I : Any, reified T: Any> request(requestConfig: RequestConfig<I>): Mono<ResponseEntity<T>> {
return prepare(defaults(requestConfig))
.retrieve()
.toEntity(object : ParameterizedTypeReference<T>() {})

View File

@@ -37,7 +37,7 @@ import {{packageName}}.infrastructure.*
@Suppress ("UNUSED")
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}class {{classname}}(basePath: kotlin.String = ApiClient.defaultBasePath, accessToken: String? = null, apiKey: MutableMap<String, String> = mutableMapOf(), apiKeyPrefix: MutableMap<String, String> = mutableMapOf(), username: String? = null, password: String? = null, vertx: Vertx): ApiClient(basePath, accessToken, apiKey, apiKeyPrefix, username, password, vertx) {
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}}(basePath: kotlin.String = ApiClient.defaultBasePath, accessToken: String? = null, apiKey: MutableMap<String, String> = mutableMapOf(), apiKeyPrefix: MutableMap<String, String> = mutableMapOf(), username: String? = null, password: String? = null, vertx: Vertx): ApiClient(basePath, accessToken, apiKey, apiKeyPrefix, username, password, vertx) {
{{#operation}}
{{#allParams}}
{{#isEnum}}

View File

@@ -26,7 +26,7 @@ import {{packageName}}.infrastructure.CollectionFormats.*
* can pass that to the request queue like:
* Volley.newRequestQueue(context.applicationContext, myCustomHttpStack)
*/
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}class {{classname}} (
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}open {{/nonPublicApi}}class {{classname}} (
private val context: Context,
private val requestQueue: Lazy<RequestQueue> = lazy(initializer = {
Volley.newRequestQueue(context.applicationContext)

View File

@@ -20,7 +20,9 @@ import io.swagger.annotations.AuthorizationScope
{{/swagger1AnnotationLibrary}}
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}
import org.springframework.web.bind.annotation.*
{{#useBeanValidation}}
@@ -28,6 +30,9 @@ import org.springframework.validation.annotation.Validated
{{/useBeanValidation}}
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.beans.factory.annotation.Autowired
{{#useRequestMappingOnController}}
import {{#apiPackage}}{{.}}.{{/apiPackage}}{{classname}}Controller.Companion.BASE_PATH
{{/useRequestMappingOnController}}
{{#useBeanValidation}}
import {{javaxPackage}}.validation.Valid
@@ -56,15 +61,18 @@ import kotlin.collections.Map
{{/swagger1AnnotationLibrary}}
{{#useRequestMappingOnController}}
{{=<% %>=}}
@RequestMapping("\${api.base-path:<%contextPath%>}")
@RequestMapping("\${openapi.<%title%>.base-path:\${api.base-path:$BASE_PATH}}")
<%={{ }}=%>
{{/useRequestMappingOnController}}
{{#operations}}
class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) val service: {{classname}}Service{{/serviceInterface}}) {
{{#operation}}
{{#swagger2AnnotationLibrary}}
@Operation(
{{#operation}}
{{^useResponseEntity}}
@ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}}){{!
}}{{/useResponseEntity}}{{!
}}{{#swagger2AnnotationLibrary}}{{!
}} @Operation(
summary = "{{{summary}}}",
operationId = "{{{operationId}}}",
description = """{{{unescapedNotes}}}""",
@@ -83,15 +91,28 @@ class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) v
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}]){{/swagger1AnnotationLibrary}}
@RequestMapping(
method = [RequestMethod.{{httpMethod}}],
value = ["{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}"]{{#singleContentTypes}}{{#hasProduces}},
value = [PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}" */]{{#singleContentTypes}}{{#hasProduces}},
produces = [{{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}}]{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
)
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): ResponseEntity<{{>returnTypes}}> {
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}
{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
{{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}{{#hasParams}}
{{/hasParams}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}} {
return {{>returnValue}}
}
{{/operation}}
companion object {
//for your own safety never directly reuse these path definitions in tests
{{#useRequestMappingOnController}}
const val BASE_PATH: String = "{{=<% %>=}}<%contextPath%><%={{ }}=%>"
{{/useRequestMappingOnController}}
{{#operation}}
const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{{path}}}"
{{/operation}}
}
}
{{/operations}}

View File

@@ -3,13 +3,16 @@ package {{package}}
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import java.util.Optional
{{#useRequestMappingOnController}}
import {{#apiPackage}}{{.}}.{{/apiPackage}}{{classname}}Controller.Companion.BASE_PATH
{{/useRequestMappingOnController}}
{{>generatedAnnotation}}
@Controller{{#beanQualifiers}}("{{package}}.{{classname}}Controller"){{/beanQualifiers}}
{{#useRequestMappingOnController}}
{{=<% %>=}}
@RequestMapping("\${openapi.<%title%>.base-path:<%>defaultBasePath%>}")
@RequestMapping("\${openapi.<%title%>.base-path:\${api.base-path:$BASE_PATH}}")
<%={{ }}=%>
{{/useRequestMappingOnController}}
{{#operations}}
@@ -30,5 +33,13 @@ class {{classname}}Controller(
{{/skipDefaultDelegateInterface}}
override fun getDelegate(): {{classname}}Delegate = delegate
{{#useRequestMappingOnController}}
companion object {
//for your own safety never directly reuse these path definitions in tests
const val BASE_PATH: String = "{{=<% %>=}}<%>defaultBasePath%><%={{ }}=%>"
}
{{/useRequestMappingOnController}}
}
{{/operations}}

View File

@@ -4,7 +4,9 @@ package {{package}}
{{/imports}}
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}
import org.springframework.web.context.request.NativeWebRequest
{{#appendRequestToHandler}}
import org.springframework.http.server.reactive.ServerHttpRequest
@@ -14,9 +16,6 @@ import kotlinx.coroutines.flow.Flow
{{/reactive}}
import java.util.Optional
{{#async}}
import java.util.concurrent.CompletableFuture
{{/async}}
{{#operations}}
/**
@@ -35,7 +34,7 @@ interface {{classname}}Delegate {
*/
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}{{#isBodyParam}}Flow<{{{baseType}}}>{{/isBodyParam}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{/isArray}}{{/reactive}}{{^-last}},
{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
{{/hasParams}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}}{{^skipDefaultDelegateInterface}} {
{{/hasParams}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{^skipDefaultDelegateInterface}} {
{{>methodBody}}{{! prevent indent}}
}{{/skipDefaultDelegateInterface}}

View File

@@ -25,7 +25,9 @@ import io.swagger.annotations.AuthorizationScope
{{/swagger1AnnotationLibrary}}
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}
import org.springframework.web.bind.annotation.*
{{#useBeanValidation}}
@@ -33,6 +35,9 @@ import org.springframework.validation.annotation.Validated
{{/useBeanValidation}}
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.beans.factory.annotation.Autowired
{{#useRequestMappingOnInterface}}
import {{#apiPackage}}{{.}}.{{/apiPackage}}{{classname}}.Companion.BASE_PATH
{{/useRequestMappingOnInterface}}
{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.DecimalMax
@@ -63,7 +68,7 @@ import kotlin.collections.Map
{{/swagger1AnnotationLibrary}}
{{#useRequestMappingOnInterface}}
{{=<% %>=}}
@RequestMapping("\${api.base-path:<%contextPath%>}")
@RequestMapping("\${openapi.<%title%>.base-path:\${api.base-path:$BASE_PATH}}")
<%={{ }}=%>
{{/useRequestMappingOnInterface}}
{{#operations}}
@@ -72,10 +77,13 @@ interface {{classname}} {
fun getDelegate(): {{classname}}Delegate{{^skipDefaultDelegateInterface}} = object: {{classname}}Delegate {}{{/skipDefaultDelegateInterface}}
{{/isDelegate}}
{{#operation}}
{{#swagger2AnnotationLibrary}}
@Operation(
{{#operation}}
{{^useResponseEntity}}
@ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}}){{!
}}{{/useResponseEntity}}{{!
}}{{#swagger2AnnotationLibrary}}{{!
}} @Operation(
tags = [{{#tags}}"{{{name}}}",{{/tags}}],
summary = "{{{summary}}}",
operationId = "{{{operationId}}}",
@@ -91,18 +99,23 @@ interface {{classname}} {
notes = "{{{notes}}}"{{#returnBaseType}},
response = {{{.}}}::class{{/returnBaseType}}{{#returnContainer}},
responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}},
authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, {{/-last}}{{/scopes}}]{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}]{{/hasAuthMethods}})
@ApiResponses(
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}}, {{/-last}}{{/responses}}]){{/swagger1AnnotationLibrary}}
@RequestMapping(
method = [RequestMethod.{{httpMethod}}],
value = ["{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}"]{{#singleContentTypes}}{{#hasProduces}},
produces = [{{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}}]{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, {{/-last}}{{/scopes}}]{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}]{{/hasAuthMethods}}
)
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): ResponseEntity<{{>returnTypes}}>{{^skipDefaultApiInterface}} {
@ApiResponses(
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}}, {{/-last}}{{/responses}}]
){{/swagger1AnnotationLibrary}}
@RequestMapping(
method = [RequestMethod.{{httpMethod}}],
value = [PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}" */]{{#singleContentTypes}}{{#hasProduces}},
produces = [{{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}}]{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
)
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}
{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
{{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}{{#hasParams}}
{{/hasParams}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{^skipDefaultApiInterface}} {
{{^isDelegate}}
return {{>returnValue}}
{{/isDelegate}}
@@ -110,6 +123,16 @@ interface {{classname}} {
return getDelegate().{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
{{/isDelegate}}
}{{/skipDefaultApiInterface}}
{{/operation}}
companion object {
//for your own safety never directly reuse these path definitions in tests
{{#useRequestMappingOnInterface}}
const val BASE_PATH: String = "{{=<% %>=}}<%contextPath%><%={{ }}=%>"
{{/useRequestMappingOnInterface}}
{{#operation}}
const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{{path}}}"
{{/operation}}
}
}
{{/operations}}

View File

@@ -7,7 +7,12 @@ import org.junit.jupiter.api.Test
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.test.runBlockingTest
{{/reactive}}
{{^useResponseEntity}}
import org.springframework.http.HttpStatus
{{/useResponseEntity}}
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}
class {{classname}}Test {
@@ -30,7 +35,7 @@ class {{classname}}Test {
val {{{paramName}}}: {{>optionalDataType}} = TODO()
{{/allParams}}
{{#includeHttpRequestContext}}val {{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}} = TODO(){{/includeHttpRequestContext}}
val response: ResponseEntity<{{>returnTypes}}> = api.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
val response: {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}} = api.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
// TODO: test validations
}

View File

@@ -1 +1 @@
{{#isBodyParam}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"], defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"]){{/defaultValue}}{{/allowableValues}}{{/isContainer}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}, allowableValues = "{{{.}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}}{{#useBeanValidation}} @Valid{{>beanValidationBodyParams}}{{/useBeanValidation}} @RequestBody{{^required}}(required = false){{/required}} {{{paramName}}}: {{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}
{{#isBodyParam}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"], defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"]){{/defaultValue}}{{/allowableValues}}{{/isContainer}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}, allowableValues = "{{{.}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}) {{/swagger1AnnotationLibrary}}{{#useBeanValidation}}@Valid{{>beanValidationBodyParams}}{{/useBeanValidation}} @RequestBody{{^required}}(required = false){{/required}} {{{paramName}}}: {{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}

View File

@@ -1 +1 @@
{{#isFormParam}}{{^isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}@RequestParam{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}} {{/isFile}}{{#isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "file detail"){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}}{{/isFile}}{{/isFormParam}}
{{#isFormParam}}{{^isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}) {{/swagger1AnnotationLibrary}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{#isModel}}@RequestPart{{/isModel}}{{^isModel}}@RequestParam{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}}{{/isFile}}{{#isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}") {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "file detail") {{/swagger1AnnotationLibrary}}{{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}}{{/isFile}}{{/isFormParam}}

View File

@@ -1 +1 @@
{{#isHeaderParam}}{{#useBeanValidation}}{{>beanValidationCore}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}", `in` = ParameterIn.HEADER{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}{{#defaultValue}}, defaultValue = {{^isString}}"{{{.}}}"{{/isString}}{{#isString}}{{#isEnum}}"{{{.}}}"{{/isEnum}}{{^isEnum}}{{{.}}}{{/isEnum}}{{/isString}}{{/defaultValue}}) {{{paramName}}}: {{>optionalDataType}}{{/isHeaderParam}}
{{#isHeaderParam}}{{#useBeanValidation}}{{>beanValidationCore}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}", `in` = ParameterIn.HEADER{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}) {{/swagger1AnnotationLibrary}}@RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}{{#defaultValue}}, defaultValue = {{^isString}}"{{{.}}}"{{/isString}}{{#isString}}{{#isEnum}}"{{{.}}}"{{/isEnum}}{{^isEnum}}{{{.}}}{{/isEnum}}{{/isString}}{{/defaultValue}}) {{{paramName}}}: {{>optionalDataType}}{{/isHeaderParam}}

View File

@@ -29,7 +29,12 @@ import io.swagger.annotations.AuthorizationScope
import org.springframework.web.service.annotation.*
import org.springframework.web.bind.annotation.*
{{^useResponseEntity}}
import org.springframework.http.HttpStatus
{{/useResponseEntity}}
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated
@@ -45,19 +50,22 @@ import reactor.core.publisher.Mono
import kotlin.collections.List
import kotlin.collections.Map
{{#useRequestMappingOnInterface}}@HttpExchange(
"{{=<% %>=}}\${api.base-path:$BASE_PATH}<%={{ }}=%>"
){{/useRequestMappingOnInterface}}
{{#useRequestMappingOnInterface}}
{{=<% %>=}}
@HttpExchange("\${openapi.<%title%>.base-path:\${api.base-path:$BASE_PATH}}")
<%={{ }}=%>
{{/useRequestMappingOnInterface}}
{{#useBeanValidation}}
@Validated
{{/useBeanValidation}}
{{#operations}}
interface {{classname}} {
{{#operation}}
{{#httpMethod}}
@HttpExchange(
url = PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}},
{{#operation}}{{!
}}{{^useResponseEntity}} @ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}})
{{/useResponseEntity}}{{!
}}{{#httpMethod}} @HttpExchange(
url = PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}" */,
method = "{{httpMethod}}"
)
{{/httpMethod}}{{!

View File

@@ -1 +1 @@
{{#isBodyParam}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"], defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"]){{/defaultValue}}{{/allowableValues}}{{/isContainer}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}, allowableValues = "{{{.}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}}{{#useBeanValidation}} @Valid{{>beanValidationBodyParams}}{{/useBeanValidation}} @RequestBody{{^required}}(required = false){{/required}} {{{paramName}}}: {{>optionalDataType}}{{/isBodyParam}}
{{#isBodyParam}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"], defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = ["{{{allowableValues}}}"]){{/defaultValue}}{{/allowableValues}}{{/isContainer}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{^isContainer}}{{#allowableValues}}, allowableValues = "{{{.}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}) {{/swagger1AnnotationLibrary}}{{#useBeanValidation}}@Valid{{>beanValidationBodyParams}}{{/useBeanValidation}} @RequestBody{{^required}}(required = false){{/required}} {{{paramName}}}: {{>optionalDataType}}{{/isBodyParam}}

View File

@@ -1,47 +1,47 @@
{{! handle reactive map and array}}
{{#reactive}}
{{#isMap}}
{{#reactiveModeReactor}}Mono<{{/reactiveModeReactor}}{{#declarativeInterfaceWrapResponses}}ResponseEntity<{{/declarativeInterfaceWrapResponses}}Map<String, {{{returnType}}}>{{#declarativeInterfaceWrapResponses}}>{{/declarativeInterfaceWrapResponses}}{{#reactiveModeReactor}}>{{/reactiveModeReactor}}
{{#reactiveModeReactor}}Mono<{{/reactiveModeReactor}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}Map<String, {{{returnType}}}>{{#useResponseEntity}}>{{/useResponseEntity}}{{#reactiveModeReactor}}>{{/reactiveModeReactor}}
{{/isMap}}
{{#isArray}}
{{! array handle reactive - reactor with/without ResponseEntity wrapper}}
{{#reactiveModeReactor}}
{{#declarativeInterfaceWrapResponses}}Mono<ResponseEntity<{{/declarativeInterfaceWrapResponses}}Flux<{{{returnType}}}>{{#declarativeInterfaceWrapResponses}}>>{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}Mono<ResponseEntity<{{/useResponseEntity}}Flux<{{{returnType}}}>{{#useResponseEntity}}>>{{/useResponseEntity}}
{{/reactiveModeReactor}}
{{! array handle reactive - coroutines with/without ResponseEntity wrapper}}
{{#reactiveModeCoroutines}}
{{#declarativeInterfaceWrapResponses}}ResponseEntity<{{/declarativeInterfaceWrapResponses}}{{{returnContainer}}}<{{{returnType}}}>{{#declarativeInterfaceWrapResponses}}>{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{{returnContainer}}}<{{{returnType}}}>{{#useResponseEntity}}>{{/useResponseEntity}}
{{/reactiveModeCoroutines}}
{{/isArray}}
{{! handle reactive non-container - with/without ResponseEntity wrapper}}
{{^returnContainer}}
{{#reactiveModeReactor}}
Mono<{{#declarativeInterfaceWrapResponses}}ResponseEntity<{{/declarativeInterfaceWrapResponses}}{{{returnType}}}{{#declarativeInterfaceWrapResponses}}>{{/declarativeInterfaceWrapResponses}}>
Mono<{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{{returnType}}}{{#useResponseEntity}}>{{/useResponseEntity}}>
{{/reactiveModeReactor}}
{{#reactiveModeCoroutines}}
{{#declarativeInterfaceWrapResponses}}
ResponseEntity<{{/declarativeInterfaceWrapResponses}}{{{returnType}}}{{#declarativeInterfaceWrapResponses}}>
{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}
ResponseEntity<{{/useResponseEntity}}{{{returnType}}}{{#useResponseEntity}}>
{{/useResponseEntity}}
{{/reactiveModeCoroutines}}
{{/returnContainer}}
{{/reactive}}
{{^reactive}}
{{! handle non-reactive map and array}}
{{#isMap}}
{{#declarativeInterfaceWrapResponses}}
ResponseEntity<{{/declarativeInterfaceWrapResponses}}Map<String, {{{returnType}}}>{{#declarativeInterfaceWrapResponses}}>
{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}
ResponseEntity<{{/useResponseEntity}}Map<String, {{{returnType}}}>{{#useResponseEntity}}>
{{/useResponseEntity}}
{{/isMap}}
{{#isArray}}
{{! array handle non-reactive - with/without ResponseEntity wrapper}}
{{#declarativeInterfaceWrapResponses}}
ResponseEntity<{{/declarativeInterfaceWrapResponses}}{{{returnContainer}}}<{{{returnType}}}>{{#declarativeInterfaceWrapResponses}}>
{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}
ResponseEntity<{{/useResponseEntity}}{{{returnContainer}}}<{{{returnType}}}>{{#useResponseEntity}}>
{{/useResponseEntity}}
{{/isArray}}
{{! handle reactive non-container - with/without ResponseEntity wrapper}}
{{^returnContainer}}
{{#declarativeInterfaceWrapResponses}}
ResponseEntity<{{/declarativeInterfaceWrapResponses}}{{{returnType}}}{{#declarativeInterfaceWrapResponses}}>
{{/declarativeInterfaceWrapResponses}}
{{#useResponseEntity}}
ResponseEntity<{{/useResponseEntity}}{{{returnType}}}{{#useResponseEntity}}>
{{/useResponseEntity}}
{{/returnContainer}}
{{/reactive}}

View File

@@ -1,28 +1,23 @@
{{^reactive}}
{{#examples}}
{{#-first}}
{{#async}}
return CompletableFuture.supplyAsync(()-> {
{{/async}}getRequest().ifPresent { request ->
{{#async}} {{/async}} for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
getRequest().ifPresent { request ->
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
{{/-first}}
{{#async}} {{/async}}{{^async}} {{/async}} if (mediaType.isCompatibleWith(MediaType.valueOf("{{{contentType}}}"))) {
{{#async}} {{/async}}{{^async}} {{/async}} ApiUtil.setExampleResponse(request, "{{{contentType}}}", "{{#lambdaRemoveLineBreak}}{{#lambdaEscapeInNormalString}}{{{example}}}{{/lambdaEscapeInNormalString}}{{/lambdaRemoveLineBreak}}")
{{#async}} {{/async}}{{^async}} {{/async}} break
{{#async}} {{/async}}{{^async}} {{/async}} }
if (mediaType.isCompatibleWith(MediaType.valueOf("{{{contentType}}}"))) {
ApiUtil.setExampleResponse(request, "{{{contentType}}}", "{{#lambdaRemoveLineBreak}}{{#lambdaEscapeInNormalString}}{{{example}}}{{/lambdaEscapeInNormalString}}{{/lambdaRemoveLineBreak}}")
break
}
{{#-last}}
{{#async}} {{/async}}{{^async}} {{/async}} }
{{#async}} {{/async}} }
{{#async}} {{/async}} return ResponseEntity({{#returnSuccessCode}}HttpStatus.valueOf({{{statusCode}}}){{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}})
{{#async}}
}, Runnable::run)
{{/async}}
}
}
return {{#useResponseEntity}}ResponseEntity({{#returnSuccessCode}}HttpStatus.valueOf({{{statusCode}}}){{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}}){{/useResponseEntity}}{{^useResponseEntity}}TODO("Not yet implemented"){{/useResponseEntity}}
{{/-last}}
{{/examples}}
{{^examples}}
return {{#async}}CompletableFuture.completedFuture({{/async}}ResponseEntity({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}})
return {{#useResponseEntity}}ResponseEntity({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}}){{/useResponseEntity}}{{^useResponseEntity}}TODO("Not yet implemented"){{/useResponseEntity}}
{{/examples}}
{{/reactive}}
{{#reactive}}
return ResponseEntity({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}})
return {{#useResponseEntity}}ResponseEntity({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}}){{/useResponseEntity}}{{^useResponseEntity}}TODO("Not yet implemented"){{/useResponseEntity}}
{{/reactive}}

View File

@@ -1 +1 @@
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}}
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}) {{/swagger1AnnotationLibrary}}@PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}}

View File

@@ -1 +1 @@
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}){{/swagger1AnnotationLibrary}}{{#useBeanValidation}} @Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}){{/isModel}}{{#isDate}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE){{/isDate}}{{#isDateTime}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME){{/isDateTime}} {{{paramName}}}: {{>optionalDataType}}{{/isQueryParam}}
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}) {{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}) {{/swagger1AnnotationLibrary}}{{#useBeanValidation}}@Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}){{/isModel}}{{#isDate}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE){{/isDate}}{{#isDateTime}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME){{/isDateTime}} {{{paramName}}}: {{>optionalDataType}}{{/isQueryParam}}

View File

@@ -1 +1,4 @@
{{#serviceInterface}}ResponseEntity(service.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}), {{#responses}}{{#-first}}HttpStatus.valueOf({{code}}){{/-first}}{{/responses}}){{/serviceInterface}}{{^serviceInterface}}ResponseEntity(HttpStatus.NOT_IMPLEMENTED){{/serviceInterface}}
{{!}}{{#useResponseEntity}}{{#serviceInterface}}ResponseEntity(service.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}), {{#responses}}{{#-first}}HttpStatus.valueOf({{code}}){{/-first}}{{/responses}}){{/serviceInterface}}{{/useResponseEntity}}{{!
---}}{{#useResponseEntity}}{{^serviceInterface}}ResponseEntity(HttpStatus.NOT_IMPLEMENTED){{/serviceInterface}}{{/useResponseEntity}}{{!
---}}{{^useResponseEntity}}{{#serviceInterface}}service.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}){{/serviceInterface}}{{/useResponseEntity}}{{!
---}}{{^useResponseEntity}}{{^serviceInterface}}TODO("Not yet implemented"){{/serviceInterface}}{{/useResponseEntity}}

View File

@@ -36,7 +36,7 @@ class SpringFoxConfiguration {
@Bean
{{=<% %>=}}
fun customImplementation(servletContext: ServletContext, @Value("\${openapi.<%title%>.base-path:<%>defaultBasePath%>}") basePath: String): Docket {
fun customImplementation(servletContext: ServletContext, @Value("\${openapi.<%title%>.base-path:\${api.base-path:<%>defaultBasePath%>}}") basePath: String): Docket {
<%={{ }}=%>
return Docket(DocumentationType.SWAGGER_2)
.select()

View File

@@ -33,7 +33,9 @@ include = ["{{packageName}}/py.typed"]
[tool.poetry.dependencies]
python = "^3.9"
{{^async}}
urllib3 = ">= 2.1.0, < 3.0.0"
{{/async}}
python-dateutil = ">= 2.8.2"
{{#asyncio}}
aiohttp = ">= 3.8.4"
@@ -59,7 +61,9 @@ lazy-imports = ">= 1, < 2"
requires-python = ">=3.9"
dependencies = [
{{^async}}
"urllib3 (>=2.1.0,<3.0.0)",
{{/async}}
"python-dateutil (>=2.8.2)",
{{#httpx}}
"httpx (>=0.28.1)",

View File

@@ -1,4 +1,6 @@
{{^async}}
urllib3 >= 2.1.0, < 3.0.0
{{/async}}
python_dateutil >= 2.8.2
{{#asyncio}}
aiohttp >= 3.8.4

View File

@@ -15,7 +15,9 @@ NAME = "{{{projectName}}}"
VERSION = "{{packageVersion}}"
PYTHON_REQUIRES = ">= 3.9"
REQUIRES = [
{{^async}}
"urllib3 >= 2.1.0, < 3.0.0",
{{/async}}
"python-dateutil >= 2.8.2",
{{#asyncio}}
"aiohttp >= 3.8.4",

View File

@@ -533,7 +533,7 @@ pub fn check_xss_map<T>(v: &std::collections::HashMap<String, T>) -> std::result
/// which helps with FFI.
#[allow(non_camel_case_types, clippy::large_enum_variant)]
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, {{^isAnyType}}PartialOrd, Ord,{{/isAnyType}} serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum {{{classname}}} {
{{#allowableValues}}
@@ -584,7 +584,7 @@ impl std::str::FromStr for {{{classname}}} {
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
{{/isMap}}
{{^isMap}}
#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, {{^isAnyType}}PartialOrd, {{/isAnyType}} serde::Serialize, serde::Deserialize)]
{{/isMap}}
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
pub struct {{{classname}}}(pub {{{dataType}}});

View File

@@ -47,7 +47,7 @@ client = [
"serde_urlencoded",
{{/usesUrlEncodedForm}}
{{#hasCallbacks}}
"serde_ignored", "regex", "percent-encoding", "lazy_static",
"serde_ignored", "percent-encoding", {{^apiUsesByteArray}}"lazy_static", "regex",{{/apiUsesByteArray}}
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list below }}
"hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url"
@@ -66,7 +66,7 @@ server = [
"native-tls", "hyper-openssl", "hyper-tls", "openssl",
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list above }}
"serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static"
"serde_ignored", "hyper", "percent-encoding", "url" {{^apiUsesByteArray}},"lazy_static", "regex"{{/apiUsesByteArray}}
]
cli = [
{{#apiHasDeleteMethods}}
@@ -96,6 +96,10 @@ mime = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
validator = { version = "0.16", features = ["derive"] }
{{#apiUsesByteArray}}
lazy_static = "1.5"
regex = "1.12"
{{/apiUsesByteArray}}
# Crates included if required by the API definition
{{#usesXml}}
@@ -126,9 +130,11 @@ serde_urlencoded = {version = "0.6.1", optional = true}
{{/usesUrlEncodedForm}}
# Server, and client callback-specific
{{^apiUsesByteArray}}
lazy_static = { version = "1.4", optional = true }
percent-encoding = {version = "2.1.0", optional = true}
regex = {version = "1.3", optional = true}
{{/apiUsesByteArray}}
percent-encoding = {version = "2.1.0", optional = true}
# CLI-specific
anyhow = { version = "1", optional = true }

View File

@@ -1,7 +1,6 @@
use std::collections::BTreeSet;
use crate::server::Authorization;
use serde::{Deserialize, Serialize};
use swagger::{ApiError, auth::{Basic, Bearer}};
use swagger::{ApiError, auth::{Basic, Bearer, Authorization}};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
@@ -24,7 +23,7 @@ pub trait AuthenticationApi {
/// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization
fn basic_authorization(&self, basic: &Basic) -> Result<Authorization, ApiError>;
}
}
// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization)
use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes};

View File

@@ -6,10 +6,8 @@ use futures::Stream;
use std::error::Error;
use std::collections::BTreeSet;
use std::task::{Poll, Context};
use swagger::{ApiError, ContextWrapper};
use swagger::{ApiError, ContextWrapper, auth::Authorization};
use serde::{Serialize, Deserialize};
use crate::server::Authorization;
type ServiceError = Box<dyn Error + Send + Sync + 'static>;

View File

@@ -44,7 +44,7 @@ client = [
"serde_urlencoded",
{{/usesUrlEncodedForm}}
{{#hasCallbacks}}
"serde_ignored", "regex", "percent-encoding", "lazy_static",
"serde_ignored", "percent-encoding", {{^apiUsesByteArray}}"lazy_static", "regex",{{/apiUsesByteArray}}
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list below }}
"hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url"
@@ -60,7 +60,8 @@ server = [
"native-tls", "hyper-openssl", "hyper-tls", "openssl",
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list above }}
"serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static"
"serde_ignored", "hyper", "percent-encoding", "url",
{{^apiUsesByteArray}}"lazy_static", "regex"{{/apiUsesByteArray}}
]
cli = [
{{#apiHasDeleteMethods}}
@@ -88,8 +89,14 @@ futures = "0.3"
swagger = { version = "7.0.0", features = ["serdejson", "server", "client", "tls"] }
headers = "0.4.0"
log = "0.4.27"
mime = "0.3"
mockall = { version = "0.13.1", optional = true }
{{#apiUsesByteArray}}
lazy_static = "1.5"
regex = "1.12"
{{/apiUsesByteArray}}
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@@ -124,9 +131,11 @@ serde_urlencoded = { version = "0.7.1", optional = true }
tower-service = "0.3.3"
# Server, and client callback-specific
{{^apiUsesByteArray}}
lazy_static = { version = "1.5", optional = true }
percent-encoding = { version = "2.3.1", optional = true }
regex = { version = "1.12", optional = true }
{{/apiUsesByteArray}}
percent-encoding = { version = "2.3.1", optional = true }
# CLI-specific
anyhow = { version = "1", optional = true }

View File

@@ -1,7 +1,6 @@
use std::collections::BTreeSet;
use crate::server::Authorization;
use serde::{Deserialize, Serialize};
use swagger::ApiError;
use swagger::{ApiError, auth::Authorization};
use headers::authorization::{Basic, Bearer};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {

View File

@@ -1,4 +1,4 @@
let (body_string, multipart_header) = {
let (body_bytes, multipart_header) = {
let mut multipart = Multipart::new();
{{#exts}}
@@ -43,9 +43,9 @@
Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))),
};
let mut body_string = String::new();
let mut body_bytes = Vec::new();
match fields.read_to_string(&mut body_string) {
match fields.read_to_end(&mut body_bytes) {
Ok(_) => (),
Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))),
}
@@ -54,10 +54,10 @@
let multipart_header = format!("multipart/form-data;boundary={boundary}");
(body_string, multipart_header)
};
(body_bytes, multipart_header)
};
*request.body_mut() = body_from_string(body_string);
*request.body_mut() = BoxBody::new(Full::new(Bytes::from(body_bytes)));
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
Ok(h) => h,

View File

@@ -8,11 +8,10 @@ use mockall::automock;
use std::error::Error;
use std::collections::BTreeSet;
use std::task::{Poll, Context};
use swagger::{ApiError, ContextWrapper};
use swagger::{ApiError, ContextWrapper, auth::Authorization};
use serde::{Serialize, Deserialize};
use crate::server::Authorization;
#[cfg(any(feature = "client", feature = "server"))]
type ServiceError = Box<dyn Error + Send + Sync + 'static>;
pub const BASE_PATH: &str = "{{{basePathWithoutHost}}}";

View File

@@ -23,7 +23,7 @@
{{/x-produces-json}}
{{#x-produces-bytes}}
// Binary Body
let body = String::from_utf8(body.0).expect("Error converting octet stream to string");
*response.body_mut() = BoxBody::new(Full::new(Bytes::from(body.0)));
{{/x-produces-bytes}}
{{#x-produces-plain-text}}
// Plain text Body
@@ -42,7 +42,12 @@
&["multipart/related; boundary=".as_bytes(), &boundary].concat())
.expect("Unable to create Content-Type header for multipart/related"));
{{/formParams}}
*response.body_mut() = BoxBody::new(Full::new(Bytes::from(body.0)));
{{/x-produces-multipart-related}}
{{/exts}}
{{^x-produces-bytes}}
{{^x-produces-multipart-related}}
*response.body_mut() = body_from_string(body);
{{/x-produces-multipart-related}}
{{/x-produces-bytes}}
{{/exts}}
{{/dataType}}

View File

@@ -97,7 +97,7 @@ rustls-tls = ["reqwest/rustls-tls"]
{{/reqwest}}
{{#reqwestTrait}}
async-trait = "^0.1"
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart"] }
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart", "stream"] }
{{#supportMiddleware}}
reqwest-middleware = { version = "^0.4", features = ["json", "multipart"] }
{{/supportMiddleware}}

View File

@@ -391,7 +391,14 @@ impl {{classname}} for {{classname}}Client {
let mut local_var_form = reqwest::multipart::Form::new();
{{#formParams}}
{{#isFile}}
// TODO: support file upload for '{{{baseName}}}' parameter
{{^isRequired}}
if let Some(ref path) = {{{baseName}}} {
local_var_form = local_var_form.file("{{{baseName}}}", path.as_os_str()).await?;
}
{{/isRequired}}
{{#isRequired}}
local_var_form = local_var_form.file("{{{baseName}}}", {{{baseName}}}.as_os_str()).await?;
{{/isRequired}}
{{/isFile}}
{{^isFile}}
{{#required}}

View File

@@ -397,13 +397,20 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
{{/isNullable}}
{{/required}}
{{^required}}
if let Some(param_value) = {{{vendorExtensions.x-rust-param-identifier}}} {
if let Some(ref param_value) = {{{vendorExtensions.x-rust-param-identifier}}} {
multipart_form = multipart_form.file("{{{baseName}}}", param_value)?;
}
{{/required}}
{{/supportAsync}}
{{#supportAsync}}
// TODO: support file upload for '{{{baseName}}}' parameter
{{^required}}
if let Some(ref param_value) = {{{vendorExtensions.x-rust-param-identifier}}} {
multipart_form = multipart_form.file("{{{baseName}}}", param_value.as_os_str()).await?;
}
{{/required}}
{{#required}}
multipart_form = multipart_form.file("{{{baseName}}}", {{{vendorExtensions.x-rust-param-identifier}}}.as_os_str()).await?;
{{/required}}
{{/supportAsync}}
{{/isFile}}
{{^isFile}}
@@ -420,7 +427,12 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
{{/required}}
{{^required}}
if let Some(param_value) = {{{vendorExtensions.x-rust-param-identifier}}} {
multipart_form = multipart_form.text("{{{baseName}}}", param_value{{#isArray}}.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(","){{/isArray}}.to_string());
{{#isPrimitiveType}}
multipart_form = multipart_form.text("{{{baseName}}}", param_value.to_string());
{{/isPrimitiveType}}
{{^isPrimitiveType}}
multipart_form = multipart_form.text("{{{baseName}}}", serde_json::to_string(&param_value)?);
{{/isPrimitiveType}}
}
{{/required}}
{{/isFile}}

View File

@@ -2,6 +2,7 @@
import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http';
import { CustomHttpParameterCodec } from './encoder';
import { {{configurationClassName}} } from './configuration';
import { OpenApiHttpParams, QueryParamStyle, concatHttpParamsObject} from './query.params';
export class BaseService {
protected basePath = '{{{basePath}}}';
@@ -29,47 +30,58 @@ export class BaseService {
return consumes.indexOf('multipart/form-data') !== -1;
}
protected addToHttpParams(httpParams: HttpParams, value: any, key?: string, isDeep: boolean = false): HttpParams {
// If the value is an object (but not a Date), recursively add its keys.
if (typeof value === 'object' && !(value instanceof Date)) {
return this.addToHttpParamsRecursive(httpParams, value, isDeep ? key : undefined, isDeep);
}
return this.addToHttpParamsRecursive(httpParams, value, key);
}
protected addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string, isDeep: boolean = false): HttpParams {
protected addToHttpParams(httpParams: OpenApiHttpParams, key: string, value: any | null | undefined, paramStyle: QueryParamStyle, explode: boolean): OpenApiHttpParams {
if (value === null || value === undefined) {
return httpParams;
}
if (typeof value === 'object') {
// If JSON format is preferred, key must be provided.
if (key != null) {
return isDeep
? Object.keys(value as Record<string, any>).reduce(
(hp, k) => hp.append(`${key}[${k}]`, value[k]),
httpParams,
)
: httpParams.append(key, JSON.stringify(value));
if (paramStyle === QueryParamStyle.DeepObject) {
if (typeof value !== 'object') {
throw Error(`An object must be provided for key ${key} as it is a deep object`);
}
// Otherwise, if it's an array, add each element.
if (Array.isArray(value)) {
value.forEach(elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
return Object.keys(value as Record<string, any>).reduce(
(hp, k) => hp.append(`${key}[${k}]`, value[k]),
httpParams,
);
} else if (paramStyle === QueryParamStyle.Json) {
return httpParams.append(key, JSON.stringify(value));
} else {
// Form-style, SpaceDelimited or PipeDelimited
if (Object(value) !== value) {
// If it is a primitive type, add its string representation
return httpParams.append(key, value.toString());
} else if (value instanceof Date) {
if (key != null) {
httpParams = httpParams.append(key, value.toISOString());
return httpParams.append(key, value.toISOString());
} else if (Array.isArray(value)) {
// Otherwise, if it's an array, add each element.
if (paramStyle === QueryParamStyle.Form) {
return httpParams.set(key, value, {explode: explode, delimiter: ','});
} else if (paramStyle === QueryParamStyle.SpaceDelimited) {
return httpParams.set(key, value, {explode: explode, delimiter: ' '});
} else {
throw Error("key may not be null if value is Date");
// PipeDelimited
return httpParams.set(key, value, {explode: explode, delimiter: '|'});
}
} else {
Object.keys(value).forEach(k => {
const paramKey = key ? `${key}.${k}` : k;
httpParams = this.addToHttpParamsRecursive(httpParams, value[k], paramKey);
});
// Otherwise, if it's an object, add each field.
if (paramStyle === QueryParamStyle.Form) {
if (explode) {
Object.keys(value).forEach(k => {
httpParams = this.addToHttpParams(httpParams, k, value[k], paramStyle, explode);
});
return httpParams;
} else {
return concatHttpParamsObject(httpParams, key, value, ',');
}
} else if (paramStyle === QueryParamStyle.SpaceDelimited) {
return concatHttpParamsObject(httpParams, key, value, ' ');
} else {
// PipeDelimited
return concatHttpParamsObject(httpParams, key, value, '|');
}
}
return httpParams;
} else if (key != null) {
return httpParams.append(key, value);
}
throw Error("key may not be null if value is not object or array");
}
}

View File

@@ -3,10 +3,10 @@
import { Inject, Injectable, Optional } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams,
HttpResponse, HttpEvent, HttpParameterCodec{{#httpContextInOptions}}, HttpContext {{/httpContextInOptions}}
HttpResponse, HttpEvent{{#httpContextInOptions}}, HttpContext {{/httpContextInOptions}}
} from '@angular/common/http';
import { CustomHttpParameterCodec } from '../encoder';
import { Observable } from 'rxjs';
import { OpenApiHttpParams, QueryParamStyle } from '../query.params';
{{#imports}}
// @ts-ignore
@@ -87,6 +87,7 @@ export class {{classname}} extends BaseService {
{{/useSingleRequestParameter}}
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
* @param options additional options
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
@@ -107,32 +108,46 @@ export class {{classname}} extends BaseService {
{{/allParams}}
{{#hasQueryParamsOrAuth}}
let localVarQueryParameters = new HttpParams({encoder: this.encoder});
let localVarQueryParameters = new OpenApiHttpParams(this.encoder);
{{#queryParams}}
{{#isArray}}
if ({{paramName}}) {
{{#isQueryParamObjectFormatJson}}
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>{{paramName}}, '{{baseName}}');
{{/isQueryParamObjectFormatJson}}
{{^isQueryParamObjectFormatJson}}
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>element, '{{baseName}}');
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
[...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}']), '{{baseName}}');
{{/isCollectionFormatMulti}}
{{/isQueryParamObjectFormatJson}}
}
{{/isArray}}
{{^isArray}}
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>{{paramName}}, '{{baseName}}'{{#isDeepObject}}, true{{/isDeepObject}});
{{/isArray}}
localVarQueryParameters = this.addToHttpParams(
localVarQueryParameters,
'{{baseName}}',
<any>{{paramName}},
{{#isQueryParamObjectFormatJson}}
QueryParamStyle.Json,
{{/isQueryParamObjectFormatJson}}
{{^isQueryParamObjectFormatJson}}
{{^style}}
{{#queryIsJsonMimeType}}
QueryParamStyle.Json,
{{/queryIsJsonMimeType}}
{{^queryIsJsonMimeType}}
QueryParamStyle.Form,
{{/queryIsJsonMimeType}}
{{/style}}
{{#style}}
{{#isDeepObject}}
QueryParamStyle.DeepObject,
{{/isDeepObject}}
{{#isFormStyle}}
QueryParamStyle.Form,
{{/isFormStyle}}
{{#isSpaceDelimited}}
QueryParamStyle.SpaceDelimited,
{{/isSpaceDelimited}}
{{#isPipeDelimited}}
QueryParamStyle.PipeDelimited,
{{/isPipeDelimited}}
{{#queryIsJsonMimeType}}
QueryParamStyle.Json,
{{/queryIsJsonMimeType}}
{{/style}}
{{/isQueryParamObjectFormatJson}}
{{isExplode}},
);
{{/queryParams}}
{{/hasQueryParamsOrAuth}}
@@ -291,7 +306,7 @@ export class {{classname}} extends BaseService {
{{/hasFormParams}}
{{/bodyParam}}
{{#hasQueryParamsOrAuth}}
params: localVarQueryParameters,
params: localVarQueryParameters.toHttpParams(),
{{/hasQueryParamsOrAuth}}
{{#isResponseFile}}
responseType: "blob",

View File

@@ -18,3 +18,18 @@ export class CustomHttpParameterCodec implements HttpParameterCodec {
return decodeURIComponent(v);
}
}
export class IdentityHttpParameterCodec implements HttpParameterCodec {
encodeKey(k: string): string {
return k;
}
encodeValue(v: string): string {
return v;
}
decodeKey(k: string): string {
return k;
}
decodeValue(v: string): string {
return v;
}
}

View File

@@ -0,0 +1,160 @@
import { HttpParams, HttpParameterCodec } from '@angular/common/http';
import { CustomHttpParameterCodec, IdentityHttpParameterCodec } from './encoder';
export enum QueryParamStyle {
Json,
Form,
DeepObject,
SpaceDelimited,
PipeDelimited,
}
export type Delimiter = "," | " " | "|" | "\t";
export interface ParamOptions {
/** When true, serialized as multiple repeated key=value pairs. When false, serialized as a single key with joined values using `delimiter`. */
explode?: boolean;
/** Delimiter used when explode=false. The delimiter itself is inserted unencoded between encoded values. */
delimiter?: Delimiter;
}
interface ParamEntry {
values: string[];
options: Required<ParamOptions>;
}
export class OpenApiHttpParams {
private params: Map<string, ParamEntry> = new Map();
private defaults: Required<ParamOptions>;
private encoder: HttpParameterCodec;
/**
* @param encoder Parameter serializer
* @param defaults Global defaults used when a specific parameter has no explicit options.
* By OpenAPI default, explode is true for query params with style=form.
*/
constructor(encoder?: HttpParameterCodec, defaults?: { explode?: boolean; delimiter?: Delimiter }) {
this.encoder = encoder || new CustomHttpParameterCodec();
this.defaults = {
explode: defaults?.explode ?? true,
delimiter: defaults?.delimiter ?? ",",
};
}
private resolveOptions(local?: ParamOptions): Required<ParamOptions> {
return {
explode: local?.explode ?? this.defaults.explode,
delimiter: local?.delimiter ?? this.defaults.delimiter,
};
}
/**
* Replace the parameter's values and (optionally) its options.
* Options are stored per-parameter (not global).
*/
set(key: string, values: string[] | string, options?: ParamOptions): this {
const arr = Array.isArray(values) ? values.slice() : [values];
const opts = this.resolveOptions(options);
this.params.set(key, {values: arr, options: opts});
return this;
}
/**
* Append a single value to the parameter. If the parameter didn't exist it will be created
* and use resolved options (global defaults merged with any provided options).
*/
append(key: string, value: string, options?: ParamOptions): this {
const entry = this.params.get(key);
if (entry) {
// If new options provided, override the stored options for subsequent serialization
if (options) {
entry.options = this.resolveOptions({...entry.options, ...options});
}
entry.values.push(value);
} else {
this.set(key, [value], options);
}
return this;
}
/**
* Serialize to a query string according to per-parameter OpenAPI options.
* - If explode=true for that parameter → repeated key=value pairs (each value encoded).
* - If explode=false for that parameter → single key=value where values are individually encoded
* and joined using the configured delimiter. The delimiter character is inserted AS-IS
* (not percent-encoded).
*/
toString(): string {
const records = this.toRecord();
const parts: string[] = [];
for (const key in records) {
parts.push(`${key}=${records[key]}`);
}
return parts.join("&");
}
/**
* Return parameters as a plain record.
* - If a parameter has exactly one value, returns that value directly.
* - If a parameter has multiple values, returns a readonly array of values.
*/
toRecord(): Record<string, string | number | boolean | ReadonlyArray<string | number | boolean>> {
const parts: Record<string, string | number | boolean | ReadonlyArray<string | number | boolean>> = {};
for (const [key, entry] of this.params.entries()) {
const encodedKey = this.encoder.encodeKey(key);
if (entry.options.explode) {
parts[encodedKey] = entry.values.map((v) => this.encoder.encodeValue(v));
} else {
const encodedValues = entry.values.map((v) => this.encoder.encodeValue(v));
// join with the delimiter *unencoded*
parts[encodedKey] = encodedValues.join(entry.options.delimiter);
}
}
return parts;
}
/**
* Return an Angular's HttpParams with an identity parameter codec as the parameters are already encoded.
*/
toHttpParams(): HttpParams {
const records = this.toRecord();
let httpParams = new HttpParams({encoder: new IdentityHttpParameterCodec()});
return httpParams.appendAll(records);
}
}
export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: string, item: {
[index: string]: any
}, delimiter: Delimiter): OpenApiHttpParams {
let keyAndValues: string[] = [];
for (const k in item) {
keyAndValues.push(k);
const value = item[k];
if (Array.isArray(value)) {
keyAndValues.push(...value.map(convertToString));
} else {
keyAndValues.push(convertToString(value));
}
}
return httpParams.set(key, keyAndValues, {explode: false, delimiter: delimiter});
}
function convertToString(value: any): string {
if (value instanceof Date) {
return value.toISOString();
} else {
return value.toString();
}
}

View File

@@ -5,6 +5,9 @@
"noImplicitAny": false,
"target": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}es5{{/supportsES6}}",
"module": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}commonjs{{/supportsES6}}",
{{^supportsES6}}
"downlevelIteration": true,
{{/supportsES6}}
"moduleResolution": "node",
"removeComments": true,
"strictNullChecks": true,

View File

@@ -3,8 +3,7 @@
// TODO: evaluate if we can easily get rid of this library
import {{^supportsES6}}* as{{/supportsES6}} FormData from "form-data";
import { URL, URLSearchParams } from 'url';
import * as http from 'http';
import * as https from 'https';
import { type Dispatcher } from 'undici';
{{/node}}
{{/platforms}}
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};
@@ -106,7 +105,7 @@ export class RequestContext {
private signal: AbortSignal | undefined = undefined;
{{#platforms}}
{{#node}}
private agent: http.Agent | https.Agent | undefined = undefined;
private dispatcher: Dispatcher | undefined = undefined;
{{/node}}
{{/platforms}}
@@ -203,13 +202,12 @@ export class RequestContext {
{{#platforms}}
{{#node}}
public setAgent(agent: http.Agent | https.Agent) {
this.agent = agent;
public setDispatcher(dispatcher: Dispatcher): void {
this.dispatcher = dispatcher;
}
public getAgent(): http.Agent | https.Agent | undefined {
return this.agent;
public getDispatcher(): Dispatcher | undefined {
return this.dispatcher;
}
{{/node}}
{{/platforms}}

View File

@@ -2,7 +2,7 @@ import {HttpLibrary, RequestContext, ResponseContext} from './http{{importFileEx
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};
{{#platforms}}
{{#node}}
import fetch from "node-fetch";
import { fetch } from 'undici';
{{/node}}
{{#browser}}
import "whatwg-fetch";
@@ -22,7 +22,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary {
signal: request.getSignal(),
{{#platforms}}
{{#node}}
agent: request.getAgent(),
dispatcher: request.getDispatcher(),
{{/node}}
{{#browser}}
credentials: "same-origin"

View File

@@ -24,13 +24,11 @@
{{/supportsES6}}
"exports": {
".": {
{{#supportsES6}}
"import": "./dist/index.js",
{{/supportsES6}}
{{^supportsES6}}
"require": "./dist/index.js",
{{/supportsES6}}
"types": "./dist/index.d.js"
"types": "./dist/index.d.ts"
}
},
"files": [
@@ -46,8 +44,7 @@
{{#fetch-api}}
{{#platforms}}
{{#node}}
"node-fetch": "^2.7.0",
"@types/node-fetch": "^2.6.13",
"undici": "^7.16.0",
{{/node}}
{{#browser}}
"whatwg-fetch": "^3.0.0",
@@ -61,7 +58,7 @@
{{/frameworks}}
{{#platforms}}
{{#node}}
"@types/node": "^16.18.126",
"@types/node": "^20.17.10",
"form-data": "^4.0.4",
{{/node}}
{{/platforms}}

View File

@@ -8,6 +8,7 @@
{{/supportsES6}}
{{^supportsES6}}
"target": "es5",
"module": "commonjs",
{{/supportsES6}}
"moduleResolution": "node",
"declaration": true,

View File

@@ -191,7 +191,8 @@ public class KotlinReservedWordsTest {
File resultSourcePath = new File(output, "src/main/kotlin");
assertFileContains(Paths.get(resultSourcePath.getAbsolutePath() + baseApiPackage + "AnnotationsApiController.kt"),
"fun annotationsPost(@Parameter(description = \"\", required = true) @Valid @RequestBody `annotation`: Annotation",
"fun annotationsPost("
+ " @Parameter(description = \"\", required = true) @Valid @RequestBody `annotation`: Annotation",
"return ResponseEntity(service.annotationsPost(`annotation`), HttpStatus.valueOf(200))"
);

View File

@@ -143,7 +143,11 @@ public class KotlinSpringServerCodegenTest {
// Check that the @RequestMapping annotation is generated in the ApiController file
assertFileContains(
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApiController.kt"),
"@RequestMapping(\"\\${"
"@RequestMapping(\"\\${openapi.openAPIPetstore.base-path:\\${api.base-path:$BASE_PATH}}\")",
" companion object {\n"
+ " //for your own safety never directly reuse these path definitions in tests\n"
+ " const val BASE_PATH: String = \"/v2\"\n"
+ " }"
);
}
@@ -154,7 +158,10 @@ public class KotlinSpringServerCodegenTest {
// Check that the @RequestMapping annotation is generated in the Api file
assertFileContains(
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApi.kt"),
"@RequestMapping(\"\\${"
"@RequestMapping(\"\\${openapi.openAPIPetstore.base-path:\\${api.base-path:$BASE_PATH}}\")",
" companion object {\n"
+ " //for your own safety never directly reuse these path definitions in tests\n"
+ " const val BASE_PATH: String = \"/v2\""
);
// Check that the @RequestMapping annotation is not generated in the ApiController file
assertFileNotContains(
@@ -402,13 +409,17 @@ public class KotlinSpringServerCodegenTest {
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NullableMultipartfileApiController.kt"),
"file: org.springframework.web.multipart.MultipartFile?)");
"file: org.springframework.web.multipart.MultipartFile?"
+ " )");
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NullableMultipartfileArrayApiController.kt"),
"files: Array<org.springframework.web.multipart.MultipartFile>?)");
"files: Array<org.springframework.web.multipart.MultipartFile>?"
+ " )");
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NonNullableMultipartfileApiController.kt"),
"file: org.springframework.web.multipart.MultipartFile)");
"file: org.springframework.web.multipart.MultipartFile"
+ " )");
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NonNullableMultipartfileArrayApiController.kt"),
"files: Array<org.springframework.web.multipart.MultipartFile>)");
"files: Array<org.springframework.web.multipart.MultipartFile>"
+ " )");
}
@Test
@@ -1038,7 +1049,7 @@ public class KotlinSpringServerCodegenTest {
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, true);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_REACTIVE_MODE, "reactor");
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, true);
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, true);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
@@ -1061,20 +1072,20 @@ public class KotlinSpringServerCodegenTest {
"import reactor.core.publisher.Flux\n"
+ "import reactor.core.publisher.Mono",
" @HttpExchange(\n"
+ " url = PATH_GET_INVENTORY,\n"
+ " url = PATH_GET_INVENTORY /* \"/store/inventory\" */,\n"
+ " method = \"GET\"\n"
+ " )\n"
+ " fun getInventory(\n"
+ " ): Mono<ResponseEntity<Map<String, kotlin.Int>>>",
" @HttpExchange(\n"
+ " url = PATH_DELETE_ORDER,\n"
+ " url = PATH_DELETE_ORDER /* \"/store/order/{orderId}\" */,\n"
+ " method = \"DELETE\"\n"
+ " )\n"
+ " fun deleteOrder(\n"
+ " @Parameter(description = \"ID of the order that needs to be deleted\", required = true) @PathVariable(\"orderId\") orderId: kotlin.String\n"
+ " ): Mono<ResponseEntity<Unit>>",
" @HttpExchange(\n"
+ " url = PATH_PLACE_ORDER,\n"
+ " url = PATH_PLACE_ORDER /* \"/store/order\" */,\n"
+ " method = \"POST\"\n"
+ " )\n"
+ " fun placeOrder(\n"
@@ -1105,7 +1116,7 @@ public class KotlinSpringServerCodegenTest {
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, true);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_REACTIVE_MODE, "coroutines");
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, true);
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, true);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
@@ -1147,7 +1158,7 @@ public class KotlinSpringServerCodegenTest {
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, true);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_REACTIVE_MODE, "reactor");
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, false);
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, false);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
@@ -1184,7 +1195,6 @@ public class KotlinSpringServerCodegenTest {
);
}
@Test
public void generateHttpInterfaceReactiveWithCoroutines() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
@@ -1196,7 +1206,7 @@ public class KotlinSpringServerCodegenTest {
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, true);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_REACTIVE_MODE, "coroutines");
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, false);
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, false);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
@@ -1237,7 +1247,7 @@ public class KotlinSpringServerCodegenTest {
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, false);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, true);
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, true);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
@@ -1282,8 +1292,8 @@ public class KotlinSpringServerCodegenTest {
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-declarative-http-interface");
codegen.additionalProperties().put(REACTIVE, false);
codegen.additionalProperties().put(DECLARATIVE_INTERFACE_WRAP_RESPONSES, false);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "none");
codegen.additionalProperties().put(USE_RESPONSE_ENTITY, false);
codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "api_interface");
codegen.additionalProperties().put(USE_FLOW_FOR_ARRAY_RETURN_TYPE, false);
ClientOptInput input = new ClientOptInput()
@@ -1302,6 +1312,9 @@ public class KotlinSpringServerCodegenTest {
Path path = Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/StoreApiClient.kt");
assertFileContains(
path,
"@HttpExchange(\n"
+ "\"\\${openapi.openAPIPetstore.base-path:\\${api.base-path:$BASE_PATH}}\"\n"
+ ")",
" fun getInventory(\n"
+ " ): Map<String, kotlin.Int>",
" fun deleteOrder(\n"
@@ -1383,7 +1396,12 @@ public class KotlinSpringServerCodegenTest {
for (var expectedSnippetsByPathToFile : expectedSnippetsByPathsToFiles.entrySet()) {
assertFileContains(expectedSnippetsByPathToFile.getKey(), expectedSnippetsByPathToFile.getValue().toArray(new String[0]));
}
}
private void verifyGeneratedFilesNotContain(Map<Path, List<String>> unexpectedSnippetsByPathsToFiles) {
for (var unexpectedSnippetsByPathToFile : unexpectedSnippetsByPathsToFiles.entrySet()) {
assertFileNotContains(unexpectedSnippetsByPathToFile.getKey(), unexpectedSnippetsByPathToFile.getValue().toArray(new String[0]));
}
}
@Test
@@ -1405,8 +1423,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(@Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange)")
)
@@ -1432,8 +1457,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange")
)
@@ -1459,8 +1491,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>")
)
@@ -1486,8 +1525,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>")
)
@@ -1513,8 +1557,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(@Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1540,8 +1591,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1567,8 +1625,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1594,8 +1659,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>")
)
@@ -1621,8 +1691,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>")
)
@@ -1648,8 +1725,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>")
)
@@ -1675,8 +1759,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>")
)
@@ -1702,8 +1793,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>")
)
@@ -1729,8 +1825,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1756,8 +1859,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1783,8 +1893,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>")
)
@@ -1811,8 +1928,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/test/kotlin/org/openapitools/api/PetApiTest.kt"), List.of(
@@ -1825,7 +1949,6 @@ public class KotlinSpringServerCodegenTest {
);
}
@Test
public void reactiveWithHttpRequestContextControllerImplAnnotationNoneNoDelegateWithApiTests() throws Exception {
Path root = generateApiSources(Map.of(
@@ -1846,8 +1969,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApiController.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApiController.kt"), List.of(
"logoutUser(exchange: org.springframework.web.server.ServerWebExchange)"),
root.resolve("src/test/kotlin/org/openapitools/api/PetApiTest.kt"), List.of(
@@ -1879,8 +2009,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>")
)
@@ -1906,8 +2041,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -1938,8 +2080,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -1970,8 +2119,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2002,8 +2158,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2034,8 +2195,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2066,8 +2234,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2098,8 +2273,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"fun deletePet(\n"
+ " @PathVariable(\"petId\") petId: kotlin.Long,\n"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,\n"
+ " request: javax.servlet.http.HttpServletRequest\n"
+ " ): ResponseEntity<Unit> {",
"fun getPetById(\n"
+ " @PathVariable(\"petId\") petId: kotlin.Long,\n"
+ " request: javax.servlet.http.HttpServletRequest\n"
+ " ): ResponseEntity<Pet> {"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2130,8 +2312,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2162,8 +2349,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2194,8 +2388,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2226,8 +2427,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " exchange: org.springframework.web.server.ServerWebExchange"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(exchange: org.springframework.web.server.ServerWebExchange): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2258,8 +2466,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2290,8 +2503,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @Parameter(description = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(description = \"\", `in` = ParameterIn.HEADER) @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @Parameter(description = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@Parameter(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2322,8 +2542,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet(@ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,@ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById(@ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long, @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @ApiParam(value = \"Pet id to delete\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(value = \"\") @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @ApiParam(value = \"ID of pet to return\", required = true) @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(@ApiParam(hidden = true) request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2354,8 +2581,15 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long, request: javax.servlet.http.HttpServletRequest): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " request: javax.servlet.http.HttpServletRequest"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(request: javax.servlet.http.HttpServletRequest): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2386,8 +2620,13 @@ public class KotlinSpringServerCodegenTest {
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"deletePet( @PathVariable(\"petId\") petId: kotlin.Long, @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?): ResponseEntity<Unit>",
"getPetById( @PathVariable(\"petId\") petId: kotlin.Long): ResponseEntity<Pet>"),
"deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"logoutUser(): ResponseEntity<Unit>"),
root.resolve("src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"), List.of(
@@ -2399,6 +2638,174 @@ public class KotlinSpringServerCodegenTest {
);
}
@Test
public void reactiveWithoutResponseEntity() throws Exception {
Path root = generateApiSources(Map.of(
KotlinSpringServerCodegen.REACTIVE, true,
KotlinSpringServerCodegen.DOCUMENTATION_PROVIDER, "none",
KotlinSpringServerCodegen.ANNOTATION_LIBRARY, "none",
KotlinSpringServerCodegen.INTERFACE_ONLY, true,
KotlinSpringServerCodegen.USE_RESPONSE_ENTITY, false
), Map.of(
CodegenConstants.MODELS, "false",
CodegenConstants.MODEL_TESTS, "false",
CodegenConstants.MODEL_DOCS, "false",
CodegenConstants.APIS, "true",
CodegenConstants.SUPPORTING_FILES, "false"
));
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"@ResponseStatus(HttpStatus.BAD_REQUEST)",
"suspend fun deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): Unit",
"@ResponseStatus(HttpStatus.OK)",
"suspend fun getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): Pet"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"@ResponseStatus(HttpStatus.OK)",
"suspend fun logoutUser(): Unit"
),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of(
"@ResponseStatus(HttpStatus.OK)",
"suspend fun getInventory(): Map<String, kotlin.Int>")
)
);
}
@Test
public void nonReactiveWithoutResponseEntity() throws Exception {
Path root = generateApiSources(Map.of(
KotlinSpringServerCodegen.REACTIVE, false,
KotlinSpringServerCodegen.DOCUMENTATION_PROVIDER, "none",
KotlinSpringServerCodegen.ANNOTATION_LIBRARY, "none",
KotlinSpringServerCodegen.INTERFACE_ONLY, true,
KotlinSpringServerCodegen.USE_RESPONSE_ENTITY, false
), Map.of(
CodegenConstants.MODELS, "false",
CodegenConstants.MODEL_TESTS, "false",
CodegenConstants.MODEL_DOCS, "false",
CodegenConstants.APIS, "true",
CodegenConstants.SUPPORTING_FILES, "false"
));
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"@ResponseStatus(HttpStatus.BAD_REQUEST)",
"fun deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): Unit",
"@ResponseStatus(HttpStatus.OK)",
"fun getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): Pet"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"@ResponseStatus(HttpStatus.OK)",
"fun logoutUser(): Unit"
),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of(
"@ResponseStatus(HttpStatus.OK)",
"fun getInventory(): Map<String, kotlin.Int>")
)
);
verifyGeneratedFilesNotContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of("suspend"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of("suspend"),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of("suspend")
)
);
}
@Test
public void reactiveWithResponseEntity() throws Exception {
Path root = generateApiSources(Map.of(
KotlinSpringServerCodegen.REACTIVE, true,
KotlinSpringServerCodegen.DOCUMENTATION_PROVIDER, "none",
KotlinSpringServerCodegen.ANNOTATION_LIBRARY, "none",
KotlinSpringServerCodegen.INTERFACE_ONLY, true,
KotlinSpringServerCodegen.USE_RESPONSE_ENTITY, true
), Map.of(
CodegenConstants.MODELS, "false",
CodegenConstants.MODEL_TESTS, "false",
CodegenConstants.MODEL_DOCS, "false",
CodegenConstants.APIS, "true",
CodegenConstants.SUPPORTING_FILES, "false"
));
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"suspend fun deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"suspend fun getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"suspend fun logoutUser(): ResponseEntity<Unit>"
),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of(
"suspend fun getInventory(): ResponseEntity<Map<String, kotlin.Int>>")
)
);
verifyGeneratedFilesNotContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of("@ResponseStatus(HttpStatus."),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of("@ResponseStatus(HttpStatus."),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of("@ResponseStatus(HttpStatus.")
)
);
}
@Test
public void nonReactiveWithResponseEntity() throws Exception {
Path root = generateApiSources(Map.of(
KotlinSpringServerCodegen.REACTIVE, false,
KotlinSpringServerCodegen.DOCUMENTATION_PROVIDER, "none",
KotlinSpringServerCodegen.ANNOTATION_LIBRARY, "none",
KotlinSpringServerCodegen.INTERFACE_ONLY, true,
KotlinSpringServerCodegen.USE_RESPONSE_ENTITY, true
), Map.of(
CodegenConstants.MODELS, "false",
CodegenConstants.MODEL_TESTS, "false",
CodegenConstants.MODEL_DOCS, "false",
CodegenConstants.APIS, "true",
CodegenConstants.SUPPORTING_FILES, "false"
));
verifyGeneratedFilesContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of(
"fun deletePet("
+ " @PathVariable(\"petId\") petId: kotlin.Long,"
+ " @RequestHeader(value = \"api_key\", required = false) apiKey: kotlin.String?"
+ " ): ResponseEntity<Unit>",
"fun getPetById("
+ " @PathVariable(\"petId\") petId: kotlin.Long"
+ " ): ResponseEntity<Pet>"),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of(
"fun logoutUser(): ResponseEntity<Unit>"
),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of(
"fun getInventory(): ResponseEntity<Map<String, kotlin.Int>>")
)
);
verifyGeneratedFilesNotContain(
Map.of(
root.resolve("src/main/kotlin/org/openapitools/api/PetApi.kt"), List.of("suspend", "@ResponseStatus(HttpStatus."),
root.resolve("src/main/kotlin/org/openapitools/api/UserApi.kt"), List.of("suspend", "@ResponseStatus(HttpStatus."),
root.resolve("src/main/kotlin/org/openapitools/api/StoreApi.kt"), List.of("suspend", "@ResponseStatus(HttpStatus.")
)
);
}
@Test
public void reactiveWithoutFlow() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();

View File

@@ -486,7 +486,7 @@ public class TypeScriptAngularClientCodegenTest {
// THEN
final String fileContents = Files.readString(Paths.get(output + "/api/default.service.ts"));
assertThat(fileContents).containsOnlyOnce("<any>options, 'options', true);");
assertThat(fileContents).containsOnlyOnce("<any>inputOptions, 'inputOptions', true);");
assertThat(fileContents).containsSubsequence("'options',\n", "<any>options,\n", "QueryParamStyle.DeepObject,\n", "true,\n");
assertThat(fileContents).containsSubsequence("'inputOptions',\n", "<any>inputOptions,\n", "QueryParamStyle.DeepObject,\n", "true,\n");
}
}

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