Skip to content

Commit f9dedd7

Browse files
authored
[kotlin] [multiplatform] [jvm-ktor] Fix formdata file upload (#21056)
* fix: kotlin multiplatform form-data file upload * generate samples * fix form data binary for jvm-ktor
1 parent be77442 commit f9dedd7

File tree

14 files changed

+30
-26
lines changed
  • modules/openapi-generator/src/main
  • samples/client/petstore
    • kotlin-default-values-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis
    • kotlin-jvm-ktor-gson
    • kotlin-jvm-ktor-jackson
    • kotlin-jvm-ktor-kotlinx_serialization
    • kotlin-multiplatform
    • kotlin-multiplatform-kotlinx-datetime

14 files changed

+30
-26
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,11 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
10211021
if ((JVM_KTOR.equals(getLibrary()) || MULTIPLATFORM.equals(getLibrary())) && operation.allParams != null) {
10221022
for (CodegenParameter param : operation.allParams) {
10231023
if (param.dataFormat != null && param.dataFormat.equals("binary")) {
1024-
param.baseType = param.dataType = "io.ktor.client.request.forms.InputProvider";
1024+
if (param.isContainer) {
1025+
param.baseType = param.dataType = typeMapping.get(collectionType) + "<io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>>";
1026+
} else {
1027+
param.baseType = param.dataType = "io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>";
1028+
}
10251029
}
10261030
}
10271031
}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
6363
formData {
6464
{{#formParams}}
6565
{{#isFile}}
66-
{{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
66+
{{{paramName}}}?.apply { append({{{paramName}}}) }
6767
{{/isFile}}
6868
{{^isFile}}
6969
{{^isArray}}
@@ -81,7 +81,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
8181
{{/isArray}}
8282
{{#isArray}}
8383
for (x in {{paramName}} ?: listOf()) {
84-
append("{{{baseName}}}", x.toString())
84+
{{#isFile}}append(it){{/isFile}}{{^isFile}}append("{{{baseName}}}", x.toString()){{/isFile}}
8585
}
8686
{{/isArray}}
8787
{{/isFile}}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ import kotlinx.serialization.encoding.*
7676
{{#formParams}}
7777
{{#isArray}}
7878
{{{paramName}}}?.onEach {
79-
append("{{{baseName}}}[]", it)
79+
{{#isFile}}append(it){{/isFile}}{{^isFile}}append("{{{baseName}}}", it){{/isFile}}
8080
}
8181
{{/isArray}}
8282
{{^isArray}}
83-
{{{paramName}}}?.apply { append("{{{baseName}}}", {{^isEnumOrRef}}{{{paramName}}}{{/isEnumOrRef}}{{#isEnumOrRef}}{{{paramName}}}.value{{/isEnumOrRef}}) }
83+
{{{paramName}}}?.apply { {{#isFile}}append({{{baseName}}}){{/isFile}}{{^isFile}}append("{{{baseName}}}", {{^isEnumOrRef}}{{{paramName}}}{{/isEnumOrRef}}{{#isEnumOrRef}}{{{paramName}}}.value{{/isEnumOrRef}}){{/isFile}} }
8484
{{/isArray}}
8585
{{/formParams}}
8686
}

samples/client/petstore/kotlin-default-values-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/DefaultApi.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ open class DefaultApi : ApiClient {
9090
fn2?.apply { append("fn2", fn2) }
9191
fn3?.apply { append("fn3", fn3) }
9292
fn4?.onEach {
93-
append("fn4[]", it)
93+
append("fn4", it)
9494
}
9595
}
9696

samples/client/petstore/kotlin-jvm-ktor-gson/docs/PetApi.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ uploads an image
360360
val apiInstance = PetApi()
361361
val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update
362362
val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server
363-
val file : io.ktor.client.request.forms.InputProvider = BINARY_DATA_HERE // io.ktor.client.request.forms.InputProvider | file to upload
363+
val file : io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> = BINARY_DATA_HERE // io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> | file to upload
364364
try {
365365
val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file)
366366
println(result)
@@ -378,7 +378,7 @@ try {
378378
| **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] |
379379
| Name | Type | Description | Notes |
380380
| ------------- | ------------- | ------------- | ------------- |
381-
| **file** | **io.ktor.client.request.forms.InputProvider**| file to upload | [optional] |
381+
| **file** | **io.ktor.client.request.forms.FormPart&lt;io.ktor.client.request.forms.InputProvider&gt;**| file to upload | [optional] |
382382

383383
### Return type
384384

samples/client/petstore/kotlin-jvm-ktor-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,14 @@ import java.text.DateFormat
290290
* @return ModelApiResponse
291291
*/
292292
@Suppress("UNCHECKED_CAST")
293-
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.InputProvider?): HttpResponse<ModelApiResponse> {
293+
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>?): HttpResponse<ModelApiResponse> {
294294

295295
val localVariableAuthNames = listOf<String>("petstore_auth")
296296

297297
val localVariableBody =
298298
formData {
299299
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
300-
file?.apply { append("file", file) }
300+
file?.apply { append(file) }
301301
}
302302

303303
val localVariableQuery = mutableMapOf<String, List<String>>()

samples/client/petstore/kotlin-jvm-ktor-jackson/docs/PetApi.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ uploads an image
360360
val apiInstance = PetApi()
361361
val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update
362362
val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server
363-
val file : io.ktor.client.request.forms.InputProvider = BINARY_DATA_HERE // io.ktor.client.request.forms.InputProvider | file to upload
363+
val file : io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> = BINARY_DATA_HERE // io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> | file to upload
364364
try {
365365
val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file)
366366
println(result)
@@ -378,7 +378,7 @@ try {
378378
| **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] |
379379
| Name | Type | Description | Notes |
380380
| ------------- | ------------- | ------------- | ------------- |
381-
| **file** | **io.ktor.client.request.forms.InputProvider**| file to upload | [optional] |
381+
| **file** | **io.ktor.client.request.forms.FormPart&lt;io.ktor.client.request.forms.InputProvider&gt;**| file to upload | [optional] |
382382

383383
### Return type
384384

samples/client/petstore/kotlin-jvm-ktor-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,14 @@ import com.fasterxml.jackson.databind.ObjectMapper
288288
* @return ModelApiResponse
289289
*/
290290
@Suppress("UNCHECKED_CAST")
291-
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.InputProvider?): HttpResponse<ModelApiResponse> {
291+
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>?): HttpResponse<ModelApiResponse> {
292292

293293
val localVariableAuthNames = listOf<String>("petstore_auth")
294294

295295
val localVariableBody =
296296
formData {
297297
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
298-
file?.apply { append("file", file) }
298+
file?.apply { append(file) }
299299
}
300300

301301
val localVariableQuery = mutableMapOf<String, List<String>>()

samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/docs/PetApi.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ uploads an image
372372
val apiInstance = PetApi()
373373
val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update
374374
val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server
375-
val file : io.ktor.client.request.forms.InputProvider = BINARY_DATA_HERE // io.ktor.client.request.forms.InputProvider | file to upload
375+
val file : io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> = BINARY_DATA_HERE // io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> | file to upload
376376
try {
377377
val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file)
378378
println(result)
@@ -390,7 +390,7 @@ try {
390390
| **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] |
391391
| Name | Type | Description | Notes |
392392
| ------------- | ------------- | ------------- | ------------- |
393-
| **file** | **io.ktor.client.request.forms.InputProvider**| file to upload | [optional] |
393+
| **file** | **io.ktor.client.request.forms.FormPart&lt;io.ktor.client.request.forms.InputProvider&gt;**| file to upload | [optional] |
394394

395395
### Return type
396396

samples/client/petstore/kotlin-jvm-ktor-kotlinx_serialization/src/main/kotlin/org/openapitools/client/apis/PetApi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,14 +287,14 @@ import io.ktor.http.ParametersBuilder
287287
* @return ModelApiResponse
288288
*/
289289
@Suppress("UNCHECKED_CAST")
290-
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.InputProvider?): HttpResponse<ModelApiResponse> {
290+
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>?): HttpResponse<ModelApiResponse> {
291291

292292
val localVariableAuthNames = listOf<String>("petstore_auth")
293293

294294
val localVariableBody =
295295
formData {
296296
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
297-
file?.apply { append("file", file) }
297+
file?.apply { append(file) }
298298
}
299299

300300
val localVariableQuery = mutableMapOf<String, List<String>>()

samples/client/petstore/kotlin-multiplatform-kotlinx-datetime/docs/PetApi.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ uploads an image
360360
val apiInstance = PetApi()
361361
val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update
362362
val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server
363-
val file : io.ktor.client.request.forms.InputProvider = BINARY_DATA_HERE // io.ktor.client.request.forms.InputProvider | file to upload
363+
val file : io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> = BINARY_DATA_HERE // io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> | file to upload
364364
try {
365365
val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file)
366366
println(result)
@@ -378,7 +378,7 @@ try {
378378
| **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] |
379379
| Name | Type | Description | Notes |
380380
| ------------- | ------------- | ------------- | ------------- |
381-
| **file** | **io.ktor.client.request.forms.InputProvider**| file to upload | [optional] |
381+
| **file** | **io.ktor.client.request.forms.FormPart&lt;io.ktor.client.request.forms.InputProvider&gt;**| file to upload | [optional] |
382382

383383
### Return type
384384

samples/client/petstore/kotlin-multiplatform-kotlinx-datetime/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,14 @@ open class PetApi : ApiClient {
324324
* @return ModelApiResponse
325325
*/
326326
@Suppress("UNCHECKED_CAST")
327-
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.InputProvider? = null): HttpResponse<ModelApiResponse> {
327+
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>? = null): HttpResponse<ModelApiResponse> {
328328

329329
val localVariableAuthNames = listOf<String>("petstore_auth")
330330

331331
val localVariableBody =
332332
formData {
333333
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
334-
file?.apply { append("file", file) }
334+
file?.apply { append(file) }
335335
}
336336

337337
val localVariableQuery = mutableMapOf<String, List<String>>()

samples/client/petstore/kotlin-multiplatform/docs/PetApi.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ uploads an image
360360
val apiInstance = PetApi()
361361
val petId : kotlin.Long = 789 // kotlin.Long | ID of pet to update
362362
val additionalMetadata : kotlin.String = additionalMetadata_example // kotlin.String | Additional data to pass to server
363-
val file : io.ktor.client.request.forms.InputProvider = BINARY_DATA_HERE // io.ktor.client.request.forms.InputProvider | file to upload
363+
val file : io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> = BINARY_DATA_HERE // io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider> | file to upload
364364
try {
365365
val result : ModelApiResponse = apiInstance.uploadFile(petId, additionalMetadata, file)
366366
println(result)
@@ -378,7 +378,7 @@ try {
378378
| **additionalMetadata** | **kotlin.String**| Additional data to pass to server | [optional] |
379379
| Name | Type | Description | Notes |
380380
| ------------- | ------------- | ------------- | ------------- |
381-
| **file** | **io.ktor.client.request.forms.InputProvider**| file to upload | [optional] |
381+
| **file** | **io.ktor.client.request.forms.FormPart&lt;io.ktor.client.request.forms.InputProvider&gt;**| file to upload | [optional] |
382382

383383
### Return type
384384

samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,14 @@ open class PetApi : ApiClient {
324324
* @return ModelApiResponse
325325
*/
326326
@Suppress("UNCHECKED_CAST")
327-
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.InputProvider? = null): HttpResponse<ModelApiResponse> {
327+
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String? = null, file: io.ktor.client.request.forms.FormPart<io.ktor.client.request.forms.InputProvider>? = null): HttpResponse<ModelApiResponse> {
328328

329329
val localVariableAuthNames = listOf<String>("petstore_auth")
330330

331331
val localVariableBody =
332332
formData {
333333
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
334-
file?.apply { append("file", file) }
334+
file?.apply { append(file) }
335335
}
336336

337337
val localVariableQuery = mutableMapOf<String, List<String>>()

0 commit comments

Comments
 (0)