diff --git a/.github/workflows/compilation-check.yml b/.github/workflows/compilation-check.yml index 57bc947..a14cab1 100644 --- a/.github/workflows/compilation-check.yml +++ b/.github/workflows/compilation-check.yml @@ -8,14 +8,14 @@ on: jobs: build: - runs-on: macOS-11 + runs-on: macOS-latest steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Check plugin run: ./gradlew -p network-generator build publishToMavenLocal - name: Check runtime diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7dce356..8b6c3ca 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: Publish library at mavenCentral - runs-on: macOS-11 + runs-on: macOS-latest env: OSSRH_USER: ${{ secrets.OSSRH_USER }} OSSRH_KEY: ${{ secrets.OSSRH_KEY }} @@ -21,14 +21,21 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 - - name: Publish plugin - run: ./gradlew -p network-generator publishPlugins -Pgradle.publish.key=${{ secrets.GRADLE_PLUGIN_PORTAL_KEY }} -Pgradle.publish.secret=${{ secrets.GRADLE_PLUGIN_PORTAL_SECRET }} + java-version: 17 + - name: Prebuild plugin + run: ./gradlew -p network-generator publishToMavenLocal + - name: Prebuild library + run: ./gradlew publishToMavenLocal - name: Publish library - run: ./gradlew publish + run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository + - name: Publish plugin to maven central + run: ./gradlew -p network-generator publishToSonatype closeAndReleaseSonatypeStagingRepository + - name: Publish plugin to Gradle Plugin Portal + run: ./gradlew -p network-generator publishPlugins -Pgradle.publish.key=${{ secrets.GRADLE_PLUGIN_PORTAL_KEY }} -Pgradle.publish.secret=${{ secrets.GRADLE_PLUGIN_PORTAL_SECRET }} + release: name: Create release needs: publish diff --git a/.gitignore b/.gitignore index 77fd544..b0ee716 100755 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .classpath .vscode .idea +.kotlin build *.iml Pods diff --git a/README.md b/README.md index f4e0f89..3e977f9 100755 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ buildscript { } dependencies { - classpath "dev.icerock.moko:network-generator:0.21.2" + classpath "dev.icerock.moko:network-generator:0.22.0" } } @@ -53,10 +53,10 @@ project build.gradle apply plugin: "dev.icerock.mobile.multiplatform-network-generator" dependencies { - commonMainApi("dev.icerock.moko:network:0.21.2") - commonMainApi("dev.icerock.moko:network-engine:0.21.2") // configured HttpClientEngine - commonMainApi("dev.icerock.moko:network-bignum:0.21.2") // kbignum serializer - commonMainApi("dev.icerock.moko:network-errors:0.21.2") // moko-errors integration + commonMainApi("dev.icerock.moko:network:0.22.0") + commonMainApi("dev.icerock.moko:network-engine:0.22.0") // configured HttpClientEngine + commonMainApi("dev.icerock.moko:network-bignum:0.22.0") // kbignum serializer + commonMainApi("dev.icerock.moko:network-errors:0.22.0") // moko-errors integration } ``` diff --git a/build.gradle.kts b/build.gradle.kts index feae419..5dedbf9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ /* * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -import org.gradle.api.internal.artifacts.DefaultModuleVersionSelector buildscript { repositories { @@ -25,17 +24,6 @@ val mokoVersion = libs.versions.mokoNetworkVersion.get() allprojects { this.group = "dev.icerock.moko" this.version = mokoVersion - - configurations.configureEach { - resolutionStrategy { - val coroutines: MinimalExternalModuleDependency = rootProject.libs.coroutines.get() - val forcedCoroutines: ModuleVersionSelector = DefaultModuleVersionSelector.newSelector( - coroutines.module, - coroutines.versionConstraint.requiredVersion - ) - force(forcedCoroutines) - } - } } tasks.register("clean", Delete::class).configure { diff --git a/gradle.properties b/gradle.properties index f8573ea..39823b5 100755 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.mpp.androidSourceSetLayoutVersion=2 +kotlin.mpp.applyDefaultHierarchyTemplate=false android.useAndroidX=true @@ -13,8 +14,8 @@ mobile.multiplatform.iosTargetWarning=false xcodeproj=./sample/ios-app -moko.android.targetSdk=33 -moko.android.compileSdk=33 +moko.android.targetSdk=34 +moko.android.compileSdk=34 moko.android.minSdk=16 moko.publish.name=MOKO network diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7ac0147..dc64c93 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlinVersion = "1.8.10" +kotlinVersion = "2.0.20" # android lifecycleViewModelVersion = "2.6.1" @@ -12,15 +12,15 @@ openApiGeneratorVersion = "5.2.0" guavaVersion = "30.1-jre" # kotlinx -kotlinxSerializationVersion = "1.5.0" -coroutinesVersion = "1.6.4" +kotlinxSerializationVersion = "1.7.3" +coroutinesVersion = "1.9.0" # moko -mokoResourcesVersion = "0.21.2" +mokoResourcesVersion = "0.24.4" mokoMvvmVersion = "0.16.0" mokoErrorsVersion = "0.7.0" mokoTestVersion = "0.6.1" -mokoNetworkVersion = "0.21.2" +mokoNetworkVersion = "0.22.0" # tests espressoCoreVersion = "3.5.1" @@ -30,7 +30,7 @@ androidxTestVersion = "1.5.0" robolectricVersion = "4.9" # other -ktorClientVersion = "2.2.2" +ktorVersion = "3.0.0" kbignumVersion = "2.4.12" multidexVersion = "2.0.1" @@ -38,7 +38,7 @@ multidexVersion = "2.0.1" # android appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidAppCompatVersion" } glide = { module = "com.github.bumptech.glide:glide", version.ref = "glideVersion" } -lifecycleViewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelVersion" } +lifecycleViewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelVersion" } multidex = { module = "androidx.multidex:multidex", version.ref = "multidexVersion" } coreKtx = { module = "androidx.core:core-ktx", version.ref = "coreKtxVersion" } @@ -47,22 +47,26 @@ kotlinSerialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-js coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutinesVersion" } # ktor -ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktorClientVersion" } -ktorClient = { module = "io.ktor:ktor-client-core", version.ref = "ktorClientVersion" } -ktorClientLogging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorClientVersion" } -ktorClientWebSocket = { module = "io.ktor:ktor-client-websockets", version.ref = "ktorClientVersion" } -ktorClientMock = { module = "io.ktor:ktor-client-mock", version.ref = "ktorClientVersion" } -ktorClientIos = { module = "io.ktor:ktor-client-ios", version.ref = "ktorClientVersion" } +ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktorVersion" } +ktorClient = { module = "io.ktor:ktor-client-core", version.ref = "ktorVersion" } +ktorClientLogging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorVersion" } +ktorClientWebSocket = { module = "io.ktor:ktor-client-websockets", version.ref = "ktorVersion" } +ktorClientMock = { module = "io.ktor:ktor-client-mock", version.ref = "ktorVersion" } +ktorClientIos = { module = "io.ktor:ktor-client-ios", version.ref = "ktorVersion" } + +ktorServerNetty = { module = "io.ktor:ktor-server-netty", version.ref = "ktorVersion" } +ktorServerCore = { module = "io.ktor:ktor-server-core", version.ref = "ktorVersion" } +ktorServerWebSockets = { module = "io.ktor:ktor-server-websockets", version.ref = "ktorVersion" } # korlibs -kbignum = { module = "com.soywiz.korlibs.kbignum:kbignum", version.ref = "kbignumVersion" } +kbignum = { module = "com.soywiz.korlibs.kbignum:kbignum", version.ref = "kbignumVersion" } # moko -mokoMvvmDataBinding = { module = "dev.icerock.moko:mvvm-databinding", version.ref = "mokoMvvmVersion" } +mokoMvvmDataBinding = { module = "dev.icerock.moko:mvvm-databinding", version.ref = "mokoMvvmVersion" } mokoResources = { module = "dev.icerock.moko:resources", version.ref = "mokoResourcesVersion" } mokoMvvmCore = { module = "dev.icerock.moko:mvvm-core", version.ref = "mokoMvvmVersion" } mokoMvvmLiveData = { module = "dev.icerock.moko:mvvm-livedata", version.ref = "mokoMvvmVersion" } -mokoErrors = { module = "dev.icerock.moko:errors", version.ref = "mokoErrorsVersion" } +mokoErrors = { module = "dev.icerock.moko:errors", version.ref = "mokoErrorsVersion" } # tests espressoCore = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCoreVersion" } @@ -72,17 +76,17 @@ robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectr testRunner = { module = "androidx.test:runner", version.ref = "testRunnerVersion" } testRules = { module = "androidx.test:rules", version.ref = "testRunnerVersion" } testExtJunit = { module = "androidx.test.ext:junit", version.ref = "testExtJunitVersion" } -kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlinVersion" } -kotlinTestAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlinVersion" } -mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } +kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlinVersion" } +mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } # jvm openApiGenerator = { module = "org.openapitools:openapi-generator-gradle-plugin", version.ref = "openApiGeneratorVersion" } guava = { module = "com.google.guava:guava", version.ref = "guavaVersion" } +logback = { module = "ch.qos.logback:logback-classic", version = "1.5.21" } # gradle plugins kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlinVersion" } kotlinSerializationGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlinVersion" } -androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "7.4.2" } +androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.5.2" } mokoResourcesGradlePlugin = { module = "dev.icerock.moko:resources-generator", version.ref = "mokoResourcesVersion" } -mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.3.0" } +mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.6.0" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 31cca49..2fa91c5 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt b/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt index 2accd2a..e4c160a 100644 --- a/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt +++ b/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt @@ -5,6 +5,7 @@ package dev.icerock.moko.network.bignum import com.soywiz.kbignum.BigNum +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializer import kotlinx.serialization.descriptors.PrimitiveKind @@ -12,6 +13,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = BigNum::class) object BigNumSerializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor( diff --git a/network-errors/build.gradle.kts b/network-errors/build.gradle.kts index 8537ff2..5c408fe 100644 --- a/network-errors/build.gradle.kts +++ b/network-errors/build.gradle.kts @@ -21,8 +21,13 @@ dependencies { commonMainApi(libs.mokoResources) commonMainImplementation(projects.network) + + // temporary workaround for + // e: KLIB resolver: Could not find "dev.icerock.moko:parcelize + // caused moko-errors + iosMainApi("dev.icerock.moko:parcelize:0.9.0") } multiplatformResources { - multiplatformResourcesPackage = "dev.icerock.moko.network.errors" + resourcesPackage = "dev.icerock.moko.network.errors" } diff --git a/network-errors/src/commonMain/resources/MR/base/strings.xml b/network-errors/src/commonMain/moko-resources/base/strings.xml similarity index 100% rename from network-errors/src/commonMain/resources/MR/base/strings.xml rename to network-errors/src/commonMain/moko-resources/base/strings.xml diff --git a/network-errors/src/commonMain/resources/MR/ru/strings.xml b/network-errors/src/commonMain/moko-resources/ru/strings.xml similarity index 100% rename from network-errors/src/commonMain/resources/MR/ru/strings.xml rename to network-errors/src/commonMain/moko-resources/ru/strings.xml diff --git a/network-generator/build.gradle.kts b/network-generator/build.gradle.kts index e9c3fa6..cf876ae 100644 --- a/network-generator/build.gradle.kts +++ b/network-generator/build.gradle.kts @@ -2,8 +2,11 @@ * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { - id("com.gradle.plugin-publish") version ("0.15.0") + id("com.gradle.plugin-publish") version ("1.3.1") id("java-gradle-plugin") } @@ -42,40 +45,23 @@ java { withSourcesJar() } -configure { - publications.register("mavenJava", MavenPublication::class) { - from(components["java"]) +tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) } } -tasks.withType().configureEach { - kotlinOptions.jvmTarget = "1.8" -} - gradlePlugin { + website.set("https://github.com/icerockdev/moko-network") + vcsUrl.set("https://github.com/icerockdev/moko-network") + plugins { create("multiplatform-network-generator") { id = "dev.icerock.mobile.multiplatform-network-generator" + displayName = "MOKO network generator plugin" implementationClass = "dev.icerock.moko.network.MultiPlatformNetworkGeneratorPlugin" + description = "Plugin to provide network components for iOS & Android" + tags = listOf("moko-network", "moko", "kotlin", "kotlin-multiplatform") } } } - -pluginBundle { - website = "https://github.com/icerockdev/moko-network" - vcsUrl = "https://github.com/icerockdev/moko-network" - description = "Plugin to provide network components for iOS & Android" - tags = listOf("moko-network", "moko", "kotlin", "kotlin-multiplatform") - - plugins { - getByName("multiplatform-network-generator") { - displayName = "MOKO network generator plugin" - } - } - - mavenCoordinates { - groupId = project.group as String - artifactId = project.name - version = project.version as String - } -} \ No newline at end of file diff --git a/network-generator/settings.gradle.kts b/network-generator/settings.gradle.kts index eb7a3f9..1f97078 100644 --- a/network-generator/settings.gradle.kts +++ b/network-generator/settings.gradle.kts @@ -1,7 +1,6 @@ /* * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { repositories { diff --git a/network/build.gradle.kts b/network/build.gradle.kts index 06a0437..d9dc954 100644 --- a/network/build.gradle.kts +++ b/network/build.gradle.kts @@ -50,7 +50,6 @@ dependencies { commonTestImplementation(libs.ktorClientMock) commonTestImplementation(libs.kotlinTest) - commonTestImplementation(libs.kotlinTestAnnotations) androidTestImplementation(libs.kotlinTestJUnit) } diff --git a/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 0f02181..cf474ce 100644 --- a/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -9,7 +9,7 @@ import androidx.core.os.ConfigurationCompat import dev.icerock.moko.network.plugins.LanguagePlugin actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String? { + actual override fun getLanguageCode(): String? { return ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)?.language } } diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 54eaa90..1dfb36b 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -4,7 +4,9 @@ package dev.icerock.moko.network -import dev.icerock.moko.network.plugins.LanguagePlugin +import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider @Suppress("EmptyDefaultConstructor") -expect class LanguageProvider() : LanguagePlugin.LanguageCodeProvider +expect class LanguageProvider() : LanguageCodeProvider { + override fun getLanguageCode(): String? +} diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt index 99fd63a..04bfd43 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt @@ -12,8 +12,9 @@ import io.ktor.client.plugins.plugin import io.ktor.client.statement.bodyAsChannel import io.ktor.http.isSuccess import io.ktor.util.AttributeKey -import io.ktor.utils.io.charsets.Charset +import io.ktor.utils.io.charsets.Charsets import io.ktor.utils.io.core.readText +import io.ktor.utils.io.readRemaining class ExceptionPlugin(private val exceptionFactory: ExceptionFactory) { @@ -36,7 +37,7 @@ class ExceptionPlugin(private val exceptionFactory: ExceptionFactory) { val call = execute(request) if (!call.response.status.isSuccess()) { val packet = call.response.bodyAsChannel().readRemaining() - val responseString = packet.readText(charset = Charset.forName("UTF-8")) + val responseString = packet.readText(charset = Charsets.UTF_8) throw plugin.exceptionFactory.createException( request = call.request, response = call.response, diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt index 4418004..45b26e0 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt @@ -7,7 +7,6 @@ package dev.icerock.moko.network.plugins import io.ktor.client.HttpClient import io.ktor.client.plugins.HttpClientPlugin import io.ktor.client.request.HttpRequest -import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.request import io.ktor.client.request.takeFrom import io.ktor.client.statement.HttpReceivePipeline @@ -51,11 +50,14 @@ class RefreshTokenPlugin( } refreshTokenHttpPluginMutex.withLock { + val originalRequest = subject.request + // If token of the request isn't actual, then token has already been updated and // let's just to try repeat request if (!plugin.isCredentialsActual(subject.request)) { - val requestBuilder = HttpRequestBuilder().takeFrom(subject.request) - val result: HttpResponse = scope.request(requestBuilder) + val result: HttpResponse = scope.request { + takeFrom(originalRequest) + } proceedWith(result) return@intercept } @@ -64,8 +66,9 @@ class RefreshTokenPlugin( // refresh request. if (plugin.updateTokenHandler.invoke()) { // If the request refresh was successful, then let's just to try repeat request - val requestBuilder = HttpRequestBuilder().takeFrom(subject.request) - val result: HttpResponse = scope.request(requestBuilder) + val result: HttpResponse = scope.request { + takeFrom(originalRequest) + } proceedWith(result) } else { // If the request refresh was unsuccessful diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt index 9639369..a48b062 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt @@ -30,11 +30,12 @@ class TokenPlugin private constructor( override fun prepare(block: Config.() -> Unit) = Config().apply(block).build() override fun install(plugin: TokenPlugin, scope: HttpClient) { - scope.requestPipeline.intercept(HttpRequestPipeline.State) { + scope.requestPipeline.intercept(HttpRequestPipeline.Before) { plugin.tokenProvider.getToken()?.apply { context.headers.remove(plugin.tokenHeaderName) context.header(plugin.tokenHeaderName, this) } + proceed() } } } diff --git a/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt b/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt index 6610d7f..e3741c2 100644 --- a/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt +++ b/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt @@ -9,6 +9,8 @@ import io.ktor.client.engine.mock.MockEngine import io.ktor.client.engine.mock.MockRequestHandler import io.ktor.client.engine.mock.respondError import io.ktor.client.engine.mock.respondOk +import io.ktor.client.request.HttpRequest +import io.ktor.client.request.HttpRequestData import io.ktor.client.request.get import io.ktor.client.statement.request import io.ktor.http.HttpStatusCode @@ -49,6 +51,8 @@ class RefreshTokenPluginTest { val invalidToken = "123" val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) + var lastSuccessfulRequest: HttpRequestData? = null + val client = createMockClient( tokenProvider = { tokenHolder.value }, pluginConfig = { @@ -63,7 +67,10 @@ class RefreshTokenPluginTest { ) { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } val result = runBlocking { @@ -71,7 +78,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } @Test @@ -80,6 +87,7 @@ class RefreshTokenPluginTest { val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) var isFirstTime = true + var lastSuccessfulRequest: HttpRequestData? = null val client = createMockClient( tokenProvider = object : TokenPlugin.TokenProvider { @@ -105,7 +113,10 @@ class RefreshTokenPluginTest { handler = { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } ) @@ -122,7 +133,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } @Test @@ -131,6 +142,7 @@ class RefreshTokenPluginTest { val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) var isFirstTime = true + var lastSuccessfulRequest: HttpRequestData? = null val client = createMockClient( tokenProvider = object : TokenPlugin.TokenProvider { @@ -154,7 +166,10 @@ class RefreshTokenPluginTest { handler = { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } ) @@ -171,7 +186,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } private fun createMockClient( @@ -183,6 +198,7 @@ class RefreshTokenPluginTest { engine { addHandler(handler) } + install(RefreshTokenPlugin, pluginConfig) if (tokenProvider != null) { install(TokenPlugin) { @@ -190,7 +206,6 @@ class RefreshTokenPluginTest { this.tokenProvider = tokenProvider } } - install(RefreshTokenPlugin, pluginConfig) } } diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 22e846d..d3cdc94 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -10,7 +10,7 @@ import platform.Foundation.currentLocale import platform.Foundation.languageCode actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String { + actual override fun getLanguageCode(): String? { return NSLocale.currentLocale.languageCode } } diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt index f6ec739..3c03c91 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt @@ -7,7 +7,7 @@ package dev.icerock.moko.network import platform.Foundation.NSError -import kotlin.native.concurrent.AtomicReference +import kotlin.concurrent.AtomicReference object ThrowableToNSErrorMapper : (Throwable) -> NSError? { private val mapperRef: AtomicReference<((Throwable) -> NSError?)?> = AtomicReference(null) diff --git a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 624680b..56131de 100644 --- a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -4,11 +4,11 @@ package dev.icerock.moko.network -import dev.icerock.moko.network.plugins.LanguagePlugin +import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider import java.util.Locale -actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String? { +actual class LanguageProvider : LanguageCodeProvider { + actual override fun getLanguageCode(): String? { return Locale.getDefault().displayLanguage } } diff --git a/sample/android-app/build.gradle.kts b/sample/android-app/build.gradle.kts index 97fb190..187652d 100644 --- a/sample/android-app/build.gradle.kts +++ b/sample/android-app/build.gradle.kts @@ -18,6 +18,7 @@ android { versionCode = 1 versionName = "0.1.0" } + namespace = "com.icerockdev.app" } dependencies { @@ -25,5 +26,5 @@ dependencies { implementation(libs.appCompat) implementation(libs.mokoMvvmDataBinding) implementation(libs.multidex) - implementation(projects.sample.mppLibrary) + implementation(project(":sample:mpp-library")) } diff --git a/sample/form-data-binary-server/build.gradle.kts b/sample/form-data-binary-server/build.gradle.kts index 4955c36..07db3d0 100644 --- a/sample/form-data-binary-server/build.gradle.kts +++ b/sample/form-data-binary-server/build.gradle.kts @@ -11,12 +11,12 @@ application { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } dependencies { - implementation("io.ktor:ktor-server-netty:2.2.1") - implementation("io.ktor:ktor-server-core:2.2.1") - implementation("ch.qos.logback:logback-classic:1.2.11") + implementation(libs.ktorServerNetty) + implementation(libs.ktorServerCore) + implementation(libs.logback) } diff --git a/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt b/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt index e8be909..ce554e9 100644 --- a/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt +++ b/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt @@ -8,14 +8,11 @@ import io.ktor.http.content.PartData import io.ktor.http.content.forEachPart import io.ktor.http.content.streamProvider import io.ktor.server.application.Application -import io.ktor.server.application.call import io.ktor.server.request.receiveMultipart import io.ktor.server.response.respondText import io.ktor.server.routing.post import io.ktor.server.routing.routing import java.io.File -import kotlin.collections.mutableMapOf -import kotlin.collections.set fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) diff --git a/sample/ios-app/Podfile b/sample/ios-app/Podfile index 04ec21c..0df9ade 100644 --- a/sample/ios-app/Podfile +++ b/sample/ios-app/Podfile @@ -12,6 +12,6 @@ install! 'cocoapods', :disable_input_output_paths => true target 'TestProj' do # MultiPlatformLibrary - # для корректной установки фреймворка нужно сначала скомпилировать котлин библиотеку - compile-kotlin-framework.sh (в корневой директории репозитория) + # at first run ./gradlew :sample:mpp-library:syncMultiPlatformLibraryDebugFrameworkIosSimulatorArm64 pod 'MultiPlatformLibrary', :path => '../mpp-library' end diff --git a/sample/ios-app/Podfile.lock b/sample/ios-app/Podfile.lock index 2092641..0a7c980 100644 --- a/sample/ios-app/Podfile.lock +++ b/sample/ios-app/Podfile.lock @@ -11,6 +11,6 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: MultiPlatformLibrary: 2a9f43df7bd018c32611a2087c1e2ef74847394c -PODFILE CHECKSUM: 68b1a7b3453f9dbea0e91a6439f872724d5c91ce +PODFILE CHECKSUM: ad3ecd1afe182c0aea10da9a77e9652b5f68993b -COCOAPODS: 1.11.3 +COCOAPODS: 1.16.2 diff --git a/sample/ios-app/TestProj.xcodeproj/project.pbxproj b/sample/ios-app/TestProj.xcodeproj/project.pbxproj index 1443eb6..627b61e 100644 --- a/sample/ios-app/TestProj.xcodeproj/project.pbxproj +++ b/sample/ios-app/TestProj.xcodeproj/project.pbxproj @@ -112,7 +112,7 @@ 287627FB1F319065007FA12B /* Sources */, 287627FC1F319065007FA12B /* Frameworks */, 287627FD1F319065007FA12B /* Resources */, - 07695594F733E91F16ACB8C4 /* [CP] Embed Pods Frameworks */, + A87E251FA49FF4830EB4D71E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -173,7 +173,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 07695594F733E91F16ACB8C4 /* [CP] Embed Pods Frameworks */ = { + A87E251FA49FF4830EB4D71E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( diff --git a/sample/mpp-library/build.gradle.kts b/sample/mpp-library/build.gradle.kts index 4807cdd..1cf14bb 100644 --- a/sample/mpp-library/build.gradle.kts +++ b/sample/mpp-library/build.gradle.kts @@ -2,6 +2,9 @@ * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ +import dev.icerock.moko.network.tasks.GenerateTask +import io.gitlab.arturbosch.detekt.Detekt + plugins { id("com.android.library") id("dev.icerock.moko.gradle.android.base") @@ -15,6 +18,10 @@ plugins { id("dev.icerock.moko.gradle.tests") } +android { + namespace = "com.icerockdev.library" +} + dependencies { commonMainImplementation(libs.coroutines) commonMainImplementation(libs.ktorClient) @@ -27,22 +34,21 @@ dependencies { commonMainApi(libs.mokoMvvmLiveData) commonMainApi(projects.network) - commonMainApi(projects.networkEngine) commonMainApi(projects.networkBignum) + commonMainApi(projects.networkEngine) commonMainApi(projects.networkErrors) androidMainImplementation(libs.lifecycleViewModel) commonTestImplementation(libs.ktorClientMock) - commonTestImplementation(libs.kotlinTest) commonTestImplementation(libs.mokoTest) - commonTestImplementation(libs.kotlinTestAnnotations) + commonTestImplementation(libs.kotlinTest) androidTestImplementation(libs.kotlinTestJUnit) } multiplatformResources { - multiplatformResourcesPackage = "com.icerockdev.library" + resourcesPackage = "com.icerockdev.library" } mokoNetwork { @@ -126,3 +132,7 @@ tasks.withType() } } +val generateTasks = tasks.withType() +tasks.withType().configureEach { + dependsOn(generateTasks) +} diff --git a/sample/mpp-library/src/androidMain/AndroidManifest.xml b/sample/mpp-library/src/androidMain/AndroidManifest.xml deleted file mode 100755 index 8f69414..0000000 --- a/sample/mpp-library/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/sample/websocket-echo-server/build.gradle.kts b/sample/websocket-echo-server/build.gradle.kts index 53a3917..8638c92 100644 --- a/sample/websocket-echo-server/build.gradle.kts +++ b/sample/websocket-echo-server/build.gradle.kts @@ -11,13 +11,13 @@ application { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } dependencies { - implementation("io.ktor:ktor-server-netty:1.5.1") - implementation("io.ktor:ktor-server-core:1.5.1") - implementation("io.ktor:ktor-websockets:1.5.1") - implementation("ch.qos.logback:logback-classic:1.2.9") + implementation(libs.ktorServerNetty) + implementation(libs.ktorServerCore) + implementation(libs.ktorServerWebSockets) + implementation(libs.logback) } diff --git a/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt b/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt index 394f033..407e072 100644 --- a/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt +++ b/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt @@ -4,27 +4,26 @@ package com.icerockdev.server -import io.ktor.application.Application -import io.ktor.application.call -import io.ktor.application.install import io.ktor.http.ContentType -import io.ktor.http.cio.websocket.Frame -import io.ktor.http.cio.websocket.pingPeriod -import io.ktor.http.cio.websocket.readText -import io.ktor.http.cio.websocket.timeout -import io.ktor.response.respondText -import io.ktor.routing.get -import io.ktor.routing.routing -import io.ktor.websocket.WebSockets -import io.ktor.websocket.webSocket -import java.time.Duration +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.response.respondText +import io.ktor.server.routing.get +import io.ktor.server.routing.routing +import io.ktor.server.websocket.WebSockets +import io.ktor.server.websocket.pingPeriod +import io.ktor.server.websocket.timeout +import io.ktor.server.websocket.webSocket +import io.ktor.websocket.Frame +import io.ktor.websocket.readText +import kotlin.time.Duration.Companion.seconds fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { install(WebSockets) { - pingPeriod = Duration.ofSeconds(15) - timeout = Duration.ofSeconds(15) + pingPeriod = 15.seconds + timeout = 15.seconds maxFrameSize = Long.MAX_VALUE masking = false } diff --git a/settings.gradle.kts b/settings.gradle.kts index 336451e..9a10261 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,6 @@ * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement {