forked from loafle/openapi-generator-original
Merge branch '5.2.x'
This commit is contained in:
commit
a0c3db1157
@ -26,6 +26,7 @@ jobs:
|
|||||||
- name: Set up JDK ${{ matrix.java }}
|
- name: Set up JDK ${{ matrix.java }}
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
|
|
||||||
- uses: actions/cache@v2.1.5
|
- uses: actions/cache@v2.1.5
|
||||||
|
1
.github/workflows/sonar.yml
vendored
1
.github/workflows/sonar.yml
vendored
@ -16,6 +16,7 @@ jobs:
|
|||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- name: Compile with Maven
|
- name: Compile with Maven
|
||||||
run: mvn -B -q clean install jacoco:report
|
run: mvn -B -q clean install jacoco:report
|
||||||
|
27
README.md
27
README.md
@ -9,27 +9,17 @@
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`5.1.1`):
|
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`5.2.0`):
|
||||||
[](https://travis-ci.org/OpenAPITools/openapi-generator)
|
[](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
|
||||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||||
[](https://cloud.drone.io/OpenAPITools/openapi-generator)
|
[](https://cloud.drone.io/OpenAPITools/openapi-generator)
|
||||||
[](https://app.bitrise.io/app/4a2b10a819d12b67)
|
[](https://app.bitrise.io/app/4a2b10a819d12b67)
|
||||||
[](https://github.com/OpenAPITools/openapi-generator/actions?query=workflow%3A%22Check+Supported+Java+Versions%22)
|
[](https://github.com/OpenAPITools/openapi-generator/actions?query=workflow%3A%22Check+Supported+Java+Versions%22)
|
||||||
|
|
||||||
[5.2.x](https://github.com/OpenAPITools/openapi-generator/tree/5.2.x) (`5.2.x`):
|
|
||||||
[](https://travis-ci.org/OpenAPITools/openapi-generator)
|
|
||||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
|
||||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
|
||||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
|
||||||
[](https://cloud.drone.io/OpenAPITools/openapi-generator)
|
|
||||||
[](https://app.bitrise.io/app/4a2b10a819d12b67)
|
|
||||||
|
|
||||||
[6.0.x](https://github.com/OpenAPITools/openapi-generator/tree/6.0.x) (`6.0.x`):
|
[6.0.x](https://github.com/OpenAPITools/openapi-generator/tree/6.0.x) (`6.0.x`):
|
||||||
[](https://travis-ci.org/OpenAPITools/openapi-generator)
|
[](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
|
||||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||||
[](https://cloud.drone.io/OpenAPITools/openapi-generator)
|
[](https://cloud.drone.io/OpenAPITools/openapi-generator)
|
||||||
[](https://app.bitrise.io/app/4a2b10a819d12b67)
|
[](https://app.bitrise.io/app/4a2b10a819d12b67)
|
||||||
@ -120,9 +110,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
|
|||||||
| OpenAPI Generator Version | Release Date | Notes |
|
| OpenAPI Generator Version | Release Date | Notes |
|
||||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
|
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
|
||||||
| 6.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.0-SNAPSHOT/) | Nov/Dec 2021 | Minor release with breaking changes (no fallback) |
|
| 6.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.0-SNAPSHOT/) | Nov/Dec 2021 | Minor release with breaking changes (no fallback) |
|
||||||
| 5.2.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/5.2.0-SNAPSHOT/) | May/Jun 2021 | Minor release with breaking changes (with fallback) |
|
| 5.2.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/5.2.0-SNAPSHOT/) | Jun/Jul 2021 | Minor release with breaking changes (with fallback) |
|
||||||
| 5.1.1 (upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/5.1.1-SNAPSHOT/) | Apr/May 2021 | Patch release (enhancements, bug fixes, etc) |
|
| [5.1.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.1.1) (latest stable release) | 07.05.2021 | Patch release (enhancements, bug fixes, etc) |
|
||||||
| [5.1.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.1.0) (latest stable release) | 20.03.2021 | Minor release with breaking changes (with fallback) |
|
|
||||||
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
|
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
|
||||||
|
|
||||||
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
|
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
|
||||||
@ -179,16 +168,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
|
|||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
|
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
|
||||||
|
|
||||||
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.0/openapi-generator-cli-5.1.0.jar`
|
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.1/openapi-generator-cli-5.1.1.jar`
|
||||||
|
|
||||||
For **Mac/Linux** users:
|
For **Mac/Linux** users:
|
||||||
```sh
|
```sh
|
||||||
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.0/openapi-generator-cli-5.1.0.jar -O openapi-generator-cli.jar
|
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.1/openapi-generator-cli-5.1.1.jar -O openapi-generator-cli.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
|
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
|
||||||
```
|
```
|
||||||
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.0/openapi-generator-cli-5.1.0.jar
|
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.1/openapi-generator-cli-5.1.1.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
|
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
|
||||||
@ -413,7 +402,7 @@ openapi-generator-cli version
|
|||||||
To use a specific version of "openapi-generator-cli"
|
To use a specific version of "openapi-generator-cli"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
openapi-generator-cli version-manager set 5.1.0
|
openapi-generator-cli version-manager set 5.1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Or install it as dev-dependency:
|
Or install it as dev-dependency:
|
||||||
@ -437,7 +426,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
|
|||||||
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
|
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
|
||||||
|
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.0/openapi-generator-cli-5.1.0.jar)
|
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.1.1/openapi-generator-cli-5.1.1.jar)
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
|
|
||||||
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
|
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
# this file exists because in this file we omit setting disallowAdditionalPropertiesIfNotPresent
|
||||||
|
# which makes it default to false
|
||||||
|
# that false setting is needed for composed schemas to work
|
||||||
|
# Composed schemas are schemas that contain the allOf/oneOf/anyOf keywords. v2 specs only support the allOf keyword.
|
||||||
generatorName: python
|
generatorName: python
|
||||||
outputDir: samples/client/petstore/python
|
outputDir: samples/client/petstore/python
|
||||||
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
|
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
|
||||||
templateDir: modules/openapi-generator/src/main/resources/python
|
templateDir: modules/openapi-generator/src/main/resources/python
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
disallowAdditionalPropertiesIfNotPresent: "true"
|
|
||||||
packageName: petstore_api
|
packageName: petstore_api
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
generatorName: python
|
||||||
|
outputDir: samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent
|
||||||
|
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
|
||||||
|
templateDir: modules/openapi-generator/src/main/resources/python
|
||||||
|
additionalProperties:
|
||||||
|
disallowAdditionalPropertiesIfNotPresent: "true"
|
||||||
|
packageName: petstore_api
|
@ -106,6 +106,7 @@ The following generators are available:
|
|||||||
* [jaxrs-resteasy-eap](generators/jaxrs-resteasy-eap.md)
|
* [jaxrs-resteasy-eap](generators/jaxrs-resteasy-eap.md)
|
||||||
* [jaxrs-spec](generators/jaxrs-spec.md)
|
* [jaxrs-spec](generators/jaxrs-spec.md)
|
||||||
* [kotlin-server](generators/kotlin-server.md)
|
* [kotlin-server](generators/kotlin-server.md)
|
||||||
|
* [kotlin-server-deprecated (deprecated)](generators/kotlin-server-deprecated.md)
|
||||||
* [kotlin-spring](generators/kotlin-spring.md)
|
* [kotlin-spring](generators/kotlin-spring.md)
|
||||||
* [kotlin-vertx (beta)](generators/kotlin-vertx.md)
|
* [kotlin-vertx (beta)](generators/kotlin-vertx.md)
|
||||||
* [nodejs-express-server (beta)](generators/nodejs-express-server.md)
|
* [nodejs-express-server (beta)](generators/nodejs-express-server.md)
|
||||||
|
@ -91,6 +91,7 @@ The following generators are available:
|
|||||||
* [jaxrs-resteasy-eap](jaxrs-resteasy-eap.md)
|
* [jaxrs-resteasy-eap](jaxrs-resteasy-eap.md)
|
||||||
* [jaxrs-spec](jaxrs-spec.md)
|
* [jaxrs-spec](jaxrs-spec.md)
|
||||||
* [kotlin-server](kotlin-server.md)
|
* [kotlin-server](kotlin-server.md)
|
||||||
|
* [kotlin-server-deprecated](kotlin-server-deprecated.md)
|
||||||
* [kotlin-spring](kotlin-spring.md)
|
* [kotlin-spring](kotlin-spring.md)
|
||||||
* [kotlin-vertx (beta)](kotlin-vertx.md)
|
* [kotlin-vertx (beta)](kotlin-vertx.md)
|
||||||
* [nodejs-express-server (beta)](nodejs-express-server.md)
|
* [nodejs-express-server (beta)](nodejs-express-server.md)
|
||||||
|
214
docs/generators/kotlin-server-deprecated.md
Normal file
214
docs/generators/kotlin-server-deprecated.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
title: Config Options for kotlin-server-deprecated
|
||||||
|
sidebar_label: kotlin-server-deprecated
|
||||||
|
---
|
||||||
|
|
||||||
|
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
|
||||||
|
|
||||||
|
| Option | Description | Values | Default |
|
||||||
|
| ------ | ----------- | ------ | ------- |
|
||||||
|
|apiSuffix|suffix for api classes| |Api|
|
||||||
|
|artifactId|Generated artifact id (name of jar).| |kotlin-server-deprecated|
|
||||||
|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|
||||||
|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|
||||||
|
|featureAutoHead|Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.| |true|
|
||||||
|
|featureCORS|Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.| |false|
|
||||||
|
|featureCompression|Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.| |true|
|
||||||
|
|featureConditionalHeaders|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |false|
|
||||||
|
|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true|
|
||||||
|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|
||||||
|
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd></dl>|ktor|
|
||||||
|
|modelMutable|Create mutable models| |false|
|
||||||
|
|packageName|Generated artifact package name.| |org.openapitools.server|
|
||||||
|
|parcelizeModels|toggle "@Parcelize" for generated models| |null|
|
||||||
|
|serializableModel|boolean - toggle "implements Serializable" for generated models| |null|
|
||||||
|
|serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson' or 'jackson'| |moshi|
|
||||||
|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |null|
|
||||||
|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |null|
|
||||||
|
|sourceFolder|source folder for generated code| |src/main/kotlin|
|
||||||
|
|
||||||
|
## IMPORT MAPPING
|
||||||
|
|
||||||
|
| Type/Alias | Imports |
|
||||||
|
| ---------- | ------- |
|
||||||
|
|BigDecimal|java.math.BigDecimal|
|
||||||
|
|Date|java.time.LocalDate|
|
||||||
|
|DateTime|java.time.OffsetDateTime|
|
||||||
|
|File|java.io.File|
|
||||||
|
|LocalDate|java.time.LocalDate|
|
||||||
|
|LocalDateTime|java.time.LocalDateTime|
|
||||||
|
|LocalTime|java.time.LocalTime|
|
||||||
|
|Timestamp|java.sql.Timestamp|
|
||||||
|
|URI|java.net.URI|
|
||||||
|
|UUID|java.util.UUID|
|
||||||
|
|
||||||
|
|
||||||
|
## INSTANTIATION TYPES
|
||||||
|
|
||||||
|
| Type/Alias | Instantiated By |
|
||||||
|
| ---------- | --------------- |
|
||||||
|
|array|kotlin.collections.ArrayList|
|
||||||
|
|list|kotlin.collections.ArrayList|
|
||||||
|
|map|kotlin.collections.HashMap|
|
||||||
|
|
||||||
|
|
||||||
|
## LANGUAGE PRIMITIVES
|
||||||
|
|
||||||
|
<ul class="column-ul">
|
||||||
|
<li>kotlin.Array</li>
|
||||||
|
<li>kotlin.Boolean</li>
|
||||||
|
<li>kotlin.Byte</li>
|
||||||
|
<li>kotlin.ByteArray</li>
|
||||||
|
<li>kotlin.Char</li>
|
||||||
|
<li>kotlin.Double</li>
|
||||||
|
<li>kotlin.Float</li>
|
||||||
|
<li>kotlin.Int</li>
|
||||||
|
<li>kotlin.Long</li>
|
||||||
|
<li>kotlin.Short</li>
|
||||||
|
<li>kotlin.String</li>
|
||||||
|
<li>kotlin.collections.List</li>
|
||||||
|
<li>kotlin.collections.Map</li>
|
||||||
|
<li>kotlin.collections.Set</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
## RESERVED WORDS
|
||||||
|
|
||||||
|
<ul class="column-ul">
|
||||||
|
<li>as</li>
|
||||||
|
<li>break</li>
|
||||||
|
<li>class</li>
|
||||||
|
<li>continue</li>
|
||||||
|
<li>do</li>
|
||||||
|
<li>else</li>
|
||||||
|
<li>false</li>
|
||||||
|
<li>for</li>
|
||||||
|
<li>fun</li>
|
||||||
|
<li>if</li>
|
||||||
|
<li>in</li>
|
||||||
|
<li>interface</li>
|
||||||
|
<li>is</li>
|
||||||
|
<li>null</li>
|
||||||
|
<li>object</li>
|
||||||
|
<li>package</li>
|
||||||
|
<li>return</li>
|
||||||
|
<li>super</li>
|
||||||
|
<li>this</li>
|
||||||
|
<li>throw</li>
|
||||||
|
<li>true</li>
|
||||||
|
<li>try</li>
|
||||||
|
<li>typealias</li>
|
||||||
|
<li>typeof</li>
|
||||||
|
<li>val</li>
|
||||||
|
<li>var</li>
|
||||||
|
<li>when</li>
|
||||||
|
<li>while</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
## FEATURE SET
|
||||||
|
|
||||||
|
|
||||||
|
### Client Modification Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|BasePath|✗|ToolingExtension
|
||||||
|
|Authorizations|✗|ToolingExtension
|
||||||
|
|UserAgent|✗|ToolingExtension
|
||||||
|
|MockServer|✗|ToolingExtension
|
||||||
|
|
||||||
|
### Data Type Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|Custom|✗|OAS2,OAS3
|
||||||
|
|Int32|✓|OAS2,OAS3
|
||||||
|
|Int64|✓|OAS2,OAS3
|
||||||
|
|Float|✓|OAS2,OAS3
|
||||||
|
|Double|✓|OAS2,OAS3
|
||||||
|
|Decimal|✓|ToolingExtension
|
||||||
|
|String|✓|OAS2,OAS3
|
||||||
|
|Byte|✓|OAS2,OAS3
|
||||||
|
|Binary|✓|OAS2,OAS3
|
||||||
|
|Boolean|✓|OAS2,OAS3
|
||||||
|
|Date|✓|OAS2,OAS3
|
||||||
|
|DateTime|✓|OAS2,OAS3
|
||||||
|
|Password|✓|OAS2,OAS3
|
||||||
|
|File|✓|OAS2
|
||||||
|
|Array|✓|OAS2,OAS3
|
||||||
|
|Maps|✓|ToolingExtension
|
||||||
|
|CollectionFormat|✓|OAS2
|
||||||
|
|CollectionFormatMulti|✓|OAS2
|
||||||
|
|Enum|✓|OAS2,OAS3
|
||||||
|
|ArrayOfEnum|✓|ToolingExtension
|
||||||
|
|ArrayOfModel|✓|ToolingExtension
|
||||||
|
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|
||||||
|
|ArrayOfCollectionOfModel|✓|ToolingExtension
|
||||||
|
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|
||||||
|
|MapOfEnum|✓|ToolingExtension
|
||||||
|
|MapOfModel|✓|ToolingExtension
|
||||||
|
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|
||||||
|
|MapOfCollectionOfModel|✓|ToolingExtension
|
||||||
|
|MapOfCollectionOfEnum|✓|ToolingExtension
|
||||||
|
|
||||||
|
### Documentation Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|Readme|✓|ToolingExtension
|
||||||
|
|Model|✓|ToolingExtension
|
||||||
|
|Api|✓|ToolingExtension
|
||||||
|
|
||||||
|
### Global Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|Host|✓|OAS2,OAS3
|
||||||
|
|BasePath|✓|OAS2,OAS3
|
||||||
|
|Info|✓|OAS2,OAS3
|
||||||
|
|Schemes|✗|OAS2,OAS3
|
||||||
|
|PartialSchemes|✓|OAS2,OAS3
|
||||||
|
|Consumes|✓|OAS2
|
||||||
|
|Produces|✓|OAS2
|
||||||
|
|ExternalDocumentation|✓|OAS2,OAS3
|
||||||
|
|Examples|✓|OAS2,OAS3
|
||||||
|
|XMLStructureDefinitions|✗|OAS2,OAS3
|
||||||
|
|MultiServer|✗|OAS3
|
||||||
|
|ParameterizedServer|✗|OAS3
|
||||||
|
|ParameterStyling|✗|OAS3
|
||||||
|
|Callbacks|✗|OAS3
|
||||||
|
|LinkObjects|✗|OAS3
|
||||||
|
|
||||||
|
### Parameter Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|Path|✓|OAS2,OAS3
|
||||||
|
|Query|✓|OAS2,OAS3
|
||||||
|
|Header|✓|OAS2,OAS3
|
||||||
|
|Body|✓|OAS2
|
||||||
|
|FormUnencoded|✓|OAS2
|
||||||
|
|FormMultipart|✓|OAS2
|
||||||
|
|Cookie|✗|OAS3
|
||||||
|
|
||||||
|
### Schema Support Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|Simple|✓|OAS2,OAS3
|
||||||
|
|Composite|✓|OAS2,OAS3
|
||||||
|
|Polymorphism|✗|OAS2,OAS3
|
||||||
|
|Union|✗|OAS3
|
||||||
|
|
||||||
|
### Security Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|BasicAuth|✓|OAS2,OAS3
|
||||||
|
|ApiKey|✓|OAS2,OAS3
|
||||||
|
|OpenIDConnect|✗|OAS3
|
||||||
|
|BearerToken|✗|OAS3
|
||||||
|
|OAuth2_Implicit|✓|OAS2,OAS3
|
||||||
|
|OAuth2_Password|✗|OAS2,OAS3
|
||||||
|
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
||||||
|
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
||||||
|
|
||||||
|
### Wire Format Feature
|
||||||
|
| Name | Supported | Defined By |
|
||||||
|
| ---- | --------- | ---------- |
|
||||||
|
|JSON|✓|OAS2,OAS3
|
||||||
|
|XML|✓|OAS2,OAS3
|
||||||
|
|PROTOBUF|✗|ToolingExtension
|
||||||
|
|Custom|✗|OAS2,OAS3
|
@ -16,6 +16,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|featureCompression|Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.| |true|
|
|featureCompression|Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.| |true|
|
||||||
|featureConditionalHeaders|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |false|
|
|featureConditionalHeaders|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |false|
|
||||||
|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true|
|
|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true|
|
||||||
|
|featureLocations|Generates routes in a typed way, for both: constructing URLs and reading the parameters.| |true|
|
||||||
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|
||||||
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd></dl>|ktor|
|
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd></dl>|ktor|
|
||||||
|modelMutable|Create mutable models| |false|
|
|modelMutable|Create mutable models| |false|
|
||||||
|
@ -7,6 +7,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Option | Description | Values | Default |
|
| Option | Description | Values | Default |
|
||||||
| ------ | ----------- | ------ | ------- |
|
| ------ | ----------- | ------ | ------- |
|
||||||
|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default. NOTE: this option breaks composition and will be removed in 6.0.0</dd></dl>|false|
|
||||||
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|
||||||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|
||||||
|library|library template (sub-template) to use: asyncio, tornado, urllib3| |urllib3|
|
|library|library template (sub-template) to use: asyncio, tornado, urllib3| |urllib3|
|
||||||
@ -28,7 +29,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Type/Alias | Instantiated By |
|
| Type/Alias | Instantiated By |
|
||||||
| ---------- | --------------- |
|
| ---------- | --------------- |
|
||||||
|map|dict|
|
|
||||||
|
|
||||||
|
|
||||||
## LANGUAGE PRIMITIVES
|
## LANGUAGE PRIMITIVES
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# RELEASE_VERSION
|
# RELEASE_VERSION
|
||||||
openApiGeneratorVersion=5.1.1
|
openApiGeneratorVersion=5.2.0-SNAPSHOT
|
||||||
# /RELEASE_VERSION
|
# /RELEASE_VERSION
|
||||||
|
|
||||||
# BEGIN placeholders
|
# BEGIN placeholders
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# RELEASE_VERSION
|
# RELEASE_VERSION
|
||||||
openApiGeneratorVersion=5.1.1-SNAPSHOT
|
openApiGeneratorVersion=5.2.0-SNAPSHOT
|
||||||
# /RELEASE_VERSION
|
# /RELEASE_VERSION
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1-SNAPSHOT</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1-SNAPSHOT</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<groupId>org.openapitools</groupId>
|
<groupId>org.openapitools</groupId>
|
||||||
<artifactId>openapi-generator-project</artifactId>
|
<artifactId>openapi-generator-project</artifactId>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -42,15 +42,17 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
private Boolean hstsFeatureEnabled = true;
|
private Boolean hstsFeatureEnabled = true;
|
||||||
private Boolean corsFeatureEnabled = false;
|
private Boolean corsFeatureEnabled = false;
|
||||||
private Boolean compressionFeatureEnabled = true;
|
private Boolean compressionFeatureEnabled = true;
|
||||||
|
private Boolean locationsFeatureEnabled = true;
|
||||||
|
|
||||||
// This is here to potentially warn the user when an option is not supoprted by the target framework.
|
// This is here to potentially warn the user when an option is not supported by the target framework.
|
||||||
private Map<String, List<String>> optionsSupportedPerFramework = new ImmutableMap.Builder<String, List<String>>()
|
private Map<String, List<String>> optionsSupportedPerFramework = new ImmutableMap.Builder<String, List<String>>()
|
||||||
.put(Constants.KTOR, Arrays.asList(
|
.put(Constants.KTOR, Arrays.asList(
|
||||||
Constants.AUTOMATIC_HEAD_REQUESTS,
|
Constants.AUTOMATIC_HEAD_REQUESTS,
|
||||||
Constants.CONDITIONAL_HEADERS,
|
Constants.CONDITIONAL_HEADERS,
|
||||||
Constants.HSTS,
|
Constants.HSTS,
|
||||||
Constants.CORS,
|
Constants.CORS,
|
||||||
Constants.COMPRESSION
|
Constants.COMPRESSION,
|
||||||
|
Constants.LOCATIONS
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -85,6 +87,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
artifactId = "kotlin-server";
|
artifactId = "kotlin-server";
|
||||||
packageName = "org.openapitools.server";
|
packageName = "org.openapitools.server";
|
||||||
|
|
||||||
|
typeMapping.put("array", "kotlin.collections.List");
|
||||||
|
|
||||||
// cliOptions default redefinition need to be updated
|
// cliOptions default redefinition need to be updated
|
||||||
updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId);
|
updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId);
|
||||||
updateOption(CodegenConstants.PACKAGE_NAME, this.packageName);
|
updateOption(CodegenConstants.PACKAGE_NAME, this.packageName);
|
||||||
@ -110,6 +114,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
addSwitch(Constants.HSTS, Constants.HSTS_DESC, getHstsFeatureEnabled());
|
addSwitch(Constants.HSTS, Constants.HSTS_DESC, getHstsFeatureEnabled());
|
||||||
addSwitch(Constants.CORS, Constants.CORS_DESC, getCorsFeatureEnabled());
|
addSwitch(Constants.CORS, Constants.CORS_DESC, getCorsFeatureEnabled());
|
||||||
addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled());
|
addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled());
|
||||||
|
addSwitch(Constants.LOCATIONS, Constants.LOCATIONS_DESC, getLocationsFeatureEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getAutoHeadFeatureEnabled() {
|
public Boolean getAutoHeadFeatureEnabled() {
|
||||||
@ -156,6 +161,14 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
this.hstsFeatureEnabled = hstsFeatureEnabled;
|
this.hstsFeatureEnabled = hstsFeatureEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getLocationsFeatureEnabled() {
|
||||||
|
return locationsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocationsFeatureEnabled(Boolean locationsFeatureEnabled) {
|
||||||
|
this.locationsFeatureEnabled = locationsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "kotlin-server";
|
return "kotlin-server";
|
||||||
}
|
}
|
||||||
@ -209,6 +222,12 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
additionalProperties.put(Constants.COMPRESSION, getCompressionFeatureEnabled());
|
additionalProperties.put(Constants.COMPRESSION, getCompressionFeatureEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.LOCATIONS)) {
|
||||||
|
setLocationsFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.LOCATIONS));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.LOCATIONS, getLocationsFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean) additionalProperties.get(CodegenConstants.GENERATE_APIS);
|
boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean) additionalProperties.get(CodegenConstants.GENERATE_APIS);
|
||||||
String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator);
|
String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator);
|
||||||
String resourcesFolder = "src/main/resources"; // not sure this can be user configurable.
|
String resourcesFolder = "src/main/resources"; // not sure this can be user configurable.
|
||||||
@ -223,7 +242,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
|
supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
|
||||||
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));
|
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));
|
||||||
|
|
||||||
if (generateApis) {
|
if (generateApis && locationsFeatureEnabled) {
|
||||||
supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt"));
|
supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,6 +266,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
|
|||||||
public final static String CORS_DESC = "Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.";
|
public final static String CORS_DESC = "Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.";
|
||||||
public final static String COMPRESSION = "featureCompression";
|
public final static String COMPRESSION = "featureCompression";
|
||||||
public final static String COMPRESSION_DESC = "Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.";
|
public final static String COMPRESSION_DESC = "Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.";
|
||||||
|
public final static String LOCATIONS = "featureLocations";
|
||||||
|
public final static String LOCATIONS_DESC = "Generates routes in a typed way, for both: constructing URLs and reading the parameters.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||||
|
* Copyright 2018 SmartBear Software
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openapitools.codegen.CliOption;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.CodegenType;
|
||||||
|
import org.openapitools.codegen.SupportingFile;
|
||||||
|
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||||
|
import org.openapitools.codegen.meta.Stability;
|
||||||
|
import org.openapitools.codegen.meta.features.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class KotlinServerDeprecatedCodegen extends AbstractKotlinCodegen {
|
||||||
|
|
||||||
|
public static final String DEFAULT_LIBRARY = Constants.KTOR;
|
||||||
|
private final Logger LOGGER = LoggerFactory.getLogger(KotlinServerDeprecatedCodegen.class);
|
||||||
|
private Boolean autoHeadFeatureEnabled = true;
|
||||||
|
private Boolean conditionalHeadersFeatureEnabled = false;
|
||||||
|
private Boolean hstsFeatureEnabled = true;
|
||||||
|
private Boolean corsFeatureEnabled = false;
|
||||||
|
private Boolean compressionFeatureEnabled = true;
|
||||||
|
|
||||||
|
// This is here to potentially warn the user when an option is not supported by the target framework.
|
||||||
|
private Map<String, List<String>> optionsSupportedPerFramework = new ImmutableMap.Builder<String, List<String>>()
|
||||||
|
.put(Constants.KTOR, Arrays.asList(
|
||||||
|
Constants.AUTOMATIC_HEAD_REQUESTS,
|
||||||
|
Constants.CONDITIONAL_HEADERS,
|
||||||
|
Constants.HSTS,
|
||||||
|
Constants.CORS,
|
||||||
|
Constants.COMPRESSION
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of `KotlinServerDeprecatedCodegen`.
|
||||||
|
*/
|
||||||
|
public KotlinServerDeprecatedCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
modifyFeatureSet(features -> features
|
||||||
|
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||||
|
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
|
||||||
|
.securityFeatures(EnumSet.of(
|
||||||
|
SecurityFeature.BasicAuth,
|
||||||
|
SecurityFeature.ApiKey,
|
||||||
|
SecurityFeature.OAuth2_Implicit
|
||||||
|
))
|
||||||
|
.excludeGlobalFeatures(
|
||||||
|
GlobalFeature.XMLStructureDefinitions,
|
||||||
|
GlobalFeature.Callbacks,
|
||||||
|
GlobalFeature.LinkObjects,
|
||||||
|
GlobalFeature.ParameterStyling
|
||||||
|
)
|
||||||
|
.excludeSchemaSupportFeatures(
|
||||||
|
SchemaSupportFeature.Polymorphism
|
||||||
|
)
|
||||||
|
.excludeParameterFeatures(
|
||||||
|
ParameterFeature.Cookie
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||||
|
.stability(Stability.DEPRECATED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
artifactId = "kotlin-server-deprecated";
|
||||||
|
packageName = "org.openapitools.server";
|
||||||
|
|
||||||
|
// cliOptions default redefinition need to be updated
|
||||||
|
updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId);
|
||||||
|
updateOption(CodegenConstants.PACKAGE_NAME, this.packageName);
|
||||||
|
|
||||||
|
outputFolder = "generated-code" + File.separator + "kotlin-server-deprecated";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".kt");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".kt");
|
||||||
|
embeddedTemplateDir = templateDir = "kotlin-server-deprecated";
|
||||||
|
apiPackage = packageName + ".apis";
|
||||||
|
modelPackage = packageName + ".models";
|
||||||
|
|
||||||
|
supportedLibraries.put(Constants.KTOR, "ktor framework");
|
||||||
|
|
||||||
|
// TODO: Configurable server engine. Defaults to netty in build.gradle.
|
||||||
|
CliOption library = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC);
|
||||||
|
library.setDefault(DEFAULT_LIBRARY);
|
||||||
|
library.setEnum(supportedLibraries);
|
||||||
|
|
||||||
|
cliOptions.add(library);
|
||||||
|
|
||||||
|
addSwitch(Constants.AUTOMATIC_HEAD_REQUESTS, Constants.AUTOMATIC_HEAD_REQUESTS_DESC, getAutoHeadFeatureEnabled());
|
||||||
|
addSwitch(Constants.CONDITIONAL_HEADERS, Constants.CONDITIONAL_HEADERS_DESC, getConditionalHeadersFeatureEnabled());
|
||||||
|
addSwitch(Constants.HSTS, Constants.HSTS_DESC, getHstsFeatureEnabled());
|
||||||
|
addSwitch(Constants.CORS, Constants.CORS_DESC, getCorsFeatureEnabled());
|
||||||
|
addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAutoHeadFeatureEnabled() {
|
||||||
|
return autoHeadFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoHeadFeatureEnabled(Boolean autoHeadFeatureEnabled) {
|
||||||
|
this.autoHeadFeatureEnabled = autoHeadFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCompressionFeatureEnabled() {
|
||||||
|
return compressionFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompressionFeatureEnabled(Boolean compressionFeatureEnabled) {
|
||||||
|
this.compressionFeatureEnabled = compressionFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getConditionalHeadersFeatureEnabled() {
|
||||||
|
return conditionalHeadersFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConditionalHeadersFeatureEnabled(Boolean conditionalHeadersFeatureEnabled) {
|
||||||
|
this.conditionalHeadersFeatureEnabled = conditionalHeadersFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCorsFeatureEnabled() {
|
||||||
|
return corsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCorsFeatureEnabled(Boolean corsFeatureEnabled) {
|
||||||
|
this.corsFeatureEnabled = corsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Kotlin server (Ktor v1.1.3). IMPORTANT: this generator has been deprecated." +
|
||||||
|
" Please migrate to `kotlin-server` which supports Ktor v1.5.2+.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getHstsFeatureEnabled() {
|
||||||
|
return hstsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHstsFeatureEnabled(Boolean hstsFeatureEnabled) {
|
||||||
|
this.hstsFeatureEnabled = hstsFeatureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "kotlin-server-deprecated";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) {
|
||||||
|
this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY));
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default library to "ktor"
|
||||||
|
if (StringUtils.isEmpty(library)) {
|
||||||
|
this.setLibrary(DEFAULT_LIBRARY);
|
||||||
|
additionalProperties.put(CodegenConstants.LIBRARY, DEFAULT_LIBRARY);
|
||||||
|
LOGGER.info("`library` option is empty. Default to " + DEFAULT_LIBRARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.AUTOMATIC_HEAD_REQUESTS)) {
|
||||||
|
setAutoHeadFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.AUTOMATIC_HEAD_REQUESTS));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.AUTOMATIC_HEAD_REQUESTS, getAutoHeadFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.CONDITIONAL_HEADERS)) {
|
||||||
|
setConditionalHeadersFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.CONDITIONAL_HEADERS));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.CONDITIONAL_HEADERS, getConditionalHeadersFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.HSTS)) {
|
||||||
|
setHstsFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.HSTS));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.HSTS, getHstsFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.CORS)) {
|
||||||
|
setCorsFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.CORS));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.CORS, getCorsFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(Constants.COMPRESSION)) {
|
||||||
|
setCompressionFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.COMPRESSION));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(Constants.COMPRESSION, getCompressionFeatureEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean) additionalProperties.get(CodegenConstants.GENERATE_APIS);
|
||||||
|
String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator);
|
||||||
|
String resourcesFolder = "src/main/resources"; // not sure this can be user configurable.
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties"));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
|
||||||
|
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));
|
||||||
|
|
||||||
|
if (generateApis) {
|
||||||
|
supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("application.conf.mustache", resourcesFolder, "application.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("logback.xml", resourcesFolder, "logback.xml"));
|
||||||
|
|
||||||
|
final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", File.separator);
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("ApiKeyAuth.kt.mustache", infrastructureFolder, "ApiKeyAuth.kt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Constants {
|
||||||
|
public final static String KTOR = "ktor";
|
||||||
|
public final static String AUTOMATIC_HEAD_REQUESTS = "featureAutoHead";
|
||||||
|
public final static String AUTOMATIC_HEAD_REQUESTS_DESC = "Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.";
|
||||||
|
public final static String CONDITIONAL_HEADERS = "featureConditionalHeaders";
|
||||||
|
public final static String CONDITIONAL_HEADERS_DESC = "Avoid sending content if client already has same content, by checking ETag or LastModified properties.";
|
||||||
|
public final static String HSTS = "featureHSTS";
|
||||||
|
public final static String HSTS_DESC = "Avoid sending content if client already has same content, by checking ETag or LastModified properties.";
|
||||||
|
public final static String CORS = "featureCORS";
|
||||||
|
public final static String CORS_DESC = "Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.";
|
||||||
|
public final static String COMPRESSION = "featureCompression";
|
||||||
|
public final static String COMPRESSION_DESC = "Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcess() {
|
||||||
|
System.out.println("################################################################################");
|
||||||
|
System.out.println("# Thanks for using OpenAPI Generator. #");
|
||||||
|
System.out.println("# Please consider donation to help us maintain this project \uD83D\uDE4F #");
|
||||||
|
System.out.println("# https://opencollective.com/openapi_generator/donate #");
|
||||||
|
System.out.println("# #");
|
||||||
|
System.out.println("# This generator's contributed by Jim Schubert (https://github.com/jimschubert)#");
|
||||||
|
System.out.println("# Please support his work directly via https://patreon.com/jimschubert \uD83D\uDE4F #");
|
||||||
|
System.out.println("################################################################################");
|
||||||
|
}
|
||||||
|
}
|
@ -67,10 +67,6 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
// in other code generators, support needs to be enabled on a case-by-case basis.
|
// in other code generators, support needs to be enabled on a case-by-case basis.
|
||||||
supportsAdditionalPropertiesWithComposedSchema = true;
|
supportsAdditionalPropertiesWithComposedSchema = true;
|
||||||
|
|
||||||
// When the 'additionalProperties' keyword is not present in a OAS schema, allow
|
|
||||||
// undeclared properties. This is compliant with the JSON schema specification.
|
|
||||||
this.setDisallowAdditionalPropertiesIfNotPresent(false);
|
|
||||||
|
|
||||||
modifyFeatureSet(features -> features
|
modifyFeatureSet(features -> features
|
||||||
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||||
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
|
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
|
||||||
@ -96,9 +92,8 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
ParameterFeature.Cookie
|
ParameterFeature.Cookie
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
// needed for type object with additionalProperties: false
|
||||||
// this may set datatype right for additional properties
|
typeMapping.put("object", "dict");
|
||||||
instantiationTypes.put("map", "dict");
|
|
||||||
|
|
||||||
languageSpecificPrimitives.add("file_type");
|
languageSpecificPrimitives.add("file_type");
|
||||||
languageSpecificPrimitives.add("none_type");
|
languageSpecificPrimitives.add("none_type");
|
||||||
@ -113,6 +108,20 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
cliOptions.add(new CliOption(CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET, CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET_DESC)
|
cliOptions.add(new CliOption(CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET, CodegenConstants.PYTHON_ATTR_NONE_IF_UNSET_DESC)
|
||||||
.defaultValue(Boolean.FALSE.toString()));
|
.defaultValue(Boolean.FALSE.toString()));
|
||||||
|
|
||||||
|
// option to change how we process + set the data in the 'additionalProperties' keyword.
|
||||||
|
CliOption disallowAdditionalPropertiesIfNotPresentOpt = CliOption.newBoolean(
|
||||||
|
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT,
|
||||||
|
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT_DESC).defaultValue(Boolean.FALSE.toString());
|
||||||
|
Map<String, String> disallowAdditionalPropertiesIfNotPresentOpts = new HashMap<>();
|
||||||
|
disallowAdditionalPropertiesIfNotPresentOpts.put("false",
|
||||||
|
"The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.");
|
||||||
|
disallowAdditionalPropertiesIfNotPresentOpts.put("true",
|
||||||
|
"Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default. NOTE: "+
|
||||||
|
"this option breaks composition and will be removed in 6.0.0"
|
||||||
|
);
|
||||||
|
disallowAdditionalPropertiesIfNotPresentOpt.setEnum(disallowAdditionalPropertiesIfNotPresentOpts);
|
||||||
|
cliOptions.add(disallowAdditionalPropertiesIfNotPresentOpt);
|
||||||
|
|
||||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||||
.stability(Stability.EXPERIMENTAL)
|
.stability(Stability.EXPERIMENTAL)
|
||||||
.build();
|
.build();
|
||||||
@ -162,6 +171,18 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
}
|
}
|
||||||
additionalProperties.put("attrNoneIfUnset", attrNoneIfUnset);
|
additionalProperties.put("attrNoneIfUnset", attrNoneIfUnset);
|
||||||
|
|
||||||
|
// When the 'additionalProperties' keyword is not present in a OAS schema, allow
|
||||||
|
// undeclared properties. This is compliant with the JSON schema specification.
|
||||||
|
// setting this to false is required to have composed schemas work because:
|
||||||
|
// anyOf SchemaA + SchemaB, requires that props present only in A are accepted in B because in B
|
||||||
|
// they are additional properties
|
||||||
|
Boolean disallowAddProps = false;
|
||||||
|
if (additionalProperties.containsKey(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT)) {
|
||||||
|
disallowAddProps = Boolean.valueOf(additionalProperties.get(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT).toString());
|
||||||
|
}
|
||||||
|
this.setDisallowAdditionalPropertiesIfNotPresent(disallowAddProps);
|
||||||
|
|
||||||
|
|
||||||
// check library option to ensure only urllib3 is supported
|
// check library option to ensure only urllib3 is supported
|
||||||
if (!DEFAULT_LIBRARY.equals(getLibrary())) {
|
if (!DEFAULT_LIBRARY.equals(getLibrary())) {
|
||||||
throw new RuntimeException("Only the `urllib3` library is supported in the refactored `python` client generator at the moment. Please fall back to `python-legacy` client generator for the time being. We welcome contributions to add back `asyncio`, `tornado` support to the `python` client generator.");
|
throw new RuntimeException("Only the `urllib3` library is supported in the refactored `python` client generator at the moment. Please fall back to `python-legacy` client generator for the time being. We welcome contributions to add back `asyncio`, `tornado` support to the `python` client generator.");
|
||||||
@ -730,6 +751,62 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Schema getAdditionalProperties(Schema schema) {
|
||||||
|
/*
|
||||||
|
Use cases:
|
||||||
|
1. addProps set to schema in spec: return that schema
|
||||||
|
2. addProps unset w/ getDisallowAdditionalPropertiesIfNotPresent -> null
|
||||||
|
3. addProps unset w/ getDisallowAdditionalPropertiesIfNotPresent=False -> new Schema()
|
||||||
|
4. addProps true -> new Schema() NOTE: v3 only
|
||||||
|
5. addprops false -> null NOTE: v3 only
|
||||||
|
*/
|
||||||
|
Object addProps = schema.getAdditionalProperties();
|
||||||
|
if (addProps instanceof Schema) {
|
||||||
|
return (Schema) addProps;
|
||||||
|
}
|
||||||
|
if (addProps == null) {
|
||||||
|
// When reaching this code path, this should indicate the 'additionalProperties' keyword is
|
||||||
|
// not present in the OAS schema. This is true for OAS 3.0 documents.
|
||||||
|
// However, the parsing logic is broken for OAS 2.0 documents because of the
|
||||||
|
// https://github.com/swagger-api/swagger-parser/issues/1369 issue.
|
||||||
|
// When OAS 2.0 documents are parsed, the swagger-v2-converter ignores the 'additionalProperties'
|
||||||
|
// keyword if the value is boolean. That means codegen is unable to determine whether
|
||||||
|
// additional properties are allowed or not.
|
||||||
|
//
|
||||||
|
// The original behavior was to assume additionalProperties had been set to false.
|
||||||
|
if (getDisallowAdditionalPropertiesIfNotPresent()) {
|
||||||
|
// If the 'additionalProperties' keyword is not present in a OAS schema,
|
||||||
|
// interpret as if the 'additionalProperties' keyword had been set to false.
|
||||||
|
// This is NOT compliant with the JSON schema specification. It is the original
|
||||||
|
// 'openapi-generator' behavior.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// The disallowAdditionalPropertiesIfNotPresent CLI option has been set to true,
|
||||||
|
// but for now that only works with OAS 3.0 documents.
|
||||||
|
// The new behavior does not work with OAS 2.0 documents.
|
||||||
|
if (extensions == null || !extensions.containsKey(EXTENSION_OPENAPI_DOC_VERSION)) {
|
||||||
|
// Fallback to the legacy behavior.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Get original swagger version from OAS extension.
|
||||||
|
// Note openAPI.getOpenapi() is always set to 3.x even when the document
|
||||||
|
// is converted from a OAS/Swagger 2.0 document.
|
||||||
|
// https://github.com/swagger-api/swagger-parser/pull/1374
|
||||||
|
SemVer version = new SemVer((String)extensions.get(EXTENSION_OPENAPI_DOC_VERSION));
|
||||||
|
if (version.major != 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (addProps == null || (addProps instanceof Boolean && (Boolean) addProps)) {
|
||||||
|
// Return empty schema to allow any type
|
||||||
|
return new Schema();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string representation of the Python types for the specified OAS schema.
|
* Return a string representation of the Python types for the specified OAS schema.
|
||||||
* Primitive types in the OAS specification are implemented in Python using the corresponding
|
* Primitive types in the OAS specification are implemented in Python using the corresponding
|
||||||
@ -769,16 +846,39 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isAnyTypeSchema(p)) {
|
if (isAnyTypeSchema(p)) {
|
||||||
|
// for v2 specs only, swagger-parser never generates an AnyType schemas even though it should generate them
|
||||||
|
// https://github.com/swagger-api/swagger-parser/issues/1378
|
||||||
|
// switch to v3 if you need AnyType to work
|
||||||
return prefix + "bool, date, datetime, dict, float, int, list, str, none_type" + suffix;
|
return prefix + "bool, date, datetime, dict, float, int, list, str, none_type" + suffix;
|
||||||
}
|
}
|
||||||
|
String originalSpecVersion = "X";
|
||||||
|
if (this.openAPI.getExtensions() != null && this.openAPI.getExtensions().containsKey("x-original-swagger-version")) {
|
||||||
|
originalSpecVersion = (String) this.openAPI.getExtensions().get("x-original-swagger-version");
|
||||||
|
originalSpecVersion = originalSpecVersion.substring(0, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
Boolean v2DisallowAdditionalPropertiesIfNotPresentAddPropsNullCase = (getAdditionalProperties(p) == null && this.getDisallowAdditionalPropertiesIfNotPresent() && originalSpecVersion.equals("2"));
|
||||||
|
Schema emptySchema = new Schema();
|
||||||
|
Boolean v2WithCompositionAddPropsAnyTypeSchemaCase = (getAdditionalProperties(p) != null && emptySchema.equals(getAdditionalProperties(p)) && originalSpecVersion.equals("2"));
|
||||||
|
if (isFreeFormObject(p) && (v2DisallowAdditionalPropertiesIfNotPresentAddPropsNullCase || v2WithCompositionAddPropsAnyTypeSchemaCase)) {
|
||||||
|
// for v2 specs only, input AnyType schemas (type unset) or schema {} results in FreeFromObject schemas
|
||||||
|
// per https://github.com/swagger-api/swagger-parser/issues/1378
|
||||||
|
// v2 spec uses cases
|
||||||
|
// 1. AnyType schemas
|
||||||
|
// 2. type object schema with no other info
|
||||||
|
// use case 1 + 2 -> both become use case 1
|
||||||
|
// switch to v3 if you need use cases 1 + 2 to work correctly
|
||||||
|
return prefix + "bool, date, datetime, dict, float, int, list, str, none_type" + fullSuffix;
|
||||||
|
}
|
||||||
// Resolve $ref because ModelUtils.isXYZ methods do not automatically resolve references.
|
// Resolve $ref because ModelUtils.isXYZ methods do not automatically resolve references.
|
||||||
if (ModelUtils.isNullable(ModelUtils.getReferencedSchema(this.openAPI, p))) {
|
if (ModelUtils.isNullable(ModelUtils.getReferencedSchema(this.openAPI, p))) {
|
||||||
fullSuffix = ", none_type" + suffix;
|
fullSuffix = ", none_type" + suffix;
|
||||||
}
|
}
|
||||||
if (isFreeFormObject(p) && getAdditionalProperties(p) == null) {
|
Boolean v3WithCompositionAddPropsAnyTypeSchemaCase = (getAdditionalProperties(p) != null && emptySchema.equals(getAdditionalProperties(p)) && originalSpecVersion.equals("3"));
|
||||||
return prefix + "bool, date, datetime, dict, float, int, list, str" + fullSuffix;
|
if (isFreeFormObject(p) && v3WithCompositionAddPropsAnyTypeSchemaCase) {
|
||||||
}
|
// v3 code path, use case: type object schema with no other schema info
|
||||||
if ((ModelUtils.isMapSchema(p) || "object".equals(p.getType())) && getAdditionalProperties(p) != null) {
|
return prefix + "{str: (bool, date, datetime, dict, float, int, list, str, none_type)}" + fullSuffix;
|
||||||
|
} else if ((ModelUtils.isMapSchema(p) || "object".equals(p.getType())) && getAdditionalProperties(p) != null) {
|
||||||
Schema inner = getAdditionalProperties(p);
|
Schema inner = getAdditionalProperties(p);
|
||||||
return prefix + "{str: " + getTypeString(inner, "(", ")", referencedModelNames) + "}" + fullSuffix;
|
return prefix + "{str: " + getTypeString(inner, "(", ")", referencedModelNames) + "}" + fullSuffix;
|
||||||
} else if (ModelUtils.isArraySchema(p)) {
|
} else if (ModelUtils.isArraySchema(p)) {
|
||||||
@ -837,7 +937,7 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
|
|||||||
// The 'addProps' may be a reference, getTypeDeclaration will resolve
|
// The 'addProps' may be a reference, getTypeDeclaration will resolve
|
||||||
// the reference.
|
// the reference.
|
||||||
List<String> referencedModelNames = new ArrayList<String>();
|
List<String> referencedModelNames = new ArrayList<String>();
|
||||||
codegenModel.additionalPropertiesType = getTypeString(addProps, "", "", referencedModelNames);
|
getTypeString(addProps, "", "", referencedModelNames);
|
||||||
if (referencedModelNames.size() != 0) {
|
if (referencedModelNames.size() != 0) {
|
||||||
// Models that are referenced in the 'additionalPropertiesType' keyword
|
// Models that are referenced in the 'additionalPropertiesType' keyword
|
||||||
// must be added to the imports.
|
// must be added to the imports.
|
||||||
|
@ -36,6 +36,7 @@ public class PythonLegacyClientCodegen extends AbstractPythonCodegen implements
|
|||||||
// nose is a python testing framework, we use pytest if USE_NOSE is unset
|
// nose is a python testing framework, we use pytest if USE_NOSE is unset
|
||||||
public static final String USE_NOSE = "useNose";
|
public static final String USE_NOSE = "useNose";
|
||||||
public static final String RECURSION_LIMIT = "recursionLimit";
|
public static final String RECURSION_LIMIT = "recursionLimit";
|
||||||
|
public static final String PYTHON_ATTR_NONE_IF_UNSET = "pythonAttrNoneIfUnset";
|
||||||
|
|
||||||
protected String packageUrl;
|
protected String packageUrl;
|
||||||
protected String apiDocPath = "docs/";
|
protected String apiDocPath = "docs/";
|
||||||
|
@ -44,6 +44,7 @@ org.openapitools.codegen.languages.GraphQLNodeJSExpressServerCodegen
|
|||||||
org.openapitools.codegen.languages.GroovyClientCodegen
|
org.openapitools.codegen.languages.GroovyClientCodegen
|
||||||
org.openapitools.codegen.languages.KotlinClientCodegen
|
org.openapitools.codegen.languages.KotlinClientCodegen
|
||||||
org.openapitools.codegen.languages.KotlinServerCodegen
|
org.openapitools.codegen.languages.KotlinServerCodegen
|
||||||
|
org.openapitools.codegen.languages.KotlinServerDeprecatedCodegen
|
||||||
org.openapitools.codegen.languages.KotlinSpringServerCodegen
|
org.openapitools.codegen.languages.KotlinSpringServerCodegen
|
||||||
org.openapitools.codegen.languages.KotlinVertxServerCodegen
|
org.openapitools.codegen.languages.KotlinVertxServerCodegen
|
||||||
org.openapitools.codegen.languages.KtormSchemaCodegen
|
org.openapitools.codegen.languages.KtormSchemaCodegen
|
||||||
|
84
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache
vendored
Normal file
84
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# {{packageName}} - Kotlin Server library for {{appName}}
|
||||||
|
|
||||||
|
## Requires
|
||||||
|
|
||||||
|
* Kotlin 1.1.2
|
||||||
|
* Gradle 3.3
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
First, create the gradle wrapper script:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradle wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew check assemble
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs all tests and packages the library.
|
||||||
|
|
||||||
|
## Features/Implementation Notes
|
||||||
|
|
||||||
|
* Supports JSON inputs/outputs, File inputs, and Form inputs.
|
||||||
|
* Supports collection formats for query parameters: csv, tsv, ssv, pipes.
|
||||||
|
* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
|
||||||
|
|
||||||
|
{{#generateApiDocs}}
|
||||||
|
<a name="documentation-for-api-endpoints"></a>
|
||||||
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
All URIs are relative to *{{{basePath}}}*
|
||||||
|
|
||||||
|
Class | Method | HTTP request | Description
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{{summary}}}{{/summary}}
|
||||||
|
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||||
|
{{/generateApiDocs}}
|
||||||
|
|
||||||
|
{{#generateModelDocs}}
|
||||||
|
<a name="documentation-for-models"></a>
|
||||||
|
## Documentation for Models
|
||||||
|
|
||||||
|
{{#modelPackage}}
|
||||||
|
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
|
||||||
|
{{/model}}{{/models}}
|
||||||
|
{{/modelPackage}}
|
||||||
|
{{^modelPackage}}
|
||||||
|
No model defined in this package
|
||||||
|
{{/modelPackage}}
|
||||||
|
{{/generateModelDocs}}
|
||||||
|
|
||||||
|
<a name="documentation-for-authorization"></a>{{! TODO: optional documentation for authorization? }}
|
||||||
|
## Documentation for Authorization
|
||||||
|
|
||||||
|
{{^authMethods}}
|
||||||
|
All endpoints do not require authorization.
|
||||||
|
{{/authMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
{{#last}}
|
||||||
|
Authentication schemes defined for the API:
|
||||||
|
{{/last}}
|
||||||
|
{{/authMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
<a name="{{name}}"></a>
|
||||||
|
### {{name}}
|
||||||
|
|
||||||
|
{{#isApiKey}}- **Type**: API key
|
||||||
|
- **API key parameter name**: {{keyParamName}}
|
||||||
|
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
|
||||||
|
{{/isApiKey}}
|
||||||
|
{{#isBasic}}- **Type**: HTTP basic authentication
|
||||||
|
{{/isBasic}}
|
||||||
|
{{#isOAuth}}- **Type**: OAuth
|
||||||
|
- **Flow**: {{flow}}
|
||||||
|
- **Authorization URL**: {{authorizationUrl}}
|
||||||
|
- **Scopes**: {{^scopes}}N/A{{/scopes}}
|
||||||
|
{{#scopes}} - {{scope}}: {{description}}
|
||||||
|
{{/scopes}}
|
||||||
|
{{/isOAuth}}
|
||||||
|
|
||||||
|
{{/authMethods}}
|
65
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/api_doc.mustache
vendored
Normal file
65
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/api_doc.mustache
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# {{classname}}{{#description}}
|
||||||
|
{{description}}{{/description}}
|
||||||
|
|
||||||
|
All URIs are relative to *{{basePath}}*
|
||||||
|
|
||||||
|
Method | HTTP request | Description
|
||||||
|
------------- | ------------- | -------------
|
||||||
|
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||||
|
{{/operation}}{{/operations}}
|
||||||
|
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
<a name="{{operationId}}"></a>
|
||||||
|
# **{{operationId}}**
|
||||||
|
> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||||
|
|
||||||
|
{{summary}}{{#notes}}
|
||||||
|
|
||||||
|
{{notes}}{{/notes}}
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```kotlin
|
||||||
|
// Import classes:
|
||||||
|
//import {{{packageName}}}.infrastructure.*
|
||||||
|
//import {{{modelPackage}}}.*
|
||||||
|
|
||||||
|
{{! TODO: Auth method documentation examples}}
|
||||||
|
val apiInstance = {{{classname}}}()
|
||||||
|
{{#allParams}}
|
||||||
|
val {{{paramName}}} : {{{dataType}}} = {{{example}}} // {{{dataType}}} | {{{description}}}
|
||||||
|
{{/allParams}}
|
||||||
|
try {
|
||||||
|
{{#returnType}}val result : {{{returnType}}} = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}){{#returnType}}
|
||||||
|
println(result){{/returnType}}
|
||||||
|
} catch (e: ClientException) {
|
||||||
|
println("4xx response calling {{{classname}}}#{{{operationId}}}")
|
||||||
|
e.printStackTrace()
|
||||||
|
} catch (e: ServerException) {
|
||||||
|
println("5xx response calling {{{classname}}}#{{{operationId}}}")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
|
||||||
|
{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#generateModelDocs}}[**{{dataType}}**]({{baseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{dataType}}**{{/generateModelDocs}}{{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{defaultValue}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}}
|
||||||
|
{{/allParams}}
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#generateModelDocs}}[**{{returnType}}**]({{returnBaseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{returnType}}**{{/generateModelDocs}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}}
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](../README.md#{{name}}){{^-last}}, {{/-last}}{{/authMethods}}
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
|
||||||
|
- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
|
||||||
|
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
15
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache
vendored
Normal file
15
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# {{classname}}
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
{{#vars}}**{{name}}** | {{#isEnum}}[**inline**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}}
|
||||||
|
{{/vars}}
|
||||||
|
{{#vars}}{{#isEnum}}
|
||||||
|
|
||||||
|
<a name="{{{datatypeWithEnum}}}"></a>{{!NOTE: see java's resources "pojo_doc.mustache" once enums are fully implemented}}
|
||||||
|
## Enum: {{baseName}}
|
||||||
|
Name | Value
|
||||||
|
---- | -----{{#allowableValues}}
|
||||||
|
{{name}} | {{#values}}{{.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}
|
||||||
|
{{/isEnum}}{{/vars}}
|
52
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache
vendored
Normal file
52
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{{#parcelizeModels}}
|
||||||
|
import android.os.Parcelable
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
{{/parcelizeModels}}
|
||||||
|
{{#serializableModel}}
|
||||||
|
import java.io.Serializable
|
||||||
|
{{/serializableModel}}
|
||||||
|
/**
|
||||||
|
* {{{description}}}
|
||||||
|
{{#vars}}
|
||||||
|
* @param {{name}} {{{description}}}
|
||||||
|
{{/vars}}
|
||||||
|
*/
|
||||||
|
{{#parcelizeModels}}
|
||||||
|
@Parcelize
|
||||||
|
{{/parcelizeModels}}
|
||||||
|
data class {{classname}} (
|
||||||
|
{{#requiredVars}}
|
||||||
|
{{>data_class_req_var}}{{^-last}},
|
||||||
|
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
||||||
|
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
|
||||||
|
{{/-last}}{{/optionalVars}}
|
||||||
|
) {{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}
|
||||||
|
{{#vendorExtensions.x-has-data-class-body}}
|
||||||
|
{
|
||||||
|
{{/vendorExtensions.x-has-data-class-body}}
|
||||||
|
{{#serializableModel}}
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID: Long = 123
|
||||||
|
}
|
||||||
|
{{/serializableModel}}
|
||||||
|
{{#hasEnums}}
|
||||||
|
{{#vars}}
|
||||||
|
{{#isEnum}}
|
||||||
|
/**
|
||||||
|
* {{{description}}}
|
||||||
|
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||||
|
*/
|
||||||
|
enum class {{nameInCamelCase}}(val value: {{dataType}}){
|
||||||
|
{{#allowableValues}}
|
||||||
|
{{#enumVars}}
|
||||||
|
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||||
|
{{/enumVars}}
|
||||||
|
{{/allowableValues}}
|
||||||
|
}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/vars}}
|
||||||
|
{{/hasEnums}}
|
||||||
|
{{#vendorExtensions.x-has-data-class-body}}
|
||||||
|
}
|
||||||
|
{{/vendorExtensions.x-has-data-class-body}}
|
@ -0,0 +1,4 @@
|
|||||||
|
{{#description}}
|
||||||
|
/* {{{description}}} */
|
||||||
|
{{/description}}
|
||||||
|
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}
|
@ -0,0 +1,4 @@
|
|||||||
|
{{#description}}
|
||||||
|
/* {{{description}}} */
|
||||||
|
{{/description}}
|
||||||
|
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}
|
9
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_class.mustache
vendored
Normal file
9
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_class.mustache
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* {{{description}}}
|
||||||
|
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||||
|
*/
|
||||||
|
enum class {{classname}}(val value: {{dataType}}){
|
||||||
|
{{#allowableValues}}{{#enumVars}}
|
||||||
|
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||||
|
{{/enumVars}}{{/allowableValues}}
|
||||||
|
}
|
7
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_doc.mustache
vendored
Normal file
7
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_doc.mustache
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# {{classname}}
|
||||||
|
|
||||||
|
## Enum
|
||||||
|
|
||||||
|
{{#allowableValues}}{{#enumVars}}
|
||||||
|
* `{{name}}` (value: `{{{value}}}`)
|
||||||
|
{{/enumVars}}{{/allowableValues}}
|
@ -0,0 +1,85 @@
|
|||||||
|
package {{packageName}}.infrastructure
|
||||||
|
|
||||||
|
import io.ktor.application.ApplicationCall
|
||||||
|
import io.ktor.application.call
|
||||||
|
import io.ktor.auth.Authentication
|
||||||
|
import io.ktor.auth.AuthenticationFailedCause
|
||||||
|
import io.ktor.auth.AuthenticationPipeline
|
||||||
|
import io.ktor.auth.AuthenticationProvider
|
||||||
|
import io.ktor.auth.Credential
|
||||||
|
import io.ktor.auth.Principal
|
||||||
|
import io.ktor.auth.UnauthorizedResponse
|
||||||
|
import io.ktor.http.auth.HeaderValueEncoding
|
||||||
|
import io.ktor.http.auth.HttpAuthHeader
|
||||||
|
import io.ktor.request.ApplicationRequest
|
||||||
|
import io.ktor.response.respond
|
||||||
|
|
||||||
|
enum class ApiKeyLocation(val location: String) {
|
||||||
|
QUERY("query"),
|
||||||
|
HEADER("header")
|
||||||
|
}
|
||||||
|
data class ApiKeyCredential(val value: String): Credential
|
||||||
|
data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Api Key authentication provider
|
||||||
|
* @param name is the name of the provider, or `null` for a default provider
|
||||||
|
*/
|
||||||
|
class ApiKeyAuthenticationProvider(name: String?) : AuthenticationProvider(name) {
|
||||||
|
internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = { null }
|
||||||
|
|
||||||
|
var apiKeyName: String = "";
|
||||||
|
|
||||||
|
var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal],
|
||||||
|
* or null if credential does not correspond to an authenticated principal
|
||||||
|
*/
|
||||||
|
fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) {
|
||||||
|
authenticationFunction = body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Authentication.Configuration.apiKeyAuth(name: String? = null, configure: ApiKeyAuthenticationProvider.() -> Unit) {
|
||||||
|
val provider = ApiKeyAuthenticationProvider(name).apply(configure)
|
||||||
|
val apiKeyName = provider.apiKeyName
|
||||||
|
val apiKeyLocation = provider.apiKeyLocation
|
||||||
|
val authenticate = provider.authenticationFunction
|
||||||
|
|
||||||
|
provider.pipeline.intercept(AuthenticationPipeline.RequestAuthentication) { context ->
|
||||||
|
val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation)
|
||||||
|
val principal = credentials?.let { authenticate(call, it) }
|
||||||
|
|
||||||
|
val cause = when {
|
||||||
|
credentials == null -> AuthenticationFailedCause.NoCredentials
|
||||||
|
principal == null -> AuthenticationFailedCause.InvalidCredentials
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cause != null) {
|
||||||
|
context.challenge(apiKeyName, cause) {
|
||||||
|
// TODO: Verify correct response structure here.
|
||||||
|
call.respond(UnauthorizedResponse(HttpAuthHeader.Parameterized("API_KEY", mapOf("key" to apiKeyName), HeaderValueEncoding.QUOTED_ALWAYS)))
|
||||||
|
it.complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (principal != null) {
|
||||||
|
context.principal(principal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ApplicationRequest.apiKeyAuthenticationCredentials(apiKeyName: String, apiKeyLocation: ApiKeyLocation): ApiKeyCredential? {
|
||||||
|
val value: String? = when(apiKeyLocation) {
|
||||||
|
ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName]
|
||||||
|
ApiKeyLocation.HEADER -> this.headers[apiKeyName]
|
||||||
|
}
|
||||||
|
when (value) {
|
||||||
|
null -> return null
|
||||||
|
else -> return ApiKeyCredential(value)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
package {{packageName}}
|
||||||
|
|
||||||
|
import com.codahale.metrics.Slf4jReporter
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
import io.ktor.application.Application
|
||||||
|
import io.ktor.application.ApplicationStopping
|
||||||
|
import io.ktor.application.install
|
||||||
|
import io.ktor.application.log
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.apache.Apache
|
||||||
|
import io.ktor.config.HoconApplicationConfig
|
||||||
|
{{#featureAutoHead}}
|
||||||
|
import io.ktor.features.AutoHeadResponse
|
||||||
|
{{/featureAutoHead}}
|
||||||
|
{{#featureCompression}}
|
||||||
|
import io.ktor.features.Compression
|
||||||
|
{{/featureCompression}}
|
||||||
|
{{#featureCORS}}
|
||||||
|
import io.ktor.features.CORS
|
||||||
|
{{/featureCORS}}
|
||||||
|
{{#featureConditionalHeaders}}
|
||||||
|
import io.ktor.features.ConditionalHeaders
|
||||||
|
{{/featureConditionalHeaders}}
|
||||||
|
import io.ktor.features.ContentNegotiation
|
||||||
|
import io.ktor.features.DefaultHeaders
|
||||||
|
{{#featureHSTS}}
|
||||||
|
import io.ktor.features.HSTS
|
||||||
|
{{/featureHSTS}}
|
||||||
|
import io.ktor.gson.GsonConverter
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
|
import io.ktor.locations.Locations
|
||||||
|
import io.ktor.metrics.Metrics
|
||||||
|
import io.ktor.routing.Routing
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import io.ktor.util.KtorExperimentalAPI
|
||||||
|
{{#hasAuthMethods}}
|
||||||
|
import io.ktor.auth.Authentication
|
||||||
|
import io.ktor.auth.oauth
|
||||||
|
import org.openapitools.server.infrastructure.ApiKeyCredential
|
||||||
|
import org.openapitools.server.infrastructure.ApiPrincipal
|
||||||
|
import org.openapitools.server.infrastructure.apiKeyAuth
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}}
|
||||||
|
{{/apis}}{{/apiInfo}}{{/generateApis}}
|
||||||
|
|
||||||
|
@KtorExperimentalAPI
|
||||||
|
internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader))
|
||||||
|
|
||||||
|
object HTTP {
|
||||||
|
val client = HttpClient(Apache)
|
||||||
|
}
|
||||||
|
|
||||||
|
@KtorExperimentalAPI
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
|
fun Application.main() {
|
||||||
|
install(DefaultHeaders)
|
||||||
|
install(Metrics) {
|
||||||
|
val reporter = Slf4jReporter.forRegistry(registry)
|
||||||
|
.outputTo(log)
|
||||||
|
.convertRatesTo(TimeUnit.SECONDS)
|
||||||
|
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||||
|
.build()
|
||||||
|
reporter.start(10, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
{{#generateApis}}
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
register(ContentType.Application.Json, GsonConverter())
|
||||||
|
}
|
||||||
|
{{#featureAutoHead}}
|
||||||
|
install(AutoHeadResponse) // see http://ktor.io/features/autoheadresponse.html
|
||||||
|
{{/featureAutoHead}}
|
||||||
|
{{#featureConditionalHeaders}}
|
||||||
|
install(ConditionalHeaders) // see http://ktor.io/features/conditional-headers.html
|
||||||
|
{{/featureConditionalHeaders}}
|
||||||
|
{{#featureHSTS}}
|
||||||
|
install(HSTS, ApplicationHstsConfiguration()) // see http://ktor.io/features/hsts.html
|
||||||
|
{{/featureHSTS}}
|
||||||
|
{{#featureCORS}}
|
||||||
|
install(CORS, ApplicationCORSConfiguration()) // see http://ktor.io/features/cors.html
|
||||||
|
{{/featureCORS}}
|
||||||
|
{{#featureCompression}}
|
||||||
|
install(Compression, ApplicationCompressionConfiguration()) // see http://ktor.io/features/compression.html
|
||||||
|
{{/featureCompression}}
|
||||||
|
install(Locations) // see http://ktor.io/features/locations.html
|
||||||
|
{{#hasAuthMethods}}
|
||||||
|
install(Authentication) {
|
||||||
|
{{#authMethods}}
|
||||||
|
{{#isBasic}}
|
||||||
|
basic("{{{name}}}") {
|
||||||
|
validate { credentials ->
|
||||||
|
// TODO: "Apply your basic authentication functionality."
|
||||||
|
// Accessible in-method via call.principal<UserIdPrincipal>()
|
||||||
|
if (credentials.name == "Swagger" && "Codegen" == credentials.password) {
|
||||||
|
UserIdPrincipal(credentials.name)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/isBasic}}
|
||||||
|
{{#isApiKey}}
|
||||||
|
// "Implement API key auth ({{{name}}}) for parameter name '{{{keyParamName}}}'."
|
||||||
|
apiKeyAuth("{{{name}}}") {
|
||||||
|
validate { apikeyCredential: ApiKeyCredential ->
|
||||||
|
when {
|
||||||
|
apikeyCredential.value == "keyboardcat" -> ApiPrincipal(apikeyCredential)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/isApiKey}}
|
||||||
|
{{#isOAuth}}
|
||||||
|
{{#bodyAllowed}}
|
||||||
|
{{/bodyAllowed}}
|
||||||
|
{{^bodyAllowed}}
|
||||||
|
oauth("{{name}}") {
|
||||||
|
client = HttpClient(Apache)
|
||||||
|
providerLookup = { ApplicationAuthProviders["{{{name}}}"] }
|
||||||
|
urlProvider = { _ ->
|
||||||
|
// TODO: define a callback url here.
|
||||||
|
"/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/bodyAllowed}}
|
||||||
|
{{/isOAuth}}
|
||||||
|
{{/authMethods}}
|
||||||
|
}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
install(Routing) {
|
||||||
|
{{#apiInfo}}
|
||||||
|
{{#apis}}
|
||||||
|
{{#operations}}
|
||||||
|
{{classname}}()
|
||||||
|
{{/operations}}
|
||||||
|
{{/apis}}
|
||||||
|
{{/apiInfo}}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{/generateApis}}
|
||||||
|
|
||||||
|
environment.monitor.subscribe(ApplicationStopping)
|
||||||
|
{
|
||||||
|
HTTP.client.close()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package {{packageName}}
|
||||||
|
|
||||||
|
// Use this file to hold package-level internal functions that return receiver object passed to the `install` method.
|
||||||
|
import io.ktor.auth.OAuthServerSettings
|
||||||
|
import io.ktor.features.Compression
|
||||||
|
import io.ktor.features.HSTS
|
||||||
|
import io.ktor.features.deflate
|
||||||
|
import io.ktor.features.gzip
|
||||||
|
import io.ktor.features.minimumSize
|
||||||
|
import io.ktor.http.HttpMethod
|
||||||
|
import io.ktor.util.KtorExperimentalAPI
|
||||||
|
import java.time.Duration
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
import {{packageName}}.settings
|
||||||
|
|
||||||
|
{{#featureCORS}}
|
||||||
|
/**
|
||||||
|
* Application block for [CORS] configuration.
|
||||||
|
*
|
||||||
|
* This file may be excluded in .openapi-generator-ignore,
|
||||||
|
* and application specific configuration can be applied in this function.
|
||||||
|
*
|
||||||
|
* See http://ktor.io/features/cors.html
|
||||||
|
*/
|
||||||
|
internal fun ApplicationCORSConfiguration(): CORS.Configuration.() -> Unit {
|
||||||
|
return {
|
||||||
|
// method(HttpMethod.Options)
|
||||||
|
// header(HttpHeaders.XForwardedProto)
|
||||||
|
// anyHost()
|
||||||
|
// host("my-host")
|
||||||
|
// host("my-host:80")
|
||||||
|
// host("my-host", subDomains = listOf("www"))
|
||||||
|
// host("my-host", schemes = listOf("http", "https"))
|
||||||
|
// allowCredentials = true
|
||||||
|
// maxAge = Duration.ofDays(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/featureCORS}}
|
||||||
|
|
||||||
|
{{#featureHSTS}}
|
||||||
|
/**
|
||||||
|
* Application block for [HSTS] configuration.
|
||||||
|
*
|
||||||
|
* This file may be excluded in .openapi-generator-ignore,
|
||||||
|
* and application specific configuration can be applied in this function.
|
||||||
|
*
|
||||||
|
* See http://ktor.io/features/hsts.html
|
||||||
|
*/
|
||||||
|
internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit {
|
||||||
|
return {
|
||||||
|
maxAge = Duration.ofDays(365)
|
||||||
|
includeSubDomains = true
|
||||||
|
preload = false
|
||||||
|
|
||||||
|
// You may also apply any custom directives supported by specific user-agent. For example:
|
||||||
|
// customDirectives.put("redirectHttpToHttps", "false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/featureHSTS}}
|
||||||
|
|
||||||
|
{{#featureCompression}}
|
||||||
|
/**
|
||||||
|
* Application block for [Compression] configuration.
|
||||||
|
*
|
||||||
|
* This file may be excluded in .openapi-generator-ignore,
|
||||||
|
* and application specific configuration can be applied in this function.
|
||||||
|
*
|
||||||
|
* See http://ktor.io/features/compression.html
|
||||||
|
*/
|
||||||
|
internal fun ApplicationCompressionConfiguration(): Compression.Configuration.() -> Unit {
|
||||||
|
return {
|
||||||
|
gzip {
|
||||||
|
priority = 1.0
|
||||||
|
}
|
||||||
|
deflate {
|
||||||
|
priority = 10.0
|
||||||
|
minimumSize(1024) // condition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/featureCompression}}
|
||||||
|
|
||||||
|
// Defines authentication mechanisms used throughout the application.
|
||||||
|
@KtorExperimentalAPI
|
||||||
|
val ApplicationAuthProviders: Map<String, OAuthServerSettings> = listOf<OAuthServerSettings>(
|
||||||
|
{{#authMethods}}
|
||||||
|
{{#isOAuth}}
|
||||||
|
OAuthServerSettings.OAuth2ServerSettings(
|
||||||
|
name = "{{name}}",
|
||||||
|
authorizeUrl = "{{authorizationUrl}}",
|
||||||
|
accessTokenUrl = "{{tokenUrl}}",
|
||||||
|
requestMethod = HttpMethod.Get,
|
||||||
|
{{! TODO: flow, doesn't seem to be supported yet by ktor }}
|
||||||
|
clientId = settings.property("auth.oauth.{{name}}.clientId").getString(),
|
||||||
|
clientSecret = settings.property("auth.oauth.{{name}}.clientSecret").getString(),
|
||||||
|
defaultScopes = listOf({{#scopes}}"{{scope}}"{{^-last}}, {{/-last}}{{/scopes}})
|
||||||
|
){{^-last}},{{/-last}}
|
||||||
|
{{/isOAuth}}
|
||||||
|
{{/authMethods}}
|
||||||
|
// OAuthServerSettings.OAuth2ServerSettings(
|
||||||
|
// name = "facebook",
|
||||||
|
// authorizeUrl = "https://graph.facebook.com/oauth/authorize",
|
||||||
|
// accessTokenUrl = "https://graph.facebook.com/oauth/access_token",
|
||||||
|
// requestMethod = HttpMethod.Post,
|
||||||
|
//
|
||||||
|
// clientId = "settings.property("auth.oauth.facebook.clientId").getString()",
|
||||||
|
// clientSecret = "settings.property("auth.oauth.facebook.clientSecret").getString()",
|
||||||
|
// defaultScopes = listOf("public_profile")
|
||||||
|
// )
|
||||||
|
).associateBy { it.name }
|
||||||
|
|
||||||
|
// Provides an application-level fixed thread pool on which to execute coroutines (mainly)
|
||||||
|
internal val ApplicationExecutors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4)
|
@ -0,0 +1,7 @@
|
|||||||
|
FROM openjdk:8-jre-alpine
|
||||||
|
|
||||||
|
COPY ./build/libs/{{artifactId}}.jar /root/{{artifactId}}.jar
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
CMD ["java", "-server", "-Xms4g", "-Xmx4g", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "{{artifactId}}.jar"]
|
@ -0,0 +1,28 @@
|
|||||||
|
{{>licenseInfo}}
|
||||||
|
package {{packageName}}
|
||||||
|
|
||||||
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
|
import io.ktor.locations.Location
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
|
||||||
|
{{#apiInfo}}
|
||||||
|
object Paths {
|
||||||
|
{{#apis}}
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
{{^bodyAllowed}}
|
||||||
|
/**
|
||||||
|
* {{summary}}
|
||||||
|
* {{#unescapedNotes}}{{.}}{{/unescapedNotes}}
|
||||||
|
{{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
|
||||||
|
{{/allParams}}*/
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
|
@Location("{{path}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||||
|
|
||||||
|
{{/bodyAllowed}}
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
||||||
|
{{/apis}}
|
||||||
|
}
|
||||||
|
{{/apiInfo}}
|
101
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache
vendored
Normal file
101
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache
vendored
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# {{packageName}} - Kotlin Server library for {{appName}}
|
||||||
|
|
||||||
|
{{#unescapedAppDescription}}
|
||||||
|
{{.}}
|
||||||
|
{{/unescapedAppDescription}}
|
||||||
|
|
||||||
|
Generated by OpenAPI Generator {{generatorVersion}}{{^hideGenerationTimestamp}} ({{generatedDate}}){{/hideGenerationTimestamp}}.
|
||||||
|
|
||||||
|
## Requires
|
||||||
|
|
||||||
|
* Kotlin 1.3.21
|
||||||
|
* Gradle 4.9
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
First, create the gradle wrapper script:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradle wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew check assemble
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs all tests and packages the library.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/{{artifactId}}.jar`.
|
||||||
|
|
||||||
|
You may also run in docker:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker build -t {{artifactId}} .
|
||||||
|
docker run -p 8080:8080 {{artifactId}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features/Implementation Notes
|
||||||
|
|
||||||
|
* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info).
|
||||||
|
* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~
|
||||||
|
* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
|
||||||
|
|
||||||
|
{{#generateApiDocs}}
|
||||||
|
<a name="documentation-for-api-endpoints"></a>
|
||||||
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
All URIs are relative to *{{{basePath}}}*
|
||||||
|
|
||||||
|
Class | Method | HTTP request | Description
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{{summary}}}{{/summary}}
|
||||||
|
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||||
|
{{/generateApiDocs}}
|
||||||
|
|
||||||
|
{{#generateModelDocs}}
|
||||||
|
<a name="documentation-for-models"></a>
|
||||||
|
## Documentation for Models
|
||||||
|
|
||||||
|
{{#modelPackage}}
|
||||||
|
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
|
||||||
|
{{/model}}{{/models}}
|
||||||
|
{{/modelPackage}}
|
||||||
|
{{^modelPackage}}
|
||||||
|
No model defined in this package
|
||||||
|
{{/modelPackage}}
|
||||||
|
{{/generateModelDocs}}
|
||||||
|
|
||||||
|
<a name="documentation-for-authorization"></a>{{! TODO: optional documentation for authorization? }}
|
||||||
|
## Documentation for Authorization
|
||||||
|
|
||||||
|
{{^authMethods}}
|
||||||
|
All endpoints do not require authorization.
|
||||||
|
{{/authMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
{{#last}}
|
||||||
|
Authentication schemes defined for the API:
|
||||||
|
{{/last}}
|
||||||
|
{{/authMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
<a name="{{name}}"></a>
|
||||||
|
### {{name}}
|
||||||
|
|
||||||
|
{{#isApiKey}}- **Type**: API key
|
||||||
|
- **API key parameter name**: {{keyParamName}}
|
||||||
|
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
|
||||||
|
{{/isApiKey}}
|
||||||
|
{{#isBasic}}- **Type**: HTTP basic authentication
|
||||||
|
{{/isBasic}}
|
||||||
|
{{#isOAuth}}- **Type**: OAuth
|
||||||
|
- **Flow**: {{flow}}
|
||||||
|
- **Authorization URL**: {{authorizationUrl}}
|
||||||
|
- **Scopes**: {{^scopes}}N/A{{/scopes}}
|
||||||
|
{{#scopes}} - {{scope}}: {{description}}
|
||||||
|
{{/scopes}}
|
||||||
|
{{/isOAuth}}
|
||||||
|
|
||||||
|
{{/authMethods}}
|
@ -0,0 +1,25 @@
|
|||||||
|
{{#hasAuthMethods}}
|
||||||
|
{{>libraries/ktor/_principal}}
|
||||||
|
if (principal == null) {
|
||||||
|
call.respond(HttpStatusCode.Unauthorized)
|
||||||
|
} else {
|
||||||
|
{{#examples}}
|
||||||
|
{{#-first}}
|
||||||
|
{{#lambda.indented}}{{>_response}}{{/lambda.indented}}
|
||||||
|
{{/-first}}
|
||||||
|
{{/examples}}
|
||||||
|
{{^examples}}
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
|
{{/examples}}
|
||||||
|
}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
{{^hasAuthMethods}}
|
||||||
|
{{#examples}}
|
||||||
|
{{#-first}}
|
||||||
|
{{>libraries/ktor/_response}}
|
||||||
|
{{/-first}}
|
||||||
|
{{/examples}}
|
||||||
|
{{^examples}}
|
||||||
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
|
{{/examples}}
|
||||||
|
{{/hasAuthMethods}}
|
@ -0,0 +1,11 @@
|
|||||||
|
{{#authMethods}}
|
||||||
|
{{#isBasic}}
|
||||||
|
val principal = call.authentication.principal<UserIdPrincipal>()
|
||||||
|
{{/isBasic}}
|
||||||
|
{{#isApiKey}}
|
||||||
|
val principal = call.authentication.principal<ApiPrincipal>()
|
||||||
|
{{/isApiKey}}
|
||||||
|
{{#isOAuth}}
|
||||||
|
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
|
||||||
|
{{/isOAuth}}
|
||||||
|
{{/authMethods}}
|
@ -0,0 +1,8 @@
|
|||||||
|
val exampleContentType = "{{{contentType}}}"
|
||||||
|
val exampleContentString = """{{&example}}"""
|
||||||
|
|
||||||
|
when(exampleContentType) {
|
||||||
|
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java))
|
||||||
|
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
|
||||||
|
else -> call.respondText(exampleContentString)
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
{{>licenseInfo}}
|
||||||
|
package {{apiPackage}}
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import io.ktor.application.call
|
||||||
|
import io.ktor.auth.UserIdPrincipal
|
||||||
|
import io.ktor.auth.authentication
|
||||||
|
import io.ktor.auth.authenticate
|
||||||
|
import io.ktor.auth.OAuthAccessTokenResponse
|
||||||
|
import io.ktor.auth.OAuthServerSettings
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
|
import io.ktor.locations.delete
|
||||||
|
import io.ktor.locations.get
|
||||||
|
import io.ktor.response.respond
|
||||||
|
import io.ktor.response.respondText
|
||||||
|
import io.ktor.routing.Route
|
||||||
|
import io.ktor.routing.post
|
||||||
|
import io.ktor.routing.put
|
||||||
|
import io.ktor.routing.route
|
||||||
|
|
||||||
|
import {{packageName}}.Paths
|
||||||
|
import {{packageName}}.infrastructure.ApiPrincipal
|
||||||
|
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
|
||||||
|
{{#operations}}
|
||||||
|
@KtorExperimentalLocationsAPI
|
||||||
|
fun Route.{{classname}}() {
|
||||||
|
val gson = Gson()
|
||||||
|
val empty = mutableMapOf<String, Any?>()
|
||||||
|
{{#operation}}
|
||||||
|
{{#bodyAllowed}}
|
||||||
|
|
||||||
|
route("{{path}}") {
|
||||||
|
{{#hasAuthMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
authenticate("{{{name}}}") {
|
||||||
|
{{/authMethods}}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}} {
|
||||||
|
{{#lambda.indented_12}}{{>libraries/ktor/_api_body}}{{/lambda.indented_12}}
|
||||||
|
}
|
||||||
|
{{#hasAuthMethods}}
|
||||||
|
}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
}
|
||||||
|
{{/bodyAllowed}}
|
||||||
|
{{^bodyAllowed}}
|
||||||
|
|
||||||
|
{{! NOTE: Locations can be used on routes without body parameters.}}
|
||||||
|
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}<Paths.{{operationId}}> { _: Paths.{{operationId}} ->
|
||||||
|
{{#lambda.indented_8}}{{>libraries/ktor/_api_body}}{{/lambda.indented_8}}
|
||||||
|
}
|
||||||
|
{{/bodyAllowed}}
|
||||||
|
|
||||||
|
{{/operation}}
|
||||||
|
}
|
||||||
|
{{/operations}}
|
@ -0,0 +1,27 @@
|
|||||||
|
ktor {
|
||||||
|
deployment {
|
||||||
|
environment = development
|
||||||
|
port = 8080
|
||||||
|
autoreload = true
|
||||||
|
watch = [ {{packageName}} ]
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
modules = [ {{packageName}}.AppMainKt.main ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Typesafe config allows multiple ways to provide configuration values without hard-coding them here.
|
||||||
|
# Please see https://github.com/lightbend/config for details.
|
||||||
|
auth {
|
||||||
|
oauth {
|
||||||
|
{{#authMethods}}
|
||||||
|
{{#isOAuth}}
|
||||||
|
{{name}} {
|
||||||
|
clientId = ""
|
||||||
|
clientSecret = ""
|
||||||
|
}
|
||||||
|
{{/isOAuth}}
|
||||||
|
{{/authMethods}}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
group '{{groupId}}'
|
||||||
|
version '{{artifactVersion}}'
|
||||||
|
|
||||||
|
wrapper {
|
||||||
|
gradleVersion = '4.9'
|
||||||
|
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.3.21'
|
||||||
|
ext.ktor_version = '1.1.3'
|
||||||
|
ext.shadow_version = '2.0.3'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url "https://repo1.maven.org/maven2" }
|
||||||
|
maven {
|
||||||
|
url = "https://plugins.gradle.org/m2/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
mainClassName = "io.ktor.server.netty.DevelopmentEngine"
|
||||||
|
|
||||||
|
// Initialization order with shadow 2.0.1 and Gradle 4.3 is weird.
|
||||||
|
// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508
|
||||||
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
baseName = '{{artifactId}}'
|
||||||
|
classifier = null
|
||||||
|
version = null
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url "https://repo1.maven.org/maven2" }
|
||||||
|
maven { url "https://dl.bintray.com/kotlin/ktor" }
|
||||||
|
maven { url "https://dl.bintray.com/kotlin/kotlinx" }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
|
compile "io.ktor:ktor-server-netty:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-metrics:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-locations:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-gson:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-client-core:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-client-apache:$ktor_version"
|
||||||
|
compile "ch.qos.logback:logback-classic:1.2.1"
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.13'
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
org.gradle.caching=true
|
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* {{{appName}}}
|
||||||
|
* {{{appDescription}}}
|
||||||
|
*
|
||||||
|
* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}}
|
||||||
|
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
@ -0,0 +1,15 @@
|
|||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="trace">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<logger name="org.eclipse.jetty" level="INFO"/>
|
||||||
|
<logger name="io.netty" level="INFO"/>
|
||||||
|
|
||||||
|
</configuration>
|
11
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache
vendored
Normal file
11
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* {{{appName}}}
|
||||||
|
* {{{appDescription}}}
|
||||||
|
*
|
||||||
|
* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}}
|
||||||
|
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
11
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache
vendored
Normal file
11
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{>licenseInfo}}
|
||||||
|
package {{modelPackage}}
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
|
||||||
|
{{#models}}
|
||||||
|
{{#model}}
|
||||||
|
{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{>data_class}}{{/isEnum}}
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
1
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{#modelMutable}}var{{/modelMutable}}{{^modelMutable}}val{{/modelMutable}}
|
3
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model_doc.mustache
vendored
Normal file
3
modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model_doc.mustache
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{{#models}}{{#model}}
|
||||||
|
{{#isEnum}}{{>enum_doc}}{{/isEnum}}{{^isEnum}}{{>class_doc}}{{/isEnum}}
|
||||||
|
{{/model}}{{/models}}
|
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = '{{artifactId}}'
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
## Requires
|
## Requires
|
||||||
|
|
||||||
* Kotlin 1.1.2
|
* Kotlin 1.4.31
|
||||||
* Gradle 3.3
|
* Gradle 6.8.2
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import java.io.Serializable
|
|||||||
{{#parcelizeModels}}
|
{{#parcelizeModels}}
|
||||||
@Parcelize
|
@Parcelize
|
||||||
{{/parcelizeModels}}
|
{{/parcelizeModels}}
|
||||||
data class {{classname}} (
|
data class {{classname}}(
|
||||||
{{#requiredVars}}
|
{{#requiredVars}}
|
||||||
{{>data_class_req_var}}{{^-last}},
|
{{>data_class_req_var}}{{^-last}},
|
||||||
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* {{{description}}}
|
* {{{description}}}
|
||||||
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
|
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||||
*/
|
*/
|
||||||
enum class {{classname}}(val value: {{dataType}}){
|
enum class {{classname}}(val value: {{dataType}}) {
|
||||||
{{#allowableValues}}{{#enumVars}}
|
{{#allowableValues}}{{#enumVars}}
|
||||||
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||||
{{/enumVars}}{{/allowableValues}}
|
{{/enumVars}}{{/allowableValues}}
|
||||||
|
@ -1,85 +1,105 @@
|
|||||||
package {{packageName}}.infrastructure
|
package {{packageName}}.infrastructure
|
||||||
|
|
||||||
import io.ktor.application.ApplicationCall
|
import io.ktor.application.*
|
||||||
import io.ktor.application.call
|
import io.ktor.auth.*
|
||||||
import io.ktor.auth.Authentication
|
import io.ktor.http.auth.*
|
||||||
import io.ktor.auth.AuthenticationFailedCause
|
import io.ktor.request.*
|
||||||
import io.ktor.auth.AuthenticationPipeline
|
import io.ktor.response.*
|
||||||
import io.ktor.auth.AuthenticationProvider
|
|
||||||
import io.ktor.auth.Credential
|
|
||||||
import io.ktor.auth.Principal
|
|
||||||
import io.ktor.auth.UnauthorizedResponse
|
|
||||||
import io.ktor.http.auth.HeaderValueEncoding
|
|
||||||
import io.ktor.http.auth.HttpAuthHeader
|
|
||||||
import io.ktor.request.ApplicationRequest
|
|
||||||
import io.ktor.response.respond
|
|
||||||
|
|
||||||
enum class ApiKeyLocation(val location: String) {
|
enum class ApiKeyLocation(val location: String) {
|
||||||
QUERY("query"),
|
QUERY("query"),
|
||||||
HEADER("header")
|
HEADER("header")
|
||||||
}
|
}
|
||||||
data class ApiKeyCredential(val value: String): Credential
|
|
||||||
|
data class ApiKeyCredential(val value: String) : Credential
|
||||||
data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal
|
data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Api Key authentication provider
|
* Represents a Api Key authentication provider
|
||||||
* @param name is the name of the provider, or `null` for a default provider
|
* @param name is the name of the provider, or `null` for a default provider
|
||||||
*/
|
*/
|
||||||
class ApiKeyAuthenticationProvider(name: String?) : AuthenticationProvider(name) {
|
class ApiKeyAuthenticationProvider(configuration: Configuration) : AuthenticationProvider(configuration) {
|
||||||
internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = { null }
|
|
||||||
|
|
||||||
var apiKeyName: String = "";
|
private val authenticationFunction = configuration.authenticationFunction
|
||||||
|
|
||||||
var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY;
|
private val apiKeyName: String = configuration.apiKeyName
|
||||||
|
|
||||||
/**
|
private val apiKeyLocation: ApiKeyLocation = configuration.apiKeyLocation
|
||||||
* Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal],
|
|
||||||
* or null if credential does not correspond to an authenticated principal
|
|
||||||
*/
|
|
||||||
fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) {
|
|
||||||
authenticationFunction = body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Authentication.Configuration.apiKeyAuth(name: String? = null, configure: ApiKeyAuthenticationProvider.() -> Unit) {
|
internal fun install() {
|
||||||
val provider = ApiKeyAuthenticationProvider(name).apply(configure)
|
pipeline.intercept(AuthenticationPipeline.RequestAuthentication) { context ->
|
||||||
val apiKeyName = provider.apiKeyName
|
val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation)
|
||||||
val apiKeyLocation = provider.apiKeyLocation
|
val principal = credentials?.let { authenticationFunction(call, it) }
|
||||||
val authenticate = provider.authenticationFunction
|
|
||||||
|
|
||||||
provider.pipeline.intercept(AuthenticationPipeline.RequestAuthentication) { context ->
|
val cause = when {
|
||||||
val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation)
|
credentials == null -> AuthenticationFailedCause.NoCredentials
|
||||||
val principal = credentials?.let { authenticate(call, it) }
|
principal == null -> AuthenticationFailedCause.InvalidCredentials
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
val cause = when {
|
if (cause != null) {
|
||||||
credentials == null -> AuthenticationFailedCause.NoCredentials
|
context.challenge(apiKeyName, cause) {
|
||||||
principal == null -> AuthenticationFailedCause.InvalidCredentials
|
call.respond(
|
||||||
else -> null
|
UnauthorizedResponse(
|
||||||
}
|
HttpAuthHeader.Parameterized(
|
||||||
|
"API_KEY",
|
||||||
|
mapOf("key" to apiKeyName),
|
||||||
|
HeaderValueEncoding.QUOTED_ALWAYS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
it.complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cause != null) {
|
if (principal != null) {
|
||||||
context.challenge(apiKeyName, cause) {
|
context.principal(principal)
|
||||||
// TODO: Verify correct response structure here.
|
|
||||||
call.respond(UnauthorizedResponse(HttpAuthHeader.Parameterized("API_KEY", mapOf("key" to apiKeyName), HeaderValueEncoding.QUOTED_ALWAYS)))
|
|
||||||
it.complete()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (principal != null) {
|
class Configuration internal constructor(name: String?) : AuthenticationProvider.Configuration(name) {
|
||||||
context.principal(principal)
|
|
||||||
|
internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = {
|
||||||
|
throw NotImplementedError(
|
||||||
|
"Api Key auth validate function is not specified. Use apiKeyAuth { validate { ... } } to fix."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiKeyName: String = ""
|
||||||
|
|
||||||
|
var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal],
|
||||||
|
* or null if credential does not correspond to an authenticated principal
|
||||||
|
*/
|
||||||
|
fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) {
|
||||||
|
authenticationFunction = body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ApplicationRequest.apiKeyAuthenticationCredentials(apiKeyName: String, apiKeyLocation: ApiKeyLocation): ApiKeyCredential? {
|
fun Authentication.Configuration.apiKeyAuth(
|
||||||
val value: String? = when(apiKeyLocation) {
|
name: String? = null,
|
||||||
|
configure: ApiKeyAuthenticationProvider.Configuration.() -> Unit
|
||||||
|
) {
|
||||||
|
val configuration = ApiKeyAuthenticationProvider.Configuration(name).apply(configure)
|
||||||
|
val provider = ApiKeyAuthenticationProvider(configuration)
|
||||||
|
provider.install()
|
||||||
|
register(provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ApplicationRequest.apiKeyAuthenticationCredentials(
|
||||||
|
apiKeyName: String,
|
||||||
|
apiKeyLocation: ApiKeyLocation
|
||||||
|
): ApiKeyCredential? {
|
||||||
|
val value: String? = when (apiKeyLocation) {
|
||||||
ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName]
|
ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName]
|
||||||
ApiKeyLocation.HEADER -> this.headers[apiKeyName]
|
ApiKeyLocation.HEADER -> this.headers[apiKeyName]
|
||||||
}
|
}
|
||||||
when (value) {
|
return when (value) {
|
||||||
null -> return null
|
null -> null
|
||||||
else -> return ApiKeyCredential(value)
|
else -> ApiKeyCredential(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,15 +28,16 @@ import io.ktor.features.HSTS
|
|||||||
{{/featureHSTS}}
|
{{/featureHSTS}}
|
||||||
import io.ktor.gson.GsonConverter
|
import io.ktor.gson.GsonConverter
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
|
{{#featureLocations}}
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.locations.Locations
|
import io.ktor.locations.Locations
|
||||||
import io.ktor.metrics.Metrics
|
{{/featureLocations}}
|
||||||
import io.ktor.routing.Routing
|
import io.ktor.routing.Routing
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
|
||||||
{{#hasAuthMethods}}
|
{{#hasAuthMethods}}
|
||||||
import io.ktor.auth.Authentication
|
import io.ktor.auth.Authentication
|
||||||
import io.ktor.auth.oauth
|
import io.ktor.auth.oauth
|
||||||
|
import io.ktor.metrics.dropwizard.DropwizardMetrics
|
||||||
import org.openapitools.server.infrastructure.ApiKeyCredential
|
import org.openapitools.server.infrastructure.ApiKeyCredential
|
||||||
import org.openapitools.server.infrastructure.ApiPrincipal
|
import org.openapitools.server.infrastructure.ApiPrincipal
|
||||||
import org.openapitools.server.infrastructure.apiKeyAuth
|
import org.openapitools.server.infrastructure.apiKeyAuth
|
||||||
@ -44,23 +45,23 @@ import org.openapitools.server.infrastructure.apiKeyAuth
|
|||||||
{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}}
|
{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}}
|
||||||
{{/apis}}{{/apiInfo}}{{/generateApis}}
|
{{/apis}}{{/apiInfo}}{{/generateApis}}
|
||||||
|
|
||||||
@KtorExperimentalAPI
|
|
||||||
internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader))
|
internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader))
|
||||||
|
|
||||||
object HTTP {
|
object HTTP {
|
||||||
val client = HttpClient(Apache)
|
val client = HttpClient(Apache)
|
||||||
}
|
}
|
||||||
|
|
||||||
@KtorExperimentalAPI
|
{{#featureLocations}}
|
||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
|
{{/featureLocations}}
|
||||||
fun Application.main() {
|
fun Application.main() {
|
||||||
install(DefaultHeaders)
|
install(DefaultHeaders)
|
||||||
install(Metrics) {
|
install(DropwizardMetrics) {
|
||||||
val reporter = Slf4jReporter.forRegistry(registry)
|
val reporter = Slf4jReporter.forRegistry(registry)
|
||||||
.outputTo(log)
|
.outputTo(log)
|
||||||
.convertRatesTo(TimeUnit.SECONDS)
|
.convertRatesTo(TimeUnit.SECONDS)
|
||||||
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||||
.build()
|
.build()
|
||||||
reporter.start(10, TimeUnit.SECONDS)
|
reporter.start(10, TimeUnit.SECONDS)
|
||||||
}
|
}
|
||||||
{{#generateApis}}
|
{{#generateApis}}
|
||||||
@ -82,7 +83,9 @@ fun Application.main() {
|
|||||||
{{#featureCompression}}
|
{{#featureCompression}}
|
||||||
install(Compression, ApplicationCompressionConfiguration()) // see http://ktor.io/features/compression.html
|
install(Compression, ApplicationCompressionConfiguration()) // see http://ktor.io/features/compression.html
|
||||||
{{/featureCompression}}
|
{{/featureCompression}}
|
||||||
|
{{#featureLocations}}
|
||||||
install(Locations) // see http://ktor.io/features/locations.html
|
install(Locations) // see http://ktor.io/features/locations.html
|
||||||
|
{{/featureLocations}}
|
||||||
{{#hasAuthMethods}}
|
{{#hasAuthMethods}}
|
||||||
install(Authentication) {
|
install(Authentication) {
|
||||||
{{#authMethods}}
|
{{#authMethods}}
|
||||||
@ -117,8 +120,8 @@ fun Application.main() {
|
|||||||
client = HttpClient(Apache)
|
client = HttpClient(Apache)
|
||||||
providerLookup = { ApplicationAuthProviders["{{{name}}}"] }
|
providerLookup = { ApplicationAuthProviders["{{{name}}}"] }
|
||||||
urlProvider = { _ ->
|
urlProvider = { _ ->
|
||||||
// TODO: define a callback url here.
|
// TODO: define a callback url here.
|
||||||
"/"
|
"/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/bodyAllowed}}
|
{{/bodyAllowed}}
|
||||||
@ -138,8 +141,7 @@ fun Application.main() {
|
|||||||
|
|
||||||
{{/generateApis}}
|
{{/generateApis}}
|
||||||
|
|
||||||
environment.monitor.subscribe(ApplicationStopping)
|
environment.monitor.subscribe(ApplicationStopping) {
|
||||||
{
|
|
||||||
HTTP.client.close()
|
HTTP.client.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,7 @@ import io.ktor.features.deflate
|
|||||||
import io.ktor.features.gzip
|
import io.ktor.features.gzip
|
||||||
import io.ktor.features.minimumSize
|
import io.ktor.features.minimumSize
|
||||||
import io.ktor.http.HttpMethod
|
import io.ktor.http.HttpMethod
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
import java.util.concurrent.TimeUnit
|
||||||
import java.time.Duration
|
|
||||||
import java.util.concurrent.Executors
|
|
||||||
|
|
||||||
import {{packageName}}.settings
|
|
||||||
|
|
||||||
{{#featureCORS}}
|
{{#featureCORS}}
|
||||||
/**
|
/**
|
||||||
@ -49,7 +45,7 @@ internal fun ApplicationCORSConfiguration(): CORS.Configuration.() -> Unit {
|
|||||||
*/
|
*/
|
||||||
internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit {
|
internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit {
|
||||||
return {
|
return {
|
||||||
maxAge = Duration.ofDays(365)
|
maxAgeInSeconds = TimeUnit.DAYS.toSeconds(365)
|
||||||
includeSubDomains = true
|
includeSubDomains = true
|
||||||
preload = false
|
preload = false
|
||||||
|
|
||||||
@ -82,7 +78,6 @@ internal fun ApplicationCompressionConfiguration(): Compression.Configuration.()
|
|||||||
{{/featureCompression}}
|
{{/featureCompression}}
|
||||||
|
|
||||||
// Defines authentication mechanisms used throughout the application.
|
// Defines authentication mechanisms used throughout the application.
|
||||||
@KtorExperimentalAPI
|
|
||||||
val ApplicationAuthProviders: Map<String, OAuthServerSettings> = listOf<OAuthServerSettings>(
|
val ApplicationAuthProviders: Map<String, OAuthServerSettings> = listOf<OAuthServerSettings>(
|
||||||
{{#authMethods}}
|
{{#authMethods}}
|
||||||
{{#isOAuth}}
|
{{#isOAuth}}
|
||||||
@ -109,6 +104,3 @@ val ApplicationAuthProviders: Map<String, OAuthServerSettings> = listOf<OAuthSer
|
|||||||
// defaultScopes = listOf("public_profile")
|
// defaultScopes = listOf("public_profile")
|
||||||
// )
|
// )
|
||||||
).associateBy { it.name }
|
).associateBy { it.name }
|
||||||
|
|
||||||
// Provides an application-level fixed thread pool on which to execute coroutines (mainly)
|
|
||||||
internal val ApplicationExecutors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4)
|
|
||||||
|
@ -3,6 +3,7 @@ package {{packageName}}
|
|||||||
|
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.locations.Location
|
import io.ktor.locations.Location
|
||||||
|
import {{packageName}}.models.*
|
||||||
{{#imports}}import {{import}}
|
{{#imports}}import {{import}}
|
||||||
{{/imports}}
|
{{/imports}}
|
||||||
|
|
||||||
@ -11,7 +12,6 @@ object Paths {
|
|||||||
{{#apis}}
|
{{#apis}}
|
||||||
{{#operations}}
|
{{#operations}}
|
||||||
{{#operation}}
|
{{#operation}}
|
||||||
{{^bodyAllowed}}
|
|
||||||
/**
|
/**
|
||||||
* {{summary}}
|
* {{summary}}
|
||||||
* {{#unescapedNotes}}{{.}}{{/unescapedNotes}}
|
* {{#unescapedNotes}}{{.}}{{/unescapedNotes}}
|
||||||
@ -20,7 +20,6 @@ object Paths {
|
|||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
@Location("{{path}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
@Location("{{path}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||||
|
|
||||||
{{/bodyAllowed}}
|
|
||||||
{{/operation}}
|
{{/operation}}
|
||||||
{{/operations}}
|
{{/operations}}
|
||||||
{{/apis}}
|
{{/apis}}
|
||||||
|
@ -8,8 +8,8 @@ Generated by OpenAPI Generator {{generatorVersion}}{{^hideGenerationTimestamp}}
|
|||||||
|
|
||||||
## Requires
|
## Requires
|
||||||
|
|
||||||
* Kotlin 1.3.21
|
* Kotlin 1.4.31
|
||||||
* Gradle 4.9
|
* Gradle 6.8.2
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
{{#hasAuthMethods}}
|
{{#hasAuthMethods}}
|
||||||
{{>libraries/ktor/_principal}}
|
{{>libraries/ktor/_principal}}
|
||||||
if (principal == null) {
|
{{#examples}}
|
||||||
call.respond(HttpStatusCode.Unauthorized)
|
{{#-first}}
|
||||||
} else {
|
{{#lambda.indented}}{{>_response}}{{/lambda.indented}}
|
||||||
{{#examples}}
|
{{/-first}}
|
||||||
{{#-first}}
|
{{/examples}}
|
||||||
{{#lambda.indented}}{{>_response}}{{/lambda.indented}}
|
{{^examples}}
|
||||||
{{/-first}}
|
call.respond(HttpStatusCode.NotImplemented)
|
||||||
{{/examples}}
|
{{/examples}}
|
||||||
{{^examples}}
|
|
||||||
call.respond(HttpStatusCode.NotImplemented)
|
|
||||||
{{/examples}}
|
|
||||||
}
|
|
||||||
{{/hasAuthMethods}}
|
{{/hasAuthMethods}}
|
||||||
{{^hasAuthMethods}}
|
{{^hasAuthMethods}}
|
||||||
{{#examples}}
|
{{#examples}}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
{{#authMethods}}
|
{{#authMethods}}
|
||||||
{{#isBasic}}
|
{{#isBasic}}
|
||||||
val principal = call.authentication.principal<UserIdPrincipal>()
|
val principal = call.authentication.principal<UserIdPrincipal>()!!
|
||||||
{{/isBasic}}
|
{{/isBasic}}
|
||||||
{{#isApiKey}}
|
{{#isApiKey}}
|
||||||
val principal = call.authentication.principal<ApiPrincipal>()
|
val principal = call.authentication.principal<ApiPrincipal>()!!
|
||||||
{{/isApiKey}}
|
{{/isApiKey}}
|
||||||
{{#isOAuth}}
|
{{#isOAuth}}
|
||||||
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
|
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!!
|
||||||
{{/isOAuth}}
|
{{/isOAuth}}
|
||||||
{{/authMethods}}
|
{{/authMethods}}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
val exampleContentType = "{{{contentType}}}"
|
val exampleContentType = "{{{contentType}}}"
|
||||||
val exampleContentString = """{{&example}}"""
|
val exampleContentString = """{{&example}}"""
|
||||||
|
|
||||||
when(exampleContentType) {
|
when (exampleContentType) {
|
||||||
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java))
|
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java))
|
||||||
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
|
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
|
||||||
else -> call.respondText(exampleContentString)
|
else -> call.respondText(exampleContentString)
|
||||||
|
@ -10,17 +10,29 @@ import io.ktor.auth.OAuthAccessTokenResponse
|
|||||||
import io.ktor.auth.OAuthServerSettings
|
import io.ktor.auth.OAuthServerSettings
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
|
||||||
import io.ktor.locations.delete
|
|
||||||
import io.ktor.locations.get
|
|
||||||
import io.ktor.response.respond
|
import io.ktor.response.respond
|
||||||
import io.ktor.response.respondText
|
import io.ktor.response.respondText
|
||||||
import io.ktor.routing.Route
|
import io.ktor.routing.Route
|
||||||
|
{{#featureLocations}}
|
||||||
|
import {{packageName}}.Paths
|
||||||
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
|
import io.ktor.locations.delete
|
||||||
|
import io.ktor.locations.get
|
||||||
|
import io.ktor.locations.post
|
||||||
|
import io.ktor.locations.put
|
||||||
|
import io.ktor.locations.options
|
||||||
|
import io.ktor.locations.head
|
||||||
|
{{/featureLocations}}
|
||||||
|
{{^featureLocations}}
|
||||||
|
import io.ktor.routing.delete
|
||||||
|
import io.ktor.routing.get
|
||||||
import io.ktor.routing.post
|
import io.ktor.routing.post
|
||||||
import io.ktor.routing.put
|
import io.ktor.routing.put
|
||||||
|
import io.ktor.routing.options
|
||||||
|
import io.ktor.routing.head
|
||||||
import io.ktor.routing.route
|
import io.ktor.routing.route
|
||||||
|
{{/featureLocations}}
|
||||||
|
|
||||||
import {{packageName}}.Paths
|
|
||||||
import {{packageName}}.infrastructure.ApiPrincipal
|
import {{packageName}}.infrastructure.ApiPrincipal
|
||||||
|
|
||||||
|
|
||||||
@ -28,34 +40,33 @@ import {{packageName}}.infrastructure.ApiPrincipal
|
|||||||
{{/imports}}
|
{{/imports}}
|
||||||
|
|
||||||
{{#operations}}
|
{{#operations}}
|
||||||
|
{{#featureLocations}}
|
||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
|
{{/featureLocations}}
|
||||||
fun Route.{{classname}}() {
|
fun Route.{{classname}}() {
|
||||||
val gson = Gson()
|
val gson = Gson()
|
||||||
val empty = mutableMapOf<String, Any?>()
|
val empty = mutableMapOf<String, Any?>()
|
||||||
{{#operation}}
|
{{#operation}}
|
||||||
{{#bodyAllowed}}
|
{{#hasAuthMethods}}
|
||||||
|
{{#authMethods}}
|
||||||
|
authenticate("{{{name}}}") {
|
||||||
|
{{/authMethods}}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
{{^featureLocations}}
|
||||||
route("{{path}}") {
|
route("{{path}}") {
|
||||||
{{#hasAuthMethods}}
|
|
||||||
{{#authMethods}}
|
|
||||||
authenticate("{{{name}}}") {
|
|
||||||
{{/authMethods}}
|
|
||||||
{{/hasAuthMethods}}
|
|
||||||
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}} {
|
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}} {
|
||||||
{{#lambda.indented_12}}{{>libraries/ktor/_api_body}}{{/lambda.indented_12}}
|
{{#lambda.indented_12}}{{>libraries/ktor/_api_body}}{{/lambda.indented_12}}
|
||||||
}
|
}
|
||||||
{{#hasAuthMethods}}
|
|
||||||
}
|
|
||||||
{{/hasAuthMethods}}
|
|
||||||
}
|
}
|
||||||
{{/bodyAllowed}}
|
{{/featureLocations}}
|
||||||
{{^bodyAllowed}}
|
{{#featureLocations}}
|
||||||
|
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}<Paths.{{operationId}}> {
|
||||||
{{! NOTE: Locations can be used on routes without body parameters.}}
|
|
||||||
{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}<Paths.{{operationId}}> { _: Paths.{{operationId}} ->
|
|
||||||
{{#lambda.indented_8}}{{>libraries/ktor/_api_body}}{{/lambda.indented_8}}
|
{{#lambda.indented_8}}{{>libraries/ktor/_api_body}}{{/lambda.indented_8}}
|
||||||
}
|
}
|
||||||
{{/bodyAllowed}}
|
{{/featureLocations}}
|
||||||
|
{{#hasAuthMethods}}
|
||||||
|
}
|
||||||
|
{{/hasAuthMethods}}
|
||||||
|
|
||||||
{{/operation}}
|
{{/operation}}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ group '{{groupId}}'
|
|||||||
version '{{artifactVersion}}'
|
version '{{artifactVersion}}'
|
||||||
|
|
||||||
wrapper {
|
wrapper {
|
||||||
gradleVersion = '4.9'
|
gradleVersion = '6.8.2'
|
||||||
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
|
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.21'
|
ext.kotlin_version = '1.4.31'
|
||||||
ext.ktor_version = '1.1.3'
|
ext.ktor_version = '1.5.2'
|
||||||
ext.shadow_version = '2.0.3'
|
ext.shadow_version = '2.0.3'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -29,7 +29,7 @@ apply plugin: 'application'
|
|||||||
|
|
||||||
mainClassName = "io.ktor.server.netty.DevelopmentEngine"
|
mainClassName = "io.ktor.server.netty.DevelopmentEngine"
|
||||||
|
|
||||||
// Initialization order with shadow 2.0.1 and Gradle 4.3 is weird.
|
// Initialization order with shadow 2.0.1 and Gradle 6.8.2 is weird.
|
||||||
// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508
|
// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
@ -59,7 +59,10 @@ dependencies {
|
|||||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
compile "io.ktor:ktor-server-netty:$ktor_version"
|
compile "io.ktor:ktor-server-netty:$ktor_version"
|
||||||
compile "io.ktor:ktor-metrics:$ktor_version"
|
compile "io.ktor:ktor-metrics:$ktor_version"
|
||||||
|
compile "io.ktor:ktor-auth:$ktor_version"
|
||||||
|
{{#featureLocations}}
|
||||||
compile "io.ktor:ktor-locations:$ktor_version"
|
compile "io.ktor:ktor-locations:$ktor_version"
|
||||||
|
{{/featureLocations}}
|
||||||
compile "io.ktor:ktor-gson:$ktor_version"
|
compile "io.ktor:ktor-gson:$ktor_version"
|
||||||
compile "io.ktor:ktor-client-core:$ktor_version"
|
compile "io.ktor:ktor-client-core:$ktor_version"
|
||||||
compile "io.ktor:ktor-client-apache:$ktor_version"
|
compile "io.ktor:ktor-client-apache:$ktor_version"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* {{{appName}}}
|
* {{{appName}}}
|
||||||
* {{{appDescription}}}
|
* {{{appDescription}}}
|
||||||
*
|
*
|
||||||
* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}}
|
* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}}
|
||||||
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
@ -28,9 +28,9 @@ Name | Type | Description | Notes
|
|||||||
{{#optionalVars}}
|
{{#optionalVars}}
|
||||||
**{{name}}** | {{^complexType}}**{{dataType}}**{{/complexType}}{{#complexType}}[**{{dataType}}**]({{complexType}}.md){{/complexType}} | {{description}} | [optional] {{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}}
|
**{{name}}** | {{^complexType}}**{{dataType}}**{{/complexType}}{{#complexType}}[**{{dataType}}**]({{complexType}}.md){{/complexType}} | {{description}} | [optional] {{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}}
|
||||||
{{/optionalVars}}
|
{{/optionalVars}}
|
||||||
{{#additionalPropertiesType}}
|
{{#additionalProperties}}
|
||||||
**any string name** | **{{additionalPropertiesType}}** | any string name can be used but the value must be the correct type | [optional]
|
**any string name** | {{^complexType}}**{{dataType}}**{{/complexType}}{{#complexType}}[**{{dataType}}**]({{complexType}}.md){{/complexType}} | any string name can be used but the value must be the correct type | [optional]
|
||||||
{{/additionalPropertiesType}}
|
{{/additionalProperties}}
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
{{/optionalVars}}
|
{{/optionalVars}}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{#additionalPropertiesType}}
|
{{#additionalProperties}}
|
||||||
@cached_property
|
@cached_property
|
||||||
def additional_properties_type():
|
def additional_properties_type():
|
||||||
"""
|
"""
|
||||||
@ -72,11 +72,11 @@
|
|||||||
lazy_import()
|
lazy_import()
|
||||||
{{/-first}}
|
{{/-first}}
|
||||||
{{/imports}}
|
{{/imports}}
|
||||||
return ({{{additionalPropertiesType}}},) # noqa: E501
|
return ({{{dataType}}},) # noqa: E501
|
||||||
{{/additionalPropertiesType}}
|
{{/additionalProperties}}
|
||||||
{{^additionalPropertiesType}}
|
{{^additionalProperties}}
|
||||||
additional_properties_type = None
|
additional_properties_type = None
|
||||||
{{/additionalPropertiesType}}
|
{{/additionalProperties}}
|
||||||
|
|
||||||
_nullable = {{#isNullable}}True{{/isNullable}}{{^isNullable}}False{{/isNullable}}
|
_nullable = {{#isNullable}}True{{/isNullable}}{{^isNullable}}False{{/isNullable}}
|
||||||
|
|
||||||
|
@ -10,7 +10,52 @@
|
|||||||
'_additional_properties_model_instances',
|
'_additional_properties_model_instances',
|
||||||
])
|
])
|
||||||
|
|
||||||
{{> model_templates/method_init_shared }}
|
@convert_js_args_to_python_args
|
||||||
|
def __init__(self, *args, **kwargs): # noqa: E501
|
||||||
|
"""{{classname}} - a model defined in OpenAPI
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
{{#requiredVars}}
|
||||||
|
{{#defaultValue}}
|
||||||
|
{{name}} ({{{dataType}}}):{{#description}} {{{description}}}.{{/description}} defaults to {{{defaultValue}}}{{#allowableValues}}, must be one of [{{#enumVars}}{{{value}}}, {{/enumVars}}]{{/allowableValues}} # noqa: E501
|
||||||
|
{{/defaultValue}}
|
||||||
|
{{^defaultValue}}
|
||||||
|
{{name}} ({{{dataType}}}):{{#description}} {{{description}}}{{/description}}
|
||||||
|
{{/defaultValue}}
|
||||||
|
{{/requiredVars}}
|
||||||
|
{{> model_templates/docstring_init_required_kwargs }}
|
||||||
|
{{#optionalVars}}
|
||||||
|
{{name}} ({{{dataType}}}):{{#description}} {{{description}}}.{{/description}} [optional]{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}} # noqa: E501
|
||||||
|
{{/optionalVars}}
|
||||||
|
"""
|
||||||
|
|
||||||
|
{{#requiredVars}}
|
||||||
|
{{#defaultValue}}
|
||||||
|
{{name}} = kwargs.get('{{name}}', {{{defaultValue}}})
|
||||||
|
{{/defaultValue}}
|
||||||
|
{{/requiredVars}}
|
||||||
|
_check_type = kwargs.pop('_check_type', True)
|
||||||
|
_spec_property_naming = kwargs.pop('_spec_property_naming', False)
|
||||||
|
_path_to_item = kwargs.pop('_path_to_item', ())
|
||||||
|
_configuration = kwargs.pop('_configuration', None)
|
||||||
|
_visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
|
||||||
|
|
||||||
|
if args:
|
||||||
|
raise ApiTypeError(
|
||||||
|
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
|
||||||
|
args,
|
||||||
|
self.__class__.__name__,
|
||||||
|
),
|
||||||
|
path_to_item=_path_to_item,
|
||||||
|
valid_classes=(self.__class__,),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._data_store = {}
|
||||||
|
self._check_type = _check_type
|
||||||
|
self._spec_property_naming = _spec_property_naming
|
||||||
|
self._path_to_item = _path_to_item
|
||||||
|
self._configuration = _configuration
|
||||||
|
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
|
||||||
|
|
||||||
constant_args = {
|
constant_args = {
|
||||||
'_check_type': _check_type,
|
'_check_type': _check_type,
|
||||||
@ -19,28 +64,18 @@
|
|||||||
'_configuration': _configuration,
|
'_configuration': _configuration,
|
||||||
'_visited_composed_classes': self._visited_composed_classes,
|
'_visited_composed_classes': self._visited_composed_classes,
|
||||||
}
|
}
|
||||||
required_args = {
|
|
||||||
{{#requiredVars}}
|
|
||||||
'{{name}}': {{name}},
|
|
||||||
{{/requiredVars}}
|
|
||||||
}
|
|
||||||
model_args = {}
|
|
||||||
model_args.update(required_args)
|
|
||||||
model_args.update(kwargs)
|
|
||||||
composed_info = validate_get_composed_info(
|
composed_info = validate_get_composed_info(
|
||||||
constant_args, model_args, self)
|
constant_args, kwargs, self)
|
||||||
self._composed_instances = composed_info[0]
|
self._composed_instances = composed_info[0]
|
||||||
self._var_name_to_model_instances = composed_info[1]
|
self._var_name_to_model_instances = composed_info[1]
|
||||||
self._additional_properties_model_instances = composed_info[2]
|
self._additional_properties_model_instances = composed_info[2]
|
||||||
unused_args = composed_info[3]
|
discarded_args = composed_info[3]
|
||||||
|
|
||||||
for var_name, var_value in required_args.items():
|
|
||||||
setattr(self, var_name, var_value)
|
|
||||||
for var_name, var_value in kwargs.items():
|
for var_name, var_value in kwargs.items():
|
||||||
if var_name in unused_args and \
|
if var_name in discarded_args and \
|
||||||
self._configuration is not None and \
|
self._configuration is not None and \
|
||||||
self._configuration.discard_unknown_keys and \
|
self._configuration.discard_unknown_keys and \
|
||||||
not self._additional_properties_model_instances:
|
self._additional_properties_model_instances:
|
||||||
# discard variable.
|
# discard variable.
|
||||||
continue
|
continue
|
||||||
setattr(self, var_name, var_value)
|
setattr(self, var_name, var_value)
|
@ -4,27 +4,43 @@
|
|||||||
self.__dict__[name] = value
|
self.__dict__[name] = value
|
||||||
return
|
return
|
||||||
|
|
||||||
# set the attribute on the correct instance
|
"""
|
||||||
model_instances = self._var_name_to_model_instances.get(
|
Use cases:
|
||||||
name, self._additional_properties_model_instances)
|
1. additional_properties_type is None (additionalProperties == False in spec)
|
||||||
if model_instances:
|
Check for property presence in self.openapi_types
|
||||||
for model_instance in model_instances:
|
if not present then throw an error
|
||||||
if model_instance == self:
|
if present set in self, set attribute
|
||||||
self.set_attribute(name, value)
|
always set on composed schemas
|
||||||
else:
|
2. additional_properties_type exists
|
||||||
setattr(model_instance, name, value)
|
set attribute on self
|
||||||
if name not in self._var_name_to_model_instances:
|
always set on composed schemas
|
||||||
# we assigned an additional property
|
"""
|
||||||
self.__dict__['_var_name_to_model_instances'][name] = (
|
if self.additional_properties_type is None:
|
||||||
model_instance
|
"""
|
||||||
)
|
For an attribute to exist on a composed schema it must:
|
||||||
return None
|
- fulfill schema_requirements in the self composed schema not considering oneOf/anyOf/allOf schemas AND
|
||||||
|
- fulfill schema_requirements in each oneOf/anyOf/allOf schemas
|
||||||
|
|
||||||
raise ApiAttributeError(
|
schema_requirements:
|
||||||
"{0} has no attribute '{1}'".format(
|
For an attribute to exist on a schema it must:
|
||||||
type(self).__name__, name),
|
- be present in properties at the schema OR
|
||||||
[e for e in [self._path_to_item, name] if e]
|
- have additionalProperties unset (defaults additionalProperties = any type) OR
|
||||||
)
|
- have additionalProperties set
|
||||||
|
"""
|
||||||
|
if name not in self.openapi_types:
|
||||||
|
raise ApiAttributeError(
|
||||||
|
"{0} has no attribute '{1}'".format(
|
||||||
|
type(self).__name__, name),
|
||||||
|
[e for e in [self._path_to_item, name] if e]
|
||||||
|
)
|
||||||
|
# attribute must be set on self and composed instances
|
||||||
|
self.set_attribute(name, value)
|
||||||
|
for model_instance in self._composed_instances:
|
||||||
|
setattr(model_instance, name, value)
|
||||||
|
if name not in self._var_name_to_model_instances:
|
||||||
|
# we assigned an additional property
|
||||||
|
self.__dict__['_var_name_to_model_instances'][name] = self._composed_instances + [self]
|
||||||
|
return None
|
||||||
|
|
||||||
__unset_attribute_value__ = object()
|
__unset_attribute_value__ = object()
|
||||||
|
|
||||||
@ -34,13 +50,12 @@
|
|||||||
return self.__dict__[name]
|
return self.__dict__[name]
|
||||||
|
|
||||||
# get the attribute from the correct instance
|
# get the attribute from the correct instance
|
||||||
model_instances = self._var_name_to_model_instances.get(
|
model_instances = self._var_name_to_model_instances.get(name)
|
||||||
name, self._additional_properties_model_instances)
|
|
||||||
values = []
|
values = []
|
||||||
# A composed model stores child (oneof/anyOf/allOf) models under
|
# A composed model stores self and child (oneof/anyOf/allOf) models under
|
||||||
# self._var_name_to_model_instances. A named property can exist in
|
# self._var_name_to_model_instances.
|
||||||
# multiple child models. If the property is present in more than one
|
# Any property must exist in self and all model instances
|
||||||
# child model, the value must be the same across all the child models.
|
# The value stored in all model instances must be the same
|
||||||
if model_instances:
|
if model_instances:
|
||||||
for model_instance in model_instances:
|
for model_instance in model_instances:
|
||||||
if name in model_instance._data_store:
|
if name in model_instance._data_store:
|
||||||
|
@ -1302,8 +1302,13 @@ def get_allof_instances(self, model_args, constant_args):
|
|||||||
self: the class we are handling
|
self: the class we are handling
|
||||||
model_args (dict): var_name to var_value
|
model_args (dict): var_name to var_value
|
||||||
used to make instances
|
used to make instances
|
||||||
constant_args (dict): var_name to var_value
|
constant_args (dict):
|
||||||
used to make instances
|
metadata arguments:
|
||||||
|
_check_type
|
||||||
|
_path_to_item
|
||||||
|
_spec_property_naming
|
||||||
|
_configuration
|
||||||
|
_visited_composed_classes
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
composed_instances (list)
|
composed_instances (list)
|
||||||
@ -1311,20 +1316,8 @@ def get_allof_instances(self, model_args, constant_args):
|
|||||||
composed_instances = []
|
composed_instances = []
|
||||||
for allof_class in self._composed_schemas['allOf']:
|
for allof_class in self._composed_schemas['allOf']:
|
||||||
|
|
||||||
# no need to handle changing js keys to python because
|
|
||||||
# for composed schemas, allof parameters are included in the
|
|
||||||
# composed schema and were changed to python keys in __new__
|
|
||||||
# extract a dict of only required keys from fixed_model_args
|
|
||||||
kwargs = {}
|
|
||||||
var_names = set(allof_class.openapi_types.keys())
|
|
||||||
for var_name in var_names:
|
|
||||||
if var_name in model_args:
|
|
||||||
kwargs[var_name] = model_args[var_name]
|
|
||||||
|
|
||||||
# and use it to make the instance
|
|
||||||
kwargs.update(constant_args)
|
|
||||||
try:
|
try:
|
||||||
allof_instance = allof_class(**kwargs)
|
allof_instance = allof_class(**model_args, **constant_args)
|
||||||
composed_instances.append(allof_instance)
|
composed_instances.append(allof_instance)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
raise ApiValueError(
|
raise ApiValueError(
|
||||||
@ -1384,31 +1377,9 @@ def get_oneof_instance(cls, model_kwargs, constant_kwargs, model_arg=None):
|
|||||||
|
|
||||||
single_value_input = allows_single_value_input(oneof_class)
|
single_value_input = allows_single_value_input(oneof_class)
|
||||||
|
|
||||||
if not single_value_input:
|
|
||||||
# transform js keys from input data to python keys in fixed_model_args
|
|
||||||
fixed_model_args = change_keys_js_to_python(
|
|
||||||
model_kwargs, oneof_class)
|
|
||||||
|
|
||||||
# Extract a dict with the properties that are declared in the oneOf schema.
|
|
||||||
# Undeclared properties (e.g. properties that are allowed because of the
|
|
||||||
# additionalProperties attribute in the OAS document) are not added to
|
|
||||||
# the dict.
|
|
||||||
kwargs = {}
|
|
||||||
var_names = set(oneof_class.openapi_types.keys())
|
|
||||||
for var_name in var_names:
|
|
||||||
if var_name in fixed_model_args:
|
|
||||||
kwargs[var_name] = fixed_model_args[var_name]
|
|
||||||
|
|
||||||
# do not try to make a model with no input args
|
|
||||||
if len(kwargs) == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# and use it to make the instance
|
|
||||||
kwargs.update(constant_kwargs)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not single_value_input:
|
if not single_value_input:
|
||||||
oneof_instance = oneof_class(**kwargs)
|
oneof_instance = oneof_class(**model_kwargs, **constant_kwargs)
|
||||||
else:
|
else:
|
||||||
if issubclass(oneof_class, ModelSimple):
|
if issubclass(oneof_class, ModelSimple):
|
||||||
oneof_instance = oneof_class(model_arg, **constant_kwargs)
|
oneof_instance = oneof_class(model_arg, **constant_kwargs)
|
||||||
@ -1465,24 +1436,8 @@ def get_anyof_instances(self, model_args, constant_args):
|
|||||||
# none_type deserialization is handled in the __new__ method
|
# none_type deserialization is handled in the __new__ method
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# transform js keys to python keys in fixed_model_args
|
|
||||||
fixed_model_args = change_keys_js_to_python(model_args, anyof_class)
|
|
||||||
|
|
||||||
# extract a dict of only required keys from these_model_vars
|
|
||||||
kwargs = {}
|
|
||||||
var_names = set(anyof_class.openapi_types.keys())
|
|
||||||
for var_name in var_names:
|
|
||||||
if var_name in fixed_model_args:
|
|
||||||
kwargs[var_name] = fixed_model_args[var_name]
|
|
||||||
|
|
||||||
# do not try to make a model with no input args
|
|
||||||
if len(kwargs) == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# and use it to make the instance
|
|
||||||
kwargs.update(constant_args)
|
|
||||||
try:
|
try:
|
||||||
anyof_instance = anyof_class(**kwargs)
|
anyof_instance = anyof_class(**model_args, **constant_args)
|
||||||
anyof_instances.append(anyof_instance)
|
anyof_instances.append(anyof_instance)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@ -1495,47 +1450,34 @@ def get_anyof_instances(self, model_args, constant_args):
|
|||||||
return anyof_instances
|
return anyof_instances
|
||||||
|
|
||||||
|
|
||||||
def get_additional_properties_model_instances(
|
def get_discarded_args(self, composed_instances, model_args):
|
||||||
composed_instances, self):
|
"""
|
||||||
additional_properties_model_instances = []
|
Gathers the args that were discarded by configuration.discard_unknown_keys
|
||||||
all_instances = [self]
|
"""
|
||||||
all_instances.extend(composed_instances)
|
model_arg_keys = model_args.keys()
|
||||||
for instance in all_instances:
|
discarded_args = set()
|
||||||
if instance.additional_properties_type is not None:
|
# arguments passed to self were already converted to python names
|
||||||
additional_properties_model_instances.append(instance)
|
|
||||||
return additional_properties_model_instances
|
|
||||||
|
|
||||||
|
|
||||||
def get_var_name_to_model_instances(self, composed_instances):
|
|
||||||
var_name_to_model_instances = {}
|
|
||||||
all_instances = [self]
|
|
||||||
all_instances.extend(composed_instances)
|
|
||||||
for instance in all_instances:
|
|
||||||
for var_name in instance.openapi_types:
|
|
||||||
if var_name not in var_name_to_model_instances:
|
|
||||||
var_name_to_model_instances[var_name] = [instance]
|
|
||||||
else:
|
|
||||||
var_name_to_model_instances[var_name].append(instance)
|
|
||||||
return var_name_to_model_instances
|
|
||||||
|
|
||||||
|
|
||||||
def get_unused_args(self, composed_instances, model_args):
|
|
||||||
unused_args = dict(model_args)
|
|
||||||
# arguments apssed to self were already converted to python names
|
|
||||||
# before __init__ was called
|
# before __init__ was called
|
||||||
for var_name_py in self.attribute_map:
|
|
||||||
if var_name_py in unused_args:
|
|
||||||
del unused_args[var_name_py]
|
|
||||||
for instance in composed_instances:
|
for instance in composed_instances:
|
||||||
if instance.__class__ in self._composed_schemas['allOf']:
|
if instance.__class__ in self._composed_schemas['allOf']:
|
||||||
for var_name_py in instance.attribute_map:
|
try:
|
||||||
if var_name_py in unused_args:
|
keys = instance.to_dict().keys()
|
||||||
del unused_args[var_name_py]
|
discarded_keys = model_args - keys
|
||||||
|
discarded_args.update(discarded_keys)
|
||||||
|
except Exception:
|
||||||
|
# allOf integer schema will throw exception
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
for var_name_js in instance.attribute_map.values():
|
try:
|
||||||
if var_name_js in unused_args:
|
all_keys = set(model_to_dict(instance, serialize=False).keys())
|
||||||
del unused_args[var_name_js]
|
js_keys = model_to_dict(instance, serialize=True).keys()
|
||||||
return unused_args
|
all_keys.update(js_keys)
|
||||||
|
discarded_keys = model_arg_keys - all_keys
|
||||||
|
discarded_args.update(discarded_keys)
|
||||||
|
except Exception:
|
||||||
|
# allOf integer schema will throw exception
|
||||||
|
pass
|
||||||
|
return discarded_args
|
||||||
|
|
||||||
|
|
||||||
def validate_get_composed_info(constant_args, model_args, self):
|
def validate_get_composed_info(constant_args, model_args, self):
|
||||||
@ -1579,36 +1521,42 @@ def validate_get_composed_info(constant_args, model_args, self):
|
|||||||
composed_instances.append(oneof_instance)
|
composed_instances.append(oneof_instance)
|
||||||
anyof_instances = get_anyof_instances(self, model_args, constant_args)
|
anyof_instances = get_anyof_instances(self, model_args, constant_args)
|
||||||
composed_instances.extend(anyof_instances)
|
composed_instances.extend(anyof_instances)
|
||||||
|
"""
|
||||||
|
set additional_properties_model_instances
|
||||||
|
additional properties must be evaluated at the schema level
|
||||||
|
so self's additional properties are most important
|
||||||
|
If self is a composed schema with:
|
||||||
|
- no properties defined in self
|
||||||
|
- additionalProperties: False
|
||||||
|
Then for object payloads every property is an additional property
|
||||||
|
and they are not allowed, so only empty dict is allowed
|
||||||
|
|
||||||
|
Properties must be set on all matching schemas
|
||||||
|
so when a property is assigned toa composed instance, it must be set on all
|
||||||
|
composed instances regardless of additionalProperties presence
|
||||||
|
keeping it to prevent breaking changes in v5.0.1
|
||||||
|
TODO remove cls._additional_properties_model_instances in 6.0.0
|
||||||
|
"""
|
||||||
|
additional_properties_model_instances = []
|
||||||
|
if self.additional_properties_type is not None:
|
||||||
|
additional_properties_model_instances = [self]
|
||||||
|
|
||||||
|
"""
|
||||||
|
no need to set properties on self in here, they will be set in __init__
|
||||||
|
By here all composed schema oneOf/anyOf/allOf instances have their properties set using
|
||||||
|
model_args
|
||||||
|
"""
|
||||||
|
discarded_args = get_discarded_args(self, composed_instances, model_args)
|
||||||
|
|
||||||
# map variable names to composed_instances
|
# map variable names to composed_instances
|
||||||
var_name_to_model_instances = get_var_name_to_model_instances(
|
var_name_to_model_instances = {}
|
||||||
self, composed_instances)
|
for prop_name in model_args:
|
||||||
|
if prop_name not in discarded_args:
|
||||||
# set additional_properties_model_instances
|
var_name_to_model_instances[prop_name] = [self] + composed_instances
|
||||||
additional_properties_model_instances = (
|
|
||||||
get_additional_properties_model_instances(composed_instances, self)
|
|
||||||
)
|
|
||||||
|
|
||||||
# set any remaining values
|
|
||||||
unused_args = get_unused_args(self, composed_instances, model_args)
|
|
||||||
if len(unused_args) > 0 and \
|
|
||||||
len(additional_properties_model_instances) == 0 and \
|
|
||||||
(self._configuration is None or
|
|
||||||
not self._configuration.discard_unknown_keys):
|
|
||||||
raise ApiValueError(
|
|
||||||
"Invalid input arguments input when making an instance of "
|
|
||||||
"class %s. Not all inputs were used. The unused input data "
|
|
||||||
"is %s" % (self.__class__.__name__, unused_args)
|
|
||||||
)
|
|
||||||
|
|
||||||
# no need to add additional_properties to var_name_to_model_instances here
|
|
||||||
# because additional_properties_model_instances will direct us to that
|
|
||||||
# instance when we use getattr or setattr
|
|
||||||
# and we update var_name_to_model_instances in setattr
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
composed_instances,
|
composed_instances,
|
||||||
var_name_to_model_instances,
|
var_name_to_model_instances,
|
||||||
additional_properties_model_instances,
|
additional_properties_model_instances,
|
||||||
unused_args
|
discarded_args
|
||||||
]
|
]
|
||||||
|
@ -9,6 +9,7 @@ import org.openapitools.codegen.DefaultGenerator;
|
|||||||
import org.openapitools.codegen.languages.AbstractKotlinCodegen;
|
import org.openapitools.codegen.languages.AbstractKotlinCodegen;
|
||||||
import org.openapitools.codegen.languages.KotlinClientCodegen;
|
import org.openapitools.codegen.languages.KotlinClientCodegen;
|
||||||
import org.openapitools.codegen.languages.KotlinServerCodegen;
|
import org.openapitools.codegen.languages.KotlinServerCodegen;
|
||||||
|
import org.openapitools.codegen.languages.KotlinServerDeprecatedCodegen;
|
||||||
import org.openapitools.codegen.languages.KotlinSpringServerCodegen;
|
import org.openapitools.codegen.languages.KotlinSpringServerCodegen;
|
||||||
import org.openapitools.codegen.languages.KotlinVertxServerCodegen;
|
import org.openapitools.codegen.languages.KotlinVertxServerCodegen;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
@ -28,6 +29,7 @@ public class KotlinModelCodegenTest {
|
|||||||
return new Object[][]{
|
return new Object[][]{
|
||||||
{new KotlinClientCodegen()},
|
{new KotlinClientCodegen()},
|
||||||
{new KotlinServerCodegen()},
|
{new KotlinServerCodegen()},
|
||||||
|
{new KotlinServerDeprecatedCodegen()},
|
||||||
{new KotlinSpringServerCodegen()},
|
{new KotlinSpringServerCodegen()},
|
||||||
{new KotlinVertxServerCodegen()},
|
{new KotlinVertxServerCodegen()},
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ package org.openapitools.codegen.options;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.openapitools.codegen.CodegenConstants;
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
import org.openapitools.codegen.languages.PythonLegacyClientCodegen;
|
import org.openapitools.codegen.languages.PythonClientCodegen;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -30,6 +30,8 @@ public class PythonClientOptionsProvider implements OptionsProvider {
|
|||||||
public static final String PACKAGE_URL_VALUE = "";
|
public static final String PACKAGE_URL_VALUE = "";
|
||||||
public static final String USE_NOSE_VALUE = "false";
|
public static final String USE_NOSE_VALUE = "false";
|
||||||
public static final String RECURSION_LIMIT = "1200";
|
public static final String RECURSION_LIMIT = "1200";
|
||||||
|
public static final String DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT = "false";
|
||||||
|
public static final String PYTHON_ATTR_NONE_IF_UNSET = "false";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLanguage() {
|
public String getLanguage() {
|
||||||
@ -39,16 +41,17 @@ public class PythonClientOptionsProvider implements OptionsProvider {
|
|||||||
@Override
|
@Override
|
||||||
public Map<String, String> createOptions() {
|
public Map<String, String> createOptions() {
|
||||||
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
return builder.put(PythonLegacyClientCodegen.PACKAGE_URL, PACKAGE_URL_VALUE)
|
return builder.put(PythonClientCodegen.PACKAGE_URL, PACKAGE_URL_VALUE)
|
||||||
.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE)
|
.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE)
|
||||||
.put(CodegenConstants.PROJECT_NAME, PROJECT_NAME_VALUE)
|
.put(CodegenConstants.PROJECT_NAME, PROJECT_NAME_VALUE)
|
||||||
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
|
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
|
||||||
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
|
|
||||||
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
|
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
|
||||||
.put(CodegenConstants.SOURCECODEONLY_GENERATION, "false")
|
.put(CodegenConstants.SOURCECODEONLY_GENERATION, "false")
|
||||||
.put(CodegenConstants.LIBRARY, "urllib3")
|
.put(CodegenConstants.LIBRARY, "urllib3")
|
||||||
.put(PythonLegacyClientCodegen.USE_NOSE, USE_NOSE_VALUE)
|
.put(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT, DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT)
|
||||||
.put(PythonLegacyClientCodegen.RECURSION_LIMIT, RECURSION_LIMIT)
|
.put(PythonClientCodegen.USE_NOSE, USE_NOSE_VALUE)
|
||||||
|
.put(PythonClientCodegen.RECURSION_LIMIT, RECURSION_LIMIT)
|
||||||
|
.put(PythonClientCodegen.PYTHON_ATTR_NONE_IF_UNSET, PYTHON_ATTR_NONE_IF_UNSET)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||||
|
* Copyright 2018 SmartBear Software
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openapitools.codegen.options;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.PythonLegacyClientCodegen;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PythonLegacyClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String PACKAGE_NAME_VALUE = "swagger_client_python";
|
||||||
|
public static final String PROJECT_NAME_VALUE = "swagger-client-python";
|
||||||
|
public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT";
|
||||||
|
public static final String PACKAGE_URL_VALUE = "";
|
||||||
|
public static final String USE_NOSE_VALUE = "false";
|
||||||
|
public static final String RECURSION_LIMIT = "1200";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "python";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(PythonLegacyClientCodegen.PACKAGE_URL, PACKAGE_URL_VALUE)
|
||||||
|
.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE)
|
||||||
|
.put(CodegenConstants.PROJECT_NAME, PROJECT_NAME_VALUE)
|
||||||
|
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
|
||||||
|
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
|
||||||
|
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
|
||||||
|
.put(CodegenConstants.SOURCECODEONLY_GENERATION, "false")
|
||||||
|
.put(CodegenConstants.LIBRARY, "urllib3")
|
||||||
|
.put(PythonLegacyClientCodegen.USE_NOSE, USE_NOSE_VALUE)
|
||||||
|
.put(PythonLegacyClientCodegen.RECURSION_LIMIT, RECURSION_LIMIT)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ package org.openapitools.codegen.python;
|
|||||||
|
|
||||||
import org.openapitools.codegen.AbstractOptionsTest;
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
import org.openapitools.codegen.CodegenConfig;
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
import org.openapitools.codegen.languages.PythonLegacyClientCodegen;
|
import org.openapitools.codegen.languages.PythonClientCodegen;
|
||||||
import org.openapitools.codegen.options.PythonClientOptionsProvider;
|
import org.openapitools.codegen.options.PythonClientOptionsProvider;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
public class PythonClientOptionsTest extends AbstractOptionsTest {
|
public class PythonClientOptionsTest extends AbstractOptionsTest {
|
||||||
private PythonLegacyClientCodegen clientCodegen = mock(PythonLegacyClientCodegen.class, mockSettings);
|
private PythonClientCodegen clientCodegen = mock(PythonClientCodegen.class, mockSettings);
|
||||||
|
|
||||||
public PythonClientOptionsTest() {
|
public PythonClientOptionsTest() {
|
||||||
super(new PythonClientOptionsProvider());
|
super(new PythonClientOptionsProvider());
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||||
|
* Copyright 2018 SmartBear Software
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openapitools.codegen.python;
|
||||||
|
|
||||||
|
import org.openapitools.codegen.AbstractOptionsTest;
|
||||||
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
|
import org.openapitools.codegen.languages.PythonLegacyClientCodegen;
|
||||||
|
import org.openapitools.codegen.options.PythonLegacyClientOptionsProvider;
|
||||||
|
import org.testng.Assert;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
public class PythonLegacyClientOptionsTest extends AbstractOptionsTest {
|
||||||
|
private PythonLegacyClientCodegen clientCodegen = mock(PythonLegacyClientCodegen.class, mockSettings);
|
||||||
|
|
||||||
|
public PythonLegacyClientOptionsTest() {
|
||||||
|
super(new PythonLegacyClientOptionsProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CodegenConfig getCodegenConfig() {
|
||||||
|
return clientCodegen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
protected void verifyOptions() {
|
||||||
|
Assert.assertEquals(clientCodegen.packagePath(), PythonLegacyClientOptionsProvider.PACKAGE_NAME_VALUE.replace('.', File.separatorChar));
|
||||||
|
|
||||||
|
verify(clientCodegen).setPackageName(PythonLegacyClientOptionsProvider.PACKAGE_NAME_VALUE);
|
||||||
|
verify(clientCodegen).setProjectName(PythonLegacyClientOptionsProvider.PROJECT_NAME_VALUE);
|
||||||
|
verify(clientCodegen).setPackageVersion(PythonLegacyClientOptionsProvider.PACKAGE_VERSION_VALUE);
|
||||||
|
verify(clientCodegen).setPackageUrl(PythonLegacyClientOptionsProvider.PACKAGE_URL_VALUE);
|
||||||
|
verify(clientCodegen).setUseNose(PythonLegacyClientOptionsProvider.USE_NOSE_VALUE);
|
||||||
|
}
|
||||||
|
}
|
@ -1373,8 +1373,6 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
breed:
|
breed:
|
||||||
type: string
|
type: string
|
||||||
additionalProperties: false
|
|
||||||
additionalProperties: false
|
|
||||||
Cat:
|
Cat:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/definitions/Animal'
|
- $ref: '#/definitions/Animal'
|
||||||
@ -1523,8 +1521,7 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items: {}
|
||||||
type: object
|
|
||||||
map_map_string:
|
map_map_string:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
@ -1535,14 +1532,15 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties:
|
additionalProperties: {}
|
||||||
type: object
|
anytype_1: {}
|
||||||
anytype_1:
|
anytype_2:
|
||||||
type: object
|
description: no type is set for this
|
||||||
anytype_2: {}
|
|
||||||
anytype_3:
|
anytype_3:
|
||||||
type: object
|
type: object
|
||||||
properties: {}
|
properties: {}
|
||||||
|
description: 'because of a bug in swagger-parser, this should have values {str: (str, int, float...)}
|
||||||
|
but instead we get any type. See https://github.com/swagger-api/swagger-parser/issues/1378'
|
||||||
AdditionalPropertiesString:
|
AdditionalPropertiesString:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -2091,7 +2089,6 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
interNet:
|
interNet:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: false
|
|
||||||
GrandparentAnimal:
|
GrandparentAnimal:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
@ -1646,7 +1646,6 @@ components:
|
|||||||
Cat:
|
Cat:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/Animal'
|
- $ref: '#/components/schemas/Animal'
|
||||||
- $ref: '#/components/schemas/Address'
|
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
declawed:
|
declawed:
|
||||||
@ -2107,6 +2106,9 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
nullable: true
|
nullable: true
|
||||||
|
object_nullable:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
object_nullable_prop:
|
object_nullable_prop:
|
||||||
type: object
|
type: object
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -2124,18 +2126,27 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
nullable: true
|
nullable: true
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: object
|
|
||||||
nullable: true
|
nullable: true
|
||||||
|
ComposedSchemaWithPropsAndNoAddProps:
|
||||||
|
properties:
|
||||||
|
color:
|
||||||
|
type: string
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/Tag'
|
||||||
|
# Below additionalProperties is set to false to validate the use
|
||||||
|
# case when a composed schema has additionalProperties set to false.
|
||||||
|
# This definition will only allow in object payloads that set color and no other properties because
|
||||||
|
# additionalProperties are evaluated at the schema level and do not include composed schema
|
||||||
|
# properties. Only color is defined here, all others are additional
|
||||||
|
additionalProperties: false
|
||||||
fruit:
|
fruit:
|
||||||
|
description: a schema that tests oneOf and includes a schema level property
|
||||||
properties:
|
properties:
|
||||||
color:
|
color:
|
||||||
type: string
|
type: string
|
||||||
oneOf:
|
oneOf:
|
||||||
- $ref: '#/components/schemas/apple'
|
- $ref: '#/components/schemas/apple'
|
||||||
- $ref: '#/components/schemas/banana'
|
- $ref: '#/components/schemas/banana'
|
||||||
# Below additionalProperties is set to false to validate the use
|
|
||||||
# case when a composed schema has additionalProperties set to false.
|
|
||||||
additionalProperties: false
|
|
||||||
apple:
|
apple:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -2145,12 +2156,16 @@ components:
|
|||||||
origin:
|
origin:
|
||||||
type: string
|
type: string
|
||||||
pattern: /^[A-Z\s]*$/i
|
pattern: /^[A-Z\s]*$/i
|
||||||
|
required:
|
||||||
|
- cultivar
|
||||||
nullable: true
|
nullable: true
|
||||||
banana:
|
banana:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
lengthCm:
|
lengthCm:
|
||||||
type: number
|
type: number
|
||||||
|
required:
|
||||||
|
- lengthCm
|
||||||
mammal:
|
mammal:
|
||||||
oneOf:
|
oneOf:
|
||||||
- $ref: '#/components/schemas/whale'
|
- $ref: '#/components/schemas/whale'
|
||||||
@ -2210,13 +2225,13 @@ components:
|
|||||||
anyOf:
|
anyOf:
|
||||||
- $ref: '#/components/schemas/apple'
|
- $ref: '#/components/schemas/apple'
|
||||||
- $ref: '#/components/schemas/banana'
|
- $ref: '#/components/schemas/banana'
|
||||||
additionalProperties: false
|
|
||||||
fruitReq:
|
fruitReq:
|
||||||
|
description: a schema where additionalProperties is on in the composed schema and off in the oneOf object schemas
|
||||||
|
also, this schem accepts null as a value
|
||||||
oneOf:
|
oneOf:
|
||||||
- type: 'null'
|
- type: 'null'
|
||||||
- $ref: '#/components/schemas/appleReq'
|
- $ref: '#/components/schemas/appleReq'
|
||||||
- $ref: '#/components/schemas/bananaReq'
|
- $ref: '#/components/schemas/bananaReq'
|
||||||
additionalProperties: false
|
|
||||||
appleReq:
|
appleReq:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -2320,7 +2335,6 @@ components:
|
|||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/ShapeInterface'
|
- $ref: '#/components/schemas/ShapeInterface'
|
||||||
- $ref: '#/components/schemas/TriangleInterface'
|
- $ref: '#/components/schemas/TriangleInterface'
|
||||||
additionalProperties: false
|
|
||||||
ScaleneTriangle:
|
ScaleneTriangle:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/ShapeInterface'
|
- $ref: '#/components/schemas/ShapeInterface'
|
||||||
|
3
pom.xml
3
pom.xml
@ -10,7 +10,7 @@
|
|||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>openapi-generator-project</name>
|
<name>openapi-generator-project</name>
|
||||||
<!-- RELEASE_VERSION -->
|
<!-- RELEASE_VERSION -->
|
||||||
<version>5.1.1</version>
|
<version>5.2.0-SNAPSHOT</version>
|
||||||
<!-- /RELEASE_VERSION -->
|
<!-- /RELEASE_VERSION -->
|
||||||
<url>https://github.com/openapitools/openapi-generator</url>
|
<url>https://github.com/openapitools/openapi-generator</url>
|
||||||
<scm>
|
<scm>
|
||||||
@ -1206,6 +1206,7 @@
|
|||||||
<!--<module>samples/client/petstore/javascript-apollo</module>-->
|
<!--<module>samples/client/petstore/javascript-apollo</module>-->
|
||||||
<module>samples/client/petstore/javascript-flowtyped</module>
|
<module>samples/client/petstore/javascript-flowtyped</module>
|
||||||
<module>samples/client/petstore/python</module>
|
<module>samples/client/petstore/python</module>
|
||||||
|
<module>samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent</module>
|
||||||
<module>samples/client/petstore/python-legacy</module>
|
<module>samples/client/petstore/python-legacy</module>
|
||||||
<module>samples/client/petstore/python-asyncio</module>
|
<module>samples/client/petstore/python-asyncio</module>
|
||||||
<module>samples/client/petstore/python-tornado</module>
|
<module>samples/client/petstore/python-tornado</module>
|
||||||
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -1 +1 @@
|
|||||||
5.1.1
|
5.2.0-SNAPSHOT
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The version of the OpenAPI document: 1.0.0
|
* The version of the OpenAPI document: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI-Generator 5.1.1.
|
* NOTE: This class is auto generated by OpenAPI-Generator 5.2.0-SNAPSHOT.
|
||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user