diff --git a/.gitignore b/.gitignore index 992af4d..acbab95 100644 --- a/.gitignore +++ b/.gitignore @@ -151,3 +151,6 @@ fabric.properties !*/swiftpackage/.git swiftpackage + +.kotlin +.idea \ No newline at end of file diff --git a/README.md b/README.md index 82eeabb..a1d7d98 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The AppAuth-Kotlin SDK is a Kotlin-first SDK for AppAuth. It's API is similar to To install simply add to your common sourceset in the build gradle ```kotlin - implementation("dev.gitlive:appauth-kotlin:0.0.1") + implementation("dev.gitlive:appauth-kotlin:0.1.1") ``` Perform a gradle refresh and you should then be able to import the app auth files. diff --git a/build.gradle.kts b/build.gradle.kts index 3de6153..e07e222 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { - kotlin("multiplatform") version "1.7.20" - kotlin("native.cocoapods") version "1.7.20" + kotlin("multiplatform") version "2.1.21" + kotlin("native.cocoapods") version "2.1.21" id("com.android.library") - id("io.github.luca992.multiplatform-swiftpackage") version "2.0.5-arm64" - id("org.jlleitschuh.gradle.ktlint") version "11.0.0" + id("io.github.luca992.multiplatform-swiftpackage") version "2.2.4" + id("org.jlleitschuh.gradle.ktlint") version "12.2.0" id("org.jetbrains.kotlinx.kover") version "0.6.1" `maven-publish` signing @@ -31,72 +31,56 @@ kover { } kotlin { - android { + androidTarget { publishAllLibraryVariants() } - js(BOTH) { + js(IR) { browser { } } val xcf = XCFramework() - iosSimulatorArm64 { - binaries.framework { - baseName = MODULE_NAME - xcf.add(this) - } - } - ios { - binaries.framework { + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { iosTarget -> + iosTarget.binaries.framework { baseName = MODULE_NAME xcf.add(this) + isStatic = true } } sourceSets { - val commonMain by getting { - dependencies { - implementation("io.ktor:ktor-utils:2.1.3") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") - } + commonMain.dependencies { + implementation("io.ktor:ktor-utils:3.1.3") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") + implementation("io.github.aakira:napier:2.7.1") // or latest } - val commonTest by getting { - dependencies { - implementation(kotlin("test")) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") - } + + commonTest.dependencies { + implementation(kotlin("test")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2") } - val jsMain by getting - val jsTest by getting - val iosMain by getting {} - val iosSimulatorArm64Main by getting - iosSimulatorArm64Main.dependsOn(iosMain) - val iosTest by getting - val iosSimulatorArm64Test by getting - iosSimulatorArm64Test.dependsOn(iosTest) + jsMain.dependencies {} - val androidMain by getting { - dependencies { - implementation("net.openid:appauth:0.11.1") - } - } - val androidTest by getting { - dependencies { - implementation("junit:junit:4.13.2") - } + iosMain.dependencies {} + + + androidMain.dependencies { + implementation("net.openid:appauth:0.11.1") } } } android { - compileSdk = 31 - buildToolsVersion = "30.0.3" + compileSdk = 35 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { minSdk = 23 - targetSdk = 31 manifestPlaceholders += "appAuthRedirectScheme" to "dev.gitlive" } buildTypes { @@ -109,20 +93,15 @@ android { isIncludeAndroidResources = true } } + namespace = MODULE_PACKAGE_NAME } kotlin { cocoapods { ios.deploymentTarget = "7.0" - framework { - isStatic = true - } + noPodspec() - pod("AppAuth") { - source = git("https://github.com/philet/AppAuth-iOS.git") { - branch = "endsession-request-nullability" - } - } + pod("AppAuth") } } @@ -135,7 +114,7 @@ multiplatformSwiftPackage { } ktlint { - version.set("0.43.0") + version.set("0.50.0") } fun SigningExtension.whenRequired(block: () -> Boolean) { @@ -159,12 +138,14 @@ publishing { val PUBLISH_SCM_DEVELOPERCONNECTION: String by project repositories { - maven { - url = uri(OPEN_SOURCE_REPO) - - credentials { - username = System.getenv("sonatypeUsername") - password = System.getenv("sonatypePassword") + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/yet300/AppAuth-Kotlin") + credentials { + username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") + password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN") + } } } } diff --git a/gradle.properties b/gradle.properties index e5f73cb..ad01308 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,8 +15,11 @@ kotlin.mpp.enableCInteropCommonization=true signing.keyId="" signing.password="" +gpr.user=yet300 +gpr.key=todo + MODULE_PACKAGE_NAME=dev.gitlive -MODULE_VERSION_NUMBER=0.0.2 +MODULE_VERSION_NUMBER=0.1.2 MODULE_NAME=appauth-kotlin OPEN_SOURCE_REPO=https://oss.sonatype.org/service/local/staging/deploy/maven2/ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..e33925b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu May 22 11:49:06 GET 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 9af5c5d..91ce1a5 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -12,239 +12,216 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== dependencies: - "@jridgewell/set-array" "^1.0.1" + "@jridgewell/set-array" "^1.2.1" "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== -"@types/cookie@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" - integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== - "@types/cors@^2.8.12": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.4.10" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" - integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.5": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== -"@types/json-schema@*", "@types/json-schema@^7.0.8": +"@types/json-schema@^7.0.8": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/node@*", "@types/node@>=10.0.0": version "18.11.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.12.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== + dependencies: + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== + +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== + +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== + +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" + +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== + dependencies: + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== +"@webpack-cli/configtest@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== -"@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" +"@webpack-cli/info@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== -"@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== +"@webpack-cli/serve@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -256,11 +233,6 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abab@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - accepts@~1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -269,21 +241,35 @@ accepts@~1.3.4: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== + +acorn@^8.14.0, acorn@^8.7.1: + version "8.14.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" + integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== -acorn@^8.4.1, acorn@^8.5.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -294,10 +280,20 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ajv@^8.0.0, ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-regex@^5.0.1: version "5.0.1" @@ -379,20 +375,20 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browser-stdout@1.3.1: +browser-stdout@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.14.5: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.21.10: + version "4.25.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c" + integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001718" + electron-to-chromium "^1.5.160" + node-releases "^2.0.19" + update-browserslist-db "^1.1.3" buffer-from@^1.0.0: version "1.1.2" @@ -417,10 +413,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001434" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz#ec1ec1cfb0a93a34a0600d37903853030520a4e5" - integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA== +caniuse-lite@^1.0.30001718: + version "1.0.30001721" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz#36b90cd96901f8c98dd6698bf5c8af7d4c6872d7" + integrity sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ== chalk@^4.1.0: version "4.1.2" @@ -430,7 +426,7 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.3, chokidar@^3.5.1: +chokidar@^3.5.1: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -445,6 +441,21 @@ chokidar@3.5.3, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.2" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -485,16 +496,16 @@ colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -515,10 +526,10 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -cookie@~0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@~0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== cors@~2.8.5: version "2.8.5" @@ -554,13 +565,27 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^4.3.5: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== + dependencies: + ms "^2.1.3" + +debug@~4.3.4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -581,10 +606,10 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== dom-serialize@^2.2.1: version "2.2.1" @@ -601,10 +626,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.5.160: + version "1.5.165" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz#477b0957e42f071905a86f7c905a9848f95d2bdb" + integrity sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw== emoji-regex@^8.0.0: version "8.0.0" @@ -616,33 +641,32 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -engine.io-parser@~5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" - integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== +engine.io-parser@~5.2.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f" + integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q== -engine.io@~6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.1.tgz#e3f7826ebc4140db9bbaa9021ad6b1efb175878f" - integrity sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA== +engine.io@~6.6.0: + version "6.6.4" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.6.4.tgz#0a89a3e6b6c1d4b0c2a2a637495e7c149ec8d8ee" + integrity sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g== dependencies: - "@types/cookie" "^0.4.1" "@types/cors" "^2.8.12" "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "2.0.0" - cookie "~0.4.1" + cookie "~0.7.2" cors "~2.8.5" debug "~4.3.1" - engine.io-parser "~5.0.3" - ws "~8.2.3" + engine.io-parser "~5.2.1" + ws "~8.17.1" -enhanced-resolve@^5.9.3: - version "5.11.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.11.0.tgz#543cf6c847a85adba0c4a5e2170bded4d493919a" - integrity sha512-0Gcraf7gAJSQoPg+bTSXNhuzAYtXqLc4C011vb8S3B8XUSEkGYNBk20c68X9291VF4vvsCD8SPkr6Mza+DwU+g== +enhanced-resolve@^5.17.1: + version "5.18.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== dependencies: - graceful-fs "^4.2.9" + graceful-fs "^4.2.4" tapable "^2.2.0" ent@~2.2.0: @@ -655,22 +679,27 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@4.0.0: +escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -715,7 +744,7 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -725,6 +754,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-uri@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" + integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== + fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -750,14 +784,6 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -766,6 +792,14 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -781,7 +815,7 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -format-util@1.0.5: +format-util@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== @@ -810,6 +844,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -836,35 +875,39 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@^7.1.3, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.7: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== +glob@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.1.1" + minimatch "^5.0.1" once "^1.3.0" - path-is-absolute "^1.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -882,7 +925,14 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -he@1.2.0: +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -942,10 +992,10 @@ inherits@2, inherits@2.0.4: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== is-binary-path@~2.1.0: version "2.1.0" @@ -954,12 +1004,12 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: - has "^1.0.3" + hasown "^2.0.2" is-extglob@^2.1.1: version "2.1.1" @@ -1024,7 +1074,7 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -js-yaml@4.1.0: +js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -1041,6 +1091,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1048,10 +1103,10 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -karma-chrome-launcher@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" - integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== +karma-chrome-launcher@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz#eb9c95024f2d6dfbb3748d3415ac9b381906b9a9" + integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== dependencies: which "^1.2.1" @@ -1062,26 +1117,26 @@ karma-mocha@2.0.1: dependencies: minimist "^1.2.3" -karma-sourcemap-loader@0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" - integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== +karma-sourcemap-loader@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== dependencies: - graceful-fs "^4.1.2" + graceful-fs "^4.2.10" -karma-webpack@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" - integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== +karma-webpack@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.1.tgz#4eafd31bbe684a747a6e8f3e4ad373e53979ced4" + integrity sha512-oo38O+P3W2mSPCSUrQdySSPv1LvPpXP+f+bBimNomS5sW+1V4SuhCuW8TfJzV+rDv921w2fDSDw0xJbPe6U+kQ== dependencies: glob "^7.1.3" - minimatch "^3.0.4" + minimatch "^9.0.3" webpack-merge "^4.1.5" -karma@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" - integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== +karma@6.4.4: + version "6.4.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.4.tgz#dfa5a426cf5a8b53b43cd54ef0d0d09742351492" + integrity sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w== dependencies: "@colors/colors" "1.5.0" body-parser "^1.19.0" @@ -1102,7 +1157,7 @@ karma@6.4.0: qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" - socket.io "^4.4.1" + socket.io "^4.7.2" source-map "^0.6.1" tmp "^0.2.1" ua-parser-js "^0.7.30" @@ -1113,6 +1168,13 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +kotlin-web-helpers@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-2.0.0.tgz#b112096b273c1e733e0b86560998235c09a19286" + integrity sha512-xkVGl60Ygn/zuLkDPx+oHj7jeLR7hCvoNF99nhwXMn8a3ApB4lLiC9pk4ol4NHPjyoCbvQctBqvzUcp8pkqyWw== + dependencies: + format-util "^1.0.5" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -1137,7 +1199,7 @@ lodash@^4.17.15, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0: +log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -1183,13 +1245,6 @@ mime@^2.5.2: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1197,6 +1252,20 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1, minimatch@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.3: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.3, minimist@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" @@ -1209,33 +1278,31 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" - integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" +mocha@10.7.3: + version "10.7.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" + integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^8.1.0" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" ms@2.0.0: version "2.0.0" @@ -1247,16 +1314,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -1267,10 +1329,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1366,10 +1428,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" @@ -1429,18 +1491,23 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== dependencies: - resolve "^1.9.0" + resolve "^1.20.0" require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -1458,12 +1525,12 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.9.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.20.0: + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.16.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -1489,19 +1556,29 @@ safe-buffer@^5.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" -serialize-javascript@6.0.0, serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +schema-utils@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" + integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" @@ -1538,42 +1615,45 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -socket.io-adapter@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" - integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== +socket.io-adapter@~2.5.2: + version "2.5.5" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082" + integrity sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg== + dependencies: + debug "~4.3.4" + ws "~8.17.1" -socket.io-parser@~4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.1.tgz#01c96efa11ded938dcb21cbe590c26af5eff65e5" - integrity sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g== +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== dependencies: "@socket.io/component-emitter" "~3.1.0" debug "~4.3.1" -socket.io@^4.4.1: - version "4.5.3" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.3.tgz#44dffea48d7f5aa41df4a66377c386b953bc521c" - integrity sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg== +socket.io@^4.7.2: + version "4.8.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.8.1.tgz#fa0eaff965cc97fdf4245e8d4794618459f7558a" + integrity sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg== dependencies: accepts "~1.3.4" base64id "~2.0.0" + cors "~2.8.5" debug "~4.3.2" - engine.io "~6.2.0" - socket.io-adapter "~2.4.0" - socket.io-parser "~4.2.0" + engine.io "~6.6.0" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-loader@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.0.tgz#bdc6b118bc6c87ee4d8d851f2d4efcc5abdb2ef5" - integrity sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw== +source-map-loader@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-5.0.0.tgz#f593a916e1cc54471cfc8851b905c8a845fc7e38" + integrity sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA== dependencies: - abab "^2.0.6" iconv-lite "^0.6.3" source-map-js "^1.0.2" @@ -1625,18 +1705,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1644,6 +1717,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -1654,24 +1734,24 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +terser-webpack-plugin@^5.3.10: + version "5.3.14" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" + integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" -terser@^5.14.1: - version "5.15.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c" - integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw== +terser@^5.31.1: + version "5.41.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.41.0.tgz#11646bba11eff72d506fbafbd0086f57173141e1" + integrity sha512-H406eLPXpZbAX14+B8psIuvIr8+3c+2hkuYzpMkoE0ij+NdsVATbA78vb8neA/eqrj7rywa2pIkdmWRsXW6wmw== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.14.0" commander "^2.20.0" source-map-support "~0.5.20" @@ -1702,6 +1782,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typescript@5.5.4: + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== + ua-parser-js@^0.7.30: version "0.7.32" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.32.tgz#cd8c639cdca949e30fa68c44b7813ef13e36d211" @@ -1717,13 +1802,13 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.1" uri-js@^4.2.2: version "4.4.1" @@ -1747,30 +1832,31 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== -watchpack@^2.3.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.4" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -webpack-cli@4.10.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== +webpack-cli@5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" + integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" + "@webpack-cli/configtest" "^2.1.1" + "@webpack-cli/info" "^2.0.2" + "@webpack-cli/serve" "^2.0.5" colorette "^2.0.14" - commander "^7.0.0" + commander "^10.0.1" cross-spawn "^7.0.3" + envinfo "^7.7.3" fastest-levenshtein "^1.0.12" import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" + interpret "^3.1.1" + rechoir "^0.8.0" webpack-merge "^5.7.3" webpack-merge@^4.1.5: @@ -1793,34 +1879,33 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.73.0: - version "5.73.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" +webpack@5.94.0: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== + dependencies: + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" + acorn "^8.7.1" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.1" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" which@^1.2.1: @@ -1842,10 +1927,10 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== wrap-ansi@^7.0.0: version "7.0.0" @@ -1861,27 +1946,22 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@~8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== +ws@~8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: +yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-unparser@2.0.0: +yargs-unparser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== @@ -1891,7 +1971,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0, yargs@^16.1.1: +yargs@^16.1.1, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== diff --git a/settings.gradle.kts b/settings.gradle.kts index 1461494..50902e1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,7 +7,7 @@ pluginManagement { resolutionStrategy { eachPlugin { if (requested.id.namespace == "com.android") { - useModule("com.android.tools.build:gradle:7.0.4") + useModule("com.android.tools.build:gradle:8.5.0") } } } diff --git a/src/androidAndroidTest/AndroidManifest.xml b/src/androidAndroidTest/AndroidManifest.xml deleted file mode 100644 index bd841b1..0000000 --- a/src/androidAndroidTest/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/androidAndroidTest/kotlin/dev/gitlive/appauth/androidAndroidTest.kt b/src/androidAndroidTest/kotlin/dev/gitlive/appauth/androidAndroidTest.kt deleted file mode 100644 index c1e6917..0000000 --- a/src/androidAndroidTest/kotlin/dev/gitlive/appauth/androidAndroidTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -package dev.gitlive.appauth - -import androidx.activity.ComponentActivity -import androidx.lifecycle.Lifecycle -import androidx.test.core.app.launchActivity -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiSelector -import kotlinx.coroutines.CoroutineScope - -actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext - -actual fun simulateSignIn(): Unit = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).run { - UiSelector().run { - findObject(resourceId("username")).run { - click() - setText("MyUsername") - } - findObject(resourceId("password")).run { - click() - setText("MyPassword") - } - findObject(resourceId("login-button")).click() -// wait(Until.findObject(By.text("Send anyway")), 5000).click() - } -} - -class MyActivity : ComponentActivity() - -actual suspend fun CoroutineScope.withAuthorizationService(action: suspend (service: AuthorizationService) -> Unit) { - - val service = AuthorizationService(InstrumentationRegistry.getInstrumentation().targetContext) - - val scenario = launchActivity() - .moveToState(Lifecycle.State.CREATED) - .onActivity { service.bind(it) } - .moveToState(Lifecycle.State.RESUMED) - - action(service) - - scenario.close() -} diff --git a/src/androidMain/AndroidManifest.xml b/src/androidMain/AndroidManifest.xml index 9d4923b..74b7379 100644 --- a/src/androidMain/AndroidManifest.xml +++ b/src/androidMain/AndroidManifest.xml @@ -1,4 +1,3 @@ - + \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt new file mode 100644 index 0000000..e71c32f --- /dev/null +++ b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt @@ -0,0 +1,38 @@ +package dev.gitlive.appauth + +import android.net.Uri + +actual class AuthorizationRequest private constructor(internal val android: net.openid.appauth.AuthorizationRequest) { + actual constructor( + config: AuthorizationServiceConfiguration, + clientId: String, + scopes: List, + responseType: String, + redirectUri: String, + additionalParameters: Map? + ) : this( + net.openid.appauth.AuthorizationRequest.Builder( + config.android, + clientId, + responseType, + Uri.parse(redirectUri), + ) + .setAdditionalParameters(additionalParameters) + .setScopes(scopes) + .build() + ) + override fun toString(): String { + return buildString { + appendLine("AuthorizationRequest(") + appendLine(" clientId: ${android.clientId}") + appendLine(" scope: ${android.scope ?: "None"}") + appendLine(" responseType: ${android.responseType}") + appendLine(" redirectUri: ${android.redirectUri}") + appendLine(" additionalParameters: ${android.additionalParameters ?: "None"}") + appendLine(" config:") + appendLine(" authEndpoint: ${android.configuration.authorizationEndpoint}") + appendLine(" tokenEndpoint: ${android.configuration.tokenEndpoint}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt new file mode 100644 index 0000000..1eb86be --- /dev/null +++ b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt @@ -0,0 +1,23 @@ +package dev.gitlive.appauth + +actual class AuthorizationResponse internal constructor(private val android: net.openid.appauth.AuthorizationResponse) { + actual fun createTokenExchangeRequest() = TokenRequest(android.createTokenExchangeRequest()) + actual val idToken get() = android.idToken + actual val scope get() = android.scope + actual val authorizationCode get() = android.authorizationCode + + override fun toString(): String { + return buildString { + appendLine("AuthorizationResponse(") + appendLine(" authorizationCode: ${authorizationCode ?: "None"}") + appendLine(" idToken: ${idToken ?: "None"}") + appendLine(" scope: ${scope ?: "None"}") + appendLine(" state: ${android.state ?: "None"}") + appendLine(" tokenExchangeRequest:") + appendLine(" clientId: ${android.request.clientId}") + appendLine(" redirectUri: ${android.request.redirectUri}") + appendLine(" responseType: ${android.request.responseType}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt new file mode 100644 index 0000000..159eaec --- /dev/null +++ b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt @@ -0,0 +1,172 @@ +package dev.gitlive.appauth + +import android.content.Intent +import android.util.Base64 +import androidx.activity.result.ActivityResultCaller +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult +import io.github.aakira.napier.Napier +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import net.openid.appauth.AuthorizationException +import java.io.BufferedWriter +import java.io.OutputStreamWriter +import java.net.HttpURLConnection +import java.net.URL +import java.net.URLEncoder +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + + +actual class AuthorizationService private constructor(private val android: net.openid.appauth.AuthorizationService) { + actual constructor(context: () -> AuthorizationServiceContext) : this( + net.openid.appauth.AuthorizationService( + context() + ) + ) + + fun bind(activityOrFragment: ActivityResultCaller) { + launcher = activityOrFragment + .registerForActivityResult(StartActivityForResult()) { result -> + result.data + ?.let { AuthorizationException.fromIntent(it) } + ?.let { response.completeExceptionally(it.wrapIfNecessary()) } + ?: response.complete(result.data) + } + } + + private var response = CompletableDeferred(value = null) + + private lateinit var launcher: ActivityResultLauncher + + + actual suspend fun performAuthorizationRequest(request: AuthorizationRequest): AuthorizationResponse { + // Show the request details + Napier.d("πŸ“€ Starting AuthorizationRequest:\n${request}") + // if a previous request is still pending then wait for it to finish + response.runCatching { + Napier.d("⏳ Waiting for previous authorization request to complete...") + await() + } + response = CompletableDeferred() + Napier.d("πŸš€ Launching authorization intent") + launcher.launch(android.getAuthorizationRequestIntent(request.android)) + // Wait for the result and process it + return try { + val intent = response.await() + Napier.d("βœ… Authorization response received") + + val rawResponse = net.openid.appauth.AuthorizationResponse.fromIntent(intent!!) + Napier.d("πŸ“₯ Parsed AuthorizationResponse:\n$rawResponse") + + AuthorizationResponse(rawResponse!!) + } catch (e: Exception) { + Napier.e("❌ Authorization failed", e) + throw e + } + } + + actual suspend fun performEndSessionRequest(request: EndSessionRequest) { + // if a previous request is still pending then wait for it to finish + // Show the request details + Napier.d("πŸ“€ Starting EndSessionRequest:\n$request") + + // If a previous request is still pending, wait for it + response.runCatching { + Napier.d("⏳ Waiting for previous end session request to complete...") + await() + } + + // Prepare for the new request + response = CompletableDeferred() + + // Launch the logout intent + Napier.d("πŸš€ Launching end session intent") + launcher.launch(android.getEndSessionRequestIntent(request.android)) + + // Await the result and parse the response + return try { + val intent = response.await() + Napier.d("βœ… End session response received") + + return + } catch (e: Exception) { + Napier.e("❌ End session failed", e) + throw e + } + } + + actual suspend fun performTokenRequest(request: TokenRequest): TokenResponse = + suspendCoroutine { cont -> + Napier.d("πŸ” Starting performTokenRequest") + Napier.d("πŸ“€ TokenRequest:\n$request") + + android.performTokenRequest(request.android) { response, ex -> + if (response != null) { + Napier.d("βœ… Token response received") + Napier.d("πŸ“₯ Parsed TokenResponse:\n$response") + cont.resume(TokenResponse(response)) + } else { + Napier.e("❌ Token request failed", ex) + cont.resumeWithException(ex!!.wrapIfNecessary()) + } + } + } + + actual suspend fun performRevokeTokenRequest(request: RevokeTokenRequest) = + withContext(Dispatchers.IO) { + val endpoint = request.config.revocationEndpoint + ?: throw IllegalStateException("Revocation endpoint not found in configuration.") + + var connection: HttpURLConnection? = null + try { + Napier.d("Performing token revocation via native HttpURLConnection to $endpoint") + connection = URL(endpoint).openConnection() as HttpURLConnection + connection.requestMethod = "POST" + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") + connection.doOutput = true + + val params = mutableMapOf("token" to request.token) + if (request.clientSecret == null) { + params["client_id"] = request.clientId + } else { + val credentials = "${request.clientId}:${request.clientSecret}" + val authHeader = + "Basic ${Base64.encodeToString(credentials.toByteArray(), Base64.NO_WRAP)}" + connection.setRequestProperty("Authorization", authHeader) + } + + val writer = BufferedWriter(OutputStreamWriter(connection.outputStream, "UTF-8")) + writer.write(getPostDataString(params)) + writer.flush() + writer.close() + + val responseCode = connection.responseCode + Napier.d("Revocation response code: $responseCode") + + + if (responseCode >= 400) { + val errorStream = connection.errorStream?.bufferedReader()?.readText() + throw AuthorizationException.fromTemplate( + AuthorizationException.GeneralErrors.SERVER_ERROR, + Exception("Revocation failed with code $responseCode: $errorStream") + ) + } + + } catch (e: Exception) { + Napier.e("Revocation request failed", e) + throw e + } finally { + connection?.disconnect() + } + } + + private fun getPostDataString(params: Map): String { + return params.entries.joinToString("&") { (key, value) -> + "${URLEncoder.encode(key, "UTF-8")}=${URLEncoder.encode(value, "UTF-8")}" + } + } + +} \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt new file mode 100644 index 0000000..218dfad --- /dev/null +++ b/src/androidMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt @@ -0,0 +1,88 @@ +package dev.gitlive.appauth + +import android.net.Uri +import io.github.aakira.napier.Napier +import net.openid.appauth.AuthorizationException +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +// wrap network errors in an IOException so it matches ktor +internal fun net.openid.appauth.AuthorizationException.wrapIfNecessary() = + takeUnless { it == AuthorizationException.GeneralErrors.NETWORK_ERROR } + ?: IOException(message, this) + +actual class AuthorizationServiceConfiguration private constructor( + val android: net.openid.appauth.AuthorizationServiceConfiguration, + actual val revocationEndpoint: String? +) { + + actual constructor( + authorizationEndpoint: String, + tokenEndpoint: String, + registrationEndpoint: String?, + endSessionEndpoint: String?, + revocationEndpoint: String? + ) : this( + net.openid.appauth.AuthorizationServiceConfiguration( + Uri.parse(authorizationEndpoint), + Uri.parse(tokenEndpoint), + registrationEndpoint?.let { Uri.parse(it) }, + endSessionEndpoint?.let { Uri.parse(it) }, + ), + revocationEndpoint + ) + + actual companion object { + actual suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration = + suspendCoroutine { cont -> + Napier.d("🌐 Starting custom fetchFromIssuer for Android") + net.openid.appauth.AuthorizationServiceConfiguration.fetchFromIssuer( + Uri.parse(url) + ) { serviceConfiguration, ex -> + if (ex != null) { + Napier.e("❌ Failed to fetch base configuration", ex) + cont.resumeWithException(ex.wrapIfNecessary()) + return@fetchFromIssuer + } + if (serviceConfiguration == null) { + Napier.e("❌ Fetched configuration is null") + cont.resumeWithException(IllegalStateException("Configuration is null")) + return@fetchFromIssuer + } + + var revocationEndpoint: String? = null + try { + val discoveryDocJson: JSONObject? = serviceConfiguration.discoveryDoc?.docJson + if (discoveryDocJson != null && discoveryDocJson.has("revocation_endpoint")) { + // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ null, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ + if (!discoveryDocJson.isNull("revocation_endpoint")) { + revocationEndpoint = discoveryDocJson.getString("revocation_endpoint") + Napier.i("βœ… Found revocation_endpoint: $revocationEndpoint") + } + } + } catch (jsonEx: JSONException) { + Napier.w( + "Could not parse revocation_endpoint from discovery document", + jsonEx + ) + } + + cont.resume( + AuthorizationServiceConfiguration( + android = serviceConfiguration, + revocationEndpoint = revocationEndpoint + ) + ) + } + } + } + + actual val authorizationEndpoint get() = android.authorizationEndpoint.toString() + actual val tokenEndpoint get() = android.tokenEndpoint.toString() + actual val registrationEndpoint get() = android.registrationEndpoint?.toString() + actual val endSessionEndpoint get() = android.endSessionEndpoint?.toString() +} \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/TokenRequest.kt b/src/androidMain/kotlin/dev/gitlive/appauth/TokenRequest.kt new file mode 100644 index 0000000..62a3c92 --- /dev/null +++ b/src/androidMain/kotlin/dev/gitlive/appauth/TokenRequest.kt @@ -0,0 +1,30 @@ +package dev.gitlive.appauth + +actual class TokenRequest internal constructor(internal val android: net.openid.appauth.TokenRequest) { + actual constructor( + config: AuthorizationServiceConfiguration, + clientId: String, + grantType: String, + refreshToken: String? + ) : this( + net.openid.appauth.TokenRequest.Builder(config.android, clientId).apply { + setGrantType(grantType) + refreshToken?.let { setRefreshToken(it) } + }.build() + ) + override fun toString(): String { + return buildString { + appendLine("TokenRequest(") + appendLine(" clientId: ${android.clientId}") + appendLine(" grantType: ${android.grantType}") + appendLine(" scope: ${android.scope ?: "None"}") + appendLine(" refreshToken: ${android.refreshToken ?: "None"}") + appendLine(" redirectUri: ${android.redirectUri ?: "None"}") + appendLine(" additionalParameters: ${android.additionalParameters ?: "None"}") + appendLine(" config:") + appendLine(" tokenEndpoint: ${android.configuration.tokenEndpoint}") + appendLine(" authEndpoint: ${android.configuration.authorizationEndpoint}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/androidMain/kotlin/dev/gitlive/appauth/androidMain.kt b/src/androidMain/kotlin/dev/gitlive/appauth/androidMain.kt index b8638a6..3e1e445 100644 --- a/src/androidMain/kotlin/dev/gitlive/appauth/androidMain.kt +++ b/src/androidMain/kotlin/dev/gitlive/appauth/androidMain.kt @@ -1,159 +1,71 @@ package dev.gitlive.appauth import android.content.ContextWrapper -import android.content.Intent import android.net.Uri -import androidx.activity.result.ActivityResultCaller -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult -import io.ktor.utils.io.errors.IOException -import kotlinx.coroutines.CompletableDeferred import net.openid.appauth.AuthorizationException -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException -import kotlin.coroutines.suspendCoroutine +import net.openid.appauth.TokenResponse as AndroidTokenResponse actual typealias AuthorizationException = AuthorizationException -// wrap network errors in an IOException so it matches ktor -private fun AuthorizationException.wrapIfNecessary() = - takeUnless { it == AuthorizationException.GeneralErrors.NETWORK_ERROR } - ?: IOException(message, this) - actual typealias AuthorizationServiceContext = ContextWrapper -actual class AuthorizationService private constructor(private val android: net.openid.appauth.AuthorizationService) { - actual constructor(context: () -> AuthorizationServiceContext) : this(net.openid.appauth.AuthorizationService(context())) - - fun bind(activityOrFragment: ActivityResultCaller) { - launcher = activityOrFragment - .registerForActivityResult(StartActivityForResult()) { result -> - result.data - ?.let { AuthorizationException.fromIntent(it) } - ?.let { response.completeExceptionally(it.wrapIfNecessary()) } - ?: response.complete(result.data) - } - } - - private var response = CompletableDeferred(value = null) - - private lateinit var launcher: ActivityResultLauncher - - actual suspend fun performAuthorizationRequest(request: AuthorizationRequest): AuthorizationResponse { - // if a previous request is still pending then wait for it to finish - response.runCatching { await() } - response = CompletableDeferred() - launcher.launch(android.getAuthorizationRequestIntent(request.android)) - return AuthorizationResponse(net.openid.appauth.AuthorizationResponse.fromIntent(response.await()!!)!!) - } - - actual suspend fun performEndSessionRequest(request: EndSessionRequest): EndSessionResponse { - // if a previous request is still pending then wait for it to finish - response.runCatching { await() } - response = CompletableDeferred() - launcher.launch(android.getEndSessionRequestIntent(request.android)) - return EndSessionResponse.fromIntent(response.await()!!)!! - } - - actual suspend fun performTokenRequest(request: TokenRequest): TokenResponse = - suspendCoroutine { cont -> - android.performTokenRequest(request.android) { response, ex -> - response?.let { cont.resume(response) } - ?: cont.resumeWithException(ex!!.wrapIfNecessary()) - } - } -} - -actual class AuthorizationServiceConfiguration private constructor( - val android: net.openid.appauth.AuthorizationServiceConfiguration +actual class TokenResponse internal constructor( + private val androidTokenResponse: AndroidTokenResponse ) { - - actual constructor( - authorizationEndpoint: String, - tokenEndpoint: String, - registrationEndpoint: String?, - endSessionEndpoint: String? - ) : this( - net.openid.appauth.AuthorizationServiceConfiguration( - Uri.parse(authorizationEndpoint), - Uri.parse(tokenEndpoint), - registrationEndpoint?.let { Uri.parse(it) }, - endSessionEndpoint?.let { Uri.parse(it) }, - ) - ) - - actual companion object { - actual suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration = - suspendCoroutine { cont -> - net.openid.appauth.AuthorizationServiceConfiguration - .fetchFromIssuer(Uri.parse(url)) { serviceConfiguration, ex -> - serviceConfiguration?.let { - cont.resume(AuthorizationServiceConfiguration(it)) - } - ?: cont.resumeWithException(ex!!.wrapIfNecessary()) - } - } + actual val idToken: String? + get() = androidTokenResponse.idToken + + actual val accessToken: String? + get() = androidTokenResponse.accessToken + + actual val refreshToken: String? + get() = androidTokenResponse.refreshToken + + override fun toString(): String { + return buildString { + appendLine("TokenResponse(") + appendLine(" accessToken: ${accessToken ?: "None"}") + appendLine(" idToken: ${idToken ?: "None"}") + appendLine(" refreshToken: ${refreshToken ?: "None"}") + appendLine(" tokenType: ${androidTokenResponse.tokenType ?: "None"}") + appendLine(" scope: ${androidTokenResponse.scope ?: "None"}") + appendLine(" accessTokenExpirationTime: ${androidTokenResponse.accessTokenExpirationTime ?: "None"}") + appendLine(")") + } } - - actual val authorizationEndpoint get() = android.authorizationEndpoint.toString() - actual val tokenEndpoint get() = android.tokenEndpoint.toString() - actual val registrationEndpoint get() = android.registrationEndpoint?.toString() - actual val endSessionEndpoint get() = android.endSessionEndpoint?.toString() } -actual class AuthorizationRequest private constructor(internal val android: net.openid.appauth.AuthorizationRequest) { - actual constructor( - config: AuthorizationServiceConfiguration, - clientId: String, - scopes: List, - responseType: String, - redirectUri: String - ) : this( - net.openid.appauth.AuthorizationRequest.Builder( - config.android, - clientId, - responseType, - Uri.parse(redirectUri) - ) - .setScopes(scopes) - .build() - ) -} - -actual class AuthorizationResponse internal constructor(private val android: net.openid.appauth.AuthorizationResponse) { - actual fun createTokenExchangeRequest() = TokenRequest(android.createTokenExchangeRequest()) - actual val idToken get() = android.idToken - actual val scope get() = android.scope - actual val authorizationCode get() = android.authorizationCode -} - -actual class TokenRequest internal constructor(internal val android: net.openid.appauth.TokenRequest) { - actual constructor( - config: AuthorizationServiceConfiguration, - clientId: String, - grantType: String, - refreshToken: String? - ) : this( - net.openid.appauth.TokenRequest.Builder(config.android, clientId).apply { - setGrantType(grantType) - refreshToken?.let { setRefreshToken(it) } - }.build() - ) -} - -actual typealias TokenResponse = net.openid.appauth.TokenResponse - actual class EndSessionRequest internal constructor(internal val android: net.openid.appauth.EndSessionRequest) { actual constructor( config: AuthorizationServiceConfiguration, idTokenHint: String?, - postLogoutRedirectUri: String? + postLogoutRedirectUri: String?, + additionalParameters: Map?, ) : this( net.openid.appauth.EndSessionRequest.Builder(config.android).apply { idTokenHint?.let { setIdTokenHint(it) } postLogoutRedirectUri?.let { setPostLogoutRedirectUri(Uri.parse(postLogoutRedirectUri)) } + setAdditionalParameters(additionalParameters) }.build() ) + override fun toString(): String { + return buildString { + appendLine("EndSessionRequest(") + appendLine(" idTokenHint: ${android.idTokenHint ?: "None"}") + appendLine(" postLogoutRedirectUri: ${android.postLogoutRedirectUri ?: "None"}") + appendLine(" state: ${android.state ?: "None"}") + appendLine(" additionalParameters: ${android.additionalParameters ?: "None"}") + appendLine(" config:") + appendLine(" endSessionEndpoint: ${android.configuration.endSessionEndpoint}") + appendLine(")") + } + } } -actual typealias EndSessionResponse = net.openid.appauth.EndSessionResponse +actual class RevokeTokenRequest actual constructor( + val config: AuthorizationServiceConfiguration, + val token: String, + val clientId: String, + val clientSecret: String? +) + diff --git a/src/androidTest/kotlin/dev/gitlive/appauth/androidTest.kt b/src/androidUnitTest/kotlin/dev/gitlive/appauth/commonTest.android.kt similarity index 67% rename from src/androidTest/kotlin/dev/gitlive/appauth/androidTest.kt rename to src/androidUnitTest/kotlin/dev/gitlive/appauth/commonTest.android.kt index 0faae9f..459aaa5 100644 --- a/src/androidTest/kotlin/dev/gitlive/appauth/androidTest.kt +++ b/src/androidUnitTest/kotlin/dev/gitlive/appauth/commonTest.android.kt @@ -6,7 +6,9 @@ actual val context: Any get() = TODO("Not yet implemented") actual fun simulateSignIn() { + TODO("Not yet implemented") } -actual suspend fun CoroutineScope.withAuthorizationService(action: suspend (service: AuthorizationService) -> Unit) { -} +actual suspend fun CoroutineScope.withAuthorizationService(action: suspend (AuthorizationService) -> Unit) { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/src/commonMain/kotlin/dev/gitlive/appauth/commonMain.kt b/src/commonMain/kotlin/dev/gitlive/appauth/commonMain.kt index e749bdd..c84e7f5 100644 --- a/src/commonMain/kotlin/dev/gitlive/appauth/commonMain.kt +++ b/src/commonMain/kotlin/dev/gitlive/appauth/commonMain.kt @@ -4,24 +4,82 @@ expect class AuthorizationException : Exception expect class AuthorizationServiceContext +/** + * A service that handles the authorization flow. + * It provides methods for performing authorization, token exchange, and session management. + * This class is a KMP wrapper around the native AppAuth libraries. + */ expect class AuthorizationService(context: () -> AuthorizationServiceContext) { + /** + * Performs an authorization request to the authorization server. + * This typically involves opening a browser or a custom tab for the user to sign in. + * + * @param request The [AuthorizationRequest] containing all details for the authorization flow. + * @return An [AuthorizationResponse] containing the authorization code and other details. + * @throws AuthorizationException if the authorization flow fails. + */ suspend fun performAuthorizationRequest(request: AuthorizationRequest): AuthorizationResponse - suspend fun performEndSessionRequest(request: EndSessionRequest): EndSessionResponse + + /** + * Performs an end-session request to the authorization server to log the user out. + * This follows the OIDC RP-Initiated Logout specification. + * + * @param request The [EndSessionRequest] containing details for the logout flow. + * @throws AuthorizationException if the end-session flow fails. + */ + suspend fun performEndSessionRequest(request: EndSessionRequest) + + /** + * Performs a token request to exchange an authorization code or refresh token for new tokens. + * + * @param request The [TokenRequest] containing the grant type and relevant codes/tokens. + * @return A [TokenResponse] containing the new access, refresh, and ID tokens. + * @throws AuthorizationException if the token exchange fails. + */ suspend fun performTokenRequest(request: TokenRequest): TokenResponse + + + /** + * Performs a token revocation request as per RFC 7009. + * This directly communicates with the revocation endpoint to invalidate a token. + * + * @param request The [RevokeTokenRequest] containing the token to be revoked. + * @throws AuthorizationException if the revocation fails. + */ + suspend fun performRevokeTokenRequest(request: RevokeTokenRequest) } +/** + * Represents the configuration of an authorization service, including all necessary endpoints. + * + * @property authorizationEndpoint The URL of the authorization endpoint. + * @property tokenEndpoint The URL of the token endpoint. + * @property registrationEndpoint The URL of the dynamic client registration endpoint, if available. + * @property endSessionEndpoint The URL of the end-session (logout) endpoint, if available. + * @property revocationEndpoint The URL of the token revocation endpoint (RFC 7009), if available. + */ expect class AuthorizationServiceConfiguration( authorizationEndpoint: String, tokenEndpoint: String, registrationEndpoint: String? = null, endSessionEndpoint: String? = null, + revocationEndpoint: String? = null ) { val authorizationEndpoint: String val tokenEndpoint: String val registrationEndpoint: String? val endSessionEndpoint: String? + val revocationEndpoint: String? companion object { + /** + * Fetches the service configuration from an OIDC discovery document. + * + * @param url The issuer URL of the authorization server. The discovery document is typically + * found at `[url]/.well-known/openid-configuration`. + * @return A new [AuthorizationServiceConfiguration] instance. + * @throws Exception if the discovery document cannot be fetched or parsed. + */ suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration } } @@ -31,7 +89,8 @@ expect class AuthorizationRequest( clientId: String, scopes: List, responseType: String, - redirectUri: String + redirectUri: String, + additionalParameters: Map? ) expect class AuthorizationResponse { @@ -57,7 +116,23 @@ expect class TokenResponse { expect class EndSessionRequest( config: AuthorizationServiceConfiguration, idTokenHint: String? = null, - postLogoutRedirectUri: String? = null + postLogoutRedirectUri: String? = null, + additionalParameters: Map? = null, ) -expect class EndSessionResponse + +/** + * Encapsulates a request to revoke a token at the token revocation endpoint. + * + * @param config The service configuration, which should contain the `revocationEndpoint`. + * @param token The refresh or access token to be revoked. + * @param clientId The client ID of the application. + * @param clientSecret The client secret, if the client is confidential. If provided, it will be + * used for Basic HTTP authentication. If null, the client is treated as public. + */ +expect class RevokeTokenRequest( + config: AuthorizationServiceConfiguration, + token: String, + clientId: String, + clientSecret: String? = null +) \ No newline at end of file diff --git a/src/commonTest/kotlin/dev/gitlive/appauth/commonTest.kt b/src/commonTest/kotlin/dev/gitlive/appauth/commonTest.kt index 94a7fb0..8e13972 100644 --- a/src/commonTest/kotlin/dev/gitlive/appauth/commonTest.kt +++ b/src/commonTest/kotlin/dev/gitlive/appauth/commonTest.kt @@ -38,7 +38,8 @@ class AuthorizationServiceTest { "MyClient", listOf("profile"), "code", - "myapp://oauth2redirect" + "myapp://oauth2redirect", + null ) withAuthorizationService { service -> val actual = async(Dispatchers.Main) { service.performAuthorizationRequest(request) } @@ -58,7 +59,8 @@ class AuthorizationServiceTest { "MyClient", listOf("profile"), "code", - "myapp://oauth2redirect" + "myapp://oauth2redirect", + null ) withAuthorizationService { service -> val response = async(Dispatchers.Main) { service.performAuthorizationRequest(request) } diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt new file mode 100644 index 0000000..40afc49 --- /dev/null +++ b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationRequest.kt @@ -0,0 +1,44 @@ +@file:OptIn(ExperimentalForeignApi::class) + +package dev.gitlive.appauth + +import cocoapods.AppAuth.OIDAuthorizationRequest +import kotlinx.cinterop.ExperimentalForeignApi +import platform.Foundation.NSURL + +actual class AuthorizationRequest private constructor(internal val ios: OIDAuthorizationRequest) { + + actual constructor( + config: AuthorizationServiceConfiguration, + clientId: String, + scopes: List, + responseType: String, + redirectUri: String, + additionalParameters: Map? + ) : this( + OIDAuthorizationRequest( + configuration = config.ios, + clientId = clientId, + scopes = scopes, + redirectURL = NSURL.URLWithString(redirectUri)!!, + responseType = responseType, + additionalParameters = additionalParameters as Map?, + ) + ) + + @OptIn(ExperimentalForeignApi::class) + override fun toString(): String { + return buildString { + appendLine("AuthorizationRequest(") + appendLine(" clientId: ${ios.clientID}") + appendLine(" scope: ${ios.scope ?: "None"}") + appendLine(" responseType: ${ios.responseType}") + appendLine(" redirectUri: ${ios.redirectURL?.absoluteString ?: "None"}") + appendLine(" additionalParameters: ${ios.additionalParameters ?: "None"}") + appendLine(" config:") + appendLine(" authorizationEndpoint: ${ios.configuration.authorizationEndpoint.absoluteString}") + appendLine(" tokenEndpoint: ${ios.configuration.tokenEndpoint.absoluteString}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt new file mode 100644 index 0000000..dacb8ae --- /dev/null +++ b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationResponse.kt @@ -0,0 +1,29 @@ +package dev.gitlive.appauth + +import cocoapods.AppAuth.OIDAuthorizationResponse +import kotlinx.cinterop.ExperimentalForeignApi + +@OptIn(ExperimentalForeignApi::class) +actual class AuthorizationResponse internal constructor(internal val ios: OIDAuthorizationResponse) { + actual val authorizationCode: String? get() = ios.authorizationCode + actual val idToken: String? get() = ios.idToken + actual val scope get() = ios.scope + actual fun createTokenExchangeRequest() = TokenRequest(ios.tokenExchangeRequest()!!) + + override fun toString(): String { + return buildString { + appendLine("AuthorizationResponse(") + appendLine(" authorizationCode: ${authorizationCode ?: "None"}") + appendLine(" idToken: ${idToken ?: "None"}") + appendLine(" scope: ${scope ?: "None"}") + appendLine(" state: ${ios.state ?: "None"}") + appendLine(" redirectUri: ${ios.request?.redirectURL?.absoluteString ?: "None"}") + appendLine(" clientId: ${ios.request?.clientID ?: "None"}") + appendLine(" responseType: ${ios.request?.responseType ?: "None"}") + appendLine(" config:") + appendLine(" authorizationEndpoint: ${ios.request?.configuration?.authorizationEndpoint?.absoluteString ?: "None"}") + appendLine(" tokenEndpoint: ${ios.request?.configuration?.tokenEndpoint?.absoluteString ?: "None"}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt new file mode 100644 index 0000000..051b662 --- /dev/null +++ b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationService.kt @@ -0,0 +1,187 @@ +package dev.gitlive.appauth + +import cocoapods.AppAuth.OIDAuthorizationService +import cocoapods.AppAuth.OIDExternalUserAgentIOS +import cocoapods.AppAuth.OIDExternalUserAgentSessionProtocol +import io.github.aakira.napier.Napier +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import platform.Foundation.NSHTTPURLResponse +import platform.Foundation.NSMutableURLRequest +import platform.Foundation.NSString +import platform.Foundation.NSURL +import platform.Foundation.NSURLSession +import platform.Foundation.NSUTF8StringEncoding +import platform.Foundation.base64EncodedStringWithOptions +import platform.Foundation.create +import platform.Foundation.dataTaskWithRequest +import platform.Foundation.dataUsingEncoding +import platform.Foundation.setHTTPBody +import platform.Foundation.setHTTPMethod +import platform.Foundation.setValue +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + + + +@OptIn(ExperimentalForeignApi::class) +internal fun String.base64Encoded(): String { + val data = (this as NSString).dataUsingEncoding(NSUTF8StringEncoding) + return data?.base64EncodedStringWithOptions(0u) ?: "" +} + + +@OptIn(ExperimentalForeignApi::class) +actual class AuthorizationService actual constructor(private val context: () -> AuthorizationServiceContext) { + + private var session: OIDExternalUserAgentSessionProtocol? = null + + fun resumeExternalUserAgentFlow(url: NSURL): Boolean = + session?.resumeExternalUserAgentFlowWithURL(url) == true + + actual suspend fun performAuthorizationRequest(request: AuthorizationRequest): AuthorizationResponse = + withContext(Dispatchers.Main) { + Napier.d("πŸ” Starting iOS performAuthorizationRequest") + Napier.d("πŸ“€ AuthorizationRequest:\n$request") + + suspendCoroutine { cont -> + val viewController = context() + Napier.d("🧭 Presenting authorization from context: ${viewController::class.simpleName}") + + session = OIDAuthorizationService.presentAuthorizationRequest( + request.ios, + OIDExternalUserAgentIOS(viewController) + ) { response, error -> + Napier.d("πŸ” Authorization callback triggered") + session = null + + if (response != null) { + Napier.d("βœ… Authorization successful") + Napier.d("πŸ“₯ AuthorizationResponse:\n$response") + cont.resume(AuthorizationResponse(response)) + } else { + Napier.e( + "❌ Authorization failed: ${error?.localizedDescription}", + error!!.toException() + ) + cont.resumeWithException(error.toException()) + } + } + } + } + + + actual suspend fun performEndSessionRequest(request: EndSessionRequest) = + withContext(Dispatchers.Main) { + Napier.d("πŸ” Starting iOS performEndSessionRequest") + Napier.d("πŸ“€ EndSessionRequest:\n$request") + + suspendCoroutine { cont -> + val viewController = context() + Napier.d("🧭 Presenting end session from context: ${viewController::class.simpleName}") + + session = OIDAuthorizationService.presentEndSessionRequest( + request.ios, + OIDExternalUserAgentIOS(viewController) + ) { response, error -> + Napier.d("πŸ” End session callback triggered") + session = null + + if (response != null) { + Napier.d("βœ… End session completed successfully") + Napier.d("πŸ“₯ EndSessionResponse: $response") + cont.resume(Unit) + } else { + Napier.e( + "❌ End session failed: ${error?.localizedDescription}", + error!!.toException() + ) + cont.resumeWithException(error.toException()) + } + } + } + } + + + actual suspend fun performTokenRequest(request: TokenRequest): TokenResponse = + withContext(Dispatchers.Main) { + Napier.d("πŸ” Starting iOS performTokenRequest") + Napier.d("πŸ“€ TokenRequest:\n$request") + + suspendCoroutine { cont -> + Napier.d("πŸ“‘ Performing token request via OIDAuthorizationService") + + OIDAuthorizationService.performTokenRequest(request.ios) { response, error -> + Napier.d("πŸ” Token request callback triggered") + + if (response != null) { + Napier.d("βœ… Token request successful") + Napier.d("πŸ“₯ TokenResponse: ${TokenResponse(response)}") + cont.resume(TokenResponse(response)) + } else { + Napier.e( + "❌ Token request failed: ${error?.localizedDescription}", + error!!.toException() + ) + cont.resumeWithException(error.toException()) + } + } + } + } + + actual suspend fun performRevokeTokenRequest(request: RevokeTokenRequest) { + val endpoint = request.config.revocationEndpoint + ?: throw AuthorizationException("Revocation endpoint not found in configuration.") + + return suspendCoroutine { continuation -> + Napier.d("Performing token revocation via native URLSession to $endpoint") + + val url = NSURL(string = endpoint) + val urlRequest = NSMutableURLRequest(uRL = url) + + urlRequest.setHTTPMethod("POST") + + urlRequest.setValue( + "application/x-www-form-urlencoded", + forHTTPHeaderField = "Content-Type" + ) + + var bodyString = "token=${request.token.urlEncoded()}" + if (request.clientSecret == null) { + bodyString += "&client_id=${request.clientId.urlEncoded()}" + } else { + val credentials = "${request.clientId}:${request.clientSecret}" + val authHeader = "Basic ${credentials.base64Encoded()}" + urlRequest.setValue(authHeader, forHTTPHeaderField = "Authorization") + } + + urlRequest.setHTTPBody((bodyString as NSString).dataUsingEncoding(NSUTF8StringEncoding)) + + val task = + NSURLSession.sharedSession.dataTaskWithRequest(urlRequest) { data, response, error -> + if (error != null) { + continuation.resumeWithException(error.toException()) + return@dataTaskWithRequest + } + + val httpResponse = response as? NSHTTPURLResponse + val statusCode = httpResponse?.statusCode?.toInt() ?: 0 + Napier.d("Revocation response code: $statusCode") + + if (statusCode >= 400) { + val errorBody = data?.let { NSString.create(it, NSUTF8StringEncoding) } + continuation.resumeWithException(AuthorizationException("Revocation failed with code $statusCode: $errorBody")) + } else { + continuation.resume(Unit) + } + } + task.resume() + } + } + + private fun String.urlEncoded(): String { + return this.replace("=", "%3D").replace("+", "%2B").replace("/", "%2F") + } +} \ No newline at end of file diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt new file mode 100644 index 0000000..94ff039 --- /dev/null +++ b/src/iosMain/kotlin/dev/gitlive/appauth/AuthorizationServiceConfiguration.kt @@ -0,0 +1,86 @@ +package dev.gitlive.appauth + +import cocoapods.AppAuth.OIDAuthorizationService +import cocoapods.AppAuth.OIDServiceConfiguration +import io.github.aakira.napier.Napier +import kotlinx.cinterop.ExperimentalForeignApi +import platform.Foundation.NSURL +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + + +@OptIn(ExperimentalForeignApi::class) +actual class AuthorizationServiceConfiguration private constructor( + val ios: OIDServiceConfiguration, + actual val revocationEndpoint: String? +) { + + actual constructor( + authorizationEndpoint: String, + tokenEndpoint: String, + registrationEndpoint: String?, + endSessionEndpoint: String?, + revocationEndpoint: String? + ) : this( + OIDServiceConfiguration( + NSURL.URLWithString(authorizationEndpoint)!!, + NSURL.URLWithString(tokenEndpoint)!!, + null, + registrationEndpoint?.let { NSURL.URLWithString(it) }, + endSessionEndpoint?.let { NSURL.URLWithString(it) } + ), + revocationEndpoint + ) + + actual companion object { + @OptIn(ExperimentalForeignApi::class) + actual suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration = + suspendCoroutine { cont -> + Napier.d("🌐 Starting iOS fetchFromIssuer") + Napier.d("πŸ”— Issuer URL: $url") + + val nsUrl = NSURL.URLWithString(url) + if (nsUrl == null) { + Napier.e("❌ Invalid URL: $url") + cont.resumeWithException(IllegalArgumentException("Invalid issuer URL: $url")) + return@suspendCoroutine + } + + OIDAuthorizationService.discoverServiceConfigurationForIssuer(nsUrl) { config, error -> + Napier.d("πŸ” Discovery callback triggered") + + if (config != null) { + Napier.d("βœ… Discovery successful") + Napier.d("πŸ“₯ AuthorizationServiceConfiguration:") + Napier.d(" authorizationEndpoint: ${config.authorizationEndpoint.absoluteString}") + Napier.d(" tokenEndpoint: ${config.tokenEndpoint.absoluteString}") + Napier.d(" endSessionEndpoint: ${config.endSessionEndpoint?.absoluteString ?: "None"}") + + var revocationEndpoint: String? = null + try { + val discoveryDoc = config.discoveryDocument() + if (discoveryDoc is Map<*, *>) { + revocationEndpoint = discoveryDoc["revocation_endpoint"] as? String + if (revocationEndpoint != null) { + Napier.i("βœ… Found revocation_endpoint: $revocationEndpoint") + } + } + } catch (e: Exception) { + Napier.w("Could not parse revocation_endpoint", e) + } + + cont.resume(AuthorizationServiceConfiguration(config, revocationEndpoint)) + } else { + Napier.e("❌ Discovery failed: ${error?.localizedDescription}", error!!.toException()) + cont.resumeWithException(error.toException()) + } + } + } + } + + actual val authorizationEndpoint: String get() = ios.authorizationEndpoint.relativeString + actual val tokenEndpoint: String get() = ios.tokenEndpoint.relativeString + actual val registrationEndpoint: String? get() = ios.registrationEndpoint?.relativeString + actual val endSessionEndpoint: String? get() = ios.endSessionEndpoint?.relativeString +} diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/TokenRequest.kt b/src/iosMain/kotlin/dev/gitlive/appauth/TokenRequest.kt new file mode 100644 index 0000000..74b2c1e --- /dev/null +++ b/src/iosMain/kotlin/dev/gitlive/appauth/TokenRequest.kt @@ -0,0 +1,44 @@ +@file:OptIn(ExperimentalForeignApi::class) + +package dev.gitlive.appauth + +import cocoapods.AppAuth.OIDTokenRequest +import kotlinx.cinterop.ExperimentalForeignApi + +actual class TokenRequest internal constructor(internal val ios: OIDTokenRequest) { + actual constructor( + config: AuthorizationServiceConfiguration, + clientId: String, + grantType: String, + refreshToken: String? + ) : this( + OIDTokenRequest( + configuration = config.ios, + grantType = grantType, + authorizationCode = null, + redirectURL = null, + clientID = clientId, + clientSecret = null, + scope = null, + refreshToken = refreshToken, + codeVerifier = null, + additionalParameters = null + ) + ) + @OptIn(ExperimentalForeignApi::class) + override fun toString(): String { + return buildString { + appendLine("TokenRequest(") + appendLine(" clientId: ${ios.clientID ?: "None"}") + appendLine(" grantType: ${ios.grantType}") + appendLine(" scope: ${ios.scope ?: "None"}") + appendLine(" refreshToken: ${ios.refreshToken ?: "None"}") + appendLine(" redirectUri: ${ios.redirectURL?.absoluteString ?: "None"}") + appendLine(" additionalParameters: ${ios.additionalParameters ?: "None"}") + appendLine(" config:") + appendLine(" tokenEndpoint: ${ios.configuration.tokenEndpoint.absoluteString}") + appendLine(" authorizationEndpoint: ${ios.configuration.authorizationEndpoint.absoluteString}") + appendLine(")") + } + } +} \ No newline at end of file diff --git a/src/iosMain/kotlin/dev/gitlive/appauth/iosMain.kt b/src/iosMain/kotlin/dev/gitlive/appauth/iosMain.kt index f89bf66..44b9925 100644 --- a/src/iosMain/kotlin/dev/gitlive/appauth/iosMain.kt +++ b/src/iosMain/kotlin/dev/gitlive/appauth/iosMain.kt @@ -1,31 +1,22 @@ +@file:OptIn(ExperimentalForeignApi::class) + package dev.gitlive.appauth -import cocoapods.AppAuth.OIDAuthorizationRequest -import cocoapods.AppAuth.OIDAuthorizationResponse -import cocoapods.AppAuth.OIDAuthorizationService import cocoapods.AppAuth.OIDEndSessionRequest -import cocoapods.AppAuth.OIDEndSessionResponse import cocoapods.AppAuth.OIDErrorCodeNetworkError -import cocoapods.AppAuth.OIDExternalUserAgentIOS -import cocoapods.AppAuth.OIDExternalUserAgentSessionProtocol import cocoapods.AppAuth.OIDGeneralErrorDomain -import cocoapods.AppAuth.OIDServiceConfiguration -import cocoapods.AppAuth.OIDTokenRequest import cocoapods.AppAuth.OIDTokenResponse -import io.ktor.utils.io.errors.IOException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.io.IOException import platform.Foundation.NSError import platform.Foundation.NSURL import platform.UIKit.UIViewController -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException -import kotlin.coroutines.suspendCoroutine actual class AuthorizationException(message: String?) : Exception(message) // wrap network errors in an IOException so it matches ktor -private fun NSError.toException() = when (domain) { +@OptIn(ExperimentalForeignApi::class) +internal fun NSError.toException() = when (domain) { OIDGeneralErrorDomain -> when (code) { OIDErrorCodeNetworkError -> IOException(localizedDescription) else -> AuthorizationException(localizedDescription) @@ -33,98 +24,21 @@ private fun NSError.toException() = when (domain) { else -> AuthorizationException(localizedDescription) } -actual class AuthorizationServiceConfiguration private constructor(val ios: OIDServiceConfiguration) { - - actual constructor( - authorizationEndpoint: String, - tokenEndpoint: String, - registrationEndpoint: String?, - endSessionEndpoint: String? - ) : this( - OIDServiceConfiguration( - NSURL.URLWithString(authorizationEndpoint)!!, - NSURL.URLWithString(tokenEndpoint)!!, - null, - registrationEndpoint?.let { NSURL.URLWithString(it) }, - endSessionEndpoint?.let { NSURL.URLWithString(it) } - ) - ) - - actual companion object { - actual suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration = suspendCoroutine { cont -> - OIDAuthorizationService.discoverServiceConfigurationForIssuer(NSURL.URLWithString(url)!!) { config, error -> - config?.let { cont.resume(AuthorizationServiceConfiguration(it)) } - ?: cont.resumeWithException(error!!.toException()) - } - } - } - - actual val authorizationEndpoint: String get() = ios.authorizationEndpoint.relativeString - actual val tokenEndpoint: String get() = ios.tokenEndpoint.relativeString - actual val registrationEndpoint: String? get() = ios.registrationEndpoint?.relativeString - actual val endSessionEndpoint: String? get() = ios.endSessionEndpoint?.relativeString -} - -actual class AuthorizationRequest private constructor(internal val ios: OIDAuthorizationRequest) { - - actual constructor( - config: AuthorizationServiceConfiguration, - clientId: String, - scopes: List, - responseType: String, - redirectUri: String - ) : this( - OIDAuthorizationRequest( - configuration = config.ios, - clientId = clientId, - scopes = scopes, - redirectURL = NSURL.URLWithString(redirectUri)!!, - responseType = responseType, - additionalParameters = null - ) - ) -} - -actual class TokenRequest internal constructor(internal val ios: OIDTokenRequest) { - actual constructor( - config: AuthorizationServiceConfiguration, - clientId: String, - grantType: String, - refreshToken: String? - ) : this( - OIDTokenRequest( - configuration = config.ios, - grantType = grantType, - authorizationCode = null, - redirectURL = null, - clientID = clientId, - clientSecret = null, - scope = null, - refreshToken = refreshToken, - codeVerifier = null, - additionalParameters = null - ) - ) -} - -actual class AuthorizationResponse internal constructor(internal val ios: OIDAuthorizationResponse) { - actual val authorizationCode: String? get() = ios.authorizationCode - actual val idToken: String? get() = ios.idToken - actual val scope get() = ios.scope - actual fun createTokenExchangeRequest() = TokenRequest(ios.tokenExchangeRequest()!!) -} - actual class EndSessionRequest internal constructor(internal val ios: OIDEndSessionRequest) { actual constructor( config: AuthorizationServiceConfiguration, idTokenHint: String?, postLogoutRedirectUri: String?, + additionalParameters: Map?, ) : this( OIDEndSessionRequest( configuration = config.ios, - idTokenHint = idTokenHint, - postLogoutRedirectURL = postLogoutRedirectUri?.let { NSURL.URLWithString(it) }, - additionalParameters = null + idTokenHint = idTokenHint ?: "", + postLogoutRedirectURL = postLogoutRedirectUri?.let { uri -> + NSURL.URLWithString(uri) + ?: throw IllegalArgumentException("Invalid postLogoutRedirectUri: $uri") + } ?: NSURL.URLWithString(postLogoutRedirectUri ?: "")!!, + additionalParameters = additionalParameters?.mapValues { it.value as Any? } ) ) } @@ -135,52 +49,13 @@ actual class TokenResponse internal constructor(internal val ios: OIDTokenRespon actual val refreshToken: String? get() = ios.refreshToken } -actual typealias EndSessionResponse = OIDEndSessionResponse actual typealias AuthorizationServiceContext = UIViewController -actual class AuthorizationService actual constructor(private val context: () -> AuthorizationServiceContext) { - - private var session: OIDExternalUserAgentSessionProtocol? = null - fun resumeExternalUserAgentFlow(url: NSURL): Boolean = - session?.resumeExternalUserAgentFlowWithURL(url) == true - - actual suspend fun performAuthorizationRequest(request: AuthorizationRequest): AuthorizationResponse = - withContext(Dispatchers.Main) { - suspendCoroutine { cont -> - session = OIDAuthorizationService.presentAuthorizationRequest( - request.ios, - OIDExternalUserAgentIOS(context()) - ) { response, error -> - session = null - response?.let { cont.resume(AuthorizationResponse(it)) } - ?: cont.resumeWithException(error!!.toException()) - } - } - } - - actual suspend fun performEndSessionRequest(request: EndSessionRequest): EndSessionResponse = - withContext(Dispatchers.Main) { - suspendCoroutine { cont -> - session = OIDAuthorizationService.presentEndSessionRequest( - request.ios, - OIDExternalUserAgentIOS(context()) - ) { response, error -> - session = null - response?.let { cont.resume(it) } - ?: cont.resumeWithException(error!!.toException()) - } - } - } - - actual suspend fun performTokenRequest(request: TokenRequest): TokenResponse = - withContext(Dispatchers.Main) { - suspendCoroutine { cont -> - OIDAuthorizationService.performTokenRequest(request.ios) { response, error -> - response?.let { cont.resume(TokenResponse(it)) } - ?: cont.resumeWithException(error!!.toException()) - } - } - } -} +actual class RevokeTokenRequest actual constructor( + val config: AuthorizationServiceConfiguration, + val token: String, + val clientId: String, + val clientSecret: String? +) \ No newline at end of file diff --git a/src/jsMain/kotlin/dev/gitlive/appauth/jsMain.kt b/src/jsMain/kotlin/dev/gitlive/appauth/jsMain.kt index 4bb4c63..22eec59 100644 --- a/src/jsMain/kotlin/dev/gitlive/appauth/jsMain.kt +++ b/src/jsMain/kotlin/dev/gitlive/appauth/jsMain.kt @@ -5,7 +5,8 @@ actual class AuthorizationServiceConfiguration actual constructor( authorizationEndpoint: String, tokenEndpoint: String, registrationEndpoint: String?, - endSessionEndpoint: String? + endSessionEndpoint: String?, + revocationEndpoint: String? ) { actual companion object { actual suspend fun fetchFromIssuer(url: String): AuthorizationServiceConfiguration { @@ -21,6 +22,8 @@ actual class AuthorizationServiceConfiguration actual constructor( get() = TODO("Not yet implemented") actual val endSessionEndpoint: String? get() = TODO("Not yet implemented") + actual val revocationEndpoint: String? + get() = TODO("Not yet implemented") } actual class AuthorizationException : Exception() @@ -30,7 +33,8 @@ actual class AuthorizationRequest actual constructor( clientId: String, scopes: List, responseType: String, - redirectUri: String + redirectUri: String, + additionalParameters: Map? ) actual class AuthorizationResponse { @@ -71,7 +75,10 @@ actual class AuthorizationService actual constructor(context: () -> Authorizatio TODO("Not yet implemented") } - actual suspend fun performEndSessionRequest(request: EndSessionRequest): EndSessionResponse { + actual suspend fun performEndSessionRequest(request: EndSessionRequest) { + TODO("Not yet implemented") + } + actual suspend fun performRevokeTokenRequest(request: RevokeTokenRequest) { TODO("Not yet implemented") } } @@ -79,7 +86,13 @@ actual class AuthorizationService actual constructor(context: () -> Authorizatio actual class EndSessionRequest actual constructor( config: AuthorizationServiceConfiguration, idTokenHint: String?, - postLogoutRedirectUri: String? + postLogoutRedirectUri: String?, + additionalParameters: Map? ) -actual class EndSessionResponse +actual class RevokeTokenRequest actual constructor( + val config: AuthorizationServiceConfiguration, + val token: String, + val clientId: String, + val clientSecret: String? +) \ No newline at end of file