Skip to content

Commit af16d49

Browse files
committed
feat: add option to support non-ascii headers in kotlin client
1 parent cc40f40 commit af16d49

File tree

79 files changed

+5029
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+5029
-23
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
generatorName: kotlin
2+
outputDir: samples/client/others/kotlin-jvm-okhttp-non-ascii-headers
3+
library: jvm-okhttp4
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
6+
additionalProperties:
7+
useNonAsciiHeaders: kotlin-petstore-okhttp4-parameter-tests
8+
artifactId: kotlin-petstore-jvm-okhttp-non-ascii-headers

docs/generators/kotlin.md

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
4949
|sourceFolder|source folder for generated code| |src/main/kotlin|
5050
|supportAndroidApiLevel25AndBelow|[WARNING] This flag will generate code that has a known security vulnerability. It uses `kotlin.io.createTempFile` instead of `java.nio.file.Files.createTempFile` in order to support Android API level 25 and below. For more info, please check the following links https://github.com/OpenAPITools/openapi-generator/security/advisories/GHSA-23x4-m842-fmwf, https://github.com/OpenAPITools/openapi-generator/pull/9284| |false|
5151
|useCoroutines|Whether to use the Coroutines adapter with the retrofit2 library.| |false|
52+
|useNonAsciiHeaders|Allow to use non-ascii headers with the okhttp library| |false|
5253
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library.| |false|
5354
|useSettingsGradle|Whether the project uses settings.gradle.| |false|
5455
|useSpringBoot3|Whether to use the Spring Boot 3 with the jvm-spring-webclient library.| |false|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
7474

7575
public static final String USE_RX_JAVA3 = "useRxJava3";
7676
public static final String USE_COROUTINES = "useCoroutines";
77+
public static final String USE_NON_ASCII_HEADERS = "useNonAsciiHeaders";
7778
public static final String DO_NOT_USE_RX_AND_COROUTINES = "doNotUseRxAndCoroutines";
7879
public static final String GENERATE_ROOM_MODELS = "generateRoomModels";
7980
public static final String ROOM_MODEL_PACKAGE = "roomModelPackage";
@@ -101,7 +102,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
101102

102103
protected static final String VENDOR_EXTENSION_BASE_NAME_LITERAL = "x-base-name-literal";
103104

104-
105+
105106
@Setter protected String dateLibrary = DateLibrary.JAVA8.value;
106107
@Setter protected String requestDateConverter = RequestDateConverter.TO_JSON.value;
107108
@Setter protected String collectionType = CollectionType.LIST.value;
@@ -283,6 +284,8 @@ public KotlinClientCodegen() {
283284

284285
CliOption serializationLibraryOpt = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_DESC);
285286
cliOptions.add(serializationLibraryOpt.defaultValue(serializationLibrary.name()));
287+
288+
cliOptions.add(CliOption.newBoolean(USE_NON_ASCII_HEADERS, "Allow to use non-ascii headers with the okhttp library"));
286289
}
287290

288291
@Override

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import okhttp3.ResponseBody
1313
import okhttp3.MediaType.Companion.toMediaTypeOrNull
1414
import okhttp3.Request
1515
import okhttp3.Headers
16+
import okhttp3.Headers.Builder
1617
import okhttp3.Headers.Companion.toHeaders
1718
import okhttp3.MultipartBody
1819
import okhttp3.Call
@@ -413,7 +414,16 @@ import com.squareup.moshi.adapter
413414
RequestMethod.POST -> Request.Builder().url(url).post(requestBody(requestConfig.body, contentType))
414415
RequestMethod.OPTIONS -> Request.Builder().url(url).method("OPTIONS", null)
415416
}.apply {
416-
headers.forEach { header -> addHeader(header.key, header.value) }
417+
val headersBuilder = Headers.Builder()
418+
headers.forEach { header ->
419+
{{#useNonAsciiHeaders}}
420+
headersBuilder.addUnsafeNonAscii(header.key, header.value)
421+
{{/useNonAsciiHeaders}}
422+
{{^useNonAsciiHeaders}}
423+
headersBuilder.add(header.key, header.value)
424+
{{/useNonAsciiHeaders}}
425+
}
426+
this.headers(headersBuilder.build())
417427
}.build()
418428

419429
{{#useCoroutines}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
README.md
2+
build.gradle
3+
docs/ApiResponse.md
4+
docs/Category.md
5+
docs/Order.md
6+
docs/Pet.md
7+
docs/PetApi.md
8+
docs/StoreApi.md
9+
docs/Tag.md
10+
docs/User.md
11+
docs/UserApi.md
12+
gradle/wrapper/gradle-wrapper.jar
13+
gradle/wrapper/gradle-wrapper.properties
14+
gradlew
15+
gradlew.bat
16+
settings.gradle
17+
src/main/kotlin/org/openapitools/client/apis/PetApi.kt
18+
src/main/kotlin/org/openapitools/client/apis/StoreApi.kt
19+
src/main/kotlin/org/openapitools/client/apis/UserApi.kt
20+
src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt
21+
src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
22+
src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt
23+
src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt
24+
src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt
25+
src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt
26+
src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt
27+
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt
28+
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt
29+
src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt
30+
src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt
31+
src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt
32+
src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt
33+
src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt
34+
src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt
35+
src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt
36+
src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt
37+
src/main/kotlin/org/openapitools/client/models/Category.kt
38+
src/main/kotlin/org/openapitools/client/models/ModelApiResponse.kt
39+
src/main/kotlin/org/openapitools/client/models/Order.kt
40+
src/main/kotlin/org/openapitools/client/models/Pet.kt
41+
src/main/kotlin/org/openapitools/client/models/Tag.kt
42+
src/main/kotlin/org/openapitools/client/models/User.kt
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.11.0-SNAPSHOT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# org.openapitools.client - Kotlin client library for OpenAPI Petstore
2+
3+
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
4+
5+
## Overview
6+
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate an API client.
7+
8+
- API version: 1.0.0
9+
- Package version:
10+
- Generator version: 7.11.0-SNAPSHOT
11+
- Build package: org.openapitools.codegen.languages.KotlinClientCodegen
12+
13+
## Requires
14+
15+
* Kotlin 1.7.21
16+
* Gradle 7.5
17+
18+
## Build
19+
20+
First, create the gradle wrapper script:
21+
22+
```
23+
gradle wrapper
24+
```
25+
26+
Then, run:
27+
28+
```
29+
./gradlew check assemble
30+
```
31+
32+
This runs all tests and packages the library.
33+
34+
## Features/Implementation Notes
35+
36+
* Supports JSON inputs/outputs, File inputs, and Form inputs.
37+
* Supports collection formats for query parameters: csv, tsv, ssv, pipes.
38+
* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
39+
* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets.
40+
41+
<a id="documentation-for-api-endpoints"></a>
42+
## Documentation for API Endpoints
43+
44+
All URIs are relative to *http://petstore.swagger.io/v2*
45+
46+
| Class | Method | HTTP request | Description |
47+
| ------------ | ------------- | ------------- | ------------- |
48+
| *PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store |
49+
| *PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet |
50+
| *PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status |
51+
| *PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags |
52+
| *PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID |
53+
| *PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet |
54+
| *PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data |
55+
| *PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image |
56+
| *StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID |
57+
| *StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status |
58+
| *StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID |
59+
| *StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet |
60+
| *UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user |
61+
| *UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array |
62+
| *UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array |
63+
| *UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user |
64+
| *UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name |
65+
| *UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system |
66+
| *UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session |
67+
| *UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user |
68+
69+
70+
<a id="documentation-for-models"></a>
71+
## Documentation for Models
72+
73+
- [org.openapitools.client.models.Category](docs/Category.md)
74+
- [org.openapitools.client.models.ModelApiResponse](docs/ModelApiResponse.md)
75+
- [org.openapitools.client.models.Order](docs/Order.md)
76+
- [org.openapitools.client.models.Pet](docs/Pet.md)
77+
- [org.openapitools.client.models.Tag](docs/Tag.md)
78+
- [org.openapitools.client.models.User](docs/User.md)
79+
80+
81+
<a id="documentation-for-authorization"></a>
82+
## Documentation for Authorization
83+
84+
85+
Authentication schemes defined for the API:
86+
<a id="petstore_auth"></a>
87+
### petstore_auth
88+
89+
- **Type**: OAuth
90+
- **Flow**: implicit
91+
- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
92+
- **Scopes**:
93+
- write:pets: modify pets in your account
94+
- read:pets: read your pets
95+
96+
<a id="api_key"></a>
97+
### api_key
98+
99+
- **Type**: API key
100+
- **API key parameter name**: api_key
101+
- **Location**: HTTP header
102+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
group 'org.openapitools'
2+
version '1.0.0'
3+
4+
wrapper {
5+
gradleVersion = '8.7'
6+
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
7+
}
8+
9+
buildscript {
10+
ext.kotlin_version = '1.9.23'
11+
ext.spotless_version = "6.25.0"
12+
13+
repositories {
14+
maven { url "https://repo1.maven.org/maven2" }
15+
}
16+
dependencies {
17+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
18+
classpath "com.diffplug.spotless:spotless-plugin-gradle:$spotless_version"
19+
}
20+
}
21+
22+
apply plugin: 'kotlin'
23+
apply plugin: 'maven-publish'
24+
apply plugin: 'com.diffplug.spotless'
25+
26+
repositories {
27+
maven { url "https://repo1.maven.org/maven2" }
28+
}
29+
30+
// Use spotless plugin to automatically format code, remove unused import, etc
31+
// To apply changes directly to the file, run `gradlew spotlessApply`
32+
// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle
33+
spotless {
34+
// comment out below to run spotless as part of the `check` task
35+
enforceCheck false
36+
37+
format 'misc', {
38+
// define the files (e.g. '*.gradle', '*.md') to apply `misc` to
39+
target '.gitignore'
40+
41+
// define the steps to apply to those files
42+
trimTrailingWhitespace()
43+
indentWithSpaces() // Takes an integer argument if you don't like 4
44+
endWithNewline()
45+
}
46+
kotlin {
47+
ktfmt()
48+
}
49+
}
50+
51+
test {
52+
useJUnitPlatform()
53+
}
54+
55+
dependencies {
56+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
57+
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
58+
implementation "com.squareup.moshi:moshi-kotlin:1.15.1"
59+
implementation "com.squareup.moshi:moshi-adapters:1.15.1"
60+
implementation "com.squareup.okhttp3:okhttp:4.12.0"
61+
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2"
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
# ModelApiResponse
3+
4+
## Properties
5+
| Name | Type | Description | Notes |
6+
| ------------ | ------------- | ------------- | ------------- |
7+
| **code** | **kotlin.Int** | | [optional] |
8+
| **type** | **kotlin.String** | | [optional] |
9+
| **message** | **kotlin.String** | | [optional] |
10+
11+
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
# Category
3+
4+
## Properties
5+
| Name | Type | Description | Notes |
6+
| ------------ | ------------- | ------------- | ------------- |
7+
| **id** | **kotlin.Long** | | [optional] |
8+
| **name** | **kotlin.String** | | [optional] |
9+
10+
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
# Order
3+
4+
## Properties
5+
| Name | Type | Description | Notes |
6+
| ------------ | ------------- | ------------- | ------------- |
7+
| **id** | **kotlin.Long** | | [optional] |
8+
| **petId** | **kotlin.Long** | | [optional] |
9+
| **quantity** | **kotlin.Int** | | [optional] |
10+
| **shipDate** | [**java.time.OffsetDateTime**](java.time.OffsetDateTime.md) | | [optional] |
11+
| **status** | [**inline**](#Status) | Order Status | [optional] |
12+
| **complete** | **kotlin.Boolean** | | [optional] |
13+
14+
15+
<a id="Status"></a>
16+
## Enum: status
17+
| Name | Value |
18+
| ---- | ----- |
19+
| status | placed, approved, delivered |
20+
21+
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
# Pet
3+
4+
## Properties
5+
| Name | Type | Description | Notes |
6+
| ------------ | ------------- | ------------- | ------------- |
7+
| **name** | **kotlin.String** | | |
8+
| **photoUrls** | **kotlin.collections.List&lt;kotlin.String&gt;** | | |
9+
| **id** | **kotlin.Long** | | [optional] |
10+
| **category** | [**Category**](Category.md) | | [optional] |
11+
| **tags** | [**kotlin.collections.List&lt;Tag&gt;**](Tag.md) | | [optional] |
12+
| **status** | [**inline**](#Status) | pet status in the store | [optional] |
13+
14+
15+
<a id="Status"></a>
16+
## Enum: status
17+
| Name | Value |
18+
| ---- | ----- |
19+
| status | available, pending, sold |
20+
21+
22+

0 commit comments

Comments
 (0)