diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md
index af5c9a3f8743..19f4a5174211 100644
--- a/docs/generators/kotlin.md
+++ b/docs/generators/kotlin.md
@@ -8,7 +8,7 @@ sidebar_label: kotlin
|apiSuffix|suffix for api classes| |Api|
|artifactId|Generated artifact id (name of jar).| |kotlin-client|
|artifactVersion|Generated artifact's package version.| |1.0.0|
-|collectionType|Option. Collection type to use|
- **array**
- kotlin.Array
- **list**
- kotlin.collections.List
|array|
+|collectionType|Option. Collection type to use|- **array**
- kotlin.Array
- **list**
- kotlin.collections.List
|list|
|dateLibrary|Option. Date library to use|- **threetenbp-localdatetime**
- Threetenbp - Backport of JSR310 (jvm only, for legacy app only)
- **string**
- String
- **java8-localdatetime**
- Java 8 native JSR310 (jvm only, for legacy app only)
- **java8**
- Java 8 native JSR310 (jvm only, preferred for jdk 1.8+)
- **threetenbp**
- Threetenbp - Backport of JSR310 (jvm only, preferred for jdk < 1.8)
|java8|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index 8bfc119e766d..96eccd51021c 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -25,23 +25,7 @@
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Compiler;
import com.samskivert.mustache.Mustache.Lambda;
-import io.swagger.v3.core.util.Json;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.Operation;
-import io.swagger.v3.oas.models.PathItem;
-import io.swagger.v3.oas.models.callbacks.Callback;
-import io.swagger.v3.oas.models.examples.Example;
-import io.swagger.v3.oas.models.headers.Header;
-import io.swagger.v3.oas.models.media.*;
-import io.swagger.v3.oas.models.parameters.*;
-import io.swagger.v3.oas.models.responses.ApiResponse;
-import io.swagger.v3.oas.models.responses.ApiResponses;
-import io.swagger.v3.oas.models.security.OAuthFlow;
-import io.swagger.v3.oas.models.security.OAuthFlows;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import io.swagger.v3.oas.models.servers.ServerVariable;
-import io.swagger.v3.parser.util.SchemaTypeUtil;
+
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
@@ -59,7 +43,6 @@
import org.openapitools.codegen.templating.mustache.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.OneOfImplementorAdditionalData;
-import org.openapitools.codegen.utils.SemVer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,6 +56,24 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import io.swagger.v3.core.util.Json;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.callbacks.Callback;
+import io.swagger.v3.oas.models.examples.Example;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.media.*;
+import io.swagger.v3.oas.models.parameters.*;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import io.swagger.v3.oas.models.security.OAuthFlow;
+import io.swagger.v3.oas.models.security.OAuthFlows;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import io.swagger.v3.oas.models.servers.ServerVariable;
+import io.swagger.v3.parser.util.SchemaTypeUtil;
+
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*;
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
index 347ce1d07cfb..6c6ba19bb120 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
@@ -158,7 +158,7 @@ public AbstractKotlinCodegen() {
typeMapping.put("set", "kotlin.collections.Set");
typeMapping.put("map", "kotlin.collections.Map");
typeMapping.put("object", "kotlin.Any");
- typeMapping.put("binary", "kotlin.Array");
+ typeMapping.put("binary", "kotlin.ByteArray");
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.LocalDateTime");
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java
index fa53b2dfc906..85a2956fc4f7 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java
@@ -62,7 +62,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
protected String dateLibrary = DateLibrary.JAVA8.value;
protected String requestDateConverter = RequestDateConverter.TO_JSON.value;
- protected String collectionType = CollectionType.ARRAY.value;
+ protected String collectionType = CollectionType.LIST.value;
protected boolean useRxJava = false;
protected boolean useRxJava2 = false;
protected boolean useCoroutines = false;
@@ -593,6 +593,10 @@ public Map postProcessOperationsWithModels(Map o
List ops = (List) operations.get("operation");
for (CodegenOperation operation : ops) {
+ if (JVM_RETROFIT2.equals(getLibrary()) && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/")) {
+ operation.path = operation.path.substring(1);
+ }
+
// set multipart against all relevant operations
if (operation.hasConsumes == Boolean.TRUE) {
if (isMultipartType(operation.consumes)) {
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java
index 7d142d8a244a..909c1f59cf20 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java
@@ -18,12 +18,9 @@
import com.google.common.collect.ImmutableMap.Builder;
import com.samskivert.mustache.Mustache;
-import com.samskivert.mustache.Template;
import com.samskivert.mustache.Mustache.Lambda;
+import com.samskivert.mustache.Template;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.Operation;
-import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.meta.features.*;
@@ -37,7 +34,9 @@
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
-import java.util.stream.Collectors;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
import static org.openapitools.codegen.utils.StringUtils.camelize;
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
index e1f5062f2e2e..1b63b0878117 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
@@ -28,6 +28,7 @@ import kotlinx.serialization.internal.CommonEnumSerializer
{{#serializableModel}}
import java.io.Serializable
{{/serializableModel}}
+
/**
* {{{description}}}
{{#allVars}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/queryParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/queryParams.mustache
index b5bace590c56..0ee26c9ec0f0 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/queryParams.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/queryParams.mustache
@@ -1 +1 @@
-{{#isQueryParam}}@Query("{{baseName}}") {{{paramName}}}: {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}}{{/isQueryParam}}
\ No newline at end of file
+{{#isQueryParam}}@Query("{{baseName}}") {{{paramName}}}: {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}}{{^required}}? = null{{/required}}{{/isQueryParam}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache
index aac93219b677..d268f23a77d3 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache
@@ -17,33 +17,33 @@ import kotlinx.serialization.internal.StringDescriptor
{{#operations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}class {{classname}} @UseExperimental(UnstableDefault::class) constructor(
- baseUrl: kotlin.String = "{{{basePath}}}",
- httpClientEngine: HttpClientEngine? = null,
- serializer: KotlinxSerializer)
- : ApiClient(baseUrl, httpClientEngine, serializer) {
+ baseUrl: kotlin.String = "{{{basePath}}}",
+ httpClientEngine: HttpClientEngine? = null,
+ serializer: KotlinxSerializer
+) : ApiClient(baseUrl, httpClientEngine, serializer) {
@UseExperimental(UnstableDefault::class)
constructor(
baseUrl: kotlin.String = "{{{basePath}}}",
httpClientEngine: HttpClientEngine? = null,
- jsonConfiguration: JsonConfiguration = JsonConfiguration.Default)
- : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration)))
+ jsonConfiguration: JsonConfiguration = JsonConfiguration.Default
+ ) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration)))
{{#operation}}
/**
- * {{summary}}
- * {{notes}}
- {{#allParams}}* @param {{{paramName}}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
- {{/allParams}}* @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
- */
+ * {{summary}}
+ * {{notes}}
+ {{#allParams}} * @param {{{paramName}}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
+ {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
+ */
{{#returnType}}
@Suppress("UNCHECKED_CAST")
{{/returnType}}
- suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : HttpResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}> {
+ suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}): HttpResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}> {
val localVariableAuthNames = listOf({{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}})
- val localVariableBody = {{#hasBodyParam}}{{#bodyParam}}{{#isListContainer}}{{operationIdCamelCase}}Request({{{paramName}}}.asList()){{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}{{operationIdCamelCase}}Request({{{paramName}}}){{/isMapContainer}}{{^isMapContainer}}{{{paramName}}}{{/isMapContainer}}{{/isListContainer}}{{/bodyParam}}{{/hasBodyParam}}
+ val localVariableBody = {{#hasBodyParam}}{{#bodyParam}}{{#isListContainer}}{{operationIdCamelCase}}Request({{{paramName}}}{{^isList}}.asList(){{/isList}}){{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}{{operationIdCamelCase}}Request({{{paramName}}}){{/isMapContainer}}{{^isMapContainer}}{{{paramName}}}{{/isMapContainer}}{{/isListContainer}}{{/bodyParam}}{{/hasBodyParam}}
{{^hasBodyParam}}
{{#hasFormParams}}
{{#isMultipart}}
@@ -78,7 +78,7 @@ import kotlinx.serialization.internal.StringDescriptor
val localVariableConfig = RequestConfig(
RequestMethod.{{httpMethod}},
- "{{path}}"{{#pathParams}}.replace("{"+"{{baseName}}"+"}", "${{{paramName}}}"){{/pathParams}},
+ "{{path}}"{{#pathParams}}.replace("{" + "{{baseName}}" + "}", "${{{paramName}}}"){{/pathParams}},
query = localVariableQuery,
headers = localVariableHeaders
)
@@ -87,20 +87,20 @@ import kotlinx.serialization.internal.StringDescriptor
localVariableConfig,
localVariableBody,
localVariableAuthNames
- ).{{#isListContainer}}wrap<{{operationIdCamelCase}}Response>().map { value.toTypedArray() }{{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}wrap<{{operationIdCamelCase}}Response>().map { value }{{/isMapContainer}}{{^isMapContainer}}wrap(){{/isMapContainer}}{{/isListContainer}}
+ ).{{#isListContainer}}wrap<{{operationIdCamelCase}}Response>().map { value{{^isList}}.toTypedArray(){{/isList}} }{{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}wrap<{{operationIdCamelCase}}Response>().map { value }{{/isMapContainer}}{{^isMapContainer}}wrap(){{/isMapContainer}}{{/isListContainer}}
}
- {{#hasBodyParam}}
- {{#bodyParam}}
- {{#isListContainer}}{{>serial_wrapper_request_list}}{{/isListContainer}}{{#isMapContainer}}{{>serial_wrapper_request_map}}{{/isMapContainer}}
- {{/bodyParam}}
- {{/hasBodyParam}}
- {{#isListContainer}}
- {{>serial_wrapper_response_list}}
- {{/isListContainer}}
- {{#isMapContainer}}
- {{>serial_wrapper_response_map}}
- {{/isMapContainer}}
+{{#hasBodyParam}}
+{{#bodyParam}}
+{{#isListContainer}}{{>serial_wrapper_request_list}}{{/isListContainer}}{{#isMapContainer}}{{>serial_wrapper_request_map}}{{/isMapContainer}}
+{{/bodyParam}}
+{{/hasBodyParam}}
+{{#isListContainer}}
+{{>serial_wrapper_response_list}}
+{{/isListContainer}}
+{{#isMapContainer}}
+{{>serial_wrapper_response_map}}
+{{/isMapContainer}}
{{/operation}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_list.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_list.mustache
index 6b07c05f44e4..a44a242cbd2d 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_list.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_list.mustache
@@ -1,10 +1,10 @@
-@Serializable
-private class {{operationIdCamelCase}}Request(val value: List<{{#bodyParam}}{{baseType}}{{/bodyParam}}>) {
- @Serializer({{operationIdCamelCase}}Request::class)
- {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Request> {
- private val serializer: KSerializer> = {{#bodyParam}}{{baseType}}{{/bodyParam}}.serializer().list
- override val descriptor = StringDescriptor.withName("{{operationIdCamelCase}}Request")
- override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Request) = serializer.serialize(encoder, obj.value)
- override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Request(serializer.deserialize(decoder))
- }
-}
\ No newline at end of file
+ @Serializable
+ private class {{operationIdCamelCase}}Request(val value: List<{{#bodyParam}}{{baseType}}{{/bodyParam}}>) {
+ @Serializer({{operationIdCamelCase}}Request::class)
+ {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Request> {
+ private val serializer: KSerializer> = {{#bodyParam}}{{baseType}}{{/bodyParam}}.serializer().list
+ override val descriptor = StringDescriptor.withName("{{operationIdCamelCase}}Request")
+ override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Request) = serializer.serialize(encoder, obj.value)
+ override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Request(serializer.deserialize(decoder))
+ }
+ }
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_map.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_map.mustache
index f3a28700adf1..5dc6864aae82 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_map.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_request_map.mustache
@@ -1,10 +1,10 @@
-@Serializable
-private class {{operationIdCamelCase}}Request(val value: Map) {
- @Serializer({{operationIdCamelCase}}Request::class)
- {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Request> {
- private val serializer: KSerializer