diff --git a/docs/generators/kotlin-server-deprecated.md b/docs/generators/kotlin-server-deprecated.md index aa33465abdd6..778b13ee7b30 100644 --- a/docs/generators/kotlin-server-deprecated.md +++ b/docs/generators/kotlin-server-deprecated.md @@ -93,6 +93,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • object
  • open
  • package
  • +
  • private
  • return
  • super
  • this
  • diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index 4ea1d39a6ee1..f6e6c2603433 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -95,6 +95,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • object
  • open
  • package
  • +
  • private
  • return
  • super
  • this
  • diff --git a/docs/generators/kotlin-spring.md b/docs/generators/kotlin-spring.md index e2895ecc57fa..581524329644 100644 --- a/docs/generators/kotlin-spring.md +++ b/docs/generators/kotlin-spring.md @@ -106,6 +106,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • object
  • open
  • package
  • +
  • private
  • return
  • super
  • this
  • diff --git a/docs/generators/kotlin-vertx.md b/docs/generators/kotlin-vertx.md index 2d0fb923d13f..246ffa62a64e 100644 --- a/docs/generators/kotlin-vertx.md +++ b/docs/generators/kotlin-vertx.md @@ -87,6 +87,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • object
  • open
  • package
  • +
  • private
  • return
  • super
  • this
  • diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md index 5883c0f573e3..8f853b41cac8 100644 --- a/docs/generators/kotlin.md +++ b/docs/generators/kotlin.md @@ -14,7 +14,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |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| -|library|Library template (sub-template) to use|
    **jvm-okhttp4**
    [DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.
    **jvm-okhttp3**
    Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0.
    **jvm-retrofit2**
    Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.
    **multiplatform**
    Platform: Kotlin multiplatform. HTTP client: Ktor 1.2.4. JSON processing: Kotlinx Serialization: 0.12.0.
    |jvm-okhttp4| +|library|Library template (sub-template) to use|
    **jvm-okhttp4**
    [DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.
    **jvm-okhttp3**
    Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0.
    **jvm-retrofit2**
    Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.
    **multiplatform**
    Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.0. JSON processing: Kotlinx Serialization: 1.2.1.
    |jvm-okhttp4| |modelMutable|Create mutable models| |false| |moshiCodeGen|Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info.| |false| |packageName|Generated artifact package name.| |org.openapitools.client| @@ -97,6 +97,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • object
  • open
  • package
  • +
  • private
  • return
  • super
  • this
  • 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 8905d13a3f75..2506f6d7e0c2 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 @@ -126,6 +126,7 @@ public AbstractKotlinCodegen() { "var", "when", "while", + "private", "open", "external", "internal" 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 5c9b27ae59d9..1b71f1a9e27a 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 @@ -188,7 +188,7 @@ public KotlinClientCodegen() { supportedLibraries.put(JVM_OKHTTP4, "[DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0."); supportedLibraries.put(JVM_OKHTTP3, "Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0."); supportedLibraries.put(JVM_RETROFIT2, "Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2."); - supportedLibraries.put(MULTIPLATFORM, "Platform: Kotlin multiplatform. HTTP client: Ktor 1.2.4. JSON processing: Kotlinx Serialization: 0.12.0."); + supportedLibraries.put(MULTIPLATFORM, "Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.0. JSON processing: Kotlinx Serialization: 1.2.1."); CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "Library template (sub-template) to use"); libraryOption.setEnum(supportedLibraries); @@ -591,8 +591,13 @@ private void commonJvmMultiplatformSupportingFiles(String infrastructureFolder) private void commonSupportingFiles() { supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); - supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); - supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); + if(getLibrary().equals(MULTIPLATFORM)) { + supportingFiles.add(new SupportingFile("build.gradle.kts.mustache", "", "build.gradle.kts")); + supportingFiles.add(new SupportingFile("settings.gradle.kts.mustache", "", "settings.gradle.kts")); + } else { + supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); + supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); + } // gradle wrapper supporting files supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew")); diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache index 110b828a0b9d..546790a7fb6d 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache @@ -7,7 +7,7 @@ * Gradle 6.8.3 {{/jvm}} {{#multiplatform}} -* Kotlin 1.3.50 +* Kotlin 1.5.10 {{/multiplatform}} ## Build @@ -89,4 +89,4 @@ Authentication schemes defined for the API: {{/scopes}} {{/isOAuth}} -{{/authMethods}} \ No newline at end of file +{{/authMethods}} 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 f840db6e394e..093d30318393 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 @@ -29,7 +29,8 @@ import kotlinx.parcelize.Parcelize {{/multiplatform}} {{#multiplatform}} import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* {{/multiplatform}} {{#serializableModel}} import java.io.Serializable @@ -44,7 +45,7 @@ import java.io.Serializable {{#parcelizeModels}} @Parcelize {{/parcelizeModels}} -{{#multiplatform}}@Serializable{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} +{{#multiplatform}}{{#discriminator}}{{/discriminator}}{{^discriminator}}@Serializable{{/discriminator}}{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} {{#isDeprecated}} @Deprecated(message = "This schema is deprecated.") {{/isDeprecated}} @@ -69,9 +70,14 @@ import java.io.Serializable * {{{description}}} * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} */ + {{^multiplatform}} {{#kotlinx_serialization}} {{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}} {{/kotlinx_serialization}} + {{/multiplatform}} + {{#multiplatform}} + @Serializable + {{/multiplatform}} {{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{{nameInCamelCase}}}(val value: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}kotlin.String{{/isContainer}}) { {{#allowableValues}} {{#enumVars}} @@ -90,7 +96,7 @@ import java.io.Serializable {{/kotlinx_serialization}} {{/multiplatform}} {{#multiplatform}} - {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} + @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} {{/multiplatform}} {{/enumVars}} {{/allowableValues}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/enum_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/enum_class.mustache index 2071a6b537a2..4a6a7acfa314 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/enum_class.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/enum_class.mustache @@ -15,14 +15,14 @@ import kotlinx.serialization.Serializable {{/multiplatform}} {{#multiplatform}} import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer {{/multiplatform}} /** * {{{description}}} * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} */ -{{#multiplatform}}@Serializable(with = {{classname}}.Serializer::class){{/multiplatform}}{{#kotlinx_serialization}}@Serializable{{/kotlinx_serialization}} + +{{#multiplatform}}@Serializable{{/multiplatform}}{{#kotlinx_serialization}}@Serializable{{/kotlinx_serialization}} {{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{classname}}(val value: {{{dataType}}}) { {{#allowableValues}}{{#enumVars}} @@ -40,6 +40,9 @@ import kotlinx.serialization.internal.CommonEnumSerializer @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{/kotlinx_serialization}} {{/multiplatform}} + {{#multiplatform}} + @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) + {{/multiplatform}} {{#isArray}} {{#isList}} {{&name}}(listOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}} 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 e51da4590b88..232dda06db3c 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 @@ -6,28 +6,20 @@ package {{apiPackage}} import {{packageName}}.infrastructure.* import io.ktor.client.request.forms.formData -import kotlinx.serialization.UnstableDefault import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.serializer.KotlinxSerializer import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import io.ktor.http.ParametersBuilder import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* {{#operations}} -{{#nonPublicApi}}internal {{/nonPublicApi}}class {{classname}} @UseExperimental(UnstableDefault::class) constructor( - baseUrl: kotlin.String = "{{{basePath}}}", +{{#nonPublicApi}}internal {{/nonPublicApi}}class {{classname}}( + baseUrl: String = ApiClient.BASE_URL, 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))) + jsonSerializer: Json = ApiClient.JSON_DEFAULT +) : ApiClient(baseUrl, httpClientEngine, jsonSerializer) { {{#operation}} /** @@ -76,7 +68,7 @@ import kotlinx.serialization.internal.StringDescriptor {{{paramName}}}?.apply { localVariableHeaders["{{baseName}}"] = {{#isContainer}}this.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}this.toString(){{/isContainer}} } {{/headerParams}} - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.{{httpMethod}}, "{{path}}"{{#pathParams}}.replace("{" + "{{baseName}}" + "}", "${{{paramName}}}"){{/pathParams}}, query = localVariableQuery, @@ -103,23 +95,5 @@ import kotlinx.serialization.internal.StringDescriptor {{/isMap}} {{/operation}} - - {{#nonPublicApi}}internal {{/nonPublicApi}}companion object { - internal fun setMappers(serializer: KotlinxSerializer) { - {{#operation}} - {{#hasBodyParam}} - {{#bodyParam}} - {{#isArray}}serializer.setMapper({{operationIdCamelCase}}Request::class, {{operationIdCamelCase}}Request.serializer()){{/isArray}}{{#isMap}}serializer.setMapper({{operationIdCamelCase}}Request::class, {{operationIdCamelCase}}Request.serializer()){{/isMap}} - {{/bodyParam}} - {{/hasBodyParam}} - {{#isArray}} - serializer.setMapper({{operationIdCamelCase}}Response::class, {{operationIdCamelCase}}Response.serializer()) - {{/isArray}} - {{#isMap}} - serializer.setMapper({{operationIdCamelCase}}Response::class, {{operationIdCamelCase}}Response.serializer()) - {{/isMap}} - {{/operation}} - } - } } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.kts.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.kts.mustache new file mode 100644 index 000000000000..c6fb465777f7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.kts.mustache @@ -0,0 +1,95 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget + +plugins { + kotlin("multiplatform") version "1.5.10" // kotlin_version + kotlin("plugin.serialization") version "1.5.10" // kotlin_version +} + +group = "{{groupId}}" +version = "{{artifactVersion}}" + +val kotlin_version = "1.5.10" +val coroutines_version = "1.5.0" +val serialization_version = "1.2.1" +val ktor_version = "1.6.0" + +repositories { + mavenCentral() +} + +kotlin { + jvm() + ios { binaries { framework { freeCompilerArgs += "-Xobjc-generics" } } } + js { + browser() + nodejs() + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version") + api("io.ktor:ktor-client-core:$ktor_version") + api("io.ktor:ktor-client-json:$ktor_version") + api("io.ktor:ktor-client-serialization:$ktor_version") + } + } + + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + implementation("io.ktor:ktor-client-mock:$ktor_version") + } + } + + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib-jdk7")) + } + } + + val jvmTest by getting { + dependencies { + implementation(kotlin("test-junit")) + } + } + + val iosMain by getting { + dependencies { + api("io.ktor:ktor-client-ios:$ktor_version") + } + } + + val iosTest by getting + + val jsMain by getting { + dependencies { + api("io.ktor:ktor-client-js:$ktor_version") + } + } + + val jsTest by getting + + all { + languageSettings.apply { + useExperimentalAnnotation("kotlin.Experimental") + } + } + } +} + +tasks { + register("iosTest") { + val device = project.findProperty("device")?.toString() ?: "iPhone 8" + dependsOn("linkDebugTestIosX64") + group = JavaBasePlugin.VERIFICATION_GROUP + description = "Execute unit tests on ${device} simulator" + doLast { + val binary = kotlin.targets.getByName("iosX64").binaries.getTest("DEBUG") + exec { + commandLine("xcrun", "simctl", "spawn", device, binary.outputFile) + } + } + } +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.mustache deleted file mode 100644 index dfc6736dc6d5..000000000000 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.mustache +++ /dev/null @@ -1,161 +0,0 @@ -apply plugin: 'kotlin-multiplatform' -apply plugin: 'kotlinx-serialization' - -group '{{groupId}}' -version '{{artifactVersion}}' - -ext { - kotlin_version = '1.3.50' - kotlinx_version = '1.1.0' - coroutines_version = '1.3.1' - serialization_version = '0.12.0' - ktor_version = '1.2.4' -} - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" // $kotlin_version - classpath "org.jetbrains.kotlin:kotlin-serialization:1.3.50" // $kotlin_version - } -} - -repositories { - jcenter() -} - -kotlin { - jvm() - iosArm64() { binaries { framework { freeCompilerArgs.add("-Xobjc-generics") } } } - iosX64() { binaries { framework { freeCompilerArgs.add("-Xobjc-generics") } } } - js() - - sourceSets { - commonMain { - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version" - api "io.ktor:ktor-client-core:$ktor_version" - api "io.ktor:ktor-client-json:$ktor_version" - api "io.ktor:ktor-client-serialization:$ktor_version" - } - } - - commonTest { - dependencies { - implementation "org.jetbrains.kotlin:kotlin-test-common" - implementation "org.jetbrains.kotlin:kotlin-test-annotations-common" - implementation "io.ktor:ktor-client-mock:$ktor_version" - } - } - - jvmMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version" - api "io.ktor:ktor-client-core-jvm:$ktor_version" - api "io.ktor:ktor-client-json-jvm:$ktor_version" - api "io.ktor:ktor-client-serialization-jvm:$ktor_version" - } - } - - jvmTest { - dependsOn commonTest - dependencies { - implementation "org.jetbrains.kotlin:kotlin-test" - implementation "org.jetbrains.kotlin:kotlin-test-junit" - implementation "io.ktor:ktor-client-mock-jvm:$ktor_version" - } - } - - iosMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version" - api "io.ktor:ktor-client-ios:$ktor_version" - } - } - - iosTest { - dependsOn commonTest - dependencies { - implementation "io.ktor:ktor-client-mock-native:$ktor_version" - } - } - - iosArm64().compilations.main.defaultSourceSet { - dependsOn iosMain - dependencies { - api "io.ktor:ktor-client-ios-iosarm64:$ktor_version" - api "io.ktor:ktor-client-json-iosarm64:$ktor_version" - api "io.ktor:ktor-client-serialization-iosarm64:$ktor_version" - } - } - - iosArm64().compilations.test.defaultSourceSet { - dependsOn iosTest - } - - iosX64().compilations.main.defaultSourceSet { - dependsOn iosMain - dependencies { - api "io.ktor:ktor-client-ios-iosx64:$ktor_version" - api "io.ktor:ktor-client-json-iosx64:$ktor_version" - api "io.ktor:ktor-client-serialization-iosx64:$ktor_version" - } - } - - jsMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version" - api "io.ktor:ktor-client-js:$ktor_version" - api "io.ktor:ktor-client-json-js:$ktor_version" - api "io.ktor:ktor-client-serialization-js:$ktor_version" - } - } - - jsTest { - dependsOn commonTest - dependencies { - implementation "io.ktor:ktor-client-mock-js:$ktor_version" - implementation "io.ktor:ktor-client-js:$ktor_version" - implementation "io.ktor:ktor-client-json:$ktor_version" - implementation "io.ktor:ktor-client-serialization-js:$ktor_version" - } - } - - iosX64().compilations.test.defaultSourceSet { - dependsOn iosTest - } - - all { - languageSettings { - useExperimentalAnnotation('kotlin.Experimental') - } - } - } -} - -task iosTest { - def device = project.findProperty("device")?.toString() ?: "iPhone 8" - dependsOn 'linkDebugTestIosX64' - group = JavaBasePlugin.VERIFICATION_GROUP - description = "Execute unit tests on ${device} simulator" - doLast { - def binary = kotlin.targets.iosX64.binaries.getTest('DEBUG') - exec { commandLine 'xcrun', 'simctl', 'spawn', device, binary.outputFile } - } -} - -configurations { // workaround for https://youtrack.jetbrains.com/issue/KT-27170 - compileClasspath -} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache index b1cf9583bdbf..27b6162f1211 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache @@ -2,24 +2,21 @@ package {{packageName}}.infrastructure import io.ktor.client.HttpClient import io.ktor.client.HttpClientConfig -import io.ktor.client.call.call import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.JsonSerializer import io.ktor.client.features.json.serializer.KotlinxSerializer -import io.ktor.client.request.accept +import io.ktor.client.request.* import io.ktor.client.request.forms.FormDataContent import io.ktor.client.request.forms.MultiPartFormDataContent import io.ktor.client.request.header import io.ktor.client.request.parameter -import io.ktor.client.response.HttpResponse +import io.ktor.client.statement.HttpResponse import io.ktor.client.utils.EmptyContent import io.ktor.http.* import io.ktor.http.content.OutgoingContent import io.ktor.http.content.PartData -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import {{apiPackage}}.* import {{modelPackage}}.* @@ -28,17 +25,11 @@ import {{packageName}}.auth.* {{#nonPublicApi}}internal {{/nonPublicApi}}open class ApiClient( private val baseUrl: String, httpClientEngine: HttpClientEngine?, - serializer: KotlinxSerializer) { - - @UseExperimental(UnstableDefault::class) - constructor( - baseUrl: String, - httpClientEngine: HttpClientEngine?, - jsonConfiguration: JsonConfiguration) : - this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) + private val json: Json +) { private val serializer: JsonSerializer by lazy { - serializer.apply { setMappers(this) }.ignoreOutgoingContent() + KotlinxSerializer(json).ignoreOutgoingContent() } private val client: HttpClient by lazy { @@ -60,16 +51,9 @@ import {{packageName}}.auth.* {{/hasAuthMethods}} {{#nonPublicApi}}internal {{/nonPublicApi}}companion object { + const val BASE_URL = "{{{basePath}}}" + val JSON_DEFAULT = Json { ignoreUnknownKeys = true } protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType) - - private fun setMappers(serializer: KotlinxSerializer) { - {{#apiInfo}}{{#apis}} - {{classname}}.setMappers(serializer) - {{/apis}}{{/apiInfo}} - {{#models}} - {{#model}}{{^isAlias}}serializer.setMapper({{modelPackage}}.{{classname}}::class, {{modelPackage}}.{{classname}}.{{#isEnum}}Serializer{{/isEnum}}{{^isEnum}}serializer(){{/isEnum}}){{/isAlias}}{{/model}} - {{/models}} - } } /** @@ -140,26 +124,26 @@ import {{packageName}}.auth.* auth.bearerToken = bearerToken } - protected suspend fun multipartFormRequest(requestConfig: RequestConfig, body: kotlin.collections.List?, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun multipartFormRequest(requestConfig: RequestConfig, body: kotlin.collections.List?, authNames: kotlin.collections.List): HttpResponse { return request(requestConfig, MultiPartFormDataContent(body ?: listOf()), authNames) } - protected suspend fun urlEncodedFormRequest(requestConfig: RequestConfig, body: Parameters?, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun urlEncodedFormRequest(requestConfig: RequestConfig, body: Parameters?, authNames: kotlin.collections.List): HttpResponse { return request(requestConfig, FormDataContent(body ?: Parameters.Empty), authNames) } - protected suspend fun jsonRequest(requestConfig: RequestConfig, body: Any? = null, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun jsonRequest(requestConfig: RequestConfig, body: Any? = null, authNames: kotlin.collections.List): HttpResponse { val contentType = (requestConfig.headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) } ?: ContentType.Application.Json) return if (body != null) request(requestConfig, serializer.write(body, contentType), authNames) else request(requestConfig, authNames = authNames) } - protected suspend inline fun request(requestConfig: RequestConfig, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List): HttpResponse { - requestConfig.updateForAuth(authNames) + protected suspend fun request(requestConfig: RequestConfig, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List): HttpResponse { + requestConfig.updateForAuth(authNames) val headers = requestConfig.headers - return client.call { + return client.request { this.url { this.takeFrom(URLBuilder(baseUrl)) appendPath(requestConfig.path.trimStart('/').split('/')) @@ -174,10 +158,10 @@ import {{packageName}}.auth.* if (requestConfig.method in listOf(RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH)) this.body = body - }.response + } } - private fun RequestConfig.updateForAuth(authNames: kotlin.collections.List) { + private fun RequestConfig.updateForAuth(authNames: kotlin.collections.List) { for (authName in authNames) { val auth = authentications?.get(authName) ?: throw Exception("Authentication undefined: $authName") auth.apply(query, headers) diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Base64ByteArray.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Base64ByteArray.kt.mustache index 168cfc993c3b..c3122bd2a597 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Base64ByteArray.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Base64ByteArray.kt.mustache @@ -1,13 +1,14 @@ package {{packageName}}.infrastructure import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* @Serializable class Base64ByteArray(val value: ByteArray) { @Serializer(Base64ByteArray::class) companion object : KSerializer { - override val descriptor = StringDescriptor.withName("Base64ByteArray") + override val descriptor = PrimitiveSerialDescriptor("Base64ByteArray", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, obj: Base64ByteArray) = encoder.encodeString(obj.value.encodeBase64()) override fun deserialize(decoder: Decoder) = Base64ByteArray(decoder.decodeString().decodeBase64Bytes()) } diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Bytes.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Bytes.kt.mustache index b85013e647b2..e882220ade6d 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Bytes.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/Bytes.kt.mustache @@ -1,6 +1,6 @@ package {{packageName}}.infrastructure -import kotlinx.io.core.* +import io.ktor.utils.io.core.* import kotlin.experimental.and private val digits = "0123456789abcdef".toCharArray() @@ -32,7 +32,7 @@ internal fun hex(bytes: ByteArray): String { result[resultIndex++] = digits[b and 0x0f] } - return String(result) + return result.concatToString() } /** diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/HttpResponse.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/HttpResponse.kt.mustache index 87f27a5cf56f..12d265674611 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/HttpResponse.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/HttpResponse.kt.mustache @@ -5,7 +5,7 @@ import io.ktor.client.call.typeInfo import io.ktor.http.Headers import io.ktor.http.isSuccess -{{#nonPublicApi}}internal {{/nonPublicApi}}open class HttpResponse(val response: io.ktor.client.response.HttpResponse, val provider: BodyProvider) { +{{#nonPublicApi}}internal {{/nonPublicApi}}open class HttpResponse(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider) { val status: Int = response.status.value val success: Boolean = response.status.isSuccess() val headers: Map> = response.headers.mapEntries() @@ -22,29 +22,29 @@ import io.ktor.http.isSuccess } {{#nonPublicApi}}internal {{/nonPublicApi}}interface BodyProvider { - suspend fun body(response: io.ktor.client.response.HttpResponse): T - suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V + suspend fun body(response: io.ktor.client.statement.HttpResponse): T + suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V } {{#nonPublicApi}}internal {{/nonPublicApi}}class TypedBodyProvider(private val type: TypeInfo) : BodyProvider { @Suppress("UNCHECKED_CAST") - override suspend fun body(response: io.ktor.client.response.HttpResponse): T = + override suspend fun body(response: io.ktor.client.statement.HttpResponse): T = response.call.receive(type) as T @Suppress("UNCHECKED_CAST") - override suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V = + override suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V = response.call.receive(type) as V } {{#nonPublicApi}}internal {{/nonPublicApi}}class MappedBodyProvider(private val provider: BodyProvider, private val block: S.() -> T) : BodyProvider { - override suspend fun body(response: io.ktor.client.response.HttpResponse): T = + override suspend fun body(response: io.ktor.client.statement.HttpResponse): T = block(provider.body(response)) - override suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V = + override suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V = provider.typedBody(response, type) } -{{#nonPublicApi}}internal {{/nonPublicApi}}inline fun io.ktor.client.response.HttpResponse.wrap(): HttpResponse = +{{#nonPublicApi}}internal {{/nonPublicApi}}inline fun io.ktor.client.statement.HttpResponse.wrap(): HttpResponse = HttpResponse(this, TypedBodyProvider(typeInfo())) {{#nonPublicApi}}internal {{/nonPublicApi}}fun HttpResponse.map(block: T.() -> V): HttpResponse = diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/OctetByteArray.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/OctetByteArray.kt.mustache index c23ac3ec0001..d77a0bcbb484 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/OctetByteArray.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/infrastructure/OctetByteArray.kt.mustache @@ -1,13 +1,14 @@ package {{packageName}}.infrastructure import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* @Serializable class OctetByteArray(val value: ByteArray) { @Serializer(OctetByteArray::class) companion object : KSerializer { - override val descriptor = StringDescriptor.withName("OctetByteArray") + override val descriptor = PrimitiveSerialDescriptor("OctetByteArray", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, obj: OctetByteArray) = encoder.encodeString(hex(obj.value)) override fun deserialize(decoder: Decoder) = OctetByteArray(hex(decoder.decodeString())) } 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 a44a242cbd2d..f3b0464445ec 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 @@ -2,9 +2,9 @@ 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)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + 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 5dc6864aae82..a287882728db 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 @@ -2,9 +2,9 @@ private class {{operationIdCamelCase}}Request(val value: Map) { @Serializer({{operationIdCamelCase}}Request::class) {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Request> { - private val serializer: KSerializer> = (kotlin.String.serializer() to {{#bodyParam}}{{baseType}}{{/bodyParam}}.serializer()).map - 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)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + 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_response_list.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_list.mustache index a4e70a219ca4..227d6a351f29 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_list.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_list.mustache @@ -2,9 +2,9 @@ private class {{operationIdCamelCase}}Response(val value: List<{{returnBaseType}}>) { @Serializer({{operationIdCamelCase}}Response::class) {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Response> { - private val serializer: KSerializer> = {{returnBaseType}}.serializer().list - override val descriptor = StringDescriptor.withName("{{operationIdCamelCase}}Response") - override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Response) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Response(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Response) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Response(serializer.deserialize(decoder)) } } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_map.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_map.mustache index 8253dc1f1a1c..a6bdd6c166a1 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_map.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/serial_wrapper_response_map.mustache @@ -2,9 +2,9 @@ private class {{operationIdCamelCase}}Response(val value: Map) { @Serializer({{operationIdCamelCase}}Response::class) {{#nonPublicApi}}internal {{/nonPublicApi}}companion object : KSerializer<{{operationIdCamelCase}}Response> { - private val serializer: KSerializer> = (kotlin.String.serializer() to {{returnBaseType}}.serializer()).map - override val descriptor = StringDescriptor.withName("{{operationIdCamelCase}}Response") - override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Response) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Response(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: {{operationIdCamelCase}}Response) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = {{operationIdCamelCase}}Response(serializer.deserialize(decoder)) } } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/settings.gradle.kts.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/settings.gradle.kts.mustache new file mode 100644 index 000000000000..bf286c5e8c29 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/settings.gradle.kts.mustache @@ -0,0 +1,2 @@ +enableFeaturePreview("GRADLE_METADATA") +rootProject.name = "{{artifactId}}" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2dc1b41f00a5..adbfc2a89873 100644 --- a/pom.xml +++ b/pom.xml @@ -1267,7 +1267,6 @@ samples/server/petstore/jaxrs-spec-interface-response samples/server/petstore/java-vertx-web samples/server/petstore/java-inflector - samples/server/petstore/java-pkmst samples/server/petstore/java-play-framework samples/server/petstore/java-play-framework-no-wrap-calls samples/server/petstore/java-play-framework-no-swagger-ui diff --git a/samples/client/petstore/kotlin-multiplatform/.openapi-generator/FILES b/samples/client/petstore/kotlin-multiplatform/.openapi-generator/FILES index e79293ae5715..d95b6af6c45f 100644 --- a/samples/client/petstore/kotlin-multiplatform/.openapi-generator/FILES +++ b/samples/client/petstore/kotlin-multiplatform/.openapi-generator/FILES @@ -1,5 +1,5 @@ README.md -build.gradle +build.gradle.kts docs/ApiResponse.md docs/Category.md docs/Order.md @@ -9,7 +9,7 @@ docs/StoreApi.md docs/Tag.md docs/User.md docs/UserApi.md -settings.gradle +settings.gradle.kts src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt src/commonMain/kotlin/org/openapitools/client/apis/StoreApi.kt src/commonMain/kotlin/org/openapitools/client/apis/UserApi.kt diff --git a/samples/client/petstore/kotlin-multiplatform/README.md b/samples/client/petstore/kotlin-multiplatform/README.md index 308e8b1c99ef..28a4e3f12011 100644 --- a/samples/client/petstore/kotlin-multiplatform/README.md +++ b/samples/client/petstore/kotlin-multiplatform/README.md @@ -2,7 +2,7 @@ ## Requires -* Kotlin 1.3.50 +* Kotlin 1.5.10 ## Build diff --git a/samples/client/petstore/kotlin-multiplatform/build.gradle b/samples/client/petstore/kotlin-multiplatform/build.gradle deleted file mode 100644 index 47045bb577e1..000000000000 --- a/samples/client/petstore/kotlin-multiplatform/build.gradle +++ /dev/null @@ -1,161 +0,0 @@ -apply plugin: 'kotlin-multiplatform' -apply plugin: 'kotlinx-serialization' - -group 'org.openapitools' -version '1.0.0' - -ext { - kotlin_version = '1.3.50' - kotlinx_version = '1.1.0' - coroutines_version = '1.3.1' - serialization_version = '0.12.0' - ktor_version = '1.2.4' -} - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" // $kotlin_version - classpath "org.jetbrains.kotlin:kotlin-serialization:1.3.50" // $kotlin_version - } -} - -repositories { - jcenter() -} - -kotlin { - jvm() - iosArm64() { binaries { framework { freeCompilerArgs.add("-Xobjc-generics") } } } - iosX64() { binaries { framework { freeCompilerArgs.add("-Xobjc-generics") } } } - js() - - sourceSets { - commonMain { - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version" - api "io.ktor:ktor-client-core:$ktor_version" - api "io.ktor:ktor-client-json:$ktor_version" - api "io.ktor:ktor-client-serialization:$ktor_version" - } - } - - commonTest { - dependencies { - implementation "org.jetbrains.kotlin:kotlin-test-common" - implementation "org.jetbrains.kotlin:kotlin-test-annotations-common" - implementation "io.ktor:ktor-client-mock:$ktor_version" - } - } - - jvmMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version" - api "io.ktor:ktor-client-core-jvm:$ktor_version" - api "io.ktor:ktor-client-json-jvm:$ktor_version" - api "io.ktor:ktor-client-serialization-jvm:$ktor_version" - } - } - - jvmTest { - dependsOn commonTest - dependencies { - implementation "org.jetbrains.kotlin:kotlin-test" - implementation "org.jetbrains.kotlin:kotlin-test-junit" - implementation "io.ktor:ktor-client-mock-jvm:$ktor_version" - } - } - - iosMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version" - api "io.ktor:ktor-client-ios:$ktor_version" - } - } - - iosTest { - dependsOn commonTest - dependencies { - implementation "io.ktor:ktor-client-mock-native:$ktor_version" - } - } - - iosArm64().compilations.main.defaultSourceSet { - dependsOn iosMain - dependencies { - api "io.ktor:ktor-client-ios-iosarm64:$ktor_version" - api "io.ktor:ktor-client-json-iosarm64:$ktor_version" - api "io.ktor:ktor-client-serialization-iosarm64:$ktor_version" - } - } - - iosArm64().compilations.test.defaultSourceSet { - dependsOn iosTest - } - - iosX64().compilations.main.defaultSourceSet { - dependsOn iosMain - dependencies { - api "io.ktor:ktor-client-ios-iosx64:$ktor_version" - api "io.ktor:ktor-client-json-iosx64:$ktor_version" - api "io.ktor:ktor-client-serialization-iosx64:$ktor_version" - } - } - - jsMain { - dependsOn commonMain - dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version" - api "io.ktor:ktor-client-js:$ktor_version" - api "io.ktor:ktor-client-json-js:$ktor_version" - api "io.ktor:ktor-client-serialization-js:$ktor_version" - } - } - - jsTest { - dependsOn commonTest - dependencies { - implementation "io.ktor:ktor-client-mock-js:$ktor_version" - implementation "io.ktor:ktor-client-js:$ktor_version" - implementation "io.ktor:ktor-client-json:$ktor_version" - implementation "io.ktor:ktor-client-serialization-js:$ktor_version" - } - } - - iosX64().compilations.test.defaultSourceSet { - dependsOn iosTest - } - - all { - languageSettings { - useExperimentalAnnotation('kotlin.Experimental') - } - } - } -} - -task iosTest { - def device = project.findProperty("device")?.toString() ?: "iPhone 8" - dependsOn 'linkDebugTestIosX64' - group = JavaBasePlugin.VERIFICATION_GROUP - description = "Execute unit tests on ${device} simulator" - doLast { - def binary = kotlin.targets.iosX64.binaries.getTest('DEBUG') - exec { commandLine 'xcrun', 'simctl', 'spawn', device, binary.outputFile } - } -} - -configurations { // workaround for https://youtrack.jetbrains.com/issue/KT-27170 - compileClasspath -} diff --git a/samples/client/petstore/kotlin-multiplatform/build.gradle.kts b/samples/client/petstore/kotlin-multiplatform/build.gradle.kts new file mode 100644 index 000000000000..1b7fdd939c35 --- /dev/null +++ b/samples/client/petstore/kotlin-multiplatform/build.gradle.kts @@ -0,0 +1,95 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget + +plugins { + kotlin("multiplatform") version "1.5.10" // kotlin_version + kotlin("plugin.serialization") version "1.5.10" // kotlin_version +} + +group = "org.openapitools" +version = "1.0.0" + +val kotlin_version = "1.5.10" +val coroutines_version = "1.5.0" +val serialization_version = "1.2.1" +val ktor_version = "1.6.0" + +repositories { + mavenCentral() +} + +kotlin { + jvm() + ios { binaries { framework { freeCompilerArgs += "-Xobjc-generics" } } } + js { + browser() + nodejs() + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version") + api("io.ktor:ktor-client-core:$ktor_version") + api("io.ktor:ktor-client-json:$ktor_version") + api("io.ktor:ktor-client-serialization:$ktor_version") + } + } + + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + implementation("io.ktor:ktor-client-mock:$ktor_version") + } + } + + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib-jdk7")) + } + } + + val jvmTest by getting { + dependencies { + implementation(kotlin("test-junit")) + } + } + + val iosMain by getting { + dependencies { + api("io.ktor:ktor-client-ios:$ktor_version") + } + } + + val iosTest by getting + + val jsMain by getting { + dependencies { + api("io.ktor:ktor-client-js:$ktor_version") + } + } + + val jsTest by getting + + all { + languageSettings.apply { + useExperimentalAnnotation("kotlin.Experimental") + } + } + } +} + +tasks { + register("iosTest") { + val device = project.findProperty("device")?.toString() ?: "iPhone 8" + dependsOn("linkDebugTestIosX64") + group = JavaBasePlugin.VERIFICATION_GROUP + description = "Execute unit tests on ${device} simulator" + doLast { + val binary = kotlin.targets.getByName("iosX64").binaries.getTest("DEBUG") + exec { + commandLine("xcrun", "simctl", "spawn", device, binary.outputFile) + } + } + } +} diff --git a/samples/client/petstore/kotlin-multiplatform/settings.gradle b/samples/client/petstore/kotlin-multiplatform/settings.gradle deleted file mode 100644 index b000833f485c..000000000000 --- a/samples/client/petstore/kotlin-multiplatform/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -enableFeaturePreview('GRADLE_METADATA') -rootProject.name = 'kotlin-client-petstore-multiplatform' \ No newline at end of file diff --git a/samples/client/petstore/kotlin-multiplatform/settings.gradle.kts b/samples/client/petstore/kotlin-multiplatform/settings.gradle.kts new file mode 100644 index 000000000000..15cae2a9fd06 --- /dev/null +++ b/samples/client/petstore/kotlin-multiplatform/settings.gradle.kts @@ -0,0 +1,2 @@ +enableFeaturePreview("GRADLE_METADATA") +rootProject.name = "kotlin-client-petstore-multiplatform" \ No newline at end of file diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt index e164a6cf4d06..5df1dfc40ee4 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/PetApi.kt @@ -16,27 +16,19 @@ import org.openapitools.client.models.Pet import org.openapitools.client.infrastructure.* import io.ktor.client.request.forms.formData -import kotlinx.serialization.UnstableDefault import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.serializer.KotlinxSerializer import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import io.ktor.http.ParametersBuilder import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* -class PetApi @UseExperimental(UnstableDefault::class) constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", +class PetApi( + baseUrl: String = ApiClient.BASE_URL, httpClientEngine: HttpClientEngine? = null, - serializer: KotlinxSerializer -) : ApiClient(baseUrl, httpClientEngine, serializer) { - - @UseExperimental(UnstableDefault::class) - constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", - httpClientEngine: HttpClientEngine? = null, - jsonConfiguration: JsonConfiguration = JsonConfiguration.Default - ) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) + jsonSerializer: Json = ApiClient.JSON_DEFAULT +) : ApiClient(baseUrl, httpClientEngine, jsonSerializer) { /** * Add a new pet to the store @@ -54,7 +46,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet", query = localVariableQuery, @@ -89,7 +81,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() apiKey?.apply { localVariableHeaders["api_key"] = this.toString() } - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/pet/{petId}".replace("{" + "petId" + "}", "$petId"), query = localVariableQuery, @@ -123,7 +115,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByStatus", query = localVariableQuery, @@ -141,10 +133,10 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( private class FindPetsByStatusResponse(val value: List) { @Serializer(FindPetsByStatusResponse::class) companion object : KSerializer { - private val serializer: KSerializer> = Pet.serializer().list - override val descriptor = StringDescriptor.withName("FindPetsByStatusResponse") - override fun serialize(encoder: Encoder, obj: FindPetsByStatusResponse) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = FindPetsByStatusResponse(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: FindPetsByStatusResponse) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = FindPetsByStatusResponse(serializer.deserialize(decoder)) } } @@ -167,7 +159,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByTags", query = localVariableQuery, @@ -185,10 +177,10 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( private class FindPetsByTagsResponse(val value: List) { @Serializer(FindPetsByTagsResponse::class) companion object : KSerializer { - private val serializer: KSerializer> = Pet.serializer().list - override val descriptor = StringDescriptor.withName("FindPetsByTagsResponse") - override fun serialize(encoder: Encoder, obj: FindPetsByTagsResponse) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = FindPetsByTagsResponse(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: FindPetsByTagsResponse) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = FindPetsByTagsResponse(serializer.deserialize(decoder)) } } @@ -210,7 +202,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/{petId}".replace("{" + "petId" + "}", "$petId"), query = localVariableQuery, @@ -241,7 +233,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.PUT, "/pet", query = localVariableQuery, @@ -279,7 +271,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}".replace("{" + "petId" + "}", "$petId"), query = localVariableQuery, @@ -317,7 +309,7 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}/uploadImage".replace("{" + "petId" + "}", "$petId"), query = localVariableQuery, @@ -332,13 +324,4 @@ class PetApi @UseExperimental(UnstableDefault::class) constructor( } - - companion object { - internal fun setMappers(serializer: KotlinxSerializer) { - - serializer.setMapper(FindPetsByStatusResponse::class, FindPetsByStatusResponse.serializer()) - serializer.setMapper(FindPetsByTagsResponse::class, FindPetsByTagsResponse.serializer()) - - } - } } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/StoreApi.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/StoreApi.kt index 8ca30e8ca3a3..345ef648864b 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/StoreApi.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/StoreApi.kt @@ -15,27 +15,19 @@ import org.openapitools.client.models.Order import org.openapitools.client.infrastructure.* import io.ktor.client.request.forms.formData -import kotlinx.serialization.UnstableDefault import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.serializer.KotlinxSerializer import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import io.ktor.http.ParametersBuilder import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* -class StoreApi @UseExperimental(UnstableDefault::class) constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", +class StoreApi( + baseUrl: String = ApiClient.BASE_URL, httpClientEngine: HttpClientEngine? = null, - serializer: KotlinxSerializer -) : ApiClient(baseUrl, httpClientEngine, serializer) { - - @UseExperimental(UnstableDefault::class) - constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", - httpClientEngine: HttpClientEngine? = null, - jsonConfiguration: JsonConfiguration = JsonConfiguration.Default - ) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) + jsonSerializer: Json = ApiClient.JSON_DEFAULT +) : ApiClient(baseUrl, httpClientEngine, jsonSerializer) { /** * Delete purchase order by ID @@ -54,7 +46,7 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/store/order/{orderId}".replace("{" + "orderId" + "}", "$orderId"), query = localVariableQuery, @@ -86,7 +78,7 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/inventory", query = localVariableQuery, @@ -104,10 +96,10 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( private class GetInventoryResponse(val value: Map) { @Serializer(GetInventoryResponse::class) companion object : KSerializer { - private val serializer: KSerializer> = (kotlin.String.serializer() to kotlin.Int.serializer()).map - override val descriptor = StringDescriptor.withName("GetInventoryResponse") - override fun serialize(encoder: Encoder, obj: GetInventoryResponse) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = GetInventoryResponse(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: GetInventoryResponse) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = GetInventoryResponse(serializer.deserialize(decoder)) } } @@ -129,7 +121,7 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/order/{orderId}".replace("{" + "orderId" + "}", "$orderId"), query = localVariableQuery, @@ -161,7 +153,7 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/store/order", query = localVariableQuery, @@ -177,11 +169,4 @@ class StoreApi @UseExperimental(UnstableDefault::class) constructor( - - companion object { - internal fun setMappers(serializer: KotlinxSerializer) { - serializer.setMapper(GetInventoryResponse::class, GetInventoryResponse.serializer()) - - } - } } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/UserApi.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/UserApi.kt index 88474dc9ef80..6e1f7d50f258 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/UserApi.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/apis/UserApi.kt @@ -15,27 +15,19 @@ import org.openapitools.client.models.User import org.openapitools.client.infrastructure.* import io.ktor.client.request.forms.formData -import kotlinx.serialization.UnstableDefault import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.serializer.KotlinxSerializer import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import io.ktor.http.ParametersBuilder import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* -class UserApi @UseExperimental(UnstableDefault::class) constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", +class UserApi( + baseUrl: String = ApiClient.BASE_URL, httpClientEngine: HttpClientEngine? = null, - serializer: KotlinxSerializer -) : ApiClient(baseUrl, httpClientEngine, serializer) { - - @UseExperimental(UnstableDefault::class) - constructor( - baseUrl: kotlin.String = "http://petstore.swagger.io/v2", - httpClientEngine: HttpClientEngine? = null, - jsonConfiguration: JsonConfiguration = JsonConfiguration.Default - ) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) + jsonSerializer: Json = ApiClient.JSON_DEFAULT +) : ApiClient(baseUrl, httpClientEngine, jsonSerializer) { /** * Create user @@ -53,7 +45,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/user", query = localVariableQuery, @@ -85,7 +77,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithArray", query = localVariableQuery, @@ -103,10 +95,10 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( private class CreateUsersWithArrayInputRequest(val value: List) { @Serializer(CreateUsersWithArrayInputRequest::class) companion object : KSerializer { - private val serializer: KSerializer> = User.serializer().list - override val descriptor = StringDescriptor.withName("CreateUsersWithArrayInputRequest") - override fun serialize(encoder: Encoder, obj: CreateUsersWithArrayInputRequest) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = CreateUsersWithArrayInputRequest(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: CreateUsersWithArrayInputRequest) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = CreateUsersWithArrayInputRequest(serializer.deserialize(decoder)) } } @@ -126,7 +118,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithList", query = localVariableQuery, @@ -144,10 +136,10 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( private class CreateUsersWithListInputRequest(val value: List) { @Serializer(CreateUsersWithListInputRequest::class) companion object : KSerializer { - private val serializer: KSerializer> = User.serializer().list - override val descriptor = StringDescriptor.withName("CreateUsersWithListInputRequest") - override fun serialize(encoder: Encoder, obj: CreateUsersWithListInputRequest) = serializer.serialize(encoder, obj.value) - override fun deserialize(decoder: Decoder) = CreateUsersWithListInputRequest(serializer.deserialize(decoder)) + private val serializer: KSerializer> = serializer>() + override val descriptor = serializer.descriptor + override fun serialize(encoder: Encoder, obj: CreateUsersWithListInputRequest) = serializer.serialize(encoder, obj.value) + override fun deserialize(decoder: Decoder) = CreateUsersWithListInputRequest(serializer.deserialize(decoder)) } } @@ -168,7 +160,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/user/{username}".replace("{" + "username" + "}", "$username"), query = localVariableQuery, @@ -201,7 +193,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/{username}".replace("{" + "username" + "}", "$username"), query = localVariableQuery, @@ -237,7 +229,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/login", query = localVariableQuery, @@ -268,7 +260,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/logout", query = localVariableQuery, @@ -300,7 +292,7 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( val localVariableHeaders = mutableMapOf() - val localVariableConfig = RequestConfig( + val localVariableConfig = RequestConfig( RequestMethod.PUT, "/user/{username}".replace("{" + "username" + "}", "$username"), query = localVariableQuery, @@ -316,13 +308,4 @@ class UserApi @UseExperimental(UnstableDefault::class) constructor( - - companion object { - internal fun setMappers(serializer: KotlinxSerializer) { - - serializer.setMapper(CreateUsersWithArrayInputRequest::class, CreateUsersWithArrayInputRequest.serializer()) - serializer.setMapper(CreateUsersWithListInputRequest::class, CreateUsersWithListInputRequest.serializer()) - - } - } } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 42d2a68d5b44..9f25b1059539 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -2,24 +2,21 @@ package org.openapitools.client.infrastructure import io.ktor.client.HttpClient import io.ktor.client.HttpClientConfig -import io.ktor.client.call.call import io.ktor.client.engine.HttpClientEngine import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.JsonSerializer import io.ktor.client.features.json.serializer.KotlinxSerializer -import io.ktor.client.request.accept +import io.ktor.client.request.* import io.ktor.client.request.forms.FormDataContent import io.ktor.client.request.forms.MultiPartFormDataContent import io.ktor.client.request.header import io.ktor.client.request.parameter -import io.ktor.client.response.HttpResponse +import io.ktor.client.statement.HttpResponse import io.ktor.client.utils.EmptyContent import io.ktor.http.* import io.ktor.http.content.OutgoingContent import io.ktor.http.content.PartData -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import org.openapitools.client.apis.* import org.openapitools.client.models.* @@ -28,17 +25,11 @@ import org.openapitools.client.auth.* open class ApiClient( private val baseUrl: String, httpClientEngine: HttpClientEngine?, - serializer: KotlinxSerializer) { - - @UseExperimental(UnstableDefault::class) - constructor( - baseUrl: String, - httpClientEngine: HttpClientEngine?, - jsonConfiguration: JsonConfiguration) : - this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) + private val json: Json +) { private val serializer: JsonSerializer by lazy { - serializer.apply { setMappers(this) }.ignoreOutgoingContent() + KotlinxSerializer(json).ignoreOutgoingContent() } private val client: HttpClient by lazy { @@ -53,23 +44,9 @@ open class ApiClient( } companion object { + const val BASE_URL = "http://petstore.swagger.io/v2" + val JSON_DEFAULT = Json { ignoreUnknownKeys = true } protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType) - - private fun setMappers(serializer: KotlinxSerializer) { - - PetApi.setMappers(serializer) - - StoreApi.setMappers(serializer) - - UserApi.setMappers(serializer) - - serializer.setMapper(org.openapitools.client.models.ApiResponse::class, org.openapitools.client.models.ApiResponse.serializer()) - serializer.setMapper(org.openapitools.client.models.Category::class, org.openapitools.client.models.Category.serializer()) - serializer.setMapper(org.openapitools.client.models.Order::class, org.openapitools.client.models.Order.serializer()) - serializer.setMapper(org.openapitools.client.models.Pet::class, org.openapitools.client.models.Pet.serializer()) - serializer.setMapper(org.openapitools.client.models.Tag::class, org.openapitools.client.models.Tag.serializer()) - serializer.setMapper(org.openapitools.client.models.User::class, org.openapitools.client.models.User.serializer()) - } } /** @@ -140,26 +117,26 @@ open class ApiClient( auth.bearerToken = bearerToken } - protected suspend fun multipartFormRequest(requestConfig: RequestConfig, body: kotlin.collections.List?, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun multipartFormRequest(requestConfig: RequestConfig, body: kotlin.collections.List?, authNames: kotlin.collections.List): HttpResponse { return request(requestConfig, MultiPartFormDataContent(body ?: listOf()), authNames) } - protected suspend fun urlEncodedFormRequest(requestConfig: RequestConfig, body: Parameters?, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun urlEncodedFormRequest(requestConfig: RequestConfig, body: Parameters?, authNames: kotlin.collections.List): HttpResponse { return request(requestConfig, FormDataContent(body ?: Parameters.Empty), authNames) } - protected suspend fun jsonRequest(requestConfig: RequestConfig, body: Any? = null, authNames: kotlin.collections.List): HttpResponse { + protected suspend fun jsonRequest(requestConfig: RequestConfig, body: Any? = null, authNames: kotlin.collections.List): HttpResponse { val contentType = (requestConfig.headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) } ?: ContentType.Application.Json) return if (body != null) request(requestConfig, serializer.write(body, contentType), authNames) else request(requestConfig, authNames = authNames) } - protected suspend inline fun request(requestConfig: RequestConfig, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List): HttpResponse { - requestConfig.updateForAuth(authNames) + protected suspend fun request(requestConfig: RequestConfig, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List): HttpResponse { + requestConfig.updateForAuth(authNames) val headers = requestConfig.headers - return client.call { + return client.request { this.url { this.takeFrom(URLBuilder(baseUrl)) appendPath(requestConfig.path.trimStart('/').split('/')) @@ -174,10 +151,10 @@ open class ApiClient( if (requestConfig.method in listOf(RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH)) this.body = body - }.response + } } - private fun RequestConfig.updateForAuth(authNames: kotlin.collections.List) { + private fun RequestConfig.updateForAuth(authNames: kotlin.collections.List) { for (authName in authNames) { val auth = authentications?.get(authName) ?: throw Exception("Authentication undefined: $authName") auth.apply(query, headers) diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Base64ByteArray.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Base64ByteArray.kt index 4bc1197cf00d..7c635c14fdd8 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Base64ByteArray.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Base64ByteArray.kt @@ -1,13 +1,14 @@ package org.openapitools.client.infrastructure import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* @Serializable class Base64ByteArray(val value: ByteArray) { @Serializer(Base64ByteArray::class) companion object : KSerializer { - override val descriptor = StringDescriptor.withName("Base64ByteArray") + override val descriptor = PrimitiveSerialDescriptor("Base64ByteArray", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, obj: Base64ByteArray) = encoder.encodeString(obj.value.encodeBase64()) override fun deserialize(decoder: Decoder) = Base64ByteArray(decoder.decodeString().decodeBase64Bytes()) } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Bytes.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Bytes.kt index 8a222416cf2d..b8f12a085298 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Bytes.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/Bytes.kt @@ -1,6 +1,6 @@ package org.openapitools.client.infrastructure -import kotlinx.io.core.* +import io.ktor.utils.io.core.* import kotlin.experimental.and private val digits = "0123456789abcdef".toCharArray() @@ -32,7 +32,7 @@ internal fun hex(bytes: ByteArray): String { result[resultIndex++] = digits[b and 0x0f] } - return String(result) + return result.concatToString() } /** diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/HttpResponse.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/HttpResponse.kt index c457eb4bce0b..61e55bc5b153 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/HttpResponse.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/HttpResponse.kt @@ -5,7 +5,7 @@ import io.ktor.client.call.typeInfo import io.ktor.http.Headers import io.ktor.http.isSuccess -open class HttpResponse(val response: io.ktor.client.response.HttpResponse, val provider: BodyProvider) { +open class HttpResponse(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider) { val status: Int = response.status.value val success: Boolean = response.status.isSuccess() val headers: Map> = response.headers.mapEntries() @@ -22,29 +22,29 @@ open class HttpResponse(val response: io.ktor.client.response.HttpRespo } interface BodyProvider { - suspend fun body(response: io.ktor.client.response.HttpResponse): T - suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V + suspend fun body(response: io.ktor.client.statement.HttpResponse): T + suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V } class TypedBodyProvider(private val type: TypeInfo) : BodyProvider { @Suppress("UNCHECKED_CAST") - override suspend fun body(response: io.ktor.client.response.HttpResponse): T = + override suspend fun body(response: io.ktor.client.statement.HttpResponse): T = response.call.receive(type) as T @Suppress("UNCHECKED_CAST") - override suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V = + override suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V = response.call.receive(type) as V } class MappedBodyProvider(private val provider: BodyProvider, private val block: S.() -> T) : BodyProvider { - override suspend fun body(response: io.ktor.client.response.HttpResponse): T = + override suspend fun body(response: io.ktor.client.statement.HttpResponse): T = block(provider.body(response)) - override suspend fun typedBody(response: io.ktor.client.response.HttpResponse, type: TypeInfo): V = + override suspend fun typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V = provider.typedBody(response, type) } -inline fun io.ktor.client.response.HttpResponse.wrap(): HttpResponse = +inline fun io.ktor.client.statement.HttpResponse.wrap(): HttpResponse = HttpResponse(this, TypedBodyProvider(typeInfo())) fun HttpResponse.map(block: T.() -> V): HttpResponse = diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/OctetByteArray.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/OctetByteArray.kt index 735e4e6e3f66..04c88673331e 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/OctetByteArray.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/OctetByteArray.kt @@ -1,13 +1,14 @@ package org.openapitools.client.infrastructure import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* @Serializable class OctetByteArray(val value: ByteArray) { @Serializer(OctetByteArray::class) companion object : KSerializer { - override val descriptor = StringDescriptor.withName("OctetByteArray") + override val descriptor = PrimitiveSerialDescriptor("OctetByteArray", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, obj: OctetByteArray) = encoder.encodeString(hex(obj.value)) override fun deserialize(decoder: Decoder) = OctetByteArray(hex(decoder.decodeString())) } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/ApiResponse.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/ApiResponse.kt index a035628a8f93..91150fbf26b7 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/ApiResponse.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/ApiResponse.kt @@ -13,7 +13,8 @@ package org.openapitools.client.models import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * Describes the result of uploading an image resource diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Category.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Category.kt index d5f9a45fd4de..8c17893935b0 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Category.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Category.kt @@ -13,7 +13,8 @@ package org.openapitools.client.models import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * A category for a pet diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Order.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Order.kt index 0a53ba0740e4..f5ae575d19ed 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Order.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Order.kt @@ -13,7 +13,8 @@ package org.openapitools.client.models import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * An order for a pets from the pet store @@ -39,10 +40,11 @@ data class Order ( * Order Status * Values: placed,approved,delivered */ + @Serializable enum class Status(val value: kotlin.String) { - placed("placed"), - approved("approved"), - delivered("delivered"); + @SerialName(value = "placed") placed("placed"), + @SerialName(value = "approved") approved("approved"), + @SerialName(value = "delivered") delivered("delivered"); } } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Pet.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Pet.kt index 1649cf0fb293..55879c6c7ac6 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Pet.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Pet.kt @@ -15,7 +15,8 @@ import org.openapitools.client.models.Category import org.openapitools.client.models.Tag import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * A pet for sale in the pet store @@ -41,10 +42,11 @@ data class Pet ( * pet status in the store * Values: available,pending,sold */ + @Serializable enum class Status(val value: kotlin.String) { - available("available"), - pending("pending"), - sold("sold"); + @SerialName(value = "available") available("available"), + @SerialName(value = "pending") pending("pending"), + @SerialName(value = "sold") sold("sold"); } } diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Tag.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Tag.kt index 6116e50d3f92..54a4e01d29a0 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Tag.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/Tag.kt @@ -13,7 +13,8 @@ package org.openapitools.client.models import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * A tag for a pet diff --git a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/User.kt b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/User.kt index 97b53a049c1d..4c69c432e2e7 100644 --- a/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/User.kt +++ b/samples/client/petstore/kotlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/models/User.kt @@ -13,7 +13,8 @@ package org.openapitools.client.models import kotlinx.serialization.* -import kotlinx.serialization.internal.CommonEnumSerializer +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* /** * A User who is purchasing from the pet store diff --git a/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/models/PetEnum.kt b/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/models/PetEnum.kt index 9e1d0b06d7b1..0bc84e75f739 100644 --- a/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/models/PetEnum.kt +++ b/samples/client/petstore/kotlin-uppercase-enum/src/main/kotlin/org/openapitools/client/models/PetEnum.kt @@ -19,6 +19,7 @@ import com.squareup.moshi.Json * Values: MY_FIRST_VALUE,MY_SECOND_VALUE */ + enum class PetEnum(val value: kotlin.String) {