From 118be6edea3bbfbb00007e555f91861cf8ce1cc3 Mon Sep 17 00:00:00 2001 From: EpicSquid Date: Mon, 28 Apr 2025 16:49:07 +1000 Subject: [PATCH 1/5] Added WASM support (basic) --- .gitignore | 3 +- build.gradle.kts | 660 +++++++++--------- settings.gradle.kts | 10 +- .../com/liftric/cognito/idp/core/Engine.kt | 7 + .../com/liftric/cognito/idp/jwt/Base64.kt | 28 + 5 files changed, 376 insertions(+), 332 deletions(-) create mode 100644 src/wasmJsMain/kotlin/com/liftric/cognito/idp/core/Engine.kt create mode 100644 src/wasmJsMain/kotlin/com/liftric/cognito/idp/jwt/Base64.kt diff --git a/.gitignore b/.gitignore index e264418..f2f293e 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ DerivedData/ !*.xcodeproj/xcshareddata/ !*.xcworkspace/contents.xcworkspacedata **/xcshareddata/WorkspaceSettings.xcsettings -kotlin-js-store/ \ No newline at end of file +kotlin-js-store/ +/.kotlin/ diff --git a/build.gradle.kts b/build.gradle.kts index 667e775..7858595 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,383 +1,389 @@ +@file:OptIn(ExperimentalWasmDsl::class) + import com.android.build.gradle.LibraryExtension import com.liftric.vault.GetVaultSecretTask +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest import org.jetbrains.kotlin.gradle.tasks.* plugins { - kotlin("multiplatform") version libs.versions.kotlin - alias(libs.plugins.kotlin.serialization) - id("com.android.library") version libs.versions.android.tools.gradle - alias(libs.plugins.definitions) - alias(libs.plugins.npm.publishing) - alias(libs.plugins.versioning) - alias(libs.plugins.vault.client) - id("maven-publish") - id("signing") + kotlin("multiplatform") version libs.versions.kotlin + alias(libs.plugins.kotlin.serialization) + id("com.android.library") version libs.versions.android.tools.gradle + alias(libs.plugins.definitions) + alias(libs.plugins.npm.publishing) + alias(libs.plugins.versioning) + alias(libs.plugins.vault.client) + id("maven-publish") + id("signing") } repositories { - mavenCentral() - google() - gradlePluginPortal() + mavenCentral() + google() + gradlePluginPortal() } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } kotlin { - ios { - binaries.framework() - } - - iosSimulatorArm64() - - androidTarget() { - publishAllLibraryVariants() - } - jvm() - js(IR) { - generateTypeScriptDefinitions() - browser { - testTask { - useMocha { - timeout = "10s" - } - } - } - binaries.library() - compilations.all { - compileTaskProvider.configure { - compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false") - } - } - } - - sourceSets { - val commonMain by getting { - dependencies { - api(libs.ktor.client.core) - api(libs.kotlinx.coroutines) - api(libs.kotlinx.serialization) - } - } - val commonTest by getting { - kotlin.srcDir("${buildDir}/gen") - dependencies { - implementation(kotlin("test")) - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } - } - val androidMain by getting { - dependencies { - api(libs.ktor.client.android) - } - } - val jvmMain by getting { - dependencies { - api(libs.ktor.client.jvm) - } - } - val androidUnitTest by getting { - dependencies { - implementation(libs.roboelectric) - implementation(kotlin("test")) - implementation(kotlin("test-junit")) - implementation(libs.androidx.test.core) - implementation(libs.opt.java) - } - } - val jvmTest by getting { - dependencies { - implementation(kotlin("test")) - implementation(kotlin("test-junit")) - implementation(libs.opt.java) - } - } - val iosMain by getting { - dependencies { - api(libs.ktor.client.darwin) - } - } - val iosTest by getting - val iosSimulatorArm64Main by getting { - dependsOn(iosMain) - } - val iosSimulatorArm64Test by getting { - dependsOn(iosTest) - } - val jsMain by getting { - dependencies { - api(libs.ktor.client.js) - } - } - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - all { - languageSettings { - optIn("kotlinx.serialization.ExperimentalSerializationApi") - optIn("kotlin.js.ExperimentalJsExport") - optIn("kotlin.RequiresOptIn") - } - } - } + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { + it.binaries.framework() + } + + androidTarget() { + publishAllLibraryVariants() + } + jvm() + js(IR) { + generateTypeScriptDefinitions() + browser { + testTask { + useMocha { + timeout = "10s" + } + } + } + binaries.library() + compilations.all { + compileTaskProvider.configure { + compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false") + } + } + } + wasmJs { + browser() + binaries.library() + } + + sourceSets { + val commonMain by getting { + dependencies { + api(libs.ktor.client.core) + api(libs.kotlinx.coroutines) + api(libs.kotlinx.serialization) + } + } + val commonTest by getting { + kotlin.srcDir("${buildDir}/gen") + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val androidMain by getting { + dependencies { + api(libs.ktor.client.android) + } + } + val jvmMain by getting { + dependencies { + api(libs.ktor.client.jvm) + } + } + val androidUnitTest by getting { + dependencies { + implementation(libs.roboelectric) + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + implementation(libs.androidx.test.core) + implementation(libs.opt.java) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + implementation(libs.opt.java) + } + } + iosMain.dependencies { + api(libs.ktor.client.darwin) + } + val jsMain by getting { + dependencies { + api(libs.ktor.client.js) + } + } + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + val wasmJsMain by getting { + dependencies { + api(libs.ktor.client.cio) + api(libs.kotlinx.browser) + } + } + all { + languageSettings { + optIn("kotlinx.serialization.ExperimentalSerializationApi") + optIn("kotlin.js.ExperimentalJsExport") + optIn("kotlin.RequiresOptIn") + } + } + } } configure { - defaultConfig.apply { - compileSdk = 30 - minSdkVersion(21) - targetSdkVersion(30) - testInstrumentationRunner = "org.robolectric.RobolectricTestRunner" - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - isReturnDefaultValues = true - } - } - - namespace = "com.liftric.cognito.idp" - - publishing { - multipleVariants { - allVariants() - withJavadocJar() - } - } + defaultConfig.apply { + compileSdk = 30 + minSdkVersion(21) + targetSdkVersion(30) + testInstrumentationRunner = "org.robolectric.RobolectricTestRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + testOptions { + unitTests.apply { + isIncludeAndroidResources = true + isReturnDefaultValues = true + } + } + + namespace = "com.liftric.cognito.idp" + + publishing { + multipleVariants { + allVariants() + withJavadocJar() + } + } } group = "com.liftric" version = with(versioning.info) { - if (branch == "HEAD" && dirty.not()) tag else full + if (branch == "HEAD" && dirty.not()) tag else full } afterEvaluate { - project.publishing.publications.withType(MavenPublication::class.java).forEach { - it.groupId = group.toString() - } + project.publishing.publications.withType(MavenPublication::class.java).forEach { + it.groupId = group.toString() + } } tasks { - withType(KotlinNativeSimulatorTest::class) { - filter.excludeTestsMatching("com.liftric.cognito.idp.IdentityProviderClientTests") - } - - val testSecrets by creating(GetVaultSecretTask::class) { - secretPath.set("secret/apps/smartest/shared/cognito") - } - - val createJsEnvHack by creating { - outputs.dir("$buildDir/gen") - - if (System.getenv("region") == null || System.getenv("clientId") == null) { - // github ci provides region and clientId envs, locally we'll use vault directly - dependsOn(testSecrets) - } - - doFirst { - val (clientId, region) = with(testSecrets.secret.get()) { - ((System.getenv("clientId") ?: this["client_id_dev"].toString()) to - (System.getenv("region") ?: this["client_region_dev"].toString())) - } - - mkdir("$buildDir/gen") - with(File("$buildDir/gen/env.kt")) { - createNewFile() - writeText( - """ + withType(KotlinNativeSimulatorTest::class) { + filter.excludeTestsMatching("com.liftric.cognito.idp.IdentityProviderClientTests") + } + + val testSecrets by creating(GetVaultSecretTask::class) { + secretPath.set("secret/apps/smartest/shared/cognito") + } + + val createJsEnvHack by creating { + outputs.dir("$buildDir/gen") + + if (System.getenv("region") == null || System.getenv("clientId") == null) { + // github ci provides region and clientId envs, locally we'll use vault directly + dependsOn(testSecrets) + } + + doFirst { + val (clientId, region) = with(testSecrets.secret.get()) { + ((System.getenv("clientId") ?: this["client_id_dev"].toString()) to + (System.getenv("region") ?: this["client_region_dev"].toString())) + } + + mkdir("$buildDir/gen") + with(File("$buildDir/gen/env.kt")) { + createNewFile() + writeText( + """ val env = mapOf( "region" to "$region", "clientId" to "$clientId", ) """.trimIndent() - ) - } - } - } - - withType { - dependsOn(createJsEnvHack) - } - - withType { - kotlinOptions { - jvmTarget = "11" - languageVersion = "1.5" - freeCompilerArgs = listOf( - "-Xinline-classes" - ) - } - } - - /** - * Ugly atomicfu export hack: Coroutines core needs atomicfu-js, which generates broken d.ts entries. Excluding - * atomicfu-js breaks the ktor client and filtering d.ts types in the IR compile is currently not possible... so let's - * just rip it out after the fact - * - * The build/js/packages/cognito-idp/kotlin/cognito-idp.d.ts file should now be without errors and usable from typescript - */ - val cleanTypescriptTypes by creating { - fun MutableList.removeFromTill(from: String, till: String) { - val fromIndex = indexOfFirst { it == from } - val tillIndex = indexOfFirst { it == till } - if (fromIndex == -1 || tillIndex == -1) { - println("looks like from='$from' till='$till' already scraped") - return - } - println("removeFromTill from='$from' till='$till' fromIndex=$fromIndex") - println("removeFromTill from='$from' till='$till' tillIndex=$tillIndex") - (fromIndex..tillIndex).forEach { - removeAt(fromIndex) - } - } - - val dTsFile = file("$buildDir/js/packages/cognito-idp/kotlin/cognito-idp.d.ts") - inputs.file(dTsFile) - outputs.file(dTsFile) - - doLast { - val dTs = dTsFile.readLines().toMutableList() - dTs.removeFromTill("export namespace kotlinx.atomicfu {", "}") - dTs.removeFromTill("export namespace io.ktor.util {", "}") - dTsFile.writeText(dTs.joinToString("\n")) - } - } - val jsBrowserProductionLibraryDistribution by existing { - finalizedBy(cleanTypescriptTypes) - } - val jsProductionLibraryCompileSync by existing { - finalizedBy(cleanTypescriptTypes) - } + ) + } + } + } + + withType { + dependsOn(createJsEnvHack) + } + + withType { + kotlinOptions { + jvmTarget = "11" + languageVersion = "2.1" + freeCompilerArgs = listOf( + "-Xinline-classes" + ) + } + } + + /** + * Ugly atomicfu export hack: Coroutines core needs atomicfu-js, which generates broken d.ts entries. Excluding + * atomicfu-js breaks the ktor client and filtering d.ts types in the IR compile is currently not possible... so let's + * just rip it out after the fact + * + * The build/js/packages/cognito-idp/kotlin/cognito-idp.d.ts file should now be without errors and usable from typescript + */ + val cleanTypescriptTypes by creating { + fun MutableList.removeFromTill(from: String, till: String) { + val fromIndex = indexOfFirst { it == from } + val tillIndex = indexOfFirst { it == till } + if (fromIndex == -1 || tillIndex == -1) { + println("looks like from='$from' till='$till' already scraped") + return + } + println("removeFromTill from='$from' till='$till' fromIndex=$fromIndex") + println("removeFromTill from='$from' till='$till' tillIndex=$tillIndex") + (fromIndex..tillIndex).forEach { + removeAt(fromIndex) + } + } + + val dTsFile = file("$buildDir/js/packages/cognito-idp/kotlin/cognito-idp.d.ts") + inputs.file(dTsFile) + outputs.file(dTsFile) + + doLast { + val dTs = dTsFile.readLines().toMutableList() + dTs.removeFromTill("export namespace kotlinx.atomicfu {", "}") + dTs.removeFromTill("export namespace io.ktor.util {", "}") + dTsFile.writeText(dTs.joinToString("\n")) + } + } + val jsBrowserProductionLibraryDistribution by existing { + finalizedBy(cleanTypescriptTypes) + } + val jsProductionLibraryCompileSync by existing { + finalizedBy(cleanTypescriptTypes) + } } val ossrhUsername: String? by project val ossrhPassword: String? by project val javadocJar by tasks.registering(Jar::class) { - archiveClassifier.set("javadoc") + archiveClassifier.set("javadoc") } publishing { - repositories { - maven { - name = "sonatype" - setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") - credentials { - username = ossrhUsername - password = ossrhPassword - } - } - } - - publications.withType { - artifact(javadocJar.get()) - - pom { - name.set(project.name) - description.set("Lightweight AWS Cognito Identity Provider client for Kotlin Multiplatform projects.") - url.set("https://github.com/liftric/cognito-idp") - - licenses { - license { - name.set("MIT") - url.set("https://github.com/liftric/cognito-idp/blob/master/LICENSE") - } - } - developers { - developer { - id.set("benjohnde") - name.set("Ben John") - email.set("john@liftric.com") - } - developer { - id.set("ingwersaft") - name.set("Marcel Kesselring") - email.set("kesselring@liftric.com") - } - } - scm { - url.set("https://github.com/liftric/cognito-idp") - } - } - } + repositories { + maven { + name = "sonatype" + setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials { + username = ossrhUsername + password = ossrhPassword + } + } + } + + publications.withType { + artifact(javadocJar.get()) + + pom { + name.set(project.name) + description.set("Lightweight AWS Cognito Identity Provider client for Kotlin Multiplatform projects.") + url.set("https://github.com/liftric/cognito-idp") + + licenses { + license { + name.set("MIT") + url.set("https://github.com/liftric/cognito-idp/blob/master/LICENSE") + } + } + developers { + developer { + id.set("benjohnde") + name.set("Ben John") + email.set("john@liftric.com") + } + developer { + id.set("ingwersaft") + name.set("Marcel Kesselring") + email.set("kesselring@liftric.com") + } + } + scm { + url.set("https://github.com/liftric/cognito-idp") + } + } + } } val npmAccessKey: String? by project npmPublish { - organization.set("liftric") - access.set(PUBLIC) - readme.set(rootProject.file("README.md")) - - packages { - named("js") { - packageName.set(project.name) - packageJson { - keywords.set( - listOf( - "kotlin", - "cognito", - "identity-provider", - "liftric", - "aws" - ) - ) - license.set("MIT") - description.set("Lightweight AWS Cognito Identity Provider client.") - homepage.set("https://github.com/liftric/cognito-idp") - } - } - } - - registries { - npmjs { - uri.set(uri("https://registry.npmjs.org")) - authToken.set(npmAccessKey) - } - } + organization.set("liftric") + access.set(PUBLIC) + readme.set(rootProject.file("README.md")) + + packages { + named("js") { + packageName.set(project.name) + packageJson { + keywords.set( + listOf( + "kotlin", + "cognito", + "identity-provider", + "liftric", + "aws" + ) + ) + license.set("MIT") + description.set("Lightweight AWS Cognito Identity Provider client.") + homepage.set("https://github.com/liftric/cognito-idp") + } + } + } + + registries { + npmjs { + uri.set(uri("https://registry.npmjs.org")) + authToken.set(npmAccessKey) + } + } } signing { - val signingKey: String? by project - val signingPassword: String? by project - useInMemoryPgpKeys(signingKey, signingPassword) - sign(publishing.publications) + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications) } vault { - vaultAddress.set("https://dark-lord.liftric.io") - if (System.getenv("CI") == null) { - vaultTokenFilePath.set("${System.getProperty("user.home")}/.vault-token") - } else { - vaultToken.set(System.getenv("VAULT_TOKEN")) - } + vaultAddress.set("https://dark-lord.liftric.io") + if (System.getenv("CI") == null) { + vaultTokenFilePath.set("${System.getProperty("user.home")}/.vault-token") + } else { + vaultToken.set(System.getenv("VAULT_TOKEN")) + } } tasks { - afterEvaluate { - val signingTasks = filter { it.name.startsWith("sign") } - all { - // lets bruteforce this until the plugins play along nicely again - - if (name.contains("compile", true) && name.contains("kotlin", true)) { - dependsOn("createJsEnvHack") - } - if (name.startsWith("publish")) { - signingTasks.forEach { signTask -> - dependsOn(signTask) - } - } - } - } + afterEvaluate { + val signingTasks = filter { it.name.startsWith("sign") } + all { + // lets bruteforce this until the plugins play along nicely again + + if (name.contains("compile", true) && name.contains("kotlin", true)) { + dependsOn("createJsEnvHack") + } + if (name.startsWith("publish")) { + signingTasks.forEach { signTask -> + dependsOn(signTask) + } + } + } + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 3511839..65fccfb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,16 +17,18 @@ dependencyResolutionManagement { versionCatalogs { create("libs") { version("android-tools-gradle", "8.1.0") - version("kotlin", "1.9.10") - version("ktor", "2.3.5") + version("kotlin", "2.1.20") + version("ktor", "3.1.2") library("ktor-client-core", "io.ktor", "ktor-client-core").versionRef("ktor") library("ktor-client-android", "io.ktor", "ktor-client-android").versionRef("ktor") library("ktor-client-darwin", "io.ktor", "ktor-client-darwin-legacy").versionRef("ktor") library("ktor-client-jvm", "io.ktor", "ktor-client-java").versionRef("ktor") library("ktor-client-js", "io.ktor", "ktor-client-js").versionRef("ktor") - library("kotlinx-coroutines", "org.jetbrains.kotlinx", "kotlinx-coroutines-core").version("1.7.2") - library("kotlinx-serialization", "org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.5.1") + library("ktor-client-cio", "io.ktor", "ktor-client-cio").versionRef("ktor") + library("kotlinx-coroutines", "org.jetbrains.kotlinx", "kotlinx-coroutines-core").version("1.10.2") + library("kotlinx-serialization", "org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.8.1") + library("kotlinx-browser", "org.jetbrains.kotlinx", "kotlinx-browser").version("0.3") library("androidx-test-core", "androidx.test", "core").version("1.2.0") library("roboelectric", "org.robolectric", "robolectric").version("4.9") library("opt-java", "com.github.bastiaanjansen", "otp-java").version("1.3.2") diff --git a/src/wasmJsMain/kotlin/com/liftric/cognito/idp/core/Engine.kt b/src/wasmJsMain/kotlin/com/liftric/cognito/idp/core/Engine.kt new file mode 100644 index 0000000..c9c0c2f --- /dev/null +++ b/src/wasmJsMain/kotlin/com/liftric/cognito/idp/core/Engine.kt @@ -0,0 +1,7 @@ +package com.liftric.cognito.idp.core + +import io.ktor.client.engine.* +import io.ktor.client.engine.cio.* + +actual val Engine: HttpClientEngine + get() = CIO.create() \ No newline at end of file diff --git a/src/wasmJsMain/kotlin/com/liftric/cognito/idp/jwt/Base64.kt b/src/wasmJsMain/kotlin/com/liftric/cognito/idp/jwt/Base64.kt new file mode 100644 index 0000000..3fd70d2 --- /dev/null +++ b/src/wasmJsMain/kotlin/com/liftric/cognito/idp/jwt/Base64.kt @@ -0,0 +1,28 @@ +package com.liftric.cognito.idp.jwt + +import kotlinx.browser.window + +internal actual class Base64 { + actual companion object { + actual fun decode(input: String): String? { + // Validate the input to ensure it is proper Base64 + if (!input.matches(Regex("^[A-Za-z0-9+/]*={0,2}\$"))) { + return null + } + + return try { + // Decode using the browser's atob function + val decoded = window.atob(input) + + // Re-encode the result to compare with input (remove padding) + val reencoded = window.btoa(decoded) + .replace(Regex("=+\$"), "") + + if (input.replace(Regex("=+\$"), "") != reencoded) null else decoded + } catch (e: Throwable) { + // Return null if decoding fails + null + } + } + } +} \ No newline at end of file From bbc5b1827ae325774d8d80c271937221ff230d99 Mon Sep 17 00:00:00 2001 From: EpicSquid Date: Tue, 29 Apr 2025 08:43:07 +1000 Subject: [PATCH 2/5] Fixed tab vs space indentation --- build.gradle.kts | 660 +++++++++++++++++++++++------------------------ 1 file changed, 330 insertions(+), 330 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7858595..426723f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,383 +7,383 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTes import org.jetbrains.kotlin.gradle.tasks.* plugins { - kotlin("multiplatform") version libs.versions.kotlin - alias(libs.plugins.kotlin.serialization) - id("com.android.library") version libs.versions.android.tools.gradle - alias(libs.plugins.definitions) - alias(libs.plugins.npm.publishing) - alias(libs.plugins.versioning) - alias(libs.plugins.vault.client) - id("maven-publish") - id("signing") + kotlin("multiplatform") version libs.versions.kotlin + alias(libs.plugins.kotlin.serialization) + id("com.android.library") version libs.versions.android.tools.gradle + alias(libs.plugins.definitions) + alias(libs.plugins.npm.publishing) + alias(libs.plugins.versioning) + alias(libs.plugins.vault.client) + id("maven-publish") + id("signing") } repositories { - mavenCentral() - google() - gradlePluginPortal() + mavenCentral() + google() + gradlePluginPortal() } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } kotlin { - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { - it.binaries.framework() - } - - androidTarget() { - publishAllLibraryVariants() - } - jvm() - js(IR) { - generateTypeScriptDefinitions() - browser { - testTask { - useMocha { - timeout = "10s" - } - } - } - binaries.library() - compilations.all { - compileTaskProvider.configure { - compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false") - } - } - } - wasmJs { - browser() - binaries.library() - } - - sourceSets { - val commonMain by getting { - dependencies { - api(libs.ktor.client.core) - api(libs.kotlinx.coroutines) - api(libs.kotlinx.serialization) - } - } - val commonTest by getting { - kotlin.srcDir("${buildDir}/gen") - dependencies { - implementation(kotlin("test")) - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } - } - val androidMain by getting { - dependencies { - api(libs.ktor.client.android) - } - } - val jvmMain by getting { - dependencies { - api(libs.ktor.client.jvm) - } - } - val androidUnitTest by getting { - dependencies { - implementation(libs.roboelectric) - implementation(kotlin("test")) - implementation(kotlin("test-junit")) - implementation(libs.androidx.test.core) - implementation(libs.opt.java) - } - } - val jvmTest by getting { - dependencies { - implementation(kotlin("test")) - implementation(kotlin("test-junit")) - implementation(libs.opt.java) - } - } - iosMain.dependencies { - api(libs.ktor.client.darwin) - } - val jsMain by getting { - dependencies { - api(libs.ktor.client.js) - } - } - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - val wasmJsMain by getting { - dependencies { - api(libs.ktor.client.cio) - api(libs.kotlinx.browser) - } - } - all { - languageSettings { - optIn("kotlinx.serialization.ExperimentalSerializationApi") - optIn("kotlin.js.ExperimentalJsExport") - optIn("kotlin.RequiresOptIn") - } - } - } + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { + it.binaries.framework() + } + + androidTarget() { + publishAllLibraryVariants() + } + jvm() + js(IR) { + generateTypeScriptDefinitions() + browser { + testTask { + useMocha { + timeout = "10s" + } + } + } + binaries.library() + compilations.all { + compileTaskProvider.configure { + compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false") + } + } + } + wasmJs { + browser() + binaries.library() + } + + sourceSets { + val commonMain by getting { + dependencies { + api(libs.ktor.client.core) + api(libs.kotlinx.coroutines) + api(libs.kotlinx.serialization) + } + } + val commonTest by getting { + kotlin.srcDir("${buildDir}/gen") + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val androidMain by getting { + dependencies { + api(libs.ktor.client.android) + } + } + val jvmMain by getting { + dependencies { + api(libs.ktor.client.jvm) + } + } + val androidUnitTest by getting { + dependencies { + implementation(libs.roboelectric) + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + implementation(libs.androidx.test.core) + implementation(libs.opt.java) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + implementation(libs.opt.java) + } + } + iosMain.dependencies { + api(libs.ktor.client.darwin) + } + val jsMain by getting { + dependencies { + api(libs.ktor.client.js) + } + } + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + val wasmJsMain by getting { + dependencies { + api(libs.ktor.client.cio) + api(libs.kotlinx.browser) + } + } + all { + languageSettings { + optIn("kotlinx.serialization.ExperimentalSerializationApi") + optIn("kotlin.js.ExperimentalJsExport") + optIn("kotlin.RequiresOptIn") + } + } + } } configure { - defaultConfig.apply { - compileSdk = 30 - minSdkVersion(21) - targetSdkVersion(30) - testInstrumentationRunner = "org.robolectric.RobolectricTestRunner" - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - testOptions { - unitTests.apply { - isIncludeAndroidResources = true - isReturnDefaultValues = true - } - } - - namespace = "com.liftric.cognito.idp" - - publishing { - multipleVariants { - allVariants() - withJavadocJar() - } - } + defaultConfig.apply { + compileSdk = 30 + minSdkVersion(21) + targetSdkVersion(30) + testInstrumentationRunner = "org.robolectric.RobolectricTestRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + testOptions { + unitTests.apply { + isIncludeAndroidResources = true + isReturnDefaultValues = true + } + } + + namespace = "com.liftric.cognito.idp" + + publishing { + multipleVariants { + allVariants() + withJavadocJar() + } + } } group = "com.liftric" version = with(versioning.info) { - if (branch == "HEAD" && dirty.not()) tag else full + if (branch == "HEAD" && dirty.not()) tag else full } afterEvaluate { - project.publishing.publications.withType(MavenPublication::class.java).forEach { - it.groupId = group.toString() - } + project.publishing.publications.withType(MavenPublication::class.java).forEach { + it.groupId = group.toString() + } } tasks { - withType(KotlinNativeSimulatorTest::class) { - filter.excludeTestsMatching("com.liftric.cognito.idp.IdentityProviderClientTests") - } - - val testSecrets by creating(GetVaultSecretTask::class) { - secretPath.set("secret/apps/smartest/shared/cognito") - } - - val createJsEnvHack by creating { - outputs.dir("$buildDir/gen") - - if (System.getenv("region") == null || System.getenv("clientId") == null) { - // github ci provides region and clientId envs, locally we'll use vault directly - dependsOn(testSecrets) - } - - doFirst { - val (clientId, region) = with(testSecrets.secret.get()) { - ((System.getenv("clientId") ?: this["client_id_dev"].toString()) to - (System.getenv("region") ?: this["client_region_dev"].toString())) - } - - mkdir("$buildDir/gen") - with(File("$buildDir/gen/env.kt")) { - createNewFile() - writeText( - """ + withType(KotlinNativeSimulatorTest::class) { + filter.excludeTestsMatching("com.liftric.cognito.idp.IdentityProviderClientTests") + } + + val testSecrets by creating(GetVaultSecretTask::class) { + secretPath.set("secret/apps/smartest/shared/cognito") + } + + val createJsEnvHack by creating { + outputs.dir("$buildDir/gen") + + if (System.getenv("region") == null || System.getenv("clientId") == null) { + // github ci provides region and clientId envs, locally we'll use vault directly + dependsOn(testSecrets) + } + + doFirst { + val (clientId, region) = with(testSecrets.secret.get()) { + ((System.getenv("clientId") ?: this["client_id_dev"].toString()) to + (System.getenv("region") ?: this["client_region_dev"].toString())) + } + + mkdir("$buildDir/gen") + with(File("$buildDir/gen/env.kt")) { + createNewFile() + writeText( + """ val env = mapOf( "region" to "$region", "clientId" to "$clientId", ) """.trimIndent() - ) - } - } - } - - withType { - dependsOn(createJsEnvHack) - } - - withType { - kotlinOptions { - jvmTarget = "11" - languageVersion = "2.1" - freeCompilerArgs = listOf( - "-Xinline-classes" - ) - } - } - - /** - * Ugly atomicfu export hack: Coroutines core needs atomicfu-js, which generates broken d.ts entries. Excluding - * atomicfu-js breaks the ktor client and filtering d.ts types in the IR compile is currently not possible... so let's - * just rip it out after the fact - * - * The build/js/packages/cognito-idp/kotlin/cognito-idp.d.ts file should now be without errors and usable from typescript - */ - val cleanTypescriptTypes by creating { - fun MutableList.removeFromTill(from: String, till: String) { - val fromIndex = indexOfFirst { it == from } - val tillIndex = indexOfFirst { it == till } - if (fromIndex == -1 || tillIndex == -1) { - println("looks like from='$from' till='$till' already scraped") - return - } - println("removeFromTill from='$from' till='$till' fromIndex=$fromIndex") - println("removeFromTill from='$from' till='$till' tillIndex=$tillIndex") - (fromIndex..tillIndex).forEach { - removeAt(fromIndex) - } - } - - val dTsFile = file("$buildDir/js/packages/cognito-idp/kotlin/cognito-idp.d.ts") - inputs.file(dTsFile) - outputs.file(dTsFile) - - doLast { - val dTs = dTsFile.readLines().toMutableList() - dTs.removeFromTill("export namespace kotlinx.atomicfu {", "}") - dTs.removeFromTill("export namespace io.ktor.util {", "}") - dTsFile.writeText(dTs.joinToString("\n")) - } - } - val jsBrowserProductionLibraryDistribution by existing { - finalizedBy(cleanTypescriptTypes) - } - val jsProductionLibraryCompileSync by existing { - finalizedBy(cleanTypescriptTypes) - } + ) + } + } + } + + withType { + dependsOn(createJsEnvHack) + } + + withType { + kotlinOptions { + jvmTarget = "11" + languageVersion = "2.1" + freeCompilerArgs = listOf( + "-Xinline-classes" + ) + } + } + + /** + * Ugly atomicfu export hack: Coroutines core needs atomicfu-js, which generates broken d.ts entries. Excluding + * atomicfu-js breaks the ktor client and filtering d.ts types in the IR compile is currently not possible... so let's + * just rip it out after the fact + * + * The build/js/packages/cognito-idp/kotlin/cognito-idp.d.ts file should now be without errors and usable from typescript + */ + val cleanTypescriptTypes by creating { + fun MutableList.removeFromTill(from: String, till: String) { + val fromIndex = indexOfFirst { it == from } + val tillIndex = indexOfFirst { it == till } + if (fromIndex == -1 || tillIndex == -1) { + println("looks like from='$from' till='$till' already scraped") + return + } + println("removeFromTill from='$from' till='$till' fromIndex=$fromIndex") + println("removeFromTill from='$from' till='$till' tillIndex=$tillIndex") + (fromIndex..tillIndex).forEach { + removeAt(fromIndex) + } + } + + val dTsFile = file("$buildDir/js/packages/cognito-idp/kotlin/cognito-idp.d.ts") + inputs.file(dTsFile) + outputs.file(dTsFile) + + doLast { + val dTs = dTsFile.readLines().toMutableList() + dTs.removeFromTill("export namespace kotlinx.atomicfu {", "}") + dTs.removeFromTill("export namespace io.ktor.util {", "}") + dTsFile.writeText(dTs.joinToString("\n")) + } + } + val jsBrowserProductionLibraryDistribution by existing { + finalizedBy(cleanTypescriptTypes) + } + val jsProductionLibraryCompileSync by existing { + finalizedBy(cleanTypescriptTypes) + } } val ossrhUsername: String? by project val ossrhPassword: String? by project val javadocJar by tasks.registering(Jar::class) { - archiveClassifier.set("javadoc") + archiveClassifier.set("javadoc") } publishing { - repositories { - maven { - name = "sonatype" - setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") - credentials { - username = ossrhUsername - password = ossrhPassword - } - } - } - - publications.withType { - artifact(javadocJar.get()) - - pom { - name.set(project.name) - description.set("Lightweight AWS Cognito Identity Provider client for Kotlin Multiplatform projects.") - url.set("https://github.com/liftric/cognito-idp") - - licenses { - license { - name.set("MIT") - url.set("https://github.com/liftric/cognito-idp/blob/master/LICENSE") - } - } - developers { - developer { - id.set("benjohnde") - name.set("Ben John") - email.set("john@liftric.com") - } - developer { - id.set("ingwersaft") - name.set("Marcel Kesselring") - email.set("kesselring@liftric.com") - } - } - scm { - url.set("https://github.com/liftric/cognito-idp") - } - } - } + repositories { + maven { + name = "sonatype" + setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials { + username = ossrhUsername + password = ossrhPassword + } + } + } + + publications.withType { + artifact(javadocJar.get()) + + pom { + name.set(project.name) + description.set("Lightweight AWS Cognito Identity Provider client for Kotlin Multiplatform projects.") + url.set("https://github.com/liftric/cognito-idp") + + licenses { + license { + name.set("MIT") + url.set("https://github.com/liftric/cognito-idp/blob/master/LICENSE") + } + } + developers { + developer { + id.set("benjohnde") + name.set("Ben John") + email.set("john@liftric.com") + } + developer { + id.set("ingwersaft") + name.set("Marcel Kesselring") + email.set("kesselring@liftric.com") + } + } + scm { + url.set("https://github.com/liftric/cognito-idp") + } + } + } } val npmAccessKey: String? by project npmPublish { - organization.set("liftric") - access.set(PUBLIC) - readme.set(rootProject.file("README.md")) - - packages { - named("js") { - packageName.set(project.name) - packageJson { - keywords.set( - listOf( - "kotlin", - "cognito", - "identity-provider", - "liftric", - "aws" - ) - ) - license.set("MIT") - description.set("Lightweight AWS Cognito Identity Provider client.") - homepage.set("https://github.com/liftric/cognito-idp") - } - } - } - - registries { - npmjs { - uri.set(uri("https://registry.npmjs.org")) - authToken.set(npmAccessKey) - } - } + organization.set("liftric") + access.set(PUBLIC) + readme.set(rootProject.file("README.md")) + + packages { + named("js") { + packageName.set(project.name) + packageJson { + keywords.set( + listOf( + "kotlin", + "cognito", + "identity-provider", + "liftric", + "aws" + ) + ) + license.set("MIT") + description.set("Lightweight AWS Cognito Identity Provider client.") + homepage.set("https://github.com/liftric/cognito-idp") + } + } + } + + registries { + npmjs { + uri.set(uri("https://registry.npmjs.org")) + authToken.set(npmAccessKey) + } + } } signing { - val signingKey: String? by project - val signingPassword: String? by project - useInMemoryPgpKeys(signingKey, signingPassword) - sign(publishing.publications) + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications) } vault { - vaultAddress.set("https://dark-lord.liftric.io") - if (System.getenv("CI") == null) { - vaultTokenFilePath.set("${System.getProperty("user.home")}/.vault-token") - } else { - vaultToken.set(System.getenv("VAULT_TOKEN")) - } + vaultAddress.set("https://dark-lord.liftric.io") + if (System.getenv("CI") == null) { + vaultTokenFilePath.set("${System.getProperty("user.home")}/.vault-token") + } else { + vaultToken.set(System.getenv("VAULT_TOKEN")) + } } tasks { - afterEvaluate { - val signingTasks = filter { it.name.startsWith("sign") } - all { - // lets bruteforce this until the plugins play along nicely again - - if (name.contains("compile", true) && name.contains("kotlin", true)) { - dependsOn("createJsEnvHack") - } - if (name.startsWith("publish")) { - signingTasks.forEach { signTask -> - dependsOn(signTask) - } - } - } - } + afterEvaluate { + val signingTasks = filter { it.name.startsWith("sign") } + all { + // lets bruteforce this until the plugins play along nicely again + + if (name.contains("compile", true) && name.contains("kotlin", true)) { + dependsOn("createJsEnvHack") + } + if (name.startsWith("publish")) { + signingTasks.forEach { signTask -> + dependsOn(signTask) + } + } + } + } } From 637bc6436321c1700bb8d8e64e84783053db43e7 Mon Sep 17 00:00:00 2001 From: EpicSquid Date: Fri, 16 May 2025 10:25:34 +1000 Subject: [PATCH 3/5] Updated upload-artifact@v4 to fix issues with the pipeline --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac29368..184b2b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: xcodebuild clean test -project TestApp.xcodeproj -scheme TestApp -destination "platform=iOS Simulator,OS=16.2,name=iPhone 12" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO region=${{ secrets.region }} clientId=${{ secrets.clientid }} - name: Upload test result if: ${{ always() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: reports path: build/reports/ From 830767ef5e3455ace9ff18fb3834c557283ee553 Mon Sep 17 00:00:00 2001 From: EpicSquid Date: Mon, 19 May 2025 11:58:23 +1000 Subject: [PATCH 4/5] Build now works Updates include: - Gradle updated to use libs.version.toml for consistency with gradle standards - Removed NPM publish plugin as it is no longer maintained and is incompatible with kotlin wasm - Removed JsExport annotations as they are not compatible with wasm (which has different export restrictions). - Updated some dependencies --- build.gradle.kts | 58 +++++-------------- gradle.properties | 1 - gradle/libs.versions.toml | 37 ++++++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 36 +----------- .../com/liftric/cognito/idp/core/Payload.kt | 4 +- .../com/liftric/cognito/idp/core/Response.kt | 20 +++---- src/jsMain/kotlin/ResponseJS.kt | 8 +-- .../idp/IdentityProviderClientTests.kt | 6 +- 9 files changed, 72 insertions(+), 100 deletions(-) create mode 100644 gradle/libs.versions.toml diff --git a/build.gradle.kts b/build.gradle.kts index 426723f..2bb3544 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,11 +7,9 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTes import org.jetbrains.kotlin.gradle.tasks.* plugins { - kotlin("multiplatform") version libs.versions.kotlin + alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.kotlin.serialization) - id("com.android.library") version libs.versions.android.tools.gradle - alias(libs.plugins.definitions) - alias(libs.plugins.npm.publishing) + alias(libs.plugins.android.library) alias(libs.plugins.versioning) alias(libs.plugins.vault.client) id("maven-publish") @@ -19,14 +17,14 @@ plugins { } repositories { - mavenCentral() google() + mavenCentral() gradlePluginPortal() } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlin { @@ -38,7 +36,7 @@ kotlin { it.binaries.framework() } - androidTarget() { + androidTarget { publishAllLibraryVariants() } jvm() @@ -59,8 +57,13 @@ kotlin { } } wasmJs { - browser() + browser () binaries.library() + compilations.all { + compileTaskProvider.configure { + compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false") + } + } } sourceSets { @@ -136,7 +139,7 @@ kotlin { configure { defaultConfig.apply { - compileSdk = 30 + compileSdk = 35 minSdkVersion(21) targetSdkVersion(30) testInstrumentationRunner = "org.robolectric.RobolectricTestRunner" @@ -320,41 +323,6 @@ publishing { } } -val npmAccessKey: String? by project - -npmPublish { - organization.set("liftric") - access.set(PUBLIC) - readme.set(rootProject.file("README.md")) - - packages { - named("js") { - packageName.set(project.name) - packageJson { - keywords.set( - listOf( - "kotlin", - "cognito", - "identity-provider", - "liftric", - "aws" - ) - ) - license.set("MIT") - description.set("Lightweight AWS Cognito Identity Provider client.") - homepage.set("https://github.com/liftric/cognito-idp") - } - } - } - - registries { - npmjs { - uri.set(uri("https://registry.npmjs.org")) - authToken.set(npmAccessKey) - } - } -} - signing { val signingKey: String? by project val signingPassword: String? by project diff --git a/gradle.properties b/gradle.properties index 6d6a4e8..4b22d93 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,5 @@ kotlin.incremental=true kotlin.incremental.multiplatform=true kotlin.caching.enabled=true kotlin.code.style=official -kotlin.js.generate.externals=true kotlin.native.binary.memoryModel=experimental kotlin.js.ir.output.granularity=whole-program diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..f9ffc7c --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,37 @@ +[versions] +android-tools-gradle = "8.9.3" +kotlin = "2.1.20" +ktor = "3.1.3" +kotlinx-coroutines = "1.10.2" +kotlinx-serialization = "1.8.1" +kotlinx-browser = "0.3" +androidx-test-core = "1.6.1" +roboelectric = "4.9" +opt-java = "1.3.2" +vault-client = "2.0.0" +versioning = "3.1.0" +npm-publishing = "3.5.3" +definitions = "5.124.0" + +[libraries] +ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" } +ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" } +ktor-client-darwin = { group = "io.ktor", name = "ktor-client-darwin-legacy", version.ref = "ktor" } +ktor-client-jvm = { group = "io.ktor", name = "ktor-client-java", version.ref = "ktor" } +ktor-client-js = { group = "io.ktor", name = "ktor-client-js", version.ref = "ktor" } +ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } +kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +kotlinx-browser = { group = "org.jetbrains.kotlinx", name = "kotlinx-browser", version.ref = "kotlinx-browser" } +androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidx-test-core" } +roboelectric = { group = "org.robolectric", name = "robolectric", version.ref = "roboelectric" } +opt-java = { group = "com.github.bastiaanjansen", name = "otp-java", version.ref = "opt-java" } + +[plugins] +vault-client = { id = "com.liftric.vault-client-plugin", version.ref = "vault-client" } +versioning = { id = "net.nemerosa.versioning", version.ref = "versioning" } +npm-publishing = { id = "dev.petuska.npm.publish", version.ref = "npm-publishing" } +definitions = { id = "io.github.turansky.kfc.definitions", version.ref = "definitions" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +android-library = { id = "com.android.library", version.ref = "android-tools-gradle" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 27313fb..c6406bc 100644 --- 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-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 65fccfb..15af1fc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,38 +6,4 @@ pluginManagement { mavenCentral() gradlePluginPortal() } -} - -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - } - - versionCatalogs { - create("libs") { - version("android-tools-gradle", "8.1.0") - version("kotlin", "2.1.20") - version("ktor", "3.1.2") - - library("ktor-client-core", "io.ktor", "ktor-client-core").versionRef("ktor") - library("ktor-client-android", "io.ktor", "ktor-client-android").versionRef("ktor") - library("ktor-client-darwin", "io.ktor", "ktor-client-darwin-legacy").versionRef("ktor") - library("ktor-client-jvm", "io.ktor", "ktor-client-java").versionRef("ktor") - library("ktor-client-js", "io.ktor", "ktor-client-js").versionRef("ktor") - library("ktor-client-cio", "io.ktor", "ktor-client-cio").versionRef("ktor") - library("kotlinx-coroutines", "org.jetbrains.kotlinx", "kotlinx-coroutines-core").version("1.10.2") - library("kotlinx-serialization", "org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.8.1") - library("kotlinx-browser", "org.jetbrains.kotlinx", "kotlinx-browser").version("0.3") - library("androidx-test-core", "androidx.test", "core").version("1.2.0") - library("roboelectric", "org.robolectric", "robolectric").version("4.9") - library("opt-java", "com.github.bastiaanjansen", "otp-java").version("1.3.2") - - plugin("vault-client", "com.liftric.vault-client-plugin").version("2.0.0") - plugin("versioning", "net.nemerosa.versioning").version("3.0.0") - plugin("npm-publishing", "dev.petuska.npm.publish").version("3.0.0") - plugin("definitions", "io.github.turansky.kfc.definitions").version("5.50.0") - plugin("kotlin.serialization", "org.jetbrains.kotlin.plugin.serialization").versionRef("kotlin") - } - } -} +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/liftric/cognito/idp/core/Payload.kt b/src/commonMain/kotlin/com/liftric/cognito/idp/core/Payload.kt index cc01c4e..f646df9 100644 --- a/src/commonMain/kotlin/com/liftric/cognito/idp/core/Payload.kt +++ b/src/commonMain/kotlin/com/liftric/cognito/idp/core/Payload.kt @@ -86,7 +86,7 @@ internal data class ConfirmForgotPassword( val Password: String ) -@JsExport + @Serializable data class UserAttribute( val Name: String, @@ -134,7 +134,7 @@ internal data class SetUserMFAPreference( val SoftwareTokenMfaSettings: MfaSettings? ) -@JsExport + @Serializable data class MfaSettings( val Enabled: Boolean, diff --git a/src/commonMain/kotlin/com/liftric/cognito/idp/core/Response.kt b/src/commonMain/kotlin/com/liftric/cognito/idp/core/Response.kt index ca61389..fc9a36f 100644 --- a/src/commonMain/kotlin/com/liftric/cognito/idp/core/Response.kt +++ b/src/commonMain/kotlin/com/liftric/cognito/idp/core/Response.kt @@ -22,7 +22,7 @@ data class SignInResponse( val Session: String? ) -@JsExport + @Serializable data class AuthenticationResult( val AccessToken: String?, @@ -33,14 +33,14 @@ data class AuthenticationResult( val NewDeviceMetadata: NewDeviceMetadata?, ) -@JsExport + @Serializable data class NewDeviceMetadata( val DeviceGroupKey: String?, val DeviceKey: String?, ) -@JsExport + @Serializable data class SignUpResponse( val CodeDeliveryDetails: CodeDeliveryDetails?, @@ -48,13 +48,13 @@ data class SignUpResponse( val UserSub: String ) -@JsExport + @Serializable data class ResendConfirmationCodeResponse( val CodeDeliveryDetails: CodeDeliveryDetails ) -@JsExport + @Serializable data class CodeDeliveryDetails( val AttributeName: String?, @@ -71,7 +71,7 @@ data class GetUserResponse( val Username: String ) -@JsExport + @Serializable data class MFAOptions( val AttributeName: String?, @@ -83,26 +83,26 @@ data class UpdateUserAttributesResponse( val CodeDeliveryDetailsList: List = listOf() ) -@JsExport + @Serializable data class GetAttributeVerificationCodeResponse( val CodeDeliveryDetails: CodeDeliveryDetails ) -@JsExport + @Serializable data class ForgotPasswordResponse( val CodeDeliveryDetails: CodeDeliveryDetails ) -@JsExport + @Serializable data class AssociateSoftwareTokenResponse( val SecretCode: String, val Session: String? ) -@JsExport + @Serializable data class VerifySoftwareTokenResponse( val Session: String?, diff --git a/src/jsMain/kotlin/ResponseJS.kt b/src/jsMain/kotlin/ResponseJS.kt index 61006bd..1da347a 100644 --- a/src/jsMain/kotlin/ResponseJS.kt +++ b/src/jsMain/kotlin/ResponseJS.kt @@ -4,7 +4,7 @@ import com.liftric.cognito.idp.core.* * Adapted [Response.kt] classes for Typescript usage (Map and List aren't compatible for [kotlin.js.JsExport]) */ -@JsExport + data class SignInResponseJS( val AuthenticationResult: AuthenticationResult?, val ChallengeParameters: Array, @@ -30,7 +30,7 @@ data class SignInResponseJS( } } -@JsExport + data class GetUserResponseJS( val MFAOptions: MFAOptions?, val PreferredMfaSetting: String?, @@ -63,7 +63,7 @@ data class GetUserResponseJS( } } -@JsExport + data class UpdateUserAttributesResponseJS( val CodeDeliveryDetailsList: Array = arrayOf() ) { @@ -83,7 +83,7 @@ data class UpdateUserAttributesResponseJS( } } -@JsExport + data class MapEntry(val key: String, val value: String) internal fun Map.toMapEntries(): Array = entries.map { diff --git a/src/jsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt b/src/jsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt index 5e7bf5e..46cf59a 100644 --- a/src/jsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt +++ b/src/jsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt @@ -5,6 +5,8 @@ import kotlinx.coroutines.promise actual class IdentityProviderClientTests : AbstractIdentityProviderClientTests() -actual fun runTest(block: suspend () -> Unit): dynamic = MainScope().promise { - block.invoke() +actual fun runTest(block: suspend () -> Unit) { + MainScope().promise { + block.invoke() + } } From 1cba25b998c5e0847fe7a6e14a39b7183b2e17b9 Mon Sep 17 00:00:00 2001 From: EpicSquid Date: Mon, 19 May 2025 12:27:26 +1000 Subject: [PATCH 5/5] Added tests matching ios --- .../cognito/idp/IdentityProviderClientTests.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/wasmJsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt diff --git a/src/wasmJsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt b/src/wasmJsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt new file mode 100644 index 0000000..3122c1d --- /dev/null +++ b/src/wasmJsTest/kotlin/com/liftric/cognito/idp/IdentityProviderClientTests.kt @@ -0,0 +1,12 @@ +package com.liftric.cognito.idp + +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.promise + +actual class IdentityProviderClientTests : AbstractIdentityProviderClientTests() + +actual fun runTest(block: suspend () -> Unit) { + MainScope().promise { + block.invoke() + } +}