Skip to content

Commit

Permalink
feat: add option to support non-ascii headers in kotlin client
Browse files Browse the repository at this point in the history
  • Loading branch information
Djaler committed Dec 14, 2024
1 parent cc40f40 commit af1da3c
Show file tree
Hide file tree
Showing 79 changed files with 5,029 additions and 23 deletions.
8 changes: 8 additions & 0 deletions bin/configs/kotlin-jvm-okhttp-non-ascii-headers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
generatorName: kotlin
outputDir: samples/client/others/kotlin-jvm-okhttp-non-ascii-headers
library: jvm-okhttp4
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
additionalProperties:
useNonAsciiHeaders: true
artifactId: kotlin-petstore-jvm-okhttp-non-ascii-headers
1 change: 1 addition & 0 deletions docs/generators/kotlin.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/main/kotlin|
|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|
|useCoroutines|Whether to use the Coroutines adapter with the retrofit2 library.| |false|
|useNonAsciiHeaders|Allow to use non-ascii headers with the okhttp library| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library.| |false|
|useSettingsGradle|Whether the project uses settings.gradle.| |false|
|useSpringBoot3|Whether to use the Spring Boot 3 with the jvm-spring-webclient library.| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {

public static final String USE_RX_JAVA3 = "useRxJava3";
public static final String USE_COROUTINES = "useCoroutines";
public static final String USE_NON_ASCII_HEADERS = "useNonAsciiHeaders";
public static final String DO_NOT_USE_RX_AND_COROUTINES = "doNotUseRxAndCoroutines";
public static final String GENERATE_ROOM_MODELS = "generateRoomModels";
public static final String ROOM_MODEL_PACKAGE = "roomModelPackage";
Expand Down Expand Up @@ -101,7 +102,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {

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


@Setter protected String dateLibrary = DateLibrary.JAVA8.value;
@Setter protected String requestDateConverter = RequestDateConverter.TO_JSON.value;
@Setter protected String collectionType = CollectionType.LIST.value;
Expand Down Expand Up @@ -283,6 +284,8 @@ public KotlinClientCodegen() {

CliOption serializationLibraryOpt = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_DESC);
cliOptions.add(serializationLibraryOpt.defaultValue(serializationLibrary.name()));

cliOptions.add(CliOption.newBoolean(USE_NON_ASCII_HEADERS, "Allow to use non-ascii headers with the okhttp library"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import okhttp3.ResponseBody
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request
import okhttp3.Headers
import okhttp3.Headers.Builder
import okhttp3.Headers.Companion.toHeaders
import okhttp3.MultipartBody
import okhttp3.Call
Expand Down Expand Up @@ -413,7 +414,16 @@ import com.squareup.moshi.adapter
RequestMethod.POST -> Request.Builder().url(url).post(requestBody(requestConfig.body, contentType))
RequestMethod.OPTIONS -> Request.Builder().url(url).method("OPTIONS", null)
}.apply {
headers.forEach { header -> addHeader(header.key, header.value) }
val headersBuilder = Headers.Builder()
headers.forEach { header ->
{{#useNonAsciiHeaders}}
headersBuilder.addUnsafeNonAscii(header.key, header.value)
{{/useNonAsciiHeaders}}
{{^useNonAsciiHeaders}}
headersBuilder.add(header.key, header.value)
{{/useNonAsciiHeaders}}
}
this.headers(headersBuilder.build())
}.build()

{{#useCoroutines}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
README.md
build.gradle
docs/ApiResponse.md
docs/Category.md
docs/Order.md
docs/Pet.md
docs/PetApi.md
docs/StoreApi.md
docs/Tag.md
docs/User.md
docs/UserApi.md
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties
gradlew
gradlew.bat
settings.gradle
src/main/kotlin/org/openapitools/client/apis/PetApi.kt
src/main/kotlin/org/openapitools/client/apis/StoreApi.kt
src/main/kotlin/org/openapitools/client/apis/UserApi.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt
src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt
src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt
src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt
src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt
src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt
src/main/kotlin/org/openapitools/client/models/Category.kt
src/main/kotlin/org/openapitools/client/models/ModelApiResponse.kt
src/main/kotlin/org/openapitools/client/models/Order.kt
src/main/kotlin/org/openapitools/client/models/Pet.kt
src/main/kotlin/org/openapitools/client/models/Tag.kt
src/main/kotlin/org/openapitools/client/models/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.11.0-SNAPSHOT
102 changes: 102 additions & 0 deletions samples/client/others/kotlin-jvm-okhttp-non-ascii-headers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# org.openapitools.client - Kotlin client library for OpenAPI Petstore

This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.

## Overview
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.

- API version: 1.0.0
- Package version:
- Generator version: 7.11.0-SNAPSHOT
- Build package: org.openapitools.codegen.languages.KotlinClientCodegen

## Requires

* Kotlin 1.7.21
* Gradle 7.5

## 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.
* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets.

<a id="documentation-for-api-endpoints"></a>
## Documentation for API Endpoints

All URIs are relative to *http://petstore.swagger.io/v2*

| Class | Method | HTTP request | Description |
| ------------ | ------------- | ------------- | ------------- |
| *PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store |
| *PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet |
| *PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status |
| *PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags |
| *PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID |
| *PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet |
| *PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data |
| *PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image |
| *StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID |
| *StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status |
| *StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID |
| *StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet |
| *UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user |
| *UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array |
| *UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array |
| *UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user |
| *UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name |
| *UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system |
| *UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session |
| *UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user |


<a id="documentation-for-models"></a>
## Documentation for Models

- [org.openapitools.client.models.Category](docs/Category.md)
- [org.openapitools.client.models.ModelApiResponse](docs/ModelApiResponse.md)
- [org.openapitools.client.models.Order](docs/Order.md)
- [org.openapitools.client.models.Pet](docs/Pet.md)
- [org.openapitools.client.models.Tag](docs/Tag.md)
- [org.openapitools.client.models.User](docs/User.md)


<a id="documentation-for-authorization"></a>
## Documentation for Authorization


Authentication schemes defined for the API:
<a id="petstore_auth"></a>
### petstore_auth

- **Type**: OAuth
- **Flow**: implicit
- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
- **Scopes**:
- write:pets: modify pets in your account
- read:pets: read your pets

<a id="api_key"></a>
### api_key

- **Type**: API key
- **API key parameter name**: api_key
- **Location**: HTTP header

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
group 'org.openapitools'
version '1.0.0'

wrapper {
gradleVersion = '8.7'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}

buildscript {
ext.kotlin_version = '1.9.23'
ext.spotless_version = "6.25.0"

repositories {
maven { url "https://repo1.maven.org/maven2" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.diffplug.spotless:spotless-plugin-gradle:$spotless_version"
}
}

apply plugin: 'kotlin'
apply plugin: 'maven-publish'
apply plugin: 'com.diffplug.spotless'

repositories {
maven { url "https://repo1.maven.org/maven2" }
}

// Use spotless plugin to automatically format code, remove unused import, etc
// To apply changes directly to the file, run `gradlew spotlessApply`
// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle
spotless {
// comment out below to run spotless as part of the `check` task
enforceCheck false

format 'misc', {
// define the files (e.g. '*.gradle', '*.md') to apply `misc` to
target '.gitignore'

// define the steps to apply to those files
trimTrailingWhitespace()
indentWithSpaces() // Takes an integer argument if you don't like 4
endWithNewline()
}
kotlin {
ktfmt()
}
}

test {
useJUnitPlatform()
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "com.squareup.moshi:moshi-kotlin:1.15.1"
implementation "com.squareup.moshi:moshi-adapters:1.15.1"
implementation "com.squareup.okhttp3:okhttp:4.12.0"
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

# ModelApiResponse

## Properties
| Name | Type | Description | Notes |
| ------------ | ------------- | ------------- | ------------- |
| **code** | **kotlin.Int** | | [optional] |
| **type** | **kotlin.String** | | [optional] |
| **message** | **kotlin.String** | | [optional] |



Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# Category

## Properties
| Name | Type | Description | Notes |
| ------------ | ------------- | ------------- | ------------- |
| **id** | **kotlin.Long** | | [optional] |
| **name** | **kotlin.String** | | [optional] |



Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

# Order

## Properties
| Name | Type | Description | Notes |
| ------------ | ------------- | ------------- | ------------- |
| **id** | **kotlin.Long** | | [optional] |
| **petId** | **kotlin.Long** | | [optional] |
| **quantity** | **kotlin.Int** | | [optional] |
| **shipDate** | [**java.time.OffsetDateTime**](java.time.OffsetDateTime.md) | | [optional] |
| **status** | [**inline**](#Status) | Order Status | [optional] |
| **complete** | **kotlin.Boolean** | | [optional] |


<a id="Status"></a>
## Enum: status
| Name | Value |
| ---- | ----- |
| status | placed, approved, delivered |



Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

# Pet

## Properties
| Name | Type | Description | Notes |
| ------------ | ------------- | ------------- | ------------- |
| **name** | **kotlin.String** | | |
| **photoUrls** | **kotlin.collections.List&lt;kotlin.String&gt;** | | |
| **id** | **kotlin.Long** | | [optional] |
| **category** | [**Category**](Category.md) | | [optional] |
| **tags** | [**kotlin.collections.List&lt;Tag&gt;**](Tag.md) | | [optional] |
| **status** | [**inline**](#Status) | pet status in the store | [optional] |


<a id="Status"></a>
## Enum: status
| Name | Value |
| ---- | ----- |
| status | available, pending, sold |



Loading

0 comments on commit af1da3c

Please sign in to comment.