From b69ed9e16a1f2928c71965fe292f0cb422d227be Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 19:26:05 +0200 Subject: [PATCH 01/59] Update version numbers --- gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f37108468..a3676bfcf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,9 +14,9 @@ groupId = "de.jensklingenberg.ktorfit" ktorfit = "2.0.1" ktorfitKsp = "2.0.1-1.0.24" ktorfitCompiler = "2.0.1-2.0.10" -ktorfitCallConverter = "2.0.0" -ktorfitFlowConverter = "2.0.0" -ktorfitResponseConverter = "2.0.0" +ktorfitCallConverter = "2.0.1" +ktorfitFlowConverter = "2.0.1" +ktorfitResponseConverter = "2.0.1" ktorfitGradle = "2.0.1" ktorfitGradlePlugin = "2.0.0" From f90e590ce63c50219d7811205ff33cc0a1201fc2 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 20:10:15 +0200 Subject: [PATCH 02/59] Update Readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 965dacb52..8cc21b4b8 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,11 @@ See https://foso.github.io/Ktorfit/#compatibility | ktorfit-converters-call | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call) | | ktorfit-converters-response | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response) | +You can find all Ktorfit packages on [maven central](https://search.maven.org/search?q=de.jensklingenberg.ktorfit). + +🔎 Check the [latest changes](https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md) to update your Koin project. + +🛠 Follow the [setup page](https://foso.github.io/Ktorfit/installation/) for more details ## 👷 Project Structure From 33ccae28c7822774d4eec58851f9abf0f280d40d Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 20:10:25 +0200 Subject: [PATCH 03/59] Update Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cc21b4b8..182c277d6 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ See https://foso.github.io/Ktorfit/#compatibility |-----------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | Ktorfit Gradle Plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/de.jensklingenberg.ktorfit.gradle.plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/de.jensklingenberg.ktorfit.gradle.plugin) | | ktorfit-lib | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib) | -| compiler-plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/compiler-plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/compiler-plugin) | +| compiler-plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/compiler-plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/compiler-plugin) | | ktorfit-lib-light | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light) | | ktorfit-ksp | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-ksp) | | ktorfit-converters-flow | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow) | From 406675b5996fbf7615789fde09c50c07c49fb360 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 21:41:16 +0200 Subject: [PATCH 04/59] Update Readme --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 182c277d6..662bd58f6 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,25 @@ See https://foso.github.io/Ktorfit/#compatibility |-----------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | Ktorfit Gradle Plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/de.jensklingenberg.ktorfit.gradle.plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/de.jensklingenberg.ktorfit.gradle.plugin) | | ktorfit-lib | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib) | -| compiler-plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/compiler-plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/compiler-plugin) | | ktorfit-lib-light | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light) | +| compiler-plugin | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/compiler-plugin)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/compiler-plugin) | | ktorfit-ksp | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-ksp) | | ktorfit-converters-flow | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow) | | ktorfit-converters-call | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call) | | ktorfit-converters-response | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response) | +## Ktorfit Ktor 3 Packages +The main dependencies will stay on Ktor 2.x till Ktor 3 is stable. +When you want to use Ktor 3 you can use the following packages: + +| Project | Version | +|-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| ktorfit-lib-light-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | +| ktorfit-lib-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | +| ktorfit-converters-flow-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | +| ktorfit-converters-call-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | +| ktorfit-converters-response-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | + You can find all Ktorfit packages on [maven central](https://search.maven.org/search?q=de.jensklingenberg.ktorfit). 🔎 Check the [latest changes](https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md) to update your Koin project. From b0fb68134b62d2af2246cda6a5e2209d80ee87b0 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 23:06:14 +0200 Subject: [PATCH 05/59] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f0370dbd..9c54f8b4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,4 +55,4 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build and test with Gradle - run: ./gradlew licensee :ktorfit-annotations:publishToMavenLocal :ktorfit-ksp:test :ktorfit-lib-core:jvmTest :ktorfit-converters:call:publishToMavenLocal :ktorfit-converters:flow:publishToMavenLocal :ktorfit-converters:response:publishToMavenLocal + run: ./gradlew licensee :ktorfit-annotations:publishToMavenLocal :ktorfit-compiler-plugin:test :ktorfit-ksp:test :ktorfit-lib-core:jvmTest :ktorfit-converters:call:publishToMavenLocal :ktorfit-converters:flow:publishToMavenLocal :ktorfit-converters:response:publishToMavenLocal From 52398164031b111075481ab4a54c8d856769ee3d Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 12 Aug 2024 23:06:49 +0200 Subject: [PATCH 06/59] Update publish-converters.yml --- .github/workflows/publish-converters.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-converters.yml b/.github/workflows/publish-converters.yml index 52f86ff53..f1a049424 100644 --- a/.github/workflows/publish-converters.yml +++ b/.github/workflows/publish-converters.yml @@ -16,7 +16,7 @@ jobs: distribution: 'zulu' java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/gradle-build-action@v4 - name: Publish release run: ./gradlew :ktorfit-converters:call:publishAllPublicationsToMavenCentralRepository :ktorfit-converters:flow:publishAllPublicationsToMavenCentralRepository :ktorfit-converters:response:publishAllPublicationsToMavenCentralRepository @@ -24,4 +24,4 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY }} - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} \ No newline at end of file + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} From 7db9f33017ad45407a097d80f27812dbcf8bd5db Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 20:34:18 +0200 Subject: [PATCH 07/59] Fix test --- .../ktorfit/FunctionTransformerTest.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ktorfit-compiler-plugin/src/test/kotlin/de/jensklingenberg/ktorfit/FunctionTransformerTest.kt b/ktorfit-compiler-plugin/src/test/kotlin/de/jensklingenberg/ktorfit/FunctionTransformerTest.kt index 6d26310ec..acbfa97a1 100644 --- a/ktorfit-compiler-plugin/src/test/kotlin/de/jensklingenberg/ktorfit/FunctionTransformerTest.kt +++ b/ktorfit-compiler-plugin/src/test/kotlin/de/jensklingenberg/ktorfit/FunctionTransformerTest.kt @@ -4,6 +4,7 @@ import com.tschuchort.compiletesting.JvmCompilationResult import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.PluginOption import com.tschuchort.compiletesting.SourceFile +import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.jetbrains.kotlin.config.JvmTarget import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -11,6 +12,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder +@OptIn(ExperimentalCompilerApi::class) class FunctionTransformerTest { @Rule @JvmField @@ -59,7 +61,7 @@ interface ClassProvider assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode) - assertTrue(result.messages.contains("_TestServiceImpl")) + assertTrue(result.messages.contains("_TestServiceProvider")) } @Test @@ -109,8 +111,9 @@ fun Ktorfit.create(ktorfitService: ClassProvider? = null): T { assertTrue(result.messages.contains(CreateFuncTransformer.errorTypeArgumentNotInterface("T"))) } - private fun prepareCompilation(sourceFiles: List): KotlinCompilation { - return KotlinCompilation().apply { + private fun prepareCompilation(sourceFiles: List): KotlinCompilation = + KotlinCompilation().apply { + languageVersion = "1.9" workingDir = temporaryFolder.root compilerPluginRegistrars = listOf(CommonCompilerPluginRegistrar()) val processor = ExampleCommandLineProcessor() @@ -126,9 +129,6 @@ fun Ktorfit.create(ktorfitService: ClassProvider? = null): T { jvmTarget = JvmTarget.fromString(System.getProperty("rdt.jvmTarget", "1.8"))!!.description supportsK2 = false } - } - private fun compile(sourceFiles: List): JvmCompilationResult { - return prepareCompilation(sourceFiles).compile() - } + private fun compile(sourceFiles: List): JvmCompilationResult = prepareCompilation(sourceFiles).compile() } From 1e956428a998aea9fb2a7b7ae807ecb2cf48795a Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 20:34:38 +0200 Subject: [PATCH 08/59] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 662bd58f6..2ae90bca7 100644 --- a/README.md +++ b/README.md @@ -41,17 +41,17 @@ See https://foso.github.io/Ktorfit/#compatibility ## Ktorfit Ktor 3 Packages The main dependencies will stay on Ktor 2.x till Ktor 3 is stable. -When you want to use Ktor 3 you can use the following packages: +When you want to use Ktor 3 and WasmJs, you need to replace your dependecies with a "ktor3" version, you can use the following packages: | Project | Version | |-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| ktorfit-lib-light-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | -| ktorfit-lib-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | -| ktorfit-converters-flow-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | -| ktorfit-converters-call-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | -| ktorfit-converters-response-ktor3 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | +| ktorfit-lib-light-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | +| ktorfit-lib-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | +| ktorfit-converters-flow-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | +| ktorfit-converters-call-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | +| ktorfit-converters-response-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | -You can find all Ktorfit packages on [maven central](https://search.maven.org/search?q=de.jensklingenberg.ktorfit). +You can find all Ktorfit packages on [Maven Central](https://search.maven.org/search?q=de.jensklingenberg.ktorfit). 🔎 Check the [latest changes](https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md) to update your Koin project. From 18f882d49e2f9df71bacac72575089ed4ea30555 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 21:21:53 +0200 Subject: [PATCH 09/59] Update changelog --- docs/CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c3746e3af..676efe355 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,10 +9,6 @@ But there is no intent to bump the Ktorfit major version for every KSP update. # [2.0.1]() -compiler-plugin:2.0.1-2.0.10 - 2024-08-10 -======================================== -- Kotlin 2.0.10 - 2.0.1 - 2024-08-08 ======================================== ### Fixed @@ -21,7 +17,12 @@ compiler-plugin:2.0.1-2.0.10 - 2024-08-10 - #621 RequestConverter causing compile error - Build with Ktor 2.3.12 +### compilerPlugin +- Kotlin 2.0.0: 2.0.1-2.0.0 - 2024-08-08 +- Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 +### ktorfit-ksp +- KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 # [2.0.0]() From 3bff2c44f9529563bd9753dfe2e508ca1b143dd4 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 21:41:34 +0200 Subject: [PATCH 10/59] Downgrade gradleMavenPublishPlugin --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a3676bfcf..5aa556d14 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,8 +23,8 @@ ktorfitGradlePlugin = "2.0.0" ktorVersion = "2.3.12" mockk = "1.13.11" mockito-kotlin = "4.1.0" -gradleMavenPublishPlugin = "0.29.0" -vannikMavenPublish = "0.29.0" +gradleMavenPublishPlugin = "0.28.0" +vannikMavenPublish = "0.28.0" [libraries] android-build-gradle = "com.android.tools.build:gradle:8.2.2" From 81382bc24c89fae2da9ae0c74075f9133f1d0eb3 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 22:16:33 +0200 Subject: [PATCH 11/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 676efe355..d8f01587d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -20,7 +20,8 @@ But there is no intent to bump the Ktorfit major version for every KSP update. ### compilerPlugin - Kotlin 2.0.0: 2.0.1-2.0.0 - 2024-08-08 - Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 - +- Kotlin 2.0.20-RC: 2.0.1-2.0.20-RC - 2024-08-13 + ### ktorfit-ksp - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 From 7477ed9f6a40d394539efebb363c7b53c4909062 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 22:30:49 +0200 Subject: [PATCH 12/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d8f01587d..490d5113d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,6 +21,7 @@ But there is no intent to bump the Ktorfit major version for every KSP update. - Kotlin 2.0.0: 2.0.1-2.0.0 - 2024-08-08 - Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 - Kotlin 2.0.20-RC: 2.0.1-2.0.20-RC - 2024-08-13 +- Kotlin 2.0.20-RC2: 2.0.1-2.0.20-RC2 - 2024-08-13 ### ktorfit-ksp - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 From e922c38162bde053df82bb025fd48b65520074f7 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Tue, 13 Aug 2024 22:32:50 +0200 Subject: [PATCH 13/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 490d5113d..6cde4349d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,6 +17,9 @@ But there is no intent to bump the Ktorfit major version for every KSP update. - #621 RequestConverter causing compile error - Build with Ktor 2.3.12 +### ktorfit-annotations +- 2.0.1: The annotations are now also avaiable for WasmJs + ### compilerPlugin - Kotlin 2.0.0: 2.0.1-2.0.0 - 2024-08-08 - Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 From 309c6388cebca56dd4c1d3b02df72660665c621e Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 14 Aug 2024 19:25:36 +0200 Subject: [PATCH 14/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6cde4349d..0e2cfcec7 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -29,6 +29,17 @@ But there is no intent to bump the Ktorfit major version for every KSP update. ### ktorfit-ksp - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 +### Ktor3 +The "normal" dependencies will stay on Ktor 2.x till 3.x is stable. But here are versions that you can use when want to use Ktor3 and WasmJs + +| Project | Version | +|-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| ktorfit-lib-light-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | +| ktorfit-lib-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | +| ktorfit-converters-flow-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | +| ktorfit-converters-call-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | +| ktorfit-converters-response-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | + # [2.0.0]() ktorfit-ksp-2.0.0-1.0.24 - 2024-08-06 From 7ad56f6caba73181f2d0a37293daf64836d994b5 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 14 Aug 2024 19:26:02 +0200 Subject: [PATCH 15/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0e2cfcec7..55b9d6fad 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -30,7 +30,7 @@ But there is no intent to bump the Ktorfit major version for every KSP update. - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 ### Ktor3 -The "normal" dependencies will stay on Ktor 2.x till 3.x is stable. But here are versions that you can use when want to use Ktor3 and WasmJs +The "normal" dependencies will stay on Ktor 2.x till 3.0 is stable. But here are versions that you can use when want to use Ktor3 and WasmJs | Project | Version | |-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| From 190867f74aa1610620963115c87c32e7328fd830 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Aug 2024 10:34:43 +0200 Subject: [PATCH 16/59] fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.1 (#611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- example/AndroidOnlyExample/app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/AndroidOnlyExample/app/build.gradle.kts b/example/AndroidOnlyExample/app/build.gradle.kts index 099eccc45..a13042a6e 100644 --- a/example/AndroidOnlyExample/app/build.gradle.kts +++ b/example/AndroidOnlyExample/app/build.gradle.kts @@ -74,7 +74,7 @@ dependencies { debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_ui_version") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_ui_version") } From ebbdea024dd6675469ca5fd3c642ffb4c3921bf4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Aug 2024 08:49:26 +0000 Subject: [PATCH 17/59] fix(deps): update dependency androidx.activity:activity-compose to v1.9.1 (#635) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- example/AndroidOnlyExample/app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/AndroidOnlyExample/app/build.gradle.kts b/example/AndroidOnlyExample/app/build.gradle.kts index a13042a6e..6b9a15129 100644 --- a/example/AndroidOnlyExample/app/build.gradle.kts +++ b/example/AndroidOnlyExample/app/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.2") - implementation("androidx.activity:activity-compose:1.9.0") + implementation("androidx.activity:activity-compose:1.9.1") implementation("androidx.compose.ui:ui:$compose_ui_version") implementation("androidx.compose.ui:ui-tooling-preview:$compose_ui_version") implementation("androidx.compose.material:material:1.6.7") From 0c0cd99f24d17798237759189bd168fbee1beb42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Aug 2024 08:58:35 +0000 Subject: [PATCH 18/59] fix(deps): update dependency androidx.lifecycle:lifecycle-runtime-ktx to v2.8.4 (#636) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- example/AndroidOnlyExample/app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/AndroidOnlyExample/app/build.gradle.kts b/example/AndroidOnlyExample/app/build.gradle.kts index 6b9a15129..e4861a2c8 100644 --- a/example/AndroidOnlyExample/app/build.gradle.kts +++ b/example/AndroidOnlyExample/app/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("de.jensklingenberg.ktorfit:ktorfit-converters-flow:$ktorfit") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.2") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4") implementation("androidx.activity:activity-compose:1.9.1") implementation("androidx.compose.ui:ui:$compose_ui_version") implementation("androidx.compose.ui:ui-tooling-preview:$compose_ui_version") From e0d126e3eb09799c58794975aa023b251422f0d1 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 18 Aug 2024 19:37:45 +0200 Subject: [PATCH 19/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 55b9d6fad..049464e0e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,9 +12,9 @@ But there is no intent to bump the Ktorfit major version for every KSP update. 2.0.1 - 2024-08-08 ======================================== ### Fixed -- #594 Endpoint with types from other module -- #591 Ktorfit plugin doesn't include correct generate source if build directory changes #591 -- #621 RequestConverter causing compile error +- Endpoint with types from other module #594 +- Ktorfit plugin doesn't include correct generate source if build directory changes #591 +- RequestConverter causing compile error #621 - Build with Ktor 2.3.12 ### ktorfit-annotations From 6eef948be1229ff5887c787eec837dff0e2f231a Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Fri, 23 Aug 2024 17:45:51 +0200 Subject: [PATCH 20/59] Update to Kotlin 2.0.20 (#641) --- docs/CHANGELOG.md | 3 ++- docs/development.md | 10 ++++++- example/MultiplatformExample/build.gradle.kts | 6 ++--- .../shared/build.gradle.kts | 14 +++++----- gradle/libs.versions.toml | 8 +++--- .../ktorfit/CreateFuncTransformer.kt | 23 +++++++++++----- .../ktorfit/ReqBuilderAnnotationsTest.kt | 26 +++---------------- .../de/jensklingenberg/ktorfit/Utils.kt | 6 +++-- 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 049464e0e..8e0dae059 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -25,7 +25,8 @@ But there is no intent to bump the Ktorfit major version for every KSP update. - Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 - Kotlin 2.0.20-RC: 2.0.1-2.0.20-RC - 2024-08-13 - Kotlin 2.0.20-RC2: 2.0.1-2.0.20-RC2 - 2024-08-13 - +- Kotlin 2.0.20: 2.0.1-2.0.20 - 2024-08-23 + ### ktorfit-ksp - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 diff --git a/docs/development.md b/docs/development.md index 90c64e52f..70fe44ec0 100644 --- a/docs/development.md +++ b/docs/development.md @@ -1 +1,9 @@ -# Development \ No newline at end of file +# Development + +# Update Ktorfit for new Kotlin version +- Bump **kotlin** in libs.versions +- Change **ktorfitCompiler** in libs.versions to KTORFIT_VERSION-NEW_KOTLIN_VERSION +- Run tests in :ktorfit-compiler-plugin +- Create a PR against master +- Merge PR +- Run GitHub Actions "publish" workflow \ No newline at end of file diff --git a/example/MultiplatformExample/build.gradle.kts b/example/MultiplatformExample/build.gradle.kts index f071dc823..46058a423 100644 --- a/example/MultiplatformExample/build.gradle.kts +++ b/example/MultiplatformExample/build.gradle.kts @@ -1,6 +1,6 @@ buildscript { repositories { - //mavenLocal() + // mavenLocal() gradlePluginPortal() google() mavenCentral() @@ -9,7 +9,7 @@ buildscript { } } dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") classpath("com.android.tools.build:gradle:7.3.1") classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.0") } @@ -17,7 +17,7 @@ buildscript { allprojects { repositories { - //mavenLocal() + // mavenLocal() google() mavenCentral() maven { diff --git a/example/MultiplatformExample/shared/build.gradle.kts b/example/MultiplatformExample/shared/build.gradle.kts index 2d8550ed0..c36a5f5e7 100644 --- a/example/MultiplatformExample/shared/build.gradle.kts +++ b/example/MultiplatformExample/shared/build.gradle.kts @@ -4,9 +4,9 @@ plugins { kotlin("multiplatform") kotlin("native.cocoapods") id("com.android.library") - id("com.google.devtools.ksp") version "2.0.0-1.0.22" + id("com.google.devtools.ksp") version "2.0.20-1.0.24" id("kotlinx-serialization") - id("de.jensklingenberg.ktorfit") version "2.0.0" + id("de.jensklingenberg.ktorfit") version "2.0.1" } ktorfit { @@ -16,7 +16,7 @@ ktorfit { version = "1.0" val ktorVersion = "2.3.11" -val ktorfitVersion = "2.0.0" +val ktorfitVersion = "2.0.1" kotlin { jvmToolchain(8) @@ -46,13 +46,13 @@ kotlin { val commonMain by getting { dependencies { implementation("de.jensklingenberg.ktorfit:ktorfit-lib:$ktorfitVersion") - //implementation("de.jensklingenberg.ktorfit:ktorfit-lib-light:$ktorfitVersion") + // implementation("de.jensklingenberg.ktorfit:ktorfit-lib-light:$ktorfitVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") implementation("de.jensklingenberg.ktorfit:ktorfit-converters-response:$ktorfitVersion") implementation("de.jensklingenberg.ktorfit:ktorfit-converters-call:$ktorfitVersion") implementation("de.jensklingenberg.ktorfit:ktorfit-converters-flow:$ktorfitVersion") - //Only needed when you want to use Kotlin Serialization + // Only needed when you want to use Kotlin Serialization implementation("io.ktor:ktor-client-serialization:$ktorVersion") implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion") implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion") @@ -82,10 +82,8 @@ android { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } - } - tasks.withType { kotlinOptions { jvmTarget = "1.8" @@ -99,4 +97,4 @@ allprojects { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") } } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5aa556d14..cbda8a502 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,15 +5,15 @@ binaryCompatibilityValidator = "0.14.0" coroutines = "1.8.1" detekt = "1.23.6" junit = "4.13.2" -kctfork = "0.4.1" -kotlin = "2.0.10" +kctfork = "0.5.1" +kotlin = "2.0.20" kotlinPoet = "1.18.1" -kspVersion = "2.0.10-1.0.24" +kspVersion = "2.0.20-1.0.24" groupId = "de.jensklingenberg.ktorfit" ktorfit = "2.0.1" ktorfitKsp = "2.0.1-1.0.24" -ktorfitCompiler = "2.0.1-2.0.10" +ktorfitCompiler = "2.0.1-2.0.20" ktorfitCallConverter = "2.0.1" ktorfitFlowConverter = "2.0.1" ktorfitResponseConverter = "2.0.1" diff --git a/ktorfit-compiler-plugin/src/main/java/de/jensklingenberg/ktorfit/CreateFuncTransformer.kt b/ktorfit-compiler-plugin/src/main/java/de/jensklingenberg/ktorfit/CreateFuncTransformer.kt index 0d0ed6aed..5f2f4764a 100644 --- a/ktorfit-compiler-plugin/src/main/java/de/jensklingenberg/ktorfit/CreateFuncTransformer.kt +++ b/ktorfit-compiler-plugin/src/main/java/de/jensklingenberg/ktorfit/CreateFuncTransformer.kt @@ -2,15 +2,17 @@ package de.jensklingenberg.ktorfit import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI import org.jetbrains.kotlin.ir.types.classFqName import org.jetbrains.kotlin.ir.types.defaultType -import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.ir.util.dumpKotlinLike import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.js.descriptorUtils.getKotlinTypeFqName import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -42,10 +44,15 @@ internal class CreateFuncTransformer( // Find exampleKtorfit.create() (expression as? IrCall)?.let { irCall -> if (irCall.typeArgumentsCount > 0) { - if (!expression.symbol.owner.symbol.toString().contains(KTORFIT_PACKAGE)) { + if (!expression.symbol.owner.symbol + .toString() + .contains(KTORFIT_PACKAGE) + ) { return expression } - if (expression.symbol.owner.name.asString() != KTORFIT_CREATE) { + if (expression.symbol.owner.name + .asString() != KTORFIT_CREATE + ) { return expression } @@ -59,12 +66,14 @@ internal class CreateFuncTransformer( if (!argumentType.isInterface()) { throw IllegalStateException( - errorTypeArgumentNotInterface(argumentType.originalKotlinType.toString()), + errorTypeArgumentNotInterface(argumentType.dumpKotlinLike()), ) } if (classFqName == null) { - throw IllegalStateException(errorClassNotFound(argumentType.originalKotlinType.toString())) + throw IllegalStateException( + errorClassNotFound(argumentType.toIrBasedKotlinType().getKotlinTypeFqName(false)) + ) } val packageName = classFqName.packageName @@ -98,7 +107,9 @@ internal class CreateFuncTransformer( // Set _ExampleApiProvider() as argument for create() irCall.putValueArgument(0, newCall) debugLogger.log( - "Transformed " + argumentType.originalKotlinType.toString() + " to _$className" + "Provider", + "Transformed " + argumentType.toIrBasedKotlinType().getKotlinTypeFqName(false).substringAfterLast(".") + + " to _$className" + + "Provider", ) return super.visitExpression(irCall) } diff --git a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/ReqBuilderAnnotationsTest.kt b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/ReqBuilderAnnotationsTest.kt index a9226cd96..e916cb696 100644 --- a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/ReqBuilderAnnotationsTest.kt +++ b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/ReqBuilderAnnotationsTest.kt @@ -2,9 +2,7 @@ package de.jensklingenberg.ktorfit import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile -import com.tschuchort.compiletesting.kspIncremental import com.tschuchort.compiletesting.kspSourcesDir -import com.tschuchort.compiletesting.symbolProcessorProviders import de.jensklingenberg.ktorfit.model.KtorfitError import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -79,13 +77,7 @@ interface TestService { val expectedRequestBuilderArgumentText = "builder(this)" - val compilation = - KotlinCompilation().apply { - sources = listOf(httpReqBuilderSource, source) - inheritClassPath = true - symbolProcessorProviders = listOf(KtorfitProcessorProvider()) - kspIncremental = true - } + val compilation = getCompilation(listOf(httpReqBuilderSource, source)) val result = compilation.compile() assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode) @@ -120,13 +112,7 @@ interface TestService { """, ) - val compilation = - KotlinCompilation().apply { - sources = listOf(httpReqBuilderSource, source) - inheritClassPath = true - symbolProcessorProviders = listOf(KtorfitProcessorProvider()) - kspIncremental = true - } + val compilation = getCompilation(listOf(httpReqBuilderSource, source)) val result = compilation.compile() assertEquals(KotlinCompilation.ExitCode.COMPILATION_ERROR, result.exitCode) @@ -153,13 +139,7 @@ interface TestService { """, ) - val compilation = - KotlinCompilation().apply { - sources = listOf(httpReqBuilderSource, source) - inheritClassPath = true - symbolProcessorProviders = listOf(KtorfitProcessorProvider()) - kspIncremental = true - } + val compilation = getCompilation(listOf(httpReqBuilderSource, source)) val result = compilation.compile() assertEquals(KotlinCompilation.ExitCode.COMPILATION_ERROR, result.exitCode) diff --git a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/Utils.kt b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/Utils.kt index 5d339e688..4e6848c6b 100644 --- a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/Utils.kt +++ b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/Utils.kt @@ -4,6 +4,7 @@ import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import com.tschuchort.compiletesting.kspArgs import com.tschuchort.compiletesting.kspIncremental +import com.tschuchort.compiletesting.kspProcessorOptions import com.tschuchort.compiletesting.symbolProcessorProviders import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -13,9 +14,10 @@ fun getCompilation( kspArgs: MutableMap = mutableMapOf(), ): KotlinCompilation = KotlinCompilation().apply { + languageVersion = "1.9" this.sources = sources inheritClassPath = true - symbolProcessorProviders = listOf(KtorfitProcessorProvider()) + symbolProcessorProviders = mutableListOf(KtorfitProcessorProvider()) kspIncremental = true - this.kspArgs = kspArgs + this.kspProcessorOptions = kspArgs } From 5d1942a74892550fe7cc10877ee9434a3bd63e42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 18:53:35 +0200 Subject: [PATCH 21/59] fix(deps): update dependency io.mockk:mockk to v1.13.12 (#643) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cbda8a502..3f4442148 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ ktorfitGradle = "2.0.1" ktorfitGradlePlugin = "2.0.0" ktorVersion = "2.3.12" -mockk = "1.13.11" +mockk = "1.13.12" mockito-kotlin = "4.1.0" gradleMavenPublishPlugin = "0.28.0" vannikMavenPublish = "0.28.0" From 91b07bf5b8b0557deacbf13db63356f5236d746e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 19:15:08 +0200 Subject: [PATCH 22/59] fix(deps): update dependency io.reactivex.rxjava3:rxjava to v3.1.9 (#644) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- sandbox/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sandbox/build.gradle.kts b/sandbox/build.gradle.kts index f64a27ab1..2e8cb331c 100644 --- a/sandbox/build.gradle.kts +++ b/sandbox/build.gradle.kts @@ -84,7 +84,7 @@ kotlin { dependencies { implementation(libs.ktor.client.core.jvm) implementation(libs.kotlinx.coroutines.rx3) - implementation("io.reactivex.rxjava3:rxjava:3.1.8") + implementation("io.reactivex.rxjava3:rxjava:3.1.9") implementation(libs.ktor.client.logging) implementation(libs.ktor.serialization.gson) implementation(libs.ktor.client.cio.jvm) From f958cee5ab1ee59d845bf7e5ba006299625c7049 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 25 Aug 2024 17:34:12 +0200 Subject: [PATCH 23/59] Clean sandbox --- .../jensklingenberg/ktorfit/demo/JvMMain.kt | 3 --- sandbox/src/jvmTest/java/TestClass.kt | 22 ------------------- sandbox/src/linuxX64Main/kotlin/LinuxMain.kt | 11 +++++++--- 3 files changed, 8 insertions(+), 28 deletions(-) delete mode 100644 sandbox/src/jvmTest/java/TestClass.kt diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt index 8e4de637e..b9da8cfc7 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt @@ -2,14 +2,11 @@ package de.jensklingenberg.ktorfit.demo import com.example.UserFactory -import com.example.api.API import com.example.api.JsonPlaceHolderApi -import com.example.api._APIImpl import com.example.model.ExampleApi import com.example.model.MyOwnResponse import com.example.model.MyOwnResponseConverterFactory import com.example.model.createExampleApi -import de.jensklingenberg.ktorfit.Ktorfit import de.jensklingenberg.ktorfit.converter.CallConverterFactory import de.jensklingenberg.ktorfit.converter.FlowConverterFactory import de.jensklingenberg.ktorfit.ktorfit diff --git a/sandbox/src/jvmTest/java/TestClass.kt b/sandbox/src/jvmTest/java/TestClass.kt deleted file mode 100644 index 039d09b93..000000000 --- a/sandbox/src/jvmTest/java/TestClass.kt +++ /dev/null @@ -1,22 +0,0 @@ -import com.example.api.createGithubService -import de.jensklingenberg.ktorfit.Ktorfit -import de.jensklingenberg.ktorfit.ktorfit -import org.junit.Assert -import org.junit.Test - -class TestClass { - - private val ktorfit: Ktorfit by lazy { - ktorfit { - baseUrl("https://localhost/") - - } - } - - @Test - fun addition_isCorrect() { - ktorfit.createGithubService() - Assert.assertEquals(4, 2 + 2) - } - -} \ No newline at end of file diff --git a/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt b/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt index 757fca078..0e0526fe3 100644 --- a/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt +++ b/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt @@ -1,13 +1,18 @@ import com.example.api.JsonPlaceHolderApi import de.jensklingenberg.ktorfit.Ktorfit +import de.jensklingenberg.ktorfit.converter.FlowConverterFactory import io.ktor.client.* import kotlinx.coroutines.runBlocking fun main() { - - val linuxKtorfit = Ktorfit.Builder().baseUrl(JsonPlaceHolderApi.baseUrl).httpClient(HttpClient()) - .responseConverter(FlowResponseConverter()).build() + val linuxKtorfit = + Ktorfit + .Builder() + .baseUrl(JsonPlaceHolderApi.baseUrl) + .httpClient(HttpClient()) + .converterFactories(FlowConverterFactory()) + .build() val api = linuxKtorfit.create() runBlocking { From 7ccfab896dd497c0ed93a04612d5a642641c87fc Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 25 Aug 2024 19:04:51 +0200 Subject: [PATCH 24/59] Add multi module example --- .../src/commonMain/kotlin/com/example/ktorfittest/People.kt | 0 example/MultiplatformExample/settings.gradle.kts | 3 ++- example/MultiplatformExample/shared/build.gradle.kts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) rename example/MultiplatformExample/{shared => person}/src/commonMain/kotlin/com/example/ktorfittest/People.kt (100%) diff --git a/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/People.kt b/example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/People.kt similarity index 100% rename from example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/People.kt rename to example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/People.kt diff --git a/example/MultiplatformExample/settings.gradle.kts b/example/MultiplatformExample/settings.gradle.kts index 020bc916a..aa4df343e 100644 --- a/example/MultiplatformExample/settings.gradle.kts +++ b/example/MultiplatformExample/settings.gradle.kts @@ -13,4 +13,5 @@ pluginManagement { rootProject.name = "KtorfitMultiplatformExample" include(":androidApp") -include(":shared") \ No newline at end of file +include(":shared") +include(":person") \ No newline at end of file diff --git a/example/MultiplatformExample/shared/build.gradle.kts b/example/MultiplatformExample/shared/build.gradle.kts index c36a5f5e7..bf1b9e841 100644 --- a/example/MultiplatformExample/shared/build.gradle.kts +++ b/example/MultiplatformExample/shared/build.gradle.kts @@ -45,6 +45,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { + implementation(project(":person")) implementation("de.jensklingenberg.ktorfit:ktorfit-lib:$ktorfitVersion") // implementation("de.jensklingenberg.ktorfit:ktorfit-lib-light:$ktorfitVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") From 8e87e38671b139dd9b9ba6f65f9d4e1f16116b24 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 25 Aug 2024 19:08:33 +0200 Subject: [PATCH 25/59] Add multi module example --- .../person/build.gradle.kts | 72 +++++++++++++++++++ .../src/androidMain/AndroidManifest.xml | 2 + 2 files changed, 74 insertions(+) create mode 100644 example/MultiplatformExample/person/build.gradle.kts create mode 100644 example/MultiplatformExample/person/src/androidMain/AndroidManifest.xml diff --git a/example/MultiplatformExample/person/build.gradle.kts b/example/MultiplatformExample/person/build.gradle.kts new file mode 100644 index 000000000..1a2f794f4 --- /dev/null +++ b/example/MultiplatformExample/person/build.gradle.kts @@ -0,0 +1,72 @@ +plugins { + kotlin("multiplatform") + id("com.android.library") + id("kotlinx-serialization") +} + +version = "1.0" +val ktorVersion = "2.3.11" + +kotlin { + jvmToolchain(8) + targetHierarchy.default() + + jvm() + androidTarget() + iosX64() + iosArm64() + iosSimulatorArm64() + macosX64() + js(IR) { + this.nodejs() + binaries.executable() + } + + sourceSets { + val commonMain by getting { + dependencies { + // Only needed when you want to use Kotlin Serialization + implementation("io.ktor:ktor-client-serialization:$ktorVersion") + implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion") + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + } + } + val androidMain by getting + val jvmMain by getting + val jsMain by getting + val iosMain by getting + val macosX64Main by getting + } +} + +android { + compileSdk = 34 + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + defaultConfig { + minSdk = 21 + targetSdk = 34 + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } +} + +tasks.withType { + kotlinOptions { + jvmTarget = "1.8" + allWarningsAsErrors = false + } +} + +allprojects { + repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + } + } +} diff --git a/example/MultiplatformExample/person/src/androidMain/AndroidManifest.xml b/example/MultiplatformExample/person/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..b4adbb2cf --- /dev/null +++ b/example/MultiplatformExample/person/src/androidMain/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 0ce0f4fee3ef34ef0a4c94ee40664181cb8cbe56 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 21:19:51 +0200 Subject: [PATCH 26/59] Move null check to default converter (#648) --- .../DefaultSuspendResponseConverterFactory.kt | 20 ++++---- .../internal/KtorfitConverterHelper.kt | 47 ++++++++----------- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt index 9cd5351f5..eaadf65f5 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt @@ -11,25 +11,27 @@ import io.ktor.client.statement.HttpResponse * It is automatically applied last */ internal class DefaultSuspendResponseConverterFactory : Converter.Factory { - class DefaultSuspendResponseConverter(val typeData: TypeData) : - Converter.SuspendResponseConverter { - override suspend fun convert(result: KtorfitResult): Any { - return when (result) { + class DefaultSuspendResponseConverter( + val typeData: TypeData + ) : Converter.SuspendResponseConverter { + override suspend fun convert(result: KtorfitResult): Any? = + when (result) { is KtorfitResult.Failure -> { - throw result.throwable + if (typeData.isNullable) { + null + } else { + throw result.throwable + } } is KtorfitResult.Success -> { result.response.call.body(typeData.typeInfo) } } - } } override fun suspendResponseConverter( typeData: TypeData, ktorfit: Ktorfit, - ): Converter.SuspendResponseConverter { - return DefaultSuspendResponseConverter(typeData) - } + ): Converter.SuspendResponseConverter = DefaultSuspendResponseConverter(typeData) } diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt index cd8cd7a96..f5b4c23e8 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt @@ -55,36 +55,27 @@ public class KtorfitConverterHelper(private val ktorfit: Ktorfit) { typeData: TypeData, requestBuilder: HttpRequestBuilder.() -> Unit, ): ReturnType? { - try { - if (typeData.typeInfo.type == HttpStatement::class) { - return httpClient.prepareRequest { - requestBuilder(this) - } as ReturnType - } - - ktorfit.nextSuspendResponseConverter(null, typeData)?.let { - val result: KtorfitResult = - try { - KtorfitResult.Success( - httpClient.request { - requestBuilder(this) - }, - ) - } catch (exception: Exception) { - KtorfitResult.Failure(exception) - } - return it.convert(result) as ReturnType? - } + if (typeData.typeInfo.type == HttpStatement::class) { + return httpClient.prepareRequest { + requestBuilder(this) + } as ReturnType + } - throw IllegalStateException("No SuspendResponseConverter found to convert ${typeData.typeInfo}") - } catch (exception: Exception) { - val typeIsNullable = typeData.typeInfo.kotlinType?.isMarkedNullable ?: false - return if (typeIsNullable) { - null - } else { - throw exception - } + ktorfit.nextSuspendResponseConverter(null, typeData)?.let { + val result: KtorfitResult = + try { + KtorfitResult.Success( + httpClient.request { + requestBuilder(this) + }, + ) + } catch (exception: Exception) { + KtorfitResult.Failure(exception) + } + return it.convert(result) as ReturnType? } + + throw IllegalStateException("No SuspendResponseConverter found to convert ${typeData.typeInfo}") } public fun convertParameterType( From 4ac9ca3aae5c88757217e33bb1a964253bdba9b1 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 21:40:39 +0200 Subject: [PATCH 27/59] Reformat --- .../kotlin/de/jensklingenberg/ktorfit/Ktorfit.kt | 5 ++--- .../de/jensklingenberg/ktorfit/converter/Converter.kt | 4 +--- .../de/jensklingenberg/ktorfit/converter/KtorfitResult.kt | 8 ++++++-- .../ktorfit/internal/KtorfitConverterHelper.kt | 4 +++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/Ktorfit.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/Ktorfit.kt index e7ebbffeb..3aa7be2eb 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/Ktorfit.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/Ktorfit.kt @@ -202,13 +202,12 @@ public class Ktorfit private constructor( /** * Creates an instance of Ktorfit with specified baseUrl and HttpClient. */ - public fun build(): Ktorfit { - return Ktorfit( + public fun build(): Ktorfit = + Ktorfit( baseUrl = _baseUrl, httpClient = _httpClient ?: HttpClient(), converterFactories = _factories.toList() + listOf(DefaultSuspendResponseConverterFactory()), ) - } } } diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/Converter.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/Converter.kt index 2ee17b0cd..71a7e8b68 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/Converter.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/Converter.kt @@ -48,9 +48,7 @@ public interface Converter { public fun getUpperBoundType( index: Int, type: TypeData, - ): TypeData? { - return type.typeArgs[index] - } + ): TypeData? = type.typeArgs[index] public interface Factory { /** diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/KtorfitResult.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/KtorfitResult.kt index 7969b8d3d..e9cecea8e 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/KtorfitResult.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/KtorfitResult.kt @@ -9,11 +9,15 @@ public sealed interface KtorfitResult { * Represents a successful response. * @property response The HTTP response. */ - public class Success(public val response: HttpResponse) : KtorfitResult + public class Success( + public val response: HttpResponse + ) : KtorfitResult /** * Represents a failed response. * @property throwable The throwable associated with the failure. */ - public class Failure(public val throwable: Throwable) : KtorfitResult + public class Failure( + public val throwable: Throwable + ) : KtorfitResult } diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt index f5b4c23e8..faa9960fb 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt @@ -17,7 +17,9 @@ import kotlin.reflect.cast * Cant make this internal because it is used by generated code */ @InternalKtorfitApi -public class KtorfitConverterHelper(private val ktorfit: Ktorfit) { +public class KtorfitConverterHelper( + private val ktorfit: Ktorfit +) { private val httpClient: HttpClient = ktorfit.httpClient /** From b668d7695f5a2238b91651faa1072ec19acbf7fd Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 22:01:20 +0200 Subject: [PATCH 28/59] Reformat --- .../kotlin/com/example/UserFactory.kt | 5 +- .../kotlin/com/example/api/GithubService.kt | 24 ++- .../com/example/api/JsonPlaceHolderApi.kt | 54 +++++-- .../kotlin/com/example/api/KtorSamplesApi.kt | 41 +++-- .../kotlin/com/example/api/Response.kt | 10 +- .../kotlin/com/example/api/StarWarsApi.kt | 8 +- .../kotlin/com/example/model/CommonClient.kt | 40 ++--- .../kotlin/com/example/model/Envelope.kt | 10 +- .../kotlin/com/example/model/MyOwnResponse.kt | 12 +- .../example/model/MyOwnResponseConverter.kt | 22 ++- .../kotlin/com/example/model/People.kt | 8 +- .../kotlin/com/example/model/Post.kt | 15 +- .../kotlin/com/example/model/Specie.kt | 2 - .../model/StringToIntRequestConverter.kt | 17 +- .../model/github/GithubFollowerResponse.kt | 37 +++-- .../com/example/model/github/Issuedata.kt | 5 +- .../com/example/model/github/TestReee.kt | 146 +++++++++--------- sandbox/src/jsMain/kotlin/JsMain.kt | 10 +- .../ktorfit/demo/CreateIssue.kt | 46 +++--- .../ktorfit/demo/HeaderTestApi.kt | 39 +++-- .../jensklingenberg/ktorfit/demo/JvMMain.kt | 67 ++++---- .../ktorfit/demo/JvmPlaceHolderApi.kt | 37 +++-- .../ktorfit/demo/QueryTestApi.kt | 46 ++++-- .../jensklingenberg/ktorfit/demo/TestApi.kt | 27 ++-- .../jensklingenberg/ktorfit/demo/TestApi2.kt | 25 +-- sandbox/src/linuxX64Main/kotlin/LinuxMain.kt | 3 +- 26 files changed, 434 insertions(+), 322 deletions(-) diff --git a/sandbox/src/commonMain/kotlin/com/example/UserFactory.kt b/sandbox/src/commonMain/kotlin/com/example/UserFactory.kt index ef9fb16da..87d99ff70 100644 --- a/sandbox/src/commonMain/kotlin/com/example/UserFactory.kt +++ b/sandbox/src/commonMain/kotlin/com/example/UserFactory.kt @@ -10,21 +10,20 @@ import io.ktor.client.call.* import io.ktor.client.statement.* class UserFactory : Converter.Factory { - override fun suspendResponseConverter( typeData: TypeData, ktorfit: Ktorfit ): Converter.SuspendResponseConverter? { if (typeData.typeInfo.type == User::class) { return object : Converter.SuspendResponseConverter { - override suspend fun convert(result: KtorfitResult): Any { - when (result) { + when (result) { is KtorfitResult.Success -> { val response = result.response val envelope = response.body() return envelope.user } + is KtorfitResult.Failure -> { throw result.throwable } diff --git a/sandbox/src/commonMain/kotlin/com/example/api/GithubService.kt b/sandbox/src/commonMain/kotlin/com/example/api/GithubService.kt index 53f2b16be..a44da5bdb 100644 --- a/sandbox/src/commonMain/kotlin/com/example/api/GithubService.kt +++ b/sandbox/src/commonMain/kotlin/com/example/api/GithubService.kt @@ -4,11 +4,15 @@ import com.example.model.github.GithubFollowerResponseItem import com.example.model.github.Issuedata import com.example.model.github.TestReeeItem import de.jensklingenberg.ktorfit.Call -import de.jensklingenberg.ktorfit.http.* +import de.jensklingenberg.ktorfit.http.Body +import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Header +import de.jensklingenberg.ktorfit.http.Headers +import de.jensklingenberg.ktorfit.http.POST +import de.jensklingenberg.ktorfit.http.Path import kotlinx.coroutines.flow.Flow interface GithubService { - companion object { const val baseUrl = "https://api.github.com/" } @@ -19,10 +23,16 @@ interface GithubService { "Content-Type: application/json" ) @POST("repos/foso/experimental/issues") - suspend fun createIssue(@Body body: Map<*,String>, @Header("Acci") headi: String?): String + suspend fun createIssue( + @Body body: Map<*, String>, + @Header("Acci") headi: String? + ): String @POST("repos/foso/experimental/issues") - suspend fun createIssue2(@Body body: Issuedata, @Header("Acci") headi: String?): Call> + suspend fun createIssue2( + @Body body: Issuedata, + @Header("Acci") headi: String? + ): Call> @Headers( "Accept: application/vnd.github.v3+json", @@ -38,6 +48,8 @@ interface GithubService { "Content-Type: application/json" ) @GET("repos/{owner}/{repo}/commits") - fun listCommits(@Path owner: String, @Path repo: String): Flow> - + fun listCommits( + @Path owner: String, + @Path repo: String + ): Flow> } diff --git a/sandbox/src/commonMain/kotlin/com/example/api/JsonPlaceHolderApi.kt b/sandbox/src/commonMain/kotlin/com/example/api/JsonPlaceHolderApi.kt index 0ce342cf5..0e5aa7391 100644 --- a/sandbox/src/commonMain/kotlin/com/example/api/JsonPlaceHolderApi.kt +++ b/sandbox/src/commonMain/kotlin/com/example/api/JsonPlaceHolderApi.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.Deferred import kotlinx.coroutines.flow.Flow interface JsonPlaceHolderApi { - companion object { const val baseUrl = "https://jsonplaceholder.typicode.com/" } @@ -22,7 +21,7 @@ interface JsonPlaceHolderApi { @GET("posts") fun callPosts(): Call> - @HTTP("GET2","posts") + @HTTP("GET2", "posts") fun callPostsCustomHttp(): Call> @GET("posts") @@ -30,31 +29,48 @@ interface JsonPlaceHolderApi { @Streaming @GET("docs/response.html#streaming") - suspend fun getPostsStreaming(@QueryMap test: Map): HttpStatement + suspend fun getPostsStreaming( + @QueryMap test: Map + ): HttpStatement @GET("posts/{postId}") - suspend fun getPostById(@Path postId: Int = 4): Post + suspend fun getPostById( + @Path postId: Int = 4 + ): Post @GET("posts/{postId}/comments") - fun getFlowCommentsByPostId(@Path("postId") postId: Int, @ReqBuilder builder : HttpRequestBuilder.() -> Unit): Flow>? + fun getFlowCommentsByPostId( + @Path("postId") postId: Int, + @ReqBuilder builder: HttpRequestBuilder.() -> Unit + ): Flow>? @GET("posts/{postId}/comments") - suspend fun getCommentsByPostId(@Path("postId") postId: Int): List? + suspend fun getCommentsByPostId( + @Path("postId") postId: Int + ): List? @GET("posts/{postId}/comments") - suspend fun getCommentsByPostIdResponse(@RequestType(Int::class) @Path("postId") postId: String): MyOwnResponse> + suspend fun getCommentsByPostIdResponse( + @RequestType(Int::class) @Path("postId") postId: String + ): MyOwnResponse> @Headers(value = ["Content-Type: application/json"]) @GET("posts/{postId}/comments") - fun callCommentsByPostId(@Path("postId") postId: Int): Call> + fun callCommentsByPostId( + @Path("postId") postId: Int + ): Call> @Headers(value = ["Content-Type: application/json"]) @GET("posts/{postId}/comments") - suspend fun resCommentsByPostId(@Path("postId") postId: Int): Response> + suspend fun resCommentsByPostId( + @Path("postId") postId: Int + ): Response> @Headers(value = ["Content-Type: application/json"]) @GET("posts/{postId}/comments") - fun deferedCommentsByPostId(@Path("postId") postId: Int): Deferred> + fun deferedCommentsByPostId( + @Path("postId") postId: Int + ): Deferred> @Headers(value = ["Content-Type: application/json"]) @GET("comments") @@ -64,19 +80,25 @@ interface JsonPlaceHolderApi { @Headers(value = ["Content-Type: application/json"]) @POST("posts") - suspend fun postPosts(@Body post: Post): Post + suspend fun postPosts( + @Body post: Post + ): Post @Headers(value = ["Content-Type: application/json"]) @POST("posts") - suspend fun putPosts(@Body post: Post): Post + suspend fun putPosts( + @Body post: Post + ): Post @Headers(value = ["Content-Type: application/json"]) @PATCH("posts/{postId}/{number}") - suspend fun patchPosts(@Path("postId") postId: Int): Post + suspend fun patchPosts( + @Path("postId") postId: Int + ): Post @Headers(value = ["Content-Type: application/json"]) @DELETE("posts/{postId}") - suspend fun deletePosts(@Path("postId") postId: Int): String - + suspend fun deletePosts( + @Path("postId") postId: Int + ): String } - diff --git a/sandbox/src/commonMain/kotlin/com/example/api/KtorSamplesApi.kt b/sandbox/src/commonMain/kotlin/com/example/api/KtorSamplesApi.kt index 283c024e1..0cb551dd5 100644 --- a/sandbox/src/commonMain/kotlin/com/example/api/KtorSamplesApi.kt +++ b/sandbox/src/commonMain/kotlin/com/example/api/KtorSamplesApi.kt @@ -10,7 +10,6 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable interface KtorSamplesApi { - companion object { const val baseUrl = "http://localhost:8080/" } @@ -20,9 +19,11 @@ interface KtorSamplesApi { val test1: String @POST("signup") - suspend fun sendReg(@Body param: Parameters): String + suspend fun sendReg( + @Body param: Parameters + ): String - //client-submit-form + // client-submit-form @POST("signup") @FormUrlEncoded suspend fun signup( @@ -31,11 +32,9 @@ interface KtorSamplesApi { @Field("password") password: String, @Field("confirmation") confirmation: String, @Field("names") names: List - ): String - - //client-submit-form + // client-submit-form @POST("signup") @FormUrlEncoded suspend fun signup( @@ -45,35 +44,43 @@ interface KtorSamplesApi { @Multipart @POST("upload") - suspend fun uploadFile(@Part("description") description: String, @Part("list") file: List,@PartMap() map : Map): String + suspend fun uploadFile( + @Part("description") description: String, + @Part("list") file: List, + @PartMap() map: Map + ): String @POST("upload") - suspend fun upload(@Body map: MultiPartFormDataContent) + suspend fun upload( + @Body map: MultiPartFormDataContent + ) } - data class Query( val working: Working ) { data class Working( - val data: String + val data: String ) - data class NotWorking( - val reponse: String + val reponse: String ) } - interface API { - data class JensTest(val names: List) + data class JensTest( + val names: List + ) @Headers( - "Content-Type: application/json", "Accept: application/json" + "Content-Type: application/json", + "Accept: application/json" ) @POST("example/request") - suspend fun query(@Body query: Query): List // not sure if non-list works, haven't tested + suspend fun query( + @Body query: Query + ): List // not sure if non-list works, haven't tested } class KtorfitTest { @@ -87,4 +94,4 @@ class KtorfitTest { interface ITest { @GET("test") fun test(): KtorfitTest.TestData -} \ No newline at end of file +} diff --git a/sandbox/src/commonMain/kotlin/com/example/api/Response.kt b/sandbox/src/commonMain/kotlin/com/example/api/Response.kt index 889cae8cc..93b947e26 100644 --- a/sandbox/src/commonMain/kotlin/com/example/api/Response.kt +++ b/sandbox/src/commonMain/kotlin/com/example/api/Response.kt @@ -1,11 +1,17 @@ package com.example.api sealed class Response { - data class Success(val data: T) : Response() - class Error(val ex:Throwable) : Response() + data class Success( + val data: T + ) : Response() + + class Error( + val ex: Throwable + ) : Response() companion object { fun success(data: T) = Success(data) + fun error(ex: Throwable) = Error(ex) } } diff --git a/sandbox/src/commonMain/kotlin/com/example/api/StarWarsApi.kt b/sandbox/src/commonMain/kotlin/com/example/api/StarWarsApi.kt index 57edb3ea8..4ba91f5e0 100644 --- a/sandbox/src/commonMain/kotlin/com/example/api/StarWarsApi.kt +++ b/sandbox/src/commonMain/kotlin/com/example/api/StarWarsApi.kt @@ -6,12 +6,12 @@ import de.jensklingenberg.ktorfit.http.GET import de.jensklingenberg.ktorfit.http.Path interface StarWarsApi { - - companion object{ + companion object { const val baseUrl = "https://swapi.dev/api/" } @GET("people/{id}/") - fun getPersonById(@Path("id") peopleId: Int): Call + fun getPersonById( + @Path("id") peopleId: Int + ): Call } - diff --git a/sandbox/src/commonMain/kotlin/com/example/model/CommonClient.kt b/sandbox/src/commonMain/kotlin/com/example/model/CommonClient.kt index 7b97c2d5e..613774f58 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/CommonClient.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/CommonClient.kt @@ -9,26 +9,28 @@ import io.ktor.client.plugins.contentnegotiation.* import io.ktor.serialization.kotlinx.json.* import kotlinx.serialization.json.Json - -val commonClient = HttpClient() { - - install(ContentNegotiation) { - json(Json { isLenient = true; ignoreUnknownKeys = true }) +val commonClient = + HttpClient { + + install(ContentNegotiation) { + json( + Json { + isLenient = true + ignoreUnknownKeys = true + } + ) + } } -} - - - -val commonKtorfit = ktorfit { - baseUrl(JsonPlaceHolderApi.baseUrl) - httpClient(commonClient) - converterFactories( - CallConverterFactory(), - StringToIntRequestConverterFactory(), - MyOwnResponseConverterFactory() - ) -} +val commonKtorfit = + ktorfit { + baseUrl(JsonPlaceHolderApi.baseUrl) + httpClient(commonClient) + converterFactories( + CallConverterFactory(), + StringToIntRequestConverterFactory(), + MyOwnResponseConverterFactory() + ) + } val jsonPlaceHolderApi = commonKtorfit.createJsonPlaceHolderApi() - diff --git a/sandbox/src/commonMain/kotlin/com/example/model/Envelope.kt b/sandbox/src/commonMain/kotlin/com/example/model/Envelope.kt index 5fd2635f6..bb5c4f0ec 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/Envelope.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/Envelope.kt @@ -1,7 +1,13 @@ package com.example.model @kotlinx.serialization.Serializable -data class Envelope(val success: Boolean, val user: User) +data class Envelope( + val success: Boolean, + val user: User +) @kotlinx.serialization.Serializable -data class User(val id: Int, val name: String) \ No newline at end of file +data class User( + val id: Int, + val name: String +) diff --git a/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponse.kt b/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponse.kt index 29f8051ef..bd99ef81d 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponse.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponse.kt @@ -4,11 +4,17 @@ import kotlinx.serialization.Serializable @Serializable sealed class MyOwnResponse { - data class Success(val data: T) : MyOwnResponse() - class Error(val ex: Throwable) : MyOwnResponse() + data class Success( + val data: T + ) : MyOwnResponse() + + class Error( + val ex: Throwable + ) : MyOwnResponse() companion object { fun success(data: T) = Success(data) + fun error(ex: Throwable) = Error(ex) } -} \ No newline at end of file +} diff --git a/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt b/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt index b8d056ab8..33a039b6a 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt @@ -4,20 +4,16 @@ import de.jensklingenberg.ktorfit.Ktorfit import de.jensklingenberg.ktorfit.converter.Converter import de.jensklingenberg.ktorfit.converter.KtorfitResult import de.jensklingenberg.ktorfit.converter.TypeData -import io.ktor.client.call.* -import io.ktor.client.statement.* - +import io.ktor.client.call.body +import io.ktor.client.statement.HttpResponse class MyOwnResponseConverterFactory : Converter.Factory { - override fun suspendResponseConverter( typeData: TypeData, ktorfit: Ktorfit ): Converter.SuspendResponseConverter? { if (typeData.typeInfo.type == MyOwnResponse::class) { - return object : Converter.SuspendResponseConverter { - override suspend fun convert(result: KtorfitResult): Any { return when (result) { is KtorfitResult.Failure -> { @@ -27,11 +23,13 @@ class MyOwnResponseConverterFactory : Converter.Factory { is KtorfitResult.Success -> { val response = result.response return try { - val convertedBody = ktorfit.nextSuspendResponseConverter( - null, - typeData.typeArgs.first() - )?.convert(result) - ?: response.body(typeData.typeArgs.first().typeInfo) + val convertedBody = + ktorfit + .nextSuspendResponseConverter( + null, + typeData.typeArgs.first() + )?.convert(result) + ?: response.body(typeData.typeArgs.first().typeInfo) MyOwnResponse.success(convertedBody) } catch (ex: Throwable) { MyOwnResponse.error(ex) @@ -43,4 +41,4 @@ class MyOwnResponseConverterFactory : Converter.Factory { } return null } -} \ No newline at end of file +} diff --git a/sandbox/src/commonMain/kotlin/com/example/model/People.kt b/sandbox/src/commonMain/kotlin/com/example/model/People.kt index 817fb876c..0f3b13c02 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/People.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/People.kt @@ -1,7 +1,6 @@ package com.example.model @kotlinx.serialization.Serializable - data class People( val films: List? = null, val homeworld: String? = null, @@ -10,14 +9,13 @@ data class People( val edited: String? = null, val created: String? = null, val mass: String? = null, - //val vehicles: List? = null, + // val vehicles: List? = null, val url: String? = null, val hairColor: String? = null, val birthYear: String? = null, val eyeColor: String? = null, - //val species: List? = null, - //val starships: List? = null, + // val species: List? = null, + // val starships: List? = null, val name: String? = null, val height: String? = null ) - diff --git a/sandbox/src/commonMain/kotlin/com/example/model/Post.kt b/sandbox/src/commonMain/kotlin/com/example/model/Post.kt index f5afa4f30..3efc25c34 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/Post.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/Post.kt @@ -3,7 +3,18 @@ package com.example.model import kotlinx.serialization.Serializable @Serializable -data class Post(val userId: Int, val id: Int, val title: String, val body: String) +data class Post( + val userId: Int, + val id: Int, + val title: String, + val body: String +) @Serializable -data class Comment(val postId: Int, val id: Int, val name: String, val body: String, val email: String) +data class Comment( + val postId: Int, + val id: Int, + val name: String, + val body: String, + val email: String +) diff --git a/sandbox/src/commonMain/kotlin/com/example/model/Specie.kt b/sandbox/src/commonMain/kotlin/com/example/model/Specie.kt index b5f791f36..29e4fde9e 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/Specie.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/Specie.kt @@ -1,7 +1,6 @@ package com.example.model @kotlinx.serialization.Serializable - data class Specie( val films: List? = null, val skinColors: String? = null, @@ -19,4 +18,3 @@ data class Specie( val designation: String? = null, val averageLifespan: String? = null ) - diff --git a/sandbox/src/commonMain/kotlin/com/example/model/StringToIntRequestConverter.kt b/sandbox/src/commonMain/kotlin/com/example/model/StringToIntRequestConverter.kt index 6dd32cb86..47844b0c8 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/StringToIntRequestConverter.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/StringToIntRequestConverter.kt @@ -3,16 +3,15 @@ package com.example.model import de.jensklingenberg.ktorfit.converter.Converter import kotlin.reflect.KClass - class StringToIntRequestConverterFactory : Converter.Factory { - class StringToIntRequestConverter : Converter.RequestParameterConverter { - override fun convert(data: Any): Any { - return (data as String).toInt() - } + override fun convert(data: Any): Any = (data as String).toInt() } - private fun supportedType(parameterType: KClass<*>, requestType: KClass<*>): Boolean { + private fun supportedType( + parameterType: KClass<*>, + requestType: KClass<*> + ): Boolean { val parameterIsString = parameterType == String::class val requestIsInt = requestType == Int::class return parameterIsString && requestIsInt @@ -24,11 +23,9 @@ class StringToIntRequestConverterFactory : Converter.Factory { ): Converter.RequestParameterConverter? { if (supportedType(parameterType, requestType)) { return object : Converter.RequestParameterConverter { - override fun convert(data: Any): Any { - return (data as String).toInt() - } + override fun convert(data: Any): Any = (data as String).toInt() } } return null } -} \ No newline at end of file +} diff --git a/sandbox/src/commonMain/kotlin/com/example/model/github/GithubFollowerResponse.kt b/sandbox/src/commonMain/kotlin/com/example/model/github/GithubFollowerResponse.kt index c9f679c88..e28905e6b 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/github/GithubFollowerResponse.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/github/GithubFollowerResponse.kt @@ -2,23 +2,22 @@ package com.example.model.github @kotlinx.serialization.Serializable data class GithubFollowerResponseItem( - val gistsUrl: String? = null, - val reposUrl: String? = null, - val followingUrl: String? = null, - val starredUrl: String? = null, - val login: String? = null, - val followersUrl: String? = null, - val type: String? = null, - val url: String? = null, - val subscriptionsUrl: String? = null, - val receivedEventsUrl: String? = null, - val avatarUrl: String? = null, - val eventsUrl: String? = null, - val htmlUrl: String? = null, - val siteAdmin: Boolean? = null, - val id: Int? = null, - val gravatarId: String? = null, - val nodeId: String? = null, - val organizationsUrl: String? = null + val gistsUrl: String? = null, + val reposUrl: String? = null, + val followingUrl: String? = null, + val starredUrl: String? = null, + val login: String? = null, + val followersUrl: String? = null, + val type: String? = null, + val url: String? = null, + val subscriptionsUrl: String? = null, + val receivedEventsUrl: String? = null, + val avatarUrl: String? = null, + val eventsUrl: String? = null, + val htmlUrl: String? = null, + val siteAdmin: Boolean? = null, + val id: Int? = null, + val gravatarId: String? = null, + val nodeId: String? = null, + val organizationsUrl: String? = null ) - diff --git a/sandbox/src/commonMain/kotlin/com/example/model/github/Issuedata.kt b/sandbox/src/commonMain/kotlin/com/example/model/github/Issuedata.kt index b6dda7674..2ed441aaf 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/github/Issuedata.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/github/Issuedata.kt @@ -1,4 +1,7 @@ package com.example.model.github @kotlinx.serialization.Serializable -data class Issuedata(val title: String, val body: String) \ No newline at end of file +data class Issuedata( + val title: String, + val body: String +) diff --git a/sandbox/src/commonMain/kotlin/com/example/model/github/TestReee.kt b/sandbox/src/commonMain/kotlin/com/example/model/github/TestReee.kt index 801923123..389e8b8a4 100644 --- a/sandbox/src/commonMain/kotlin/com/example/model/github/TestReee.kt +++ b/sandbox/src/commonMain/kotlin/com/example/model/github/TestReee.kt @@ -1,96 +1,100 @@ package com.example.model.github data class TestReee( - val testReee: List? = null + val testReee: List? = null ) -@kotlinx.serialization.Serializable +@kotlinx.serialization.Serializable data class Author( - val date: String? = null, - val name: String? = null, - val email: String? = null, - val gistsUrl: String? = null, - val reposUrl: String? = null, - val followingUrl: String? = null, - val starredUrl: String? = null, - val login: String? = null, - val followersUrl: String? = null, - val type: String? = null, - val url: String? = null, - val subscriptionsUrl: String? = null, - val receivedEventsUrl: String? = null, - val avatarUrl: String? = null, - val eventsUrl: String? = null, - val htmlUrl: String? = null, - val siteAdmin: Boolean? = null, - val id: Int? = null, - val gravatarId: String? = null, - val nodeId: String? = null, - val organizationsUrl: String? = null + val date: String? = null, + val name: String? = null, + val email: String? = null, + val gistsUrl: String? = null, + val reposUrl: String? = null, + val followingUrl: String? = null, + val starredUrl: String? = null, + val login: String? = null, + val followersUrl: String? = null, + val type: String? = null, + val url: String? = null, + val subscriptionsUrl: String? = null, + val receivedEventsUrl: String? = null, + val avatarUrl: String? = null, + val eventsUrl: String? = null, + val htmlUrl: String? = null, + val siteAdmin: Boolean? = null, + val id: Int? = null, + val gravatarId: String? = null, + val nodeId: String? = null, + val organizationsUrl: String? = null ) -@kotlinx.serialization.Serializable +@kotlinx.serialization.Serializable data class Tree( - val sha: String? = null, - val url: String? = null + val sha: String? = null, + val url: String? = null ) + @kotlinx.serialization.Serializable data class TestReeeItem( - val committer: Committer? = null, - val author: Author? = null, - val htmlUrl: String? = null, - val commit: Commit? = null, - val commentsUrl: String? = null, - val sha: String? = null, - val url: String? = null, - val nodeId: String? = null, - val parents: List? = null + val committer: Committer? = null, + val author: Author? = null, + val htmlUrl: String? = null, + val commit: Commit? = null, + val commentsUrl: String? = null, + val sha: String? = null, + val url: String? = null, + val nodeId: String? = null, + val parents: List? = null ) + @kotlinx.serialization.Serializable data class Verification( - val reason: String? = null, - val signature: String? = null, - val payload: String? = null, - val verified: Boolean? = null + val reason: String? = null, + val signature: String? = null, + val payload: String? = null, + val verified: Boolean? = null ) + @kotlinx.serialization.Serializable data class Committer( - val date: String? = null, - val name: String? = null, - val email: String? = null, - val gistsUrl: String? = null, - val reposUrl: String? = null, - val followingUrl: String? = null, - val starredUrl: String? = null, - val login: String? = null, - val followersUrl: String? = null, - val type: String? = null, - val url: String? = null, - val subscriptionsUrl: String? = null, - val receivedEventsUrl: String? = null, - val avatarUrl: String? = null, - val eventsUrl: String? = null, - val htmlUrl: String? = null, - val siteAdmin: Boolean? = null, - val id: Int? = null, - val gravatarId: String? = null, - val nodeId: String? = null, - val organizationsUrl: String? = null + val date: String? = null, + val name: String? = null, + val email: String? = null, + val gistsUrl: String? = null, + val reposUrl: String? = null, + val followingUrl: String? = null, + val starredUrl: String? = null, + val login: String? = null, + val followersUrl: String? = null, + val type: String? = null, + val url: String? = null, + val subscriptionsUrl: String? = null, + val receivedEventsUrl: String? = null, + val avatarUrl: String? = null, + val eventsUrl: String? = null, + val htmlUrl: String? = null, + val siteAdmin: Boolean? = null, + val id: Int? = null, + val gravatarId: String? = null, + val nodeId: String? = null, + val organizationsUrl: String? = null ) + @kotlinx.serialization.Serializable data class ParentsItem( - val htmlUrl: String? = null, - val sha: String? = null, - val url: String? = null + val htmlUrl: String? = null, + val sha: String? = null, + val url: String? = null ) + @kotlinx.serialization.Serializable data class Commit( - val commentCount: Int? = null, - val committer: Committer? = null, - val author: Author? = null, - val tree: Tree? = null, - val message: String? = null, - val url: String? = null, - val verification: Verification? = null + val commentCount: Int? = null, + val committer: Committer? = null, + val author: Author? = null, + val tree: Tree? = null, + val message: String? = null, + val url: String? = null, + val verification: Verification? = null ) - diff --git a/sandbox/src/jsMain/kotlin/JsMain.kt b/sandbox/src/jsMain/kotlin/JsMain.kt index dcdb1181c..7c41327a9 100644 --- a/sandbox/src/jsMain/kotlin/JsMain.kt +++ b/sandbox/src/jsMain/kotlin/JsMain.kt @@ -1,5 +1,3 @@ - - import com.example.model.Comment import com.example.model.MyOwnResponse import com.example.model.jsonPlaceHolderApi @@ -7,15 +5,13 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch - fun main() { - GlobalScope.launch { println("Launch") when (val test = jsonPlaceHolderApi.getCommentsByPostIdResponse("3")) { is MyOwnResponse.Success -> { - val list = test.data as List + val list = test.data as List println(list.size) } @@ -26,9 +22,5 @@ fun main() { } delay(3000) - } - - } - diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/CreateIssue.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/CreateIssue.kt index ea665c2b6..71be0d292 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/CreateIssue.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/CreateIssue.kt @@ -10,40 +10,36 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json - fun main() { - - val jvmClient = HttpClient() { - install(ContentNegotiation) { - - json(Json { isLenient = true; ignoreUnknownKeys = true; }) + val jvmClient = + HttpClient { + install(ContentNegotiation) { + json( + Json { + isLenient = true + ignoreUnknownKeys = true + } + ) + } + expectSuccess = false } - expectSuccess = false - - - } - - val jvmKtorfit = ktorfit { - baseUrl(GithubService.baseUrl) - httpClient(jvmClient) - } + val jvmKtorfit = + ktorfit { + baseUrl(GithubService.baseUrl) + httpClient(jvmClient) + } val testApi = jvmKtorfit.createGithubService() - runBlocking { - - testApi.listCommits("foso","Experimental").collect{ + testApi.listCommits("foso", "Experimental").collect { println(it.first().author) } - - // println( testApi.createIsseu(Issuedata("hey","ho"))) -//BODY {"title":"title","body":"This is a test"} - // BODY Issuedata(title=Hallo, body=hhhh) + // println( testApi.createIsseu(Issuedata("hey","ho"))) +// BODY {"title":"title","body":"This is a test"} + // BODY Issuedata(title=Hallo, body=hhhh) delay(3000) - } - -} \ No newline at end of file +} diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/HeaderTestApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/HeaderTestApi.kt index bffe751f3..1a6953395 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/HeaderTestApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/HeaderTestApi.kt @@ -1,26 +1,41 @@ package de.jensklingenberg.ktorfit.demo import com.example.model.People -import de.jensklingenberg.ktorfit.http.* +import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Header +import de.jensklingenberg.ktorfit.http.HeaderMap +import de.jensklingenberg.ktorfit.http.Headers +import de.jensklingenberg.ktorfit.http.Path interface HeaderTestApi { - @GET("people/{id}/") - suspend fun multipleHeader(@Path("id") peopleId: Int, @Header("huhu") name: Array,@Header("hey") name2: String): People + suspend fun multipleHeader( + @Path("id") peopleId: Int, + @Header("huhu") name: Array, + @Header("hey") name2: String + ): People @GET("people/{id}/") - suspend fun testHeaderWithArray(@Path("id") peopleId: Int, @Header("huhu") name: Array): People + suspend fun testHeaderWithArray( + @Path("id") peopleId: Int, + @Header("huhu") name: Array + ): People @GET("people/{id}/") - suspend fun testHeaderWithList(@Path("id") peopleId: Int, @Header("huhu") name: List): People - + suspend fun testHeaderWithList( + @Path("id") peopleId: Int, + @Header("huhu") name: List + ): People - @Headers("Accept2: application/json","Accept: application/json2") + @Headers("Accept2: application/json", "Accept: application/json2") @GET("people/{id}/") - suspend fun testHeaders(@Path("id") peopleId: Int ): People + suspend fun testHeaders( + @Path("id") peopleId: Int + ): People @GET("people/{id}/") - suspend fun testHeaderMap(@Path("id") peopleId: Int, @HeaderMap() name: Map?): People - - -} \ No newline at end of file + suspend fun testHeaderMap( + @Path("id") peopleId: Int, + @HeaderMap() name: Map? + ): People +} diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt index b9da8cfc7..65041ab35 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt @@ -1,6 +1,5 @@ package de.jensklingenberg.ktorfit.demo - import com.example.UserFactory import com.example.api.JsonPlaceHolderApi import com.example.model.ExampleApi @@ -20,47 +19,49 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json +val jvmClient = + HttpClient { -val jvmClient = HttpClient { + install(Logging) { + // level = LogLevel.ALL + } - install(Logging) { - //level = LogLevel.ALL - } + install(ContentNegotiation) { + json( + Json { + isLenient = true + ignoreUnknownKeys = true + } + ) + } - install(ContentNegotiation) { - json(Json { isLenient = true; ignoreUnknownKeys = true }) + this.developmentMode = true + expectSuccess = false } - this.developmentMode = true - expectSuccess = false -} - - -val jvmKtorfit = ktorfit { - baseUrl(JsonPlaceHolderApi.baseUrl) - httpClient(jvmClient) - -} - - -val userKtorfit = ktorfit { - baseUrl("https://foso.github.io/Ktorfit/") - httpClient(jvmClient) +val jvmKtorfit = + ktorfit { + baseUrl(JsonPlaceHolderApi.baseUrl) + httpClient(jvmClient) + } - converterFactories( - FlowConverterFactory(), - MyOwnResponseConverterFactory(), - UserFactory(), - CallConverterFactory() - ) -} +val userKtorfit = + ktorfit { + baseUrl("https://foso.github.io/Ktorfit/") + httpClient(jvmClient) + + converterFactories( + FlowConverterFactory(), + MyOwnResponseConverterFactory(), + UserFactory(), + CallConverterFactory() + ) + } -val api : ExampleApi = userKtorfit.createExampleApi() +val api: ExampleApi = userKtorfit.createExampleApi() fun main() { - runBlocking { - val user = api.getUserResponse() when (user) { @@ -74,6 +75,4 @@ fun main() { } delay(3000) } - } - diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvmPlaceHolderApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvmPlaceHolderApi.kt index 2bdb9b061..557558191 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvmPlaceHolderApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvmPlaceHolderApi.kt @@ -8,31 +8,48 @@ import de.jensklingenberg.ktorfit.http.* import io.ktor.client.statement.* internal interface JvmPlaceHolderApi : StarWarsApi { - @GET("people/{id}/") - suspend fun getPersonById2(@Path("id") peopleId: Int): People + suspend fun getPersonById2( + @Path("id") peopleId: Int + ): People @GET("people/{id}/") - suspend fun testQuery(@Path("id") peopleId: Int, @Query world: String? = "World"): People + suspend fun testQuery( + @Path("id") peopleId: Int, + @Query world: String? = "World" + ): People @GET("people/{id}/") - suspend fun testQueryName(@Path("id") peopleId: Int, @QueryName na : List?): People + suspend fun testQueryName( + @Path("id") peopleId: Int, + @QueryName na: List? + ): People @GET("people/{id}/") - suspend fun testQueryName2(@Path("id") peopleId: Int, @QueryName na : Map?, @QueryMap na2 : Map?): People + suspend fun testQueryName2( + @Path("id") peopleId: Int, + @QueryName na: Map?, + @QueryMap na2: Map? + ): People @Streaming @GET("people/1/") suspend fun getPostsStreaming(): HttpStatement @GET("people/{id}/") - fun getPersonById2AsResponse(@Path("id") peopleId: Int): Response + fun getPersonById2AsResponse( + @Path("id") peopleId: Int + ): Response @Headers(value = ["Content-Type: application/json"]) - @GET("people/{id}/") - suspend fun callPersonById2AsResponse(@Path("id") peopleId: Int): Call> + suspend fun callPersonById2AsResponse( + @Path("id") peopleId: Int + ): Call> @GET() - suspend fun getPersonByIdByUrl(@Url peopleId: String, @QueryMap name: Map?): People -} \ No newline at end of file + suspend fun getPersonByIdByUrl( + @Url peopleId: String, + @QueryMap name: Map? + ): People +} diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt index ed9614afd..23a9d2ba5 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt @@ -1,11 +1,14 @@ package de.jensklingenberg.ktorfit.demo import com.example.model.People -import de.jensklingenberg.ktorfit.http.* +import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Path +import de.jensklingenberg.ktorfit.http.Query +import de.jensklingenberg.ktorfit.http.QueryMap +import de.jensklingenberg.ktorfit.http.QueryName import ktorfit.Test interface QueryTestApi { - @GET("people/{id}/") suspend fun testQueryWithEncodedString( @Path("id") peopleId: Int, @@ -14,25 +17,46 @@ interface QueryTestApi { ): People @GET("people/{id}/") - suspend fun testQueryWithEncodedInt(@Path("id") peopleId: Int, @Query("huhu", true) name: Int): People + suspend fun testQueryWithEncodedInt( + @Path("id") peopleId: Int, + @Query("huhu", true) name: Int + ): People @GET("people/{id}/") - suspend fun testQueryWithString(@Path("id") peopleId: Int, @Query("huhu", false) name: String): People + suspend fun testQueryWithString( + @Path("id") peopleId: Int, + @Query("huhu", false) name: String + ): People @GET("people/{id}/") - suspend fun testQueryWithEncodedArray(@Path("id") peopleId: Int, @Query("huhu", true) name: Array): People + suspend fun testQueryWithEncodedArray( + @Path("id") peopleId: Int, + @Query("huhu", true) name: Array + ): People @GET("people/{id}/") - suspend fun testQueryWithList(@Path("id") peopleId: Int, @Query("huhu") name: List): People + suspend fun testQueryWithList( + @Path("id") peopleId: Int, + @Query("huhu") name: List + ): People @GET("people/{id}/") - suspend fun testQueryWithEncodedList(@Path("id") peopleId: Int, @Query("huhu", true) name: List): People + suspend fun testQueryWithEncodedList( + @Path("id") peopleId: Int, + @Query("huhu", true) name: List + ): People @GET("people/{id}/") - suspend fun testQueryName(@Path("id") peopleId: Int, @QueryName name: String): People + suspend fun testQueryName( + @Path("id") peopleId: Int, + @QueryName name: String + ): People @GET("people/{id}/") - suspend fun testQueryNameList(@Path("id") peopleId: Int, @QueryName(false) name: List): People + suspend fun testQueryNameList( + @Path("id") peopleId: Int, + @QueryName(false) name: List + ): People @GET("people/{id}/") suspend fun testQueryEncodedMap( @@ -40,6 +64,4 @@ interface QueryTestApi { @QueryMap name: Map?, @QueryMap(true) name2: Map? ): People - - -} \ No newline at end of file +} diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt index 64de238ba..f07147314 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt @@ -7,36 +7,35 @@ import io.ktor.client.request.forms.* import io.reactivex.rxjava3.core.Observable import kotlinx.coroutines.flow.Flow - - - -interface TestApi { - +interface TestApi { @GET("pos4ts") fun getPosts(): Call> @GET("posts/{userId}") - suspend fun getPost(@Path("userId") myUserId: Int = 4): Post + suspend fun getPost( + @Path("userId") myUserId: Int = 4 + ): Post @POST("posts") - suspend fun postPost(@Body otherID: Post): Post + suspend fun postPost( + @Body otherID: Post + ): Post @GET("posts/{userId}") - suspend fun getPostsByUserId(@Path("userId") myUserId: Int): List + suspend fun getPostsByUserId( + @Path("userId") myUserId: Int + ): List @Headers(value = ["Accept: application/json"]) @GET("posts") fun getFlowPosts(): Flow> - @POST("upload") - suspend fun uppi(@Body map: MultiPartFormDataContent) + suspend fun uppi( + @Body map: MultiPartFormDataContent + ) @Headers(value = ["Accept: application/json"]) @GET("posts") fun getObserPosts(): Observable> - - - } - diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt index 9b8e9b55f..8f47e9a09 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt @@ -6,22 +6,27 @@ import de.jensklingenberg.ktorfit.http.GET import de.jensklingenberg.ktorfit.http.Path import de.jensklingenberg.ktorfit.http.QueryName -interface TestApi2 : StarWarsApi, QueryNameTestApi { +interface TestApi2 : + StarWarsApi, + QueryNameTestApi { @GET("people/{id}/") fun tste() - } -data class Test(val name: String) - +data class Test( + val name: String +) interface QueryNameTestApi { - @GET("people/{id}/") - suspend fun testQueryName(@Path("id") peopleId: Int, @QueryName name: String): People + suspend fun testQueryName( + @Path("id") peopleId: Int, + @QueryName name: String + ): People @GET("people/{id}/") - suspend fun testQueryNameList(@Path("id") peopleId: Int, @QueryName(false) name: List): People - - -} \ No newline at end of file + suspend fun testQueryNameList( + @Path("id") peopleId: Int, + @QueryName(false) name: List + ): People +} diff --git a/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt b/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt index 0e0526fe3..051ab0699 100644 --- a/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt +++ b/sandbox/src/linuxX64Main/kotlin/LinuxMain.kt @@ -1,8 +1,7 @@ import com.example.api.JsonPlaceHolderApi import de.jensklingenberg.ktorfit.Ktorfit import de.jensklingenberg.ktorfit.converter.FlowConverterFactory - -import io.ktor.client.* +import io.ktor.client.HttpClient import kotlinx.coroutines.runBlocking fun main() { From 8309551b3c8d462b7db5e58a7778e31346ddf88e Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 22:38:13 +0200 Subject: [PATCH 29/59] Reformat --- sandbox/build.gradle.kts | 3 +-- ...onverter.kt => MyOwnResponseConverterFactory.kt} | 0 .../de/jensklingenberg/ktorfit/demo/JvMMain.kt | 4 ++-- .../de/jensklingenberg/ktorfit/demo/QueryTestApi.kt | 1 - .../de/jensklingenberg/ktorfit/demo/TestApi.kt | 13 ++++++------- .../de/jensklingenberg/ktorfit/demo/TestApi2.kt | 2 +- 6 files changed, 10 insertions(+), 13 deletions(-) rename sandbox/src/commonMain/kotlin/com/example/model/{MyOwnResponseConverter.kt => MyOwnResponseConverterFactory.kt} (100%) diff --git a/sandbox/build.gradle.kts b/sandbox/build.gradle.kts index 2e8cb331c..b0edb7a44 100644 --- a/sandbox/build.gradle.kts +++ b/sandbox/build.gradle.kts @@ -83,8 +83,7 @@ kotlin { dependencies { implementation(libs.ktor.client.core.jvm) - implementation(libs.kotlinx.coroutines.rx3) - implementation("io.reactivex.rxjava3:rxjava:3.1.9") + implementation("ch.qos.logback:logback-classic:1.2.3") implementation(libs.ktor.client.logging) implementation(libs.ktor.serialization.gson) implementation(libs.ktor.client.cio.jvm) diff --git a/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt b/sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverterFactory.kt similarity index 100% rename from sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverter.kt rename to sandbox/src/commonMain/kotlin/com/example/model/MyOwnResponseConverterFactory.kt diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt index 65041ab35..9a82704e4 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/JvMMain.kt @@ -66,11 +66,11 @@ fun main() { when (user) { is MyOwnResponse.Success -> { - println(user.data) + System.out.println(user.data) } is MyOwnResponse.Error<*> -> { - println(user.ex) + System.out.println(user.ex) } } delay(3000) diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt index 23a9d2ba5..76aae9eba 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/QueryTestApi.kt @@ -6,7 +6,6 @@ import de.jensklingenberg.ktorfit.http.Path import de.jensklingenberg.ktorfit.http.Query import de.jensklingenberg.ktorfit.http.QueryMap import de.jensklingenberg.ktorfit.http.QueryName -import ktorfit.Test interface QueryTestApi { @GET("people/{id}/") diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt index f07147314..b0cbef91f 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi.kt @@ -2,9 +2,12 @@ package de.jensklingenberg.ktorfit.demo import com.example.model.Post import de.jensklingenberg.ktorfit.Call -import de.jensklingenberg.ktorfit.http.* -import io.ktor.client.request.forms.* -import io.reactivex.rxjava3.core.Observable +import de.jensklingenberg.ktorfit.http.Body +import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Headers +import de.jensklingenberg.ktorfit.http.POST +import de.jensklingenberg.ktorfit.http.Path +import io.ktor.client.request.forms.MultiPartFormDataContent import kotlinx.coroutines.flow.Flow interface TestApi { @@ -34,8 +37,4 @@ interface TestApi { suspend fun uppi( @Body map: MultiPartFormDataContent ) - - @Headers(value = ["Accept: application/json"]) - @GET("posts") - fun getObserPosts(): Observable> } diff --git a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt index 8f47e9a09..54091ce50 100644 --- a/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt +++ b/sandbox/src/jvmMain/kotlin/de/jensklingenberg/ktorfit/demo/TestApi2.kt @@ -1,4 +1,4 @@ -package ktorfit +package de.jensklingenberg.ktorfit.demo import com.example.api.StarWarsApi import com.example.model.People From eba6a4a38ce5cc889dc73e07c9d93c97bb7892f1 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 22:54:00 +0200 Subject: [PATCH 30/59] Reformat --- .../jensklingenberg/ktorfit/KtorfitLogger.kt | 5 +++- .../jensklingenberg/ktorfit/KtorfitOptions.kt | 4 ++- .../ktorfit/KtorfitProcessor.kt | 11 ++++---- .../ktorfit/model/FunctionData.kt | 3 +- .../model/annotations/FunctionAnnotation.kt | 8 ++++-- .../AttributeCodeGenerator.kt | 4 ++- .../reqBuilderExtension/BodyCodeGenerator.kt | 10 +++++-- .../CustomRequestBuilderCodeGeneration.kt | 11 ++++---- .../reqBuilderExtension/UrlCodeGeneration.kt | 8 ++++-- .../ktorfit/utils/KSValueParameterExt.kt | 15 ++++++---- .../de/jensklingenberg/ktorfit/utils/Utils.kt | 28 +++++-------------- 11 files changed, 59 insertions(+), 48 deletions(-) diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitLogger.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitLogger.kt index 7c2e8ae0e..9ebaa8446 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitLogger.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitLogger.kt @@ -3,7 +3,10 @@ package de.jensklingenberg.ktorfit import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.symbol.KSNode -class KtorfitLogger(private val kspLogger: KSPLogger, private val loggingType: Int) : KSPLogger by kspLogger { +class KtorfitLogger( + private val kspLogger: KSPLogger, + private val loggingType: Int +) : KSPLogger by kspLogger { override fun error( message: String, symbol: KSNode?, diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt index 6fde82809..3b7ccc224 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt @@ -1,6 +1,8 @@ package de.jensklingenberg.ktorfit -class KtorfitOptions(options: Map) { +class KtorfitOptions( + options: Map +) { /** * 0: Turn off all Ktorfit related error checking * diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitProcessor.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitProcessor.kt index 39723b9bb..d33fd9d0d 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitProcessor.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitProcessor.kt @@ -19,13 +19,14 @@ import de.jensklingenberg.ktorfit.http.PUT import de.jensklingenberg.ktorfit.model.toClassData class KtorfitProcessorProvider : SymbolProcessorProvider { - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return KtorfitProcessor(environment, KtorfitOptions(environment.options)) - } + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = + KtorfitProcessor(environment, KtorfitOptions(environment.options)) } -class KtorfitProcessor(private val env: SymbolProcessorEnvironment, private val ktorfitOptions: KtorfitOptions) : - SymbolProcessor { +class KtorfitProcessor( + private val env: SymbolProcessorEnvironment, + private val ktorfitOptions: KtorfitOptions +) : SymbolProcessor { private var invoked = false companion object { diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt index 575dcc4db..9578f0b25 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt @@ -53,7 +53,8 @@ fun KSFunctionDeclaration.toFunctionData(logger: KSPLogger): FunctionData { val functionName = funcDeclaration.simpleName.asString() val functionParameters = funcDeclaration.parameters.map { it.createParameterData(logger) } - val resolvedReturnType = funcDeclaration.returnType?.resolve() ?: throw IllegalStateException("Return type not found") + val resolvedReturnType = + funcDeclaration.returnType?.resolve() ?: throw IllegalStateException("Return type not found") val returnType = ReturnTypeData( diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/annotations/FunctionAnnotation.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/annotations/FunctionAnnotation.kt index 32e35b7d7..bf5bbe509 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/annotations/FunctionAnnotation.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/annotations/FunctionAnnotation.kt @@ -1,6 +1,8 @@ package de.jensklingenberg.ktorfit.model.annotations -enum class HttpMethod(val keyword: String) { +enum class HttpMethod( + val keyword: String +) { GET("GET"), POST("POST"), PUT("PUT"), @@ -15,7 +17,9 @@ enum class HttpMethod(val keyword: String) { */ open class FunctionAnnotation -class Headers(val value: List) : FunctionAnnotation() +class Headers( + val value: List +) : FunctionAnnotation() class FormUrlEncoded : FunctionAnnotation() diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/AttributeCodeGenerator.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/AttributeCodeGenerator.kt index c019e00e2..8688358ee 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/AttributeCodeGenerator.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/AttributeCodeGenerator.kt @@ -7,7 +7,9 @@ fun getAttributeCode(parameterDataList: List): String = parameterDataList .filter { it.hasAnnotation() } .joinToString("\n") { - val tag = it.findAnnotationOrNull() ?: throw IllegalStateException("Tag annotation not found") + val tag = + it.findAnnotationOrNull() + ?: throw IllegalStateException("Tag annotation not found") if (it.type.parameterType.isMarkedNullable) { "${it.name}?.let{ attributes.put(io.ktor.util.AttributeKey(\"${tag.value}\"), it) }" } else { diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/BodyCodeGenerator.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/BodyCodeGenerator.kt index 8893a1e85..1679caed0 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/BodyCodeGenerator.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/BodyCodeGenerator.kt @@ -3,6 +3,10 @@ package de.jensklingenberg.ktorfit.reqBuilderExtension import de.jensklingenberg.ktorfit.model.ParameterData import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation.Body -fun getBodyDataText(params: List): String { - return params.firstOrNull { it.hasAnnotation() }?.name?.let { "setBody($it)" }.orEmpty() -} +fun getBodyDataText(params: List): String = + params + .firstOrNull { + it.hasAnnotation() + }?.name + ?.let { "setBody($it)" } + .orEmpty() diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/CustomRequestBuilderCodeGeneration.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/CustomRequestBuilderCodeGeneration.kt index e78634679..cac2d3534 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/CustomRequestBuilderCodeGeneration.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/CustomRequestBuilderCodeGeneration.kt @@ -3,8 +3,9 @@ package de.jensklingenberg.ktorfit.reqBuilderExtension import de.jensklingenberg.ktorfit.model.ParameterData import de.jensklingenberg.ktorfit.model.annotations.ParameterAnnotation -fun getCustomRequestBuilderText(parameterDataList: List): String { - return parameterDataList.find { it.hasAnnotation() }?.let { - it.name + "(this)" - }.orEmpty() -} +fun getCustomRequestBuilderText(parameterDataList: List): String = + parameterDataList + .find { it.hasAnnotation() } + ?.let { + it.name + "(this)" + }.orEmpty() diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/UrlCodeGeneration.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/UrlCodeGeneration.kt index 424283e5e..e154730af 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/UrlCodeGeneration.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/reqBuilderExtension/UrlCodeGeneration.kt @@ -13,9 +13,11 @@ fun getUrlCode( ): String { var urlPath = methodAnnotation.path.ifEmpty { - params.firstOrNull { it.hasAnnotation() }?.let { - "\${${it.name}}" - }.orEmpty() + params + .firstOrNull { it.hasAnnotation() } + ?.let { + "\${${it.name}}" + }.orEmpty() } val baseUrl = diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/KSValueParameterExt.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/KSValueParameterExt.kt index 9d713c7ce..b34d62c49 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/KSValueParameterExt.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/KSValueParameterExt.kt @@ -128,11 +128,16 @@ fun KSValueParameter.getRequestTypeAnnotation(): RequestType? { val filteredAnnotations = this.annotations.filter { it.shortName.getShortName() == requestTypeClazz.simpleName && - it.annotationType.resolve().declaration.qualifiedName?.asString() == requestTypeClazz.qualifiedName + it.annotationType + .resolve() + .declaration.qualifiedName + ?.asString() == requestTypeClazz.qualifiedName } - return filteredAnnotations.mapNotNull { - it.arguments.map { arg -> - RequestType((arg.value as KSType)) + return filteredAnnotations + .mapNotNull { + it.arguments + .map { arg -> + RequestType((arg.value as KSType)) + }.firstOrNull() }.firstOrNull() - }.firstOrNull() } diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/Utils.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/Utils.kt index aae786868..2d1ae72ee 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/Utils.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/utils/Utils.kt @@ -10,28 +10,18 @@ fun KSType?.resolveTypeName(): String { return this.toString().removePrefix("[typealias ").removeSuffix("]") } -inline fun FunctionData.findAnnotationOrNull(): T? { - return this.annotations.firstOrNull { it is T } as? T -} +inline fun FunctionData.findAnnotationOrNull(): T? = this.annotations.firstOrNull { it is T } as? T -fun String.prefixIfNotEmpty(s: String): String { - return (s + this).takeIf { this.isNotEmpty() } ?: this -} +fun String.prefixIfNotEmpty(s: String): String = (s + this).takeIf { this.isNotEmpty() } ?: this -fun String.postfixIfNotEmpty(s: String): String { - return (this + s).takeIf { this.isNotEmpty() } ?: this -} +fun String.postfixIfNotEmpty(s: String): String = (this + s).takeIf { this.isNotEmpty() } ?: this fun String.surroundIfNotEmpty( prefix: String = "", postFix: String = "", -): String { - return this.prefixIfNotEmpty(prefix).postfixIfNotEmpty(postFix) -} +): String = this.prefixIfNotEmpty(prefix).postfixIfNotEmpty(postFix) -fun String.removeWhiteSpaces(): String { - return this.replace("\\s".toRegex(), "") -} +fun String.removeWhiteSpaces(): String = this.replace("\\s".toRegex(), "") fun FileSpec.Builder.addImports(imports: List): FileSpec.Builder { imports.forEach { @@ -47,10 +37,6 @@ fun FileSpec.Builder.addImports(imports: List): FileSpec.Builder { return this } -inline fun List<*>.anyInstance(): Boolean { - return this.filterIsInstance().isNotEmpty() -} +inline fun List<*>.anyInstance(): Boolean = this.filterIsInstance().isNotEmpty() -fun KSName?.safeString(): String { - return this?.asString() ?: "" -} +fun KSName?.safeString(): String = this?.asString() ?: "" From e888e5830f9b0c59585dc1478cfb0c9521bd358e Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Mon, 26 Aug 2024 23:14:15 +0200 Subject: [PATCH 31/59] Add proguard documentation #382 (#650) --- docs/android/proguard.md | 5 +++++ docs/index.md | 9 +-------- mkdocs.yml | 2 ++ 3 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 docs/android/proguard.md diff --git a/docs/android/proguard.md b/docs/android/proguard.md new file mode 100644 index 000000000..d4b0760f2 --- /dev/null +++ b/docs/android/proguard.md @@ -0,0 +1,5 @@ +proguard-rules.pro +``` +-keep class de.jensklingenberg.ktorfit.** { *; } +-keepclassmembers class de.jensklingenberg.ktorfit.** { *; } +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 552cd3193..c15ad6b7f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,15 +17,8 @@ inspired by [Retrofit](https://square.github.io/retrofit/) | Ktorfit-version | Kotlin | KSP | Ktor | |-------------------|:-------------:|:-----------------------------:|:----------:| -| **_2.0.1_** | **>=2.0.0** | **>=1.0.24** | **2.3.12** | +| **_2.0.1_** | **>=2.0.0** | **>=1.0.24 min** | **2.3.12** | | **_2.0.0_** | **2.0.0** | **1.0.21 (min) 1.0.24 (max)** | **2.3.11** | -| **_2.0.0-rc01_** | **2.0.0-RC3** | **1.0.20** | **2.3.11** | -| **_2.0.0-beta1_** | **2.0.0-RC1** | **1.0.20** | **2.3.10** | -| **_1.14.0_** | **2.0.0-RC1** | **1.0.20** | **2.3.10** | -| **_1.13.0_** | **1.9.23** | **1.0.20** | **2.3.10** | -| **_1.12.0_** | **1.9.22** | **1.0.16** | **2.3.6** | - - # Installation diff --git a/mkdocs.yml b/mkdocs.yml index e41b29cf2..1556ddc74 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -64,6 +64,8 @@ nav: - 'Example1': converters/example1.md - 'Migration': converters/migration.md - 'Configuration': configuration.md + - 'Android': + - 'proguard': android/proguard.md - 'Fundamentals' : - 'Scope' : fundamentals/scope.md - 'Architecture': architecture.md From b5f6ad7b8b9b322d504f5ab518b8b090c3241e57 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 19:04:31 +0200 Subject: [PATCH 32/59] Reformat --- build.gradle.kts | 2 -- ktorfit-annotations/src/androidMain/AndroidManifest.xml | 2 +- .../kotlin/de/jensklingenberg/ktorfit/http/DELETE.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/Field.kt | 5 ++++- .../kotlin/de/jensklingenberg/ktorfit/http/FieldMap.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/GET.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/HEAD.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/HTTP.kt | 6 +++++- .../kotlin/de/jensklingenberg/ktorfit/http/Header.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/Headers.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/OPTIONS.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/PATCH.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/POST.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/PUT.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/Part.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/PartMap.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/Path.kt | 5 ++++- .../kotlin/de/jensklingenberg/ktorfit/http/Query.kt | 5 ++++- .../kotlin/de/jensklingenberg/ktorfit/http/QueryMap.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/QueryName.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/RequestType.kt | 4 +++- .../kotlin/de/jensklingenberg/ktorfit/http/Tag.kt | 4 +++- 22 files changed, 66 insertions(+), 23 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3611b0d0f..0a02c14b0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,6 @@ plugins { id("org.jlleitschuh.gradle.ktlint") version "12.1.1" apply false } - - buildscript { repositories { mavenLocal() diff --git a/ktorfit-annotations/src/androidMain/AndroidManifest.xml b/ktorfit-annotations/src/androidMain/AndroidManifest.xml index 568741e54..1d26c87a1 100644 --- a/ktorfit-annotations/src/androidMain/AndroidManifest.xml +++ b/ktorfit-annotations/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/DELETE.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/DELETE.kt index d634eb093..6373fdfe4 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/DELETE.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/DELETE.kt @@ -10,4 +10,6 @@ package de.jensklingenberg.ktorfit.http * */ @Target(AnnotationTarget.FUNCTION) -annotation class DELETE(val value: String = "") +annotation class DELETE( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Field.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Field.kt index f2a842951..f4f33dbe5 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Field.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Field.kt @@ -8,4 +8,7 @@ package de.jensklingenberg.ktorfit.http * @see FieldMap */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Field(val value: String = "KTORFIT_DEFAULT_VALUE", val encoded: Boolean = false) +annotation class Field( + val value: String = "KTORFIT_DEFAULT_VALUE", + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/FieldMap.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/FieldMap.kt index 32c8d11d9..94e0b42e0 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/FieldMap.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/FieldMap.kt @@ -5,4 +5,6 @@ package de.jensklingenberg.ktorfit.http * @param encoded true means that this value is already URL encoded and will not be encoded again */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class FieldMap(val encoded: Boolean = false) +annotation class FieldMap( + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/GET.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/GET.kt index f036448fd..42bd9f0ac 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/GET.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/GET.kt @@ -8,4 +8,6 @@ package de.jensklingenberg.ktorfit.http * @param value relative url path, if empty, you need to have a parameter with [Url] * */ @Target(AnnotationTarget.FUNCTION) -annotation class GET(val value: String = "") +annotation class GET( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HEAD.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HEAD.kt index 25ea0854b..05d6a8def 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HEAD.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HEAD.kt @@ -4,4 +4,6 @@ package de.jensklingenberg.ktorfit.http * @param value relative url path, if empty, you need to have a parameter with [Url] * */ @Target(AnnotationTarget.FUNCTION) -annotation class HEAD(val value: String = "") +annotation class HEAD( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HTTP.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HTTP.kt index 3fefa9925..8961267cf 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HTTP.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/HTTP.kt @@ -10,4 +10,8 @@ package de.jensklingenberg.ktorfit.http * @param hasBody * */ @Target(AnnotationTarget.FUNCTION) -annotation class HTTP(val method: String, val path: String = "", val hasBody: Boolean = false) +annotation class HTTP( + val method: String, + val path: String = "", + val hasBody: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Header.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Header.kt index 9cdc57f2c..96a8f8f25 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Header.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Header.kt @@ -14,4 +14,6 @@ package de.jensklingenberg.ktorfit.http * @see HeaderMap */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Header(val value: String) +annotation class Header( + val value: String +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Headers.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Headers.kt index f5ca90ca5..27f3350a9 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Headers.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Headers.kt @@ -10,4 +10,6 @@ package de.jensklingenberg.ktorfit.http * ``` */ @Target(AnnotationTarget.FUNCTION) -annotation class Headers(vararg val value: String) +annotation class Headers( + vararg val value: String +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/OPTIONS.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/OPTIONS.kt index 2cc263152..9ea2d7c35 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/OPTIONS.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/OPTIONS.kt @@ -5,4 +5,6 @@ package de.jensklingenberg.ktorfit.http * @param value relative url path, if empty, you need to have a parameter with [Url] * */ @Target(AnnotationTarget.FUNCTION) -annotation class OPTIONS(val value: String = "") +annotation class OPTIONS( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PATCH.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PATCH.kt index a4dc9b318..01cbbb38d 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PATCH.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PATCH.kt @@ -9,4 +9,6 @@ package de.jensklingenberg.ktorfit.http * */ @Target(AnnotationTarget.FUNCTION) -annotation class PATCH(val value: String = "") +annotation class PATCH( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/POST.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/POST.kt index e7e25e4fd..ab19ffc55 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/POST.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/POST.kt @@ -9,4 +9,6 @@ package de.jensklingenberg.ktorfit.http * */ @Target(AnnotationTarget.FUNCTION) -annotation class POST(val value: String = "") +annotation class POST( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PUT.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PUT.kt index 4bc76c228..226dd60a4 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PUT.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PUT.kt @@ -9,4 +9,6 @@ package de.jensklingenberg.ktorfit.http * */ @Target(AnnotationTarget.FUNCTION) -annotation class PUT(val value: String = "") +annotation class PUT( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Part.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Part.kt index 4a3f84269..db6886c9f 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Part.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Part.kt @@ -11,4 +11,6 @@ package de.jensklingenberg.ktorfit.http * Part parameters type may not be nullable. */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Part(val value: String = "") +annotation class Part( + val value: String = "" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PartMap.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PartMap.kt index 8ce38bbef..94e2c15d5 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PartMap.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/PartMap.kt @@ -4,4 +4,6 @@ package de.jensklingenberg.ktorfit.http * If the type is List the value will be used directly with its content type. */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class PartMap(val encoding: String = "binary") +annotation class PartMap( + val encoding: String = "binary" +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Path.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Path.kt index c95d06925..88c8938a8 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Path.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Path.kt @@ -17,4 +17,7 @@ package de.jensklingenberg.ktorfit.http */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Path(val value: String = "KTORFIT_DEFAULT_VALUE", val encoded: Boolean = false) +annotation class Path( + val value: String = "KTORFIT_DEFAULT_VALUE", + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Query.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Query.kt index e7476250c..e0ca1b2e1 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Query.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Query.kt @@ -21,4 +21,7 @@ package de.jensklingenberg.ktorfit.http * @param encoded true means that this value is already URL encoded and will not be encoded again */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Query(val value: String = "KTORFIT_DEFAULT_VALUE", val encoded: Boolean = false) +annotation class Query( + val value: String = "KTORFIT_DEFAULT_VALUE", + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryMap.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryMap.kt index 6e9aba91a..c89694be0 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryMap.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryMap.kt @@ -8,4 +8,6 @@ package de.jensklingenberg.ktorfit.http */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class QueryMap(val encoded: Boolean = false) +annotation class QueryMap( + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryName.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryName.kt index 83c64004d..fec887302 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryName.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/QueryName.kt @@ -5,4 +5,6 @@ package de.jensklingenberg.ktorfit.http * @param encoded true means that this value is already URL encoded and will not be encoded again */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class QueryName(val encoded: Boolean = false) +annotation class QueryName( + val encoded: Boolean = false +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/RequestType.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/RequestType.kt index 8511437f2..a9c3c39c6 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/RequestType.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/RequestType.kt @@ -3,4 +3,6 @@ package de.jensklingenberg.ktorfit.http import kotlin.reflect.KClass @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class RequestType(val requestType: KClass<*>) +annotation class RequestType( + val requestType: KClass<*> +) diff --git a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Tag.kt b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Tag.kt index 4c053591b..ac4dc64b2 100644 --- a/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Tag.kt +++ b/ktorfit-annotations/src/commonMain/kotlin/de/jensklingenberg/ktorfit/http/Tag.kt @@ -14,4 +14,6 @@ package de.jensklingenberg.ktorfit.http * */ @Target(AnnotationTarget.VALUE_PARAMETER) -annotation class Tag(val value: String = "KTORFIT_DEFAULT_VALUE") +annotation class Tag( + val value: String = "KTORFIT_DEFAULT_VALUE" +) From 9f29a55a30f7c685d82acfae00abfeff893f7adf Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 20:15:21 +0200 Subject: [PATCH 33/59] Allow Body with Http Delete #647 (#651) --- docs/CHANGELOG.md | 3 +++ gradle/libs.versions.toml | 2 +- .../ktorfit/model/FunctionData.kt | 7 ----- .../ktorfit/model/KtorfitError.kt | 1 - .../ktorfit/BodyAnnotationsTest.kt | 26 ------------------- 5 files changed, 4 insertions(+), 35 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8e0dae059..1be46d798 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,6 +7,9 @@ and this project orients towards [Semantic Versioning](http://semver.org/spec/v2 Note: This project needs KSP to work and every new Ktorfit with an update of the KSP version is technically a breaking change. But there is no intent to bump the Ktorfit major version for every KSP update. +# [2.x]() +- Allow Body with Http Delete #647 + # [2.0.1]() 2.0.1 - 2024-08-08 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3f4442148..35a8790ff 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ ktorfitFlowConverter = "2.0.1" ktorfitResponseConverter = "2.0.1" ktorfitGradle = "2.0.1" -ktorfitGradlePlugin = "2.0.0" +ktorfitGradlePlugin = "2.0.1" ktorVersion = "2.3.12" mockk = "1.13.12" mockito-kotlin = "4.1.0" diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt index 9578f0b25..b1d5b54eb 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/FunctionData.kt @@ -2,7 +2,6 @@ package de.jensklingenberg.ktorfit.model import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.symbol.KSFunctionDeclaration -import de.jensklingenberg.ktorfit.model.annotations.CustomHttp import de.jensklingenberg.ktorfit.model.annotations.FunctionAnnotation import de.jensklingenberg.ktorfit.model.annotations.HttpMethod import de.jensklingenberg.ktorfit.model.annotations.HttpMethodAnnotation @@ -153,12 +152,6 @@ fun KSFunctionDeclaration.toFunctionData(logger: KSPLogger): FunctionData { when (firstHttpMethodAnnotation.httpMethod) { HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH -> {} else -> { - if (firstHttpMethodAnnotation is CustomHttp && firstHttpMethodAnnotation.hasBody) { - // Do nothing - } else if (functionParameters.any { it.hasAnnotation() }) { - logger.error(KtorfitError.NON_BODY_HTTP_METHOD_CANNOT_CONTAIN_BODY, funcDeclaration) - } - if (functionAnnotationList.anyInstance()) { logger.error( KtorfitError.MULTIPART_CAN_ONLY_BE_SPECIFIED_ON_HTTPMETHODS, diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/KtorfitError.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/KtorfitError.kt index 74f0b7de4..85511f1e7 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/KtorfitError.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/model/KtorfitError.kt @@ -25,7 +25,6 @@ internal class KtorfitError { const val PATH_PARAMETER_TYPE_MAY_NOT_BE_NULLABLE = "Path parameter type may not be nullable" const val API_DECLARATIONS_MUST_BE_INTERFACES = "API declarations must be interfaces." const val PATH_CAN_ONLY_BE_USED_WITH_RELATIVE_URL_ON = "@Path can only be used with relative url on " - const val NON_BODY_HTTP_METHOD_CANNOT_CONTAIN_BODY = "Non-body HTTP method cannot contain @Body" const val BODY_PARAMETERS_CANNOT_BE_USED_WITH_FORM_OR_MULTI_PART_ENCODING = "@Body parameters cannot be used with form or multi-part encoding" const val FOR_STREAMING_THE_RETURN_TYPE_MUST_BE_HTTP_STATEMENT = diff --git a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/BodyAnnotationsTest.kt b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/BodyAnnotationsTest.kt index 1893f8742..01eb6392e 100644 --- a/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/BodyAnnotationsTest.kt +++ b/ktorfit-ksp/src/test/kotlin/de/jensklingenberg/ktorfit/BodyAnnotationsTest.kt @@ -11,32 +11,6 @@ import org.junit.Test import java.io.File class BodyAnnotationsTest { - @Test - fun whenBodyUsedWithNonBodyMethod_ThrowCompilationError() { - val source = - SourceFile.kotlin( - "Source.kt", - """ - package com.example.api -import de.jensklingenberg.ktorfit.http.GET -import de.jensklingenberg.ktorfit.http.Body - -interface TestService { - - @GET("user") - suspend fun test(@Body id: String): String? - -} - """, - ) - - val compilation = getCompilation(listOf(source)) - - val result = compilation.compile() - assertEquals(KotlinCompilation.ExitCode.COMPILATION_ERROR, result.exitCode) - assertTrue(result.messages.contains(KtorfitError.NON_BODY_HTTP_METHOD_CANNOT_CONTAIN_BODY)) - } - @Test fun whenBodyUsedWithFormUrlEncoded_ThrowCompilationError() { val source = From 52d4176b979fddaa0bbd74a1eeced741a1edbee6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:18:34 +0200 Subject: [PATCH 34/59] fix(deps): update dependency com.android.tools.build:gradle to v8.5.2 (#582) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- example/MultiplatformExample/build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/MultiplatformExample/build.gradle.kts b/example/MultiplatformExample/build.gradle.kts index 46058a423..b570c7e20 100644 --- a/example/MultiplatformExample/build.gradle.kts +++ b/example/MultiplatformExample/build.gradle.kts @@ -10,7 +10,7 @@ buildscript { } dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") - classpath("com.android.tools.build:gradle:7.3.1") + classpath("com.android.tools.build:gradle:8.5.2") classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.0") } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35a8790ff..8c0e494e4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ gradleMavenPublishPlugin = "0.28.0" vannikMavenPublish = "0.28.0" [libraries] -android-build-gradle = "com.android.tools.build:gradle:8.2.2" +android-build-gradle = "com.android.tools.build:gradle:8.5.2" auto-service-ksp = { module = "dev.zacsweers.autoservice:auto-service-ksp", version.ref = "autoServiceKsp" } autoService = { module = "com.google.auto.service:auto-service", version.ref = "autoService" } gradle-maven-publish-plugin = { module = "com.vanniktech:gradle-maven-publish-plugin", version.ref = "gradleMavenPublishPlugin" } From bc1ad39e6add6a0ab7f3bb57c4752eb779028dff Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 21:01:50 +0200 Subject: [PATCH 35/59] Move null check to DefaultSuspendResponseConverterFactory (#652) --- ...t => ConverterDefaultResponseConverter.kt} | 5 +-- .../DefaultSuspendResponseConverterFactory.kt | 14 ++++++++ .../internal/KtorfitConverterHelper.kt | 7 +--- .../de/jensklingenberg/ktorfit/KtorfitTest.kt | 32 ++++++++++++------- ....kt => BuilderDefaultResponseConverter.kt} | 2 +- 5 files changed, 39 insertions(+), 21 deletions(-) rename ktorfit-converters/call/src/jvmTest/kotlin/{ConverterTest.kt => ConverterDefaultResponseConverter.kt} (96%) rename ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/{BuilderTest.kt => BuilderDefaultResponseConverter.kt} (98%) diff --git a/ktorfit-converters/call/src/jvmTest/kotlin/ConverterTest.kt b/ktorfit-converters/call/src/jvmTest/kotlin/ConverterDefaultResponseConverter.kt similarity index 96% rename from ktorfit-converters/call/src/jvmTest/kotlin/ConverterTest.kt rename to ktorfit-converters/call/src/jvmTest/kotlin/ConverterDefaultResponseConverter.kt index dfc3df12a..6d71b277e 100644 --- a/ktorfit-converters/call/src/jvmTest/kotlin/ConverterTest.kt +++ b/ktorfit-converters/call/src/jvmTest/kotlin/ConverterDefaultResponseConverter.kt @@ -19,7 +19,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull -class ConverterTest { +class ConverterDefaultResponseConverter { @Test fun whenCallConverterIsUsedThenRespondSuccessful() = runBlocking { @@ -39,7 +39,8 @@ class ConverterTest { val responseFunc = suspend { client.request("http://example.org/") } val converter = CallConverterFactory() val ktor = - Ktorfit.Builder() + Ktorfit + .Builder() .baseUrl("http://example.org/") .httpClient(client) .build() diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt index eaadf65f5..a6652c58d 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DefaultSuspendResponseConverterFactory.kt @@ -30,8 +30,22 @@ internal class DefaultSuspendResponseConverterFactory : Converter.Factory { } } + class DefaultResponseConverter : Converter.ResponseConverter { + override fun convert(getResponse: suspend () -> HttpResponse): Any? = null + } + override fun suspendResponseConverter( typeData: TypeData, ktorfit: Ktorfit, ): Converter.SuspendResponseConverter = DefaultSuspendResponseConverter(typeData) + + override fun responseConverter( + typeData: TypeData, + ktorfit: Ktorfit, + ): Converter.ResponseConverter? = + if (typeData.isNullable) { + DefaultResponseConverter() + } else { + null + } } diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt index faa9960fb..b42ae9f7c 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt @@ -41,12 +41,7 @@ public class KtorfitConverterHelper( } as ReturnType? } - val typeIsNullable = returnTypeData.typeInfo.kotlinType?.isMarkedNullable ?: false - return if (typeIsNullable) { - null - } else { - throw IllegalStateException("Add a ResponseConverter for " + returnTypeData.typeInfo + " or make function suspend") - } + throw IllegalStateException("Add a ResponseConverter for " + returnTypeData.typeInfo + " or make function suspend") } /** diff --git a/ktorfit-lib-core/src/commonTest/kotlin/de/jensklingenberg/ktorfit/KtorfitTest.kt b/ktorfit-lib-core/src/commonTest/kotlin/de/jensklingenberg/ktorfit/KtorfitTest.kt index eacda5384..3830dee6e 100644 --- a/ktorfit-lib-core/src/commonTest/kotlin/de/jensklingenberg/ktorfit/KtorfitTest.kt +++ b/ktorfit-lib-core/src/commonTest/kotlin/de/jensklingenberg/ktorfit/KtorfitTest.kt @@ -7,9 +7,7 @@ import de.jensklingenberg.ktorfit.converter.builtin.DefaultSuspendResponseConver import io.ktor.client.request.HttpRequestData import io.ktor.client.statement.HttpResponse import io.ktor.util.reflect.typeInfo -import kotlin.test.Ignore import kotlin.test.Test -import kotlin.test.assertEquals import kotlin.test.assertTrue class KtorfitTest { @@ -22,7 +20,8 @@ class KtorfitTest { } val ktorfit = - Ktorfit.Builder() + Ktorfit + .Builder() .httpClient(engine) .baseUrl("http://test.de/") .converterFactories(TestConverterFactory()) @@ -36,11 +35,18 @@ class KtorfitTest { assertTrue(nextConverter is TestConverterFactory.SuspendConverter) } - @Ignore() // "Will be activated when old converters are removed" @Test fun whenNoSuspendResponseConverterForStringAdded_FindDefaultConverter() { + val engine = + object : TestEngine() { + override fun getRequestData(data: HttpRequestData) { + } + } + val ktorfit = - Ktorfit.Builder() + Ktorfit + .Builder() + .httpClient(engine) .baseUrl("http://test.de/") .build() @@ -61,7 +67,8 @@ class KtorfitTest { } val ktorfit = - Ktorfit.Builder() + Ktorfit + .Builder() .httpClient(engine) .baseUrl("http://test.de/") .converterFactories(TestConverterFactory()) @@ -81,19 +88,22 @@ class KtorfitTest { } val ktorfit = - Ktorfit.Builder() + Ktorfit + .Builder() .httpClient(engine) .baseUrl("http://test.de/") .build() val nextConverter = ktorfit.nextResponseConverter(null, TypeData("kotlin.String", emptyList(), isNullable = true, typeInfo = typeInfo())) - assertEquals(null, nextConverter) + assertTrue(nextConverter is DefaultSuspendResponseConverterFactory.DefaultResponseConverter) } } private class TestConverterFactory : Converter.Factory { - class SuspendConverter(val typeData: TypeData) : Converter.SuspendResponseConverter { + class SuspendConverter( + val typeData: TypeData + ) : Converter.SuspendResponseConverter { override suspend fun convert(result: KtorfitResult): Any { when (result) { is KtorfitResult.Success -> { @@ -107,9 +117,7 @@ private class TestConverterFactory : Converter.Factory { } class ResponseConverter : Converter.ResponseConverter { - override fun convert(getKtorfitResponse: suspend () -> HttpResponse): Any { - return "" - } + override fun convert(getKtorfitResponse: suspend () -> HttpResponse): Any = "" } override fun suspendResponseConverter( diff --git a/ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderTest.kt b/ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderDefaultResponseConverter.kt similarity index 98% rename from ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderTest.kt rename to ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderDefaultResponseConverter.kt index 694d1466c..f8e7cb3b5 100644 --- a/ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderTest.kt +++ b/ktorfit-lib-core/src/jvmTest/kotlin/de/jensklingenberg/ktorfit/BuilderDefaultResponseConverter.kt @@ -14,7 +14,7 @@ interface BuilderTestApi { suspend fun checkIfBaseUrlIsSetWhenUrlCheckIsDisabled(): String } -class BuilderTest { +class BuilderDefaultResponseConverter { @Test fun whenBaseUrlNotEndingWithSlashThrowError() { try { From eed70e63ffaaef0c3e22a148a3c0bb2d53216ccb Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 21:03:30 +0200 Subject: [PATCH 36/59] Update CHANGELOG.md --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1be46d798..16a90da05 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,7 +7,7 @@ and this project orients towards [Semantic Versioning](http://semver.org/spec/v2 Note: This project needs KSP to work and every new Ktorfit with an update of the KSP version is technically a breaking change. But there is no intent to bump the Ktorfit major version for every KSP update. -# [2.x]() +# [Unrelased]() - Allow Body with Http Delete #647 # [2.0.1]() From efbec229cc2e41b0fbb4d098f63c7674d834bef7 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 21:12:26 +0200 Subject: [PATCH 37/59] update binaryCompatibilityValidator (#653) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c0e494e4..d1fe9ce66 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] autoService = "1.1.1" autoServiceKsp = "1.10" -binaryCompatibilityValidator = "0.14.0" +binaryCompatibilityValidator = "0.16.3" coroutines = "1.8.1" detekt = "1.23.6" junit = "4.13.2" From c76517af7249ff4c5907633d0772983c66490785 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Wed, 28 Aug 2024 21:24:28 +0200 Subject: [PATCH 38/59] Update to JDK 21 (#654) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/build.yml | 10 ++++---- .github/workflows/publish-converters.yml | 6 ++--- .github/workflows/publish.yml | 30 ++++++++++++------------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9a6ed6913..65c792c1a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,3 @@ ### :thinking: DOD Checklist -- [ ] I did all relevant changes to the documentation and the [changelog](https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md). +- [] I did all relevant changes to the documentation and the [changelog](https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md). diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c54f8b4f..bdbaed416 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,8 +29,8 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: - distribution: zulu - java-version: 17 + distribution: temurin + java-version: 21 - uses: gradle/actions/setup-gradle@v4 - name: API check run: ./gradlew ktLintCheck apiCheck @@ -38,11 +38,11 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: 17 - distribution: 'zulu' + java-version: 21 + distribution: 'temurin' - name: Cache Gradle and wrapper uses: actions/cache@v4 with: diff --git a/.github/workflows/publish-converters.yml b/.github/workflows/publish-converters.yml index f1a049424..db49bd42b 100644 --- a/.github/workflows/publish-converters.yml +++ b/.github/workflows/publish-converters.yml @@ -10,11 +10,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ab5fbc6e..65eb190df 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,11 +10,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v3 @@ -31,11 +31,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v3 @@ -52,11 +52,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v3 @@ -73,11 +73,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v3 @@ -94,11 +94,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install JDK 11 + - name: Install JDK 21 uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: 'temurin' + java-version: 21 - uses: gradle/gradle-build-action@v3 From 3af60dd61b98536f9a9eae8f29c683f89d2b95fd Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Fri, 30 Aug 2024 18:27:23 +0200 Subject: [PATCH 39/59] Fix example project --- example/MultiplatformExample/androidApp/build.gradle.kts | 1 + example/MultiplatformExample/person/build.gradle.kts | 1 + example/MultiplatformExample/shared/build.gradle.kts | 1 + 3 files changed, 3 insertions(+) diff --git a/example/MultiplatformExample/androidApp/build.gradle.kts b/example/MultiplatformExample/androidApp/build.gradle.kts index 3b4129673..c680dd91d 100644 --- a/example/MultiplatformExample/androidApp/build.gradle.kts +++ b/example/MultiplatformExample/androidApp/build.gradle.kts @@ -11,6 +11,7 @@ android { targetSdk = 34 versionCode = 1 versionName = "1.0" + namespace = "com.example.myapplication.android" } buildTypes { getByName("release") { diff --git a/example/MultiplatformExample/person/build.gradle.kts b/example/MultiplatformExample/person/build.gradle.kts index 1a2f794f4..e2321bedd 100644 --- a/example/MultiplatformExample/person/build.gradle.kts +++ b/example/MultiplatformExample/person/build.gradle.kts @@ -49,6 +49,7 @@ android { defaultConfig { minSdk = 21 targetSdk = 34 + namespace = "com.example.person" } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/example/MultiplatformExample/shared/build.gradle.kts b/example/MultiplatformExample/shared/build.gradle.kts index bf1b9e841..3bbca1145 100644 --- a/example/MultiplatformExample/shared/build.gradle.kts +++ b/example/MultiplatformExample/shared/build.gradle.kts @@ -78,6 +78,7 @@ android { defaultConfig { minSdk = 21 targetSdk = 34 + namespace = "com.example.ktorfittest" } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 From 9ee3dac3c36977e094c9f025f699d0df2fa6b054 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Fri, 30 Aug 2024 18:28:16 +0200 Subject: [PATCH 40/59] Fix example project --- example/MultiplatformExample/person/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/MultiplatformExample/person/build.gradle.kts b/example/MultiplatformExample/person/build.gradle.kts index e2321bedd..092634140 100644 --- a/example/MultiplatformExample/person/build.gradle.kts +++ b/example/MultiplatformExample/person/build.gradle.kts @@ -9,7 +9,7 @@ val ktorVersion = "2.3.11" kotlin { jvmToolchain(8) - targetHierarchy.default() + applyDefaultHierarchyTemplate() jvm() androidTarget() From d244ee175a881de96c7fe2d5af49ebb5cec7837f Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sat, 31 Aug 2024 21:26:36 +0200 Subject: [PATCH 41/59] Fix compilation for single target KMP projects #593 (#657) --- docs/CHANGELOG.md | 4 +- .../AndroidOnlyExample/app/build.gradle.kts | 8 +- example/AndroidOnlyExample/build.gradle | 2 +- example/MultiplatformExample/build.gradle.kts | 2 +- .../MultiplatformExample/iosApp/Podfile.lock | 2 +- .../ktorfittest/{People.kt => Person.kt} | 1 - .../shared/shared.podspec | 6 +- .../kotlin/com/example/ktorfittest/Test.kt | 11 +++ .../com/example/ktorfittest/Greeting.kt | 41 ++++----- .../com/example/ktorfittest/StarWarsApi.kt | 25 ++++-- .../src/jvmMain/kotlin/JvmExampleClass.kt | 28 +++---- .../ktorfit/gradle/KtorfitGradlePlugin.kt | 83 +++++++++---------- .../jensklingenberg/ktorfit/KtorfitOptions.kt | 5 ++ .../ktorfit/generator/ClassGenerator.kt | 18 ++-- 14 files changed, 135 insertions(+), 101 deletions(-) rename example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/{People.kt => Person.kt} (99%) create mode 100644 example/MultiplatformExample/shared/src/androidMain/kotlin/com/example/ktorfittest/Test.kt diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 16a90da05..121be7638 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,8 +7,10 @@ and this project orients towards [Semantic Versioning](http://semver.org/spec/v2 Note: This project needs KSP to work and every new Ktorfit with an update of the KSP version is technically a breaking change. But there is no intent to bump the Ktorfit major version for every KSP update. -# [Unrelased]() +# [Unreleased]() - Allow Body with Http Delete #647 +- Task with path 'kspCommonMainKotlinMetadata' not found in project #593 + # [2.0.1]() diff --git a/example/AndroidOnlyExample/app/build.gradle.kts b/example/AndroidOnlyExample/app/build.gradle.kts index e4861a2c8..e10259e31 100644 --- a/example/AndroidOnlyExample/app/build.gradle.kts +++ b/example/AndroidOnlyExample/app/build.gradle.kts @@ -1,10 +1,10 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") - id("com.google.devtools.ksp") version "2.0.0-1.0.22" - id("org.jetbrains.kotlin.plugin.serialization") version "2.0.0" - id("de.jensklingenberg.ktorfit") version "2.0.0" - id("org.jetbrains.kotlin.plugin.compose") version "2.0.0" + id("com.google.devtools.ksp") version "2.0.20-1.0.24" + id("org.jetbrains.kotlin.plugin.serialization") version "2.0.10" + id("de.jensklingenberg.ktorfit") version "2.0.1" + id("org.jetbrains.kotlin.plugin.compose") version "2.0.10" } ktorfit{ diff --git a/example/AndroidOnlyExample/build.gradle b/example/AndroidOnlyExample/build.gradle index 697c0ee8d..ed6e58b01 100644 --- a/example/AndroidOnlyExample/build.gradle +++ b/example/AndroidOnlyExample/build.gradle @@ -2,5 +2,5 @@ plugins { id 'com.android.application' version '8.4.1' apply false id 'com.android.library' version '8.4.1' apply false - id 'org.jetbrains.kotlin.android' version '2.0.0' apply false + id 'org.jetbrains.kotlin.android' version '2.0.20' apply false } \ No newline at end of file diff --git a/example/MultiplatformExample/build.gradle.kts b/example/MultiplatformExample/build.gradle.kts index b570c7e20..8da991790 100644 --- a/example/MultiplatformExample/build.gradle.kts +++ b/example/MultiplatformExample/build.gradle.kts @@ -11,7 +11,7 @@ buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") classpath("com.android.tools.build:gradle:8.5.2") - classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.0") + classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.20") } } diff --git a/example/MultiplatformExample/iosApp/Podfile.lock b/example/MultiplatformExample/iosApp/Podfile.lock index 11ec62e2d..919dca002 100644 --- a/example/MultiplatformExample/iosApp/Podfile.lock +++ b/example/MultiplatformExample/iosApp/Podfile.lock @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../shared" SPEC CHECKSUMS: - shared: 2d3b24a8fe27b7d9e65b8d075a9672fbc6a1aa10 + shared: 90ed35de669e9fcb63a61e6b4bb0521eb732cc7a PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756 diff --git a/example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/People.kt b/example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/Person.kt similarity index 99% rename from example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/People.kt rename to example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/Person.kt index ecf1764a2..10993cef6 100644 --- a/example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/People.kt +++ b/example/MultiplatformExample/person/src/commonMain/kotlin/com/example/ktorfittest/Person.kt @@ -16,4 +16,3 @@ data class Person( val name: String? = null, val height: String? = null ) - diff --git a/example/MultiplatformExample/shared/shared.podspec b/example/MultiplatformExample/shared/shared.podspec index c043d7ee5..f7d96aa32 100644 --- a/example/MultiplatformExample/shared/shared.podspec +++ b/example/MultiplatformExample/shared/shared.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |spec| spec.summary = 'Some description for the Shared Module' spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework' spec.libraries = 'c++' - spec.ios.deployment_target = '14.1' + spec.ios.deployment_target = '14.1' if !Dir.exist?('build/cocoapods/framework/shared.framework') || Dir.empty?('build/cocoapods/framework/shared.framework') @@ -22,6 +22,10 @@ Pod::Spec.new do |spec| Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" end + spec.xcconfig = { + 'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO', + } + spec.pod_target_xcconfig = { 'KOTLIN_PROJECT_PATH' => ':shared', 'PRODUCT_MODULE_NAME' => 'shared', diff --git a/example/MultiplatformExample/shared/src/androidMain/kotlin/com/example/ktorfittest/Test.kt b/example/MultiplatformExample/shared/src/androidMain/kotlin/com/example/ktorfittest/Test.kt new file mode 100644 index 000000000..1cb08dc30 --- /dev/null +++ b/example/MultiplatformExample/shared/src/androidMain/kotlin/com/example/ktorfittest/Test.kt @@ -0,0 +1,11 @@ +package com.example.ktorfittest + +import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Path + +interface Test { + @GET("people/{id}") + suspend fun getPeopleById( + @Path("id") id: Int + ): Person +} diff --git a/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/Greeting.kt b/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/Greeting.kt index b255e8c01..646652302 100644 --- a/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/Greeting.kt +++ b/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/Greeting.kt @@ -1,6 +1,5 @@ package com.example.ktorfittest - import de.jensklingenberg.ktorfit.converter.CallConverterFactory import de.jensklingenberg.ktorfit.converter.FlowConverterFactory import de.jensklingenberg.ktorfit.ktorfit @@ -12,30 +11,34 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.serialization.json.Json -val ktorfit = ktorfit { - baseUrl(StarWarsApi.baseUrl) - httpClient(HttpClient { - install(ContentNegotiation) { - json(Json { isLenient = true; ignoreUnknownKeys = true }) - } - }) - converterFactories( - FlowConverterFactory(), - CallConverterFactory() - ) -} - +val ktorfit = + ktorfit { + baseUrl(StarWarsApi.baseUrl) + httpClient( + HttpClient { + install(ContentNegotiation) { + json( + Json { + isLenient = true + ignoreUnknownKeys = true + } + ) + } + } + ) + converterFactories( + FlowConverterFactory(), + CallConverterFactory() + ) + } -val starWarsApi = ktorfit.createStarWarsApi() +val starWarsApi = ktorfit.create() class Greeting { fun greeting(): String { - loadData() return "Hello, ${Platform().platform}! Look in the LogCat" } - - } @OptIn(DelicateCoroutinesApi::class) @@ -44,4 +47,4 @@ fun loadData() { val response = starWarsApi.getPersonByIdResponse(3) println("Ktorfit:" + Platform().platform + ":" + response) } -} \ No newline at end of file +} diff --git a/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/StarWarsApi.kt b/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/StarWarsApi.kt index a65f02ee0..cad2d1ae2 100644 --- a/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/StarWarsApi.kt +++ b/example/MultiplatformExample/shared/src/commonMain/kotlin/com/example/ktorfittest/StarWarsApi.kt @@ -13,18 +13,29 @@ interface StarWarsApi { } @GET("people/{id}/") - suspend fun getPersonByIdResponse(@Path("id") peopleId: Int): Person + suspend fun getPersonByIdResponse( + @Path("id") peopleId: Int + ): Person @GET("people/{id}/") - fun getPeopleByIdFlowResponse(@Path("id") peopleId: Int, @Query("hello") world: String?): Flow + fun getPeopleByIdFlowResponse( + @Path("id") peopleId: Int, + @Query("hello") world: String? + ): Flow @GET("people/{id}/") - fun getPeopleByIdCallResponse(@Path("id") peopleId: Int): Call - + fun getPeopleByIdCallResponse( + @Path("id") peopleId: Int + ): Call @GET("people/{id}/") - fun queryTest(@Path("id") peopleId: Int, @Query("hello") world: String?): Call + fun queryTest( + @Path("id") peopleId: Int, + @Query("hello") world: String? + ): Call @GET("people/{id}/") - suspend fun getPersonResponse(@Path("id") personId: Int): Response -} \ No newline at end of file + suspend fun getPersonResponse( + @Path("id") personId: Int + ): Response +} diff --git a/example/MultiplatformExample/shared/src/jvmMain/kotlin/JvmExampleClass.kt b/example/MultiplatformExample/shared/src/jvmMain/kotlin/JvmExampleClass.kt index d28ccc2fa..e780320fa 100644 --- a/example/MultiplatformExample/shared/src/jvmMain/kotlin/JvmExampleClass.kt +++ b/example/MultiplatformExample/shared/src/jvmMain/kotlin/JvmExampleClass.kt @@ -4,25 +4,23 @@ import de.jensklingenberg.ktorfit.Callback import io.ktor.client.statement.* import kotlinx.coroutines.runBlocking - fun main() { - - starWarsApi.getPeopleByIdCallResponse(3).onExecute(object : Callback { - override fun onError(exception: Throwable) { - exception - } - - override fun onResponse(call: Person, response: HttpResponse) { - println("onResponse" + call) + starWarsApi.getPeopleByIdCallResponse(3).onExecute( + object : Callback { + override fun onError(exception: Throwable) { + } + + override fun onResponse( + call: Person, + response: HttpResponse + ) { + println("onResponse" + call) + } } - - }) + ) runBlocking { val response = starWarsApi.getPersonByIdResponse(3) println(response) - } - - -} \ No newline at end of file +} diff --git a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt index a2390aae4..316cb95e8 100644 --- a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt +++ b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt @@ -2,10 +2,10 @@ package de.jensklingenberg.ktorfit.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.kotlin.dsl.dependencies import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.targets import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask import java.util.Locale.US @@ -42,7 +42,6 @@ class KtorfitGradlePlugin : Plugin { .substringBefore(".jar") checkKSPVersion(kspVersion) - val kspExtension = extensions.findByName("ksp") ?: error("KSP config not found") val argMethod = kspExtension.javaClass.getMethod("arg", String::class.java, String::class.java) @@ -55,8 +54,29 @@ class KtorfitGradlePlugin : Plugin { "Ktorfit_QualifiedTypeName", config.generateQualifiedTypeName.toString(), ) - } + /** + * This is currently a workaround for a bug in KSP that causes the plugin + * to not work with multiplatform projects with only one target. + * https://github.com/google/ksp/issues/1525 + */ + val singleTarget = + project.kotlinExtension.targets + .toList() + .size == 2 + + if (kotlinExtension is KotlinMultiplatformExtension) { + if (singleTarget) { + argMethod.invoke(kspExtension, "Ktorfit_MultiplatformWithSingleTarget", true) + } else { + tasks.withType(KotlinCompilationTask::class.java).configureEach { + if (name != "kspCommonMainKotlinMetadata") { + dependsOn("kspCommonMainKotlinMetadata") + } + } + } + } + } val dependency = "$ktorfitKsp:$KTORFIT_VERSION-$kspVersion$SNAPSHOT" when (val kotlinExtension = kotlinExtension) { @@ -65,52 +85,31 @@ class KtorfitGradlePlugin : Plugin { } is KotlinMultiplatformExtension -> { - dependencies { - add("kspCommonMainMetadata", dependency) - } - kotlinExtension.targets.configureEach { - if (targetName == "metadata") return@configureEach - dependencies.add( - "ksp${ - targetName.replaceFirstChar { - if (it.isLowerCase()) { - it.titlecase( - US, - ) - } else { - it.toString() - } - } - }", - dependency, - ) - - dependencies.add( - "ksp${ - targetName.replaceFirstChar { - if (it.isLowerCase()) { - it.titlecase( - US, - ) - } else { - it.toString() - } + if (platformType.name == "common") { + dependencies.add("kspCommonMainMetadata", dependency) + return@configureEach + } + val capitalizedTargetName = + targetName.replaceFirstChar { + if (it.isLowerCase()) { + it.titlecase( + US, + ) + } else { + it.toString() } - }Test", - dependency, - ) + } + dependencies.add("ksp$capitalizedTargetName", dependency) + + if (this.compilations.any { it.name == "test" }) { + dependencies.add("ksp${capitalizedTargetName}Test", dependency) + } } kotlinExtension.sourceSets.named("commonMain").configure { kotlin.srcDir("${layout.buildDirectory.get()}/generated/ksp/metadata/commonMain/kotlin") } - - tasks.withType(KotlinCompilationTask::class.java).configureEach { - if (name != "kspCommonMainKotlinMetadata") { - dependsOn("kspCommonMainKotlinMetadata") - } - } } else -> Unit diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt index 3b7ccc224..b71652702 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/KtorfitOptions.kt @@ -16,4 +16,9 @@ class KtorfitOptions( * If set to true, the generated code will contain qualified type names */ val setQualifiedType = options["Ktorfit_QualifiedTypeName"]?.toBoolean() ?: false + + /** + * If the compilation is multiplatform and has only one target, this will be true + */ + val multiplatformWithSingleTarget = options["Ktorfit_MultiplatformWithSingleTarget"]?.toBoolean() ?: false } diff --git a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/generator/ClassGenerator.kt b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/generator/ClassGenerator.kt index b0440b95f..413fa2ea3 100644 --- a/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/generator/ClassGenerator.kt +++ b/ktorfit-ksp/src/main/kotlin/de/jensklingenberg/ktorfit/generator/ClassGenerator.kt @@ -17,7 +17,7 @@ fun generateImplClass( classDataList: List, codeGenerator: CodeGenerator, resolver: Resolver, - ktorfitOptions: KtorfitOptions, + ktorfitOptions: KtorfitOptions ) { classDataList.forEach { classData -> with(classData) { @@ -32,13 +32,15 @@ fun generateImplClass( "" } - if (moduleName.contains(commonMainModuleName)) { - if (!ksFile.filePath.contains(commonMainModuleName)) { - return@forEach - } - } else { - if (ksFile.filePath.contains(commonMainModuleName)) { - return@forEach + if (!ktorfitOptions.multiplatformWithSingleTarget) { + if (moduleName.contains(commonMainModuleName)) { + if (!ksFile.filePath.contains(commonMainModuleName)) { + return@forEach + } + } else { + if (ksFile.filePath.contains(commonMainModuleName)) { + return@forEach + } } } From 21187ba8dcd442026799ad867a23f4ae29f79ea4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:45:18 +0200 Subject: [PATCH 42/59] chore(deps): update dependency gradle to v8.10 (#659) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/AndroidOnlyExample/gradlew | 5 ++++- example/AndroidOnlyExample/gradlew.bat | 2 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/MultiplatformExample/gradlew | 5 ++++- example/MultiplatformExample/gradlew.bat | 2 ++ gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 5 ++++- gradlew.bat | 2 ++ 12 files changed, 21 insertions(+), 6 deletions(-) diff --git a/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.jar b/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 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 HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ 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 diff --git a/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.properties b/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.properties index a4413138c..9355b4155 100644 --- a/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.properties +++ b/example/AndroidOnlyExample/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/example/AndroidOnlyExample/gradlew b/example/AndroidOnlyExample/gradlew index b740cf133..f5feea6d6 100755 --- a/example/AndroidOnlyExample/gradlew +++ b/example/AndroidOnlyExample/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/example/AndroidOnlyExample/gradlew.bat b/example/AndroidOnlyExample/gradlew.bat index 7101f8e46..9b42019c7 100644 --- a/example/AndroidOnlyExample/gradlew.bat +++ b/example/AndroidOnlyExample/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.jar b/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 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 HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ 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 diff --git a/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.properties b/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.properties index a4413138c..9355b4155 100644 --- a/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.properties +++ b/example/MultiplatformExample/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/example/MultiplatformExample/gradlew b/example/MultiplatformExample/gradlew index b740cf133..f5feea6d6 100755 --- a/example/MultiplatformExample/gradlew +++ b/example/MultiplatformExample/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/example/MultiplatformExample/gradlew.bat b/example/MultiplatformExample/gradlew.bat index 7101f8e46..9b42019c7 100644 --- a/example/MultiplatformExample/gradlew.bat +++ b/example/MultiplatformExample/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 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 HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138c..9355b4155 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf133..f5feea6d6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 7101f8e46..9b42019c7 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From aed5a23587486ffb581511ed114139ed4718df2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 23:41:00 +0200 Subject: [PATCH 43/59] fix(deps): update dependency androidx.test.ext:junit to v1.2.1 (#660) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- example/AndroidOnlyExample/app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/AndroidOnlyExample/app/build.gradle.kts b/example/AndroidOnlyExample/app/build.gradle.kts index e10259e31..632922cbf 100644 --- a/example/AndroidOnlyExample/app/build.gradle.kts +++ b/example/AndroidOnlyExample/app/build.gradle.kts @@ -73,7 +73,7 @@ dependencies { debugImplementation("androidx.compose.ui:ui-tooling:$compose_ui_version") debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_ui_version") testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.ext:junit:1.2.1") androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_ui_version") } From a1bce2f915a882c5c068a36abbab30e29613af9e Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 09:31:56 +0200 Subject: [PATCH 44/59] Fix argument type --- .../de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt index 316cb95e8..c0ab3f38f 100644 --- a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt +++ b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt @@ -67,7 +67,7 @@ class KtorfitGradlePlugin : Plugin { if (kotlinExtension is KotlinMultiplatformExtension) { if (singleTarget) { - argMethod.invoke(kspExtension, "Ktorfit_MultiplatformWithSingleTarget", true) + argMethod.invoke(kspExtension, "Ktorfit_MultiplatformWithSingleTarget", true.toString()) } else { tasks.withType(KotlinCompilationTask::class.java).configureEach { if (name != "kspCommonMainKotlinMetadata") { From f8a1fd8714971c281379f7133770fb9e0b25a073 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:11:16 +0200 Subject: [PATCH 45/59] Update documentation --- docs/CHANGELOG.md | 26 +++++++++++-------- docs/architecture.md | 16 +++++++----- docs/configuration.md | 9 ++++--- docs/knownissues.md | 17 ++++++++++++ .../MultiplatformExample/settings.gradle.kts | 4 +-- mkdocs.yml | 5 ++-- 6 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 docs/knownissues.md diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 121be7638..f834004d0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -8,38 +8,41 @@ Note: This project needs KSP to work and every new Ktorfit with an update of the But there is no intent to bump the Ktorfit major version for every KSP update. # [Unreleased]() -- Allow Body with Http Delete #647 -- Task with path 'kspCommonMainKotlinMetadata' not found in project #593 +======================================== +## Fixed +- Allow Body with Http Delete [https://github.com/Foso/Ktorfit/issues/647](#647) +- Task with path 'kspCommonMainKotlinMetadata' not found in project [https://github.com/Foso/Ktorfit/issues/593](#593) +- Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [https://github.com/Foso/Ktorfit/issues/638](#638) # [2.0.1]() 2.0.1 - 2024-08-08 ======================================== -### Fixed +## Fixed - Endpoint with types from other module #594 - Ktorfit plugin doesn't include correct generate source if build directory changes #591 - RequestConverter causing compile error #621 - Build with Ktor 2.3.12 -### ktorfit-annotations -- 2.0.1: The annotations are now also avaiable for WasmJs +## ktorfit-annotations +- 2.0.1: The annotations are now also available for WasmJs -### compilerPlugin +## compilerPlugin - Kotlin 2.0.0: 2.0.1-2.0.0 - 2024-08-08 - Kotlin 2.0.10: 2.0.1-2.0.10 - 2024-08-10 - Kotlin 2.0.20-RC: 2.0.1-2.0.20-RC - 2024-08-13 - Kotlin 2.0.20-RC2: 2.0.1-2.0.20-RC2 - 2024-08-13 - Kotlin 2.0.20: 2.0.1-2.0.20 - 2024-08-23 -### ktorfit-ksp +## ktorfit-ksp - KSP 1.0.24: ktorfit-ksp-2.0.1-1.0.24 - 2024-08-08 -### Ktor3 +## Ktor3 The "normal" dependencies will stay on Ktor 2.x till 3.0 is stable. But here are versions that you can use when want to use Ktor3 and WasmJs -| Project | Version | -|-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| Project | Version | +|-----------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | ktorfit-lib-light-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | | ktorfit-lib-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | | ktorfit-converters-flow-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | @@ -62,7 +65,8 @@ ktorfit-ksp-2.0.0-1.0.22 - 2024-06-06 2.0.0 - 2024-05-27 ======================================== -### Changed + +# Changed - Build with KSP 1.0.21, Kotlin 2.0.0, Ktor 2.3.11 - The needed dependencies for Ktorfit KSP processor are now included in the Ktorfit Gradle plugin. You can remove the ksp() block from your build.gradle.kts file. You still need to apply the KSP plugin. diff --git a/docs/architecture.md b/docs/architecture.md index 8f3451147..d412663d9 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -34,7 +34,7 @@ Then it looks at the parent interfaces of that functions and generates, the sour public class _ExampleApiImpl( private val _ktorfit: Ktorfit, ) : ExampleApi { - public val _converter: KtorfitConverterHelper = KtorfitConverterHelper(_ktorfit) + private val _helper: KtorfitConverterHelper = KtorfitConverterHelper(_ktorfit) override suspend fun exampleGet(): People { val _ext: HttpRequestBuilder.() -> Unit = { @@ -43,14 +43,18 @@ public class _ExampleApiImpl( takeFrom(_ktorfit.baseUrl + "/test") } } - val _typeData = TypeData.createTypeData(qualifiedTypename = "com.example.model.People", - typeInfo = typeInfo()) - - return _converter.suspendRequest(_typeData,_ext)!! + val _typeData = TypeData.createTypeData( + typeInfo = typeInfo(), + ) + return _helper.suspendRequest(_typeData,_ext)!! } } -public fun Ktorfit.createExampleApi(): ExampleApi = this.create(_ExampleApiImpl(this)) +public class _ExampleApiProvider : ClassProvider { + override fun create(_ktorfit: Ktorfit): ExampleApi = _ExampleApiImpl(_ktorfit) +} + +public fun Ktorfit.createExampleApi(): ExampleApi = _ExampleApiImpl(this) ``` The next part is the compiler plugin which is added by the gradle plugin. diff --git a/docs/configuration.md b/docs/configuration.md index 19bbc6c4d..2379a9e4b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,4 +1,5 @@ -# Compile errors +# Gradle +## Compile errors By default, Ktorfit will throw compile error when it finds conditions under which it can't ensure that it will work correct. You can set it in the Ktorfit config to change this @@ -16,7 +17,7 @@ You can set it in your build.gradle.kts file, * WARNING: Turn errors into warnings -# QualifiedTypeName +## QualifiedTypeName By default, Ktorfit will keep qualifiedTypename for TypeData in the generated code empty. You can set it in the Ktorfit config to change this: ```kotlin @@ -42,9 +43,9 @@ val _typeData = TypeData.createTypeData( ... ``` +# Ktorfit Builder - -# Add your own Ktor client +## Add your own Ktor client You can set your Ktor client instance to the Ktorfit builder: ```kotlin diff --git a/docs/knownissues.md b/docs/knownissues.md new file mode 100644 index 000000000..d8474b12e --- /dev/null +++ b/docs/knownissues.md @@ -0,0 +1,17 @@ +# Known Issues + +## KMP project with single target + +* Unresolved reference for API class + +When you have a KMP project with a single target, IntelliJ will find the generated "create" extension function (e.g. +**ktorfit.createExampleApi()**) in your common module, but the compilation will fail +because of an "Unresolved reference" error. In that case, you have to use **ktorfit.create<ExampleApi>()** to make it work, even though it's already deprecated. + +Kotlin handles the compilation of a KMP project with a single target differently than with multiple targets. + +See: + +* https://youtrack.jetbrains.com/issue/KT-59129 + +* https://youtrack.jetbrains.com/issue/KT-52664/Multiplatform-projects-with-a-single-target \ No newline at end of file diff --git a/example/MultiplatformExample/settings.gradle.kts b/example/MultiplatformExample/settings.gradle.kts index aa4df343e..23937e29b 100644 --- a/example/MultiplatformExample/settings.gradle.kts +++ b/example/MultiplatformExample/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { repositories { - // mavenLocal() + mavenLocal() google() gradlePluginPortal() mavenCentral() @@ -14,4 +14,4 @@ pluginManagement { rootProject.name = "KtorfitMultiplatformExample" include(":androidApp") include(":shared") -include(":person") \ No newline at end of file +include(":person") diff --git a/mkdocs.yml b/mkdocs.yml index 1556ddc74..c25996176 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,7 +7,7 @@ docs_dir: 'docs' edit_uri: 'tree/master/docs/' # Copyright -copyright: Copyright © Apache v2 License 2022-2023 Jens Klingenberg +copyright: Copyright © Apache v2 License 2022-2024 Jens Klingenberg extra: manifest: manifest.webmanifest site: @@ -15,7 +15,7 @@ extra: ktorfit: release: "2.0.1" ktor: - release: "2.3.11" + release: "2.3.12" social: - icon: fontawesome/brands/github-alt link: 'https://github.com/foso' @@ -66,6 +66,7 @@ nav: - 'Configuration': configuration.md - 'Android': - 'proguard': android/proguard.md + - 'Known issues': knownissues.md - 'Fundamentals' : - 'Scope' : fundamentals/scope.md - 'Architecture': architecture.md From d0308b13d41ce5a93c0d627a20f0bc9a7ffc6df4 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:12:37 +0200 Subject: [PATCH 46/59] Update documentation --- docs/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f834004d0..632c4a206 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -8,6 +8,8 @@ Note: This project needs KSP to work and every new Ktorfit with an update of the But there is no intent to bump the Ktorfit major version for every KSP update. # [Unreleased]() + +Unreleased ======================================== ## Fixed From 742290489724a5b6c68f7cc93710bca1a81eb5c3 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:14:47 +0200 Subject: [PATCH 47/59] Update documentation --- docs/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 632c4a206..3cc6bb3b4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,8 +12,10 @@ But there is no intent to bump the Ktorfit major version for every KSP update. Unreleased ======================================== +## Changed +- Allow Http Delete with Body [https://github.com/Foso/Ktorfit/issues/647](#647) + ## Fixed -- Allow Body with Http Delete [https://github.com/Foso/Ktorfit/issues/647](#647) - Task with path 'kspCommonMainKotlinMetadata' not found in project [https://github.com/Foso/Ktorfit/issues/593](#593) - Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [https://github.com/Foso/Ktorfit/issues/638](#638) From f6a11b30305fce2b84335d04ff4636b291bee989 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:15:36 +0200 Subject: [PATCH 48/59] Update documentation --- docs/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3cc6bb3b4..d0f6ce671 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,8 +16,8 @@ Unreleased - Allow Http Delete with Body [https://github.com/Foso/Ktorfit/issues/647](#647) ## Fixed -- Task with path 'kspCommonMainKotlinMetadata' not found in project [https://github.com/Foso/Ktorfit/issues/593](#593) -- Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [https://github.com/Foso/Ktorfit/issues/638](#638) +- Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) +- Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [#638](https://github.com/Foso/Ktorfit/issues/638) # [2.0.1]() From d7a9ea39b0192a23301727eb62029584ab109ee7 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:15:51 +0200 Subject: [PATCH 49/59] Update documentation --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d0f6ce671..910c8f76b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,7 +13,7 @@ Unreleased ======================================== ## Changed -- Allow Http Delete with Body [https://github.com/Foso/Ktorfit/issues/647](#647) +- Allow Http Delete with Body [#647](https://github.com/Foso/Ktorfit/issues/647) ## Fixed - Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) From 590ec85736a67053993e6956de9465aba308d625 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 10:17:50 +0200 Subject: [PATCH 50/59] Update documentation --- docs/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 910c8f76b..c64a6f213 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,9 +12,13 @@ But there is no intent to bump the Ktorfit major version for every KSP update. Unreleased ======================================== +## Added +- documentation page for [known issues](https://foso.github.io/Ktorfit/knownissues/) + ## Changed - Allow Http Delete with Body [#647](https://github.com/Foso/Ktorfit/issues/647) + ## Fixed - Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) - Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [#638](https://github.com/Foso/Ktorfit/issues/638) From cc00667cbef7137bdc599693eba9d4b847a89349 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:14:52 +0200 Subject: [PATCH 51/59] Add DontSwallowExceptionsConverterFactory --- docs/CHANGELOG.md | 3 +- .../api/android/ktorfit-lib-core.api | 7 +++++ ktorfit-lib-core/api/jvm/ktorfit-lib-core.api | 7 +++++ .../DontSwallowExceptionsConverterFactory.kt | 29 +++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory.kt diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c64a6f213..61ee66686 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,7 +17,8 @@ Unreleased ## Changed - Allow Http Delete with Body [#647](https://github.com/Foso/Ktorfit/issues/647) - +- By default, nullable response types will not throw an exception. You can now override this behavior by adding the **DontSwallowExceptionsConverterFactory** +or your own ConverterFactory to the converterFactories. [#618](https://github.com/Foso/Ktorfit/issues/618) ## Fixed - Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) diff --git a/ktorfit-lib-core/api/android/ktorfit-lib-core.api b/ktorfit-lib-core/api/android/ktorfit-lib-core.api index f8270366c..f44ca7bfb 100644 --- a/ktorfit-lib-core/api/android/ktorfit-lib-core.api +++ b/ktorfit-lib-core/api/android/ktorfit-lib-core.api @@ -114,6 +114,13 @@ public final class de/jensklingenberg/ktorfit/converter/TypeData$Companion { public static synthetic fun createTypeData$default (Lde/jensklingenberg/ktorfit/converter/TypeData$Companion;Ljava/lang/String;Lio/ktor/util/reflect/TypeInfo;ILjava/lang/Object;)Lde/jensklingenberg/ktorfit/converter/TypeData; } +public final class de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory : de/jensklingenberg/ktorfit/converter/Converter$Factory { + public fun ()V + public fun requestParameterConverter (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;)Lde/jensklingenberg/ktorfit/converter/Converter$RequestParameterConverter; + public fun responseConverter (Lde/jensklingenberg/ktorfit/converter/TypeData;Lde/jensklingenberg/ktorfit/Ktorfit;)Lde/jensklingenberg/ktorfit/converter/Converter$ResponseConverter; + public fun suspendResponseConverter (Lde/jensklingenberg/ktorfit/converter/TypeData;Lde/jensklingenberg/ktorfit/Ktorfit;)Lde/jensklingenberg/ktorfit/converter/Converter$SuspendResponseConverter; +} + public abstract interface class de/jensklingenberg/ktorfit/internal/ClassProvider { public abstract fun create (Lde/jensklingenberg/ktorfit/Ktorfit;)Ljava/lang/Object; } diff --git a/ktorfit-lib-core/api/jvm/ktorfit-lib-core.api b/ktorfit-lib-core/api/jvm/ktorfit-lib-core.api index f8270366c..f44ca7bfb 100644 --- a/ktorfit-lib-core/api/jvm/ktorfit-lib-core.api +++ b/ktorfit-lib-core/api/jvm/ktorfit-lib-core.api @@ -114,6 +114,13 @@ public final class de/jensklingenberg/ktorfit/converter/TypeData$Companion { public static synthetic fun createTypeData$default (Lde/jensklingenberg/ktorfit/converter/TypeData$Companion;Ljava/lang/String;Lio/ktor/util/reflect/TypeInfo;ILjava/lang/Object;)Lde/jensklingenberg/ktorfit/converter/TypeData; } +public final class de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory : de/jensklingenberg/ktorfit/converter/Converter$Factory { + public fun ()V + public fun requestParameterConverter (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;)Lde/jensklingenberg/ktorfit/converter/Converter$RequestParameterConverter; + public fun responseConverter (Lde/jensklingenberg/ktorfit/converter/TypeData;Lde/jensklingenberg/ktorfit/Ktorfit;)Lde/jensklingenberg/ktorfit/converter/Converter$ResponseConverter; + public fun suspendResponseConverter (Lde/jensklingenberg/ktorfit/converter/TypeData;Lde/jensklingenberg/ktorfit/Ktorfit;)Lde/jensklingenberg/ktorfit/converter/Converter$SuspendResponseConverter; +} + public abstract interface class de/jensklingenberg/ktorfit/internal/ClassProvider { public abstract fun create (Lde/jensklingenberg/ktorfit/Ktorfit;)Ljava/lang/Object; } diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory.kt new file mode 100644 index 000000000..158144ccb --- /dev/null +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/converter/builtin/DontSwallowExceptionsConverterFactory.kt @@ -0,0 +1,29 @@ +package de.jensklingenberg.ktorfit.converter.builtin + +import de.jensklingenberg.ktorfit.Ktorfit +import de.jensklingenberg.ktorfit.converter.Converter +import de.jensklingenberg.ktorfit.converter.KtorfitResult +import de.jensklingenberg.ktorfit.converter.TypeData +import io.ktor.client.statement.HttpResponse + +public class DontSwallowExceptionsConverterFactory : Converter.Factory { + private class DefaultSuspendResponseConverter( + val typeData: TypeData + ) : Converter.SuspendResponseConverter { + override suspend fun convert(result: KtorfitResult): Any? = + when (result) { + is KtorfitResult.Failure -> { + throw result.throwable + } + + is KtorfitResult.Success -> { + result.response.call.body(typeData.typeInfo) + } + } + } + + override fun suspendResponseConverter( + typeData: TypeData, + ktorfit: Ktorfit, + ): Converter.SuspendResponseConverter = DefaultSuspendResponseConverter(typeData) +} From a1d8bee8863733f5bee6d84ed1b9006ac81a21e2 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:16:16 +0200 Subject: [PATCH 52/59] Catch Throwable instead of exception --- .../ktorfit/internal/KtorfitConverterHelper.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt index b42ae9f7c..2c338f135 100644 --- a/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt +++ b/ktorfit-lib-core/src/commonMain/kotlin/de/jensklingenberg/ktorfit/internal/KtorfitConverterHelper.kt @@ -66,8 +66,8 @@ public class KtorfitConverterHelper( requestBuilder(this) }, ) - } catch (exception: Exception) { - KtorfitResult.Failure(exception) + } catch (throwable: Throwable) { + KtorfitResult.Failure(throwable) } return it.convert(result) as ReturnType? } From 385b7db4a00eebf5de7f6e5dffcc21dfacaf85d9 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:42:27 +0200 Subject: [PATCH 53/59] Release 2.1.0 --- docs/CHANGELOG.md | 10 +++++++++- docs/index.md | 9 +++++---- gradle/libs.versions.toml | 8 ++++---- .../ktorfit/gradle/KtorfitGradlePlugin.kt | 4 ++-- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 61ee66686..d4dd586bf 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,7 +7,11 @@ and this project orients towards [Semantic Versioning](http://semver.org/spec/v2 Note: This project needs KSP to work and every new Ktorfit with an update of the KSP version is technically a breaking change. But there is no intent to bump the Ktorfit major version for every KSP update. -# [Unreleased]() +# [2.1.0]() + +* Supported Kotlin version: (min) 2.0.20 +* Supported KSP version: (min) 1.0.24 +* Ktor version: 2.3.12 Unreleased ======================================== @@ -26,6 +30,10 @@ or your own ConverterFactory to the converterFactories. [#618](https://github.co # [2.0.1]() +* Supported Kotlin version: (min) 2.0.0 (max) 2.0.20 +* Supported KSP version: (min) 1.0.24 (max) 1.0.24 +* Ktor version: 2.3.12 + 2.0.1 - 2024-08-08 ======================================== ## Fixed diff --git a/docs/index.md b/docs/index.md index c15ad6b7f..a0626b557 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,10 +15,11 @@ inspired by [Retrofit](https://square.github.io/retrofit/) ## Compatibility -| Ktorfit-version | Kotlin | KSP | Ktor | -|-------------------|:-------------:|:-----------------------------:|:----------:| -| **_2.0.1_** | **>=2.0.0** | **>=1.0.24 min** | **2.3.12** | -| **_2.0.0_** | **2.0.0** | **1.0.21 (min) 1.0.24 (max)** | **2.3.11** | +| Ktorfit-version | +|-------------------------------------------------------------------------------| +| **_2.1.0_** https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md#210 | +| **_2.0.1_** https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md#201 | +| **_2.0.0_** https://github.com/Foso/Ktorfit/blob/master/docs/CHANGELOG.md#200 | # Installation diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d1fe9ce66..b7aea8201 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,13 +11,13 @@ kotlinPoet = "1.18.1" kspVersion = "2.0.20-1.0.24" groupId = "de.jensklingenberg.ktorfit" -ktorfit = "2.0.1" -ktorfitKsp = "2.0.1-1.0.24" -ktorfitCompiler = "2.0.1-2.0.20" +ktorfit = "2.1.0" +ktorfitKsp = "2.1.0-1.0.24" +ktorfitCompiler = "2.1.0-2.0.20" ktorfitCallConverter = "2.0.1" ktorfitFlowConverter = "2.0.1" ktorfitResponseConverter = "2.0.1" -ktorfitGradle = "2.0.1" +ktorfitGradle = "2.1.0" ktorfitGradlePlugin = "2.0.1" ktorVersion = "2.3.12" diff --git a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt index c0ab3f38f..91e31b4de 100644 --- a/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt +++ b/ktorfit-gradle-plugin/src/main/java/de/jensklingenberg/ktorfit/gradle/KtorfitGradlePlugin.kt @@ -15,10 +15,10 @@ class KtorfitGradlePlugin : Plugin { const val GROUP_NAME = "de.jensklingenberg.ktorfit" const val ARTIFACT_NAME = "compiler-plugin" const val COMPILER_PLUGIN_ID = "ktorfitPlugin" - const val KTORFIT_VERSION = "2.0.1" // remember to bump this version before any release! + const val KTORFIT_VERSION = "2.1.0" // remember to bump this version before any release! const val SNAPSHOT = "" const val MIN_KSP_VERSION = "1.0.24" - const val MIN_KOTLIN_VERSION = "2.0.0" + const val MIN_KOTLIN_VERSION = "2.0.20" } override fun apply(project: Project) { From c53c6d2d4e31bf849b19e1c1a9cfe8d97f89f5ac Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:44:13 +0200 Subject: [PATCH 54/59] Release 2.1.0 --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d4dd586bf..2a7e3bd33 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,7 +13,7 @@ But there is no intent to bump the Ktorfit major version for every KSP update. * Supported KSP version: (min) 1.0.24 * Ktor version: 2.3.12 -Unreleased +Ktorfit-lib ======================================== ## Added From fc6311ad07dc7ae9ad09c7ad8daff961753c74a3 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:44:41 +0200 Subject: [PATCH 55/59] Release 2.1.0 --- docs/CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2a7e3bd33..77bf93caa 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,9 +13,6 @@ But there is no intent to bump the Ktorfit major version for every KSP update. * Supported KSP version: (min) 1.0.24 * Ktor version: 2.3.12 -Ktorfit-lib -======================================== - ## Added - documentation page for [known issues](https://foso.github.io/Ktorfit/knownissues/) From 0f494af4fe83d63515ad47ecf154345c9fb9f1b0 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:46:17 +0200 Subject: [PATCH 56/59] Release 2.1.0 --- docs/CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 77bf93caa..7a9a3df88 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -25,6 +25,18 @@ or your own ConverterFactory to the converterFactories. [#618](https://github.co - Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) - Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [#638](https://github.com/Foso/Ktorfit/issues/638) + +## Ktor3 +The "normal" dependencies will stay on Ktor 2.x till 3.0 is stable. But here are versions that you can use when want to use Ktor3 and WasmJs + +| Project | Version | +|-----------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| ktorfit-lib-light-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | +| ktorfit-lib-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | +| ktorfit-converters-flow-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | +| ktorfit-converters-call-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | +| ktorfit-converters-response-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | + # [2.0.1]() * Supported Kotlin version: (min) 2.0.0 (max) 2.0.20 From 9d3cb9772a644dc44c4d2681a3a73818f782756d Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:48:41 +0200 Subject: [PATCH 57/59] Release 2.1.0 --- docs/CHANGELOG.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7a9a3df88..b8df96c7d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -25,17 +25,18 @@ or your own ConverterFactory to the converterFactories. [#618](https://github.co - Task with path 'kspCommonMainKotlinMetadata' not found in project [#593](https://github.com/Foso/Ktorfit/issues/593) - Ktorfit Gradle Plugin not compatible with Android Multiplatform Library plugin [#638](https://github.com/Foso/Ktorfit/issues/638) - ## Ktor3 The "normal" dependencies will stay on Ktor 2.x till 3.0 is stable. But here are versions that you can use when want to use Ktor3 and WasmJs -| Project | Version | -|-----------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| ktorfit-lib-light-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-light-ktor-3.0.0-beta-2) | -| ktorfit-lib-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-lib-ktor-3.0.0-beta-2) | -| ktorfit-converters-flow-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-flow-ktor-3.0.0-beta-2) | -| ktorfit-converters-call-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-call-ktor-3.0.0-beta-2) | -| ktorfit-converters-response-ktor-3.0.0-beta-2 | [![Maven Central](https://img.shields.io/maven-central/v/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2)](https://central.sonatype.com/artifact/de.jensklingenberg.ktorfit/ktorfit-converters-response-ktor-3.0.0-beta-2) | +de.jensklingenberg.ktorfit:ktorfit-lib-light-ktor-3.0.0-beta-2:2.1.0 + +de.jensklingenberg.ktorfit:ktorfit-lib-ktor-3.0.0-beta-2:2.1.0 + +de.jensklingenberg.ktorfit:ktorfit-converters-flow-ktor-3.0.0-beta-2 :2.1.0 + +de.jensklingenberg.ktorfit:ktorfit-converters-call-ktor-3.0.0-beta-2:2.1.0 + +de.jensklingenberg.ktorfit:ktorfit-converters-response-ktor-3.0.0-beta-2:2.1.0 # [2.0.1]() From 5e612854ed0999dc48f2da6ac060a53c43c9d0e3 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:53:16 +0200 Subject: [PATCH 58/59] Release 2.1.0 --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index b8df96c7d..fb4c22bac 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -32,7 +32,7 @@ de.jensklingenberg.ktorfit:ktorfit-lib-light-ktor-3.0.0-beta-2:2.1.0 de.jensklingenberg.ktorfit:ktorfit-lib-ktor-3.0.0-beta-2:2.1.0 -de.jensklingenberg.ktorfit:ktorfit-converters-flow-ktor-3.0.0-beta-2 :2.1.0 +de.jensklingenberg.ktorfit:ktorfit-converters-flow-ktor-3.0.0-beta-2:2.1.0 de.jensklingenberg.ktorfit:ktorfit-converters-call-ktor-3.0.0-beta-2:2.1.0 From 682ea88102142335b3cc1acf491afa3e3f912ce8 Mon Sep 17 00:00:00 2001 From: Jens Klingenberg Date: Sun, 1 Sep 2024 11:54:49 +0200 Subject: [PATCH 59/59] Release 2.1.0 --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index c25996176..b982427be 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,7 +13,7 @@ extra: site: images: '../../images' ktorfit: - release: "2.0.1" + release: "2.1.0" ktor: release: "2.3.12" social: