diff --git a/.gitignore b/.gitignore index 10fd875..8ff463f 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,5 @@ outTmp/ /kotlin-native/dist kotlin-ide/ site/ +kotlin-js-store/ +.kotlin/ diff --git a/build.gradle.kts b/build.gradle.kts index b4d7bc1..64fe484 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.* + group = "com.trendyol" plugins { @@ -5,18 +7,35 @@ plugins { java alias(libs.plugins.spotless) alias(libs.plugins.maven.publish) + alias(libs.plugins.kover) + alias(libs.plugins.testLogger) } version = properties["version"]!! +val kmpModules = listOf( + projects.projects.kediatrCore.name, + projects.projects.kediatrKoinStarter.name, +) + subprojectsOf("projects") { + val isKmp = name in kmpModules + apply { - plugin("kotlin") - plugin("java") + if (isKmp) { + plugin("org.jetbrains.kotlin.multiplatform") + } else { + plugin("kotlin") + plugin("java") + } plugin(rootProject.libs.plugins.spotless.pluginId) plugin(rootProject.libs.plugins.maven.publish.pluginId) + plugin(rootProject.libs.plugins.kover.pluginId) + plugin(rootProject.libs.plugins.testLogger.pluginId) } + configureKotlin(isKmp) + spotless { kotlin { ktlint(rootProject.libs.ktlint.cli.get().version) @@ -24,10 +43,50 @@ subprojectsOf("projects") { } } - java { - withSourcesJar() + kover { + reports { + filters { + excludes { + packages("com.trendyol.kediatr.testing") + } + } + } + } + + dependencies { + kover(project) + } + + // KMP modules handle sources jar automatically, JVM-only modules need explicit configuration + if (!isKmp) { + java { + withSourcesJar() + } + + dependencies { + implementation(rootProject.libs.kotlinx.coroutines.core) + testImplementation(rootProject.libs.kotlinx.coroutines.test) + testImplementation(rootProject.libs.kotest.assertions.core) + testImplementation(rootProject.libs.kotest.assertions.table) + testImplementation(rootProject.libs.kotest.framework.engine) + testImplementation(rootProject.libs.kotest.runner.junit5) + } + } + + tasks.withType { + useJUnitPlatform() + configure { + setTheme("mocha") + showStandardStreams = true + } + reports { + junitXml.required.set(true) + html.required.set(true) + } } +} +subprojects.of("project", except = listOf(projects.projects.kediatrTesting.name)) { mavenPublishing { coordinates(groupId = rootProject.group.toString(), artifactId = project.name, version = rootProject.version.toString()) publishToMavenCentral() @@ -57,3 +116,21 @@ subprojectsOf("projects") { signAllPublications() } } + +fun Project.configureKotlin(isKmp: Boolean) { + val kotlinExtension = if (isKmp) { + extensions.getByType() + } else { + extensions.getByType() + } + + kotlinExtension.apply { + jvmToolchain(17) + compilerOptions { + val commonArgs = listOf("-Xskip-metadata-version-check", "-Xexpect-actual-classes") + val args = if (isKmp) commonArgs else listOf("-Xjsr305=strict") + commonArgs + freeCompilerArgs.addAll(args) + allWarningsAsErrors.set(true) + } + } +} diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock new file mode 100644 index 0000000..1f2589a --- /dev/null +++ b/kotlin-js-store/yarn.lock @@ -0,0 +1,2167 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@discoveryjs/json-ext@^0.6.1": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83" + integrity sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@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/source-map@^0.3.3": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@socket.io/component-emitter@~3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" + integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== + +"@types/cors@^2.8.12": + version "2.8.19" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" + integrity sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.8": + 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.15", "@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 "24.10.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.1.tgz#91e92182c93db8bd6224fca031e2370cef9a8f01" + integrity sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ== + dependencies: + undici-types "~7.16.0" + +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.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.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.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.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" + +"@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.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.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.14.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.14.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@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-3.0.1.tgz#76ac285b9658fa642ce238c276264589aa2b6b57" + integrity sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA== + +"@webpack-cli/info@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-3.0.1.tgz#3cff37fabb7d4ecaab6a8a4757d3826cf5888c63" + integrity sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ== + +"@webpack-cli/serve@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-3.0.1.tgz#bd8b1f824d57e30faa19eb78e4c0951056f72f00" + integrity sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +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@^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@^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-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +baseline-browser-mapping@^2.8.25: + version "2.8.30" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.30.tgz#5c7420acc2fd20f3db820a40c6521590a671d137" + integrity sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +body-parser@^1.19.0: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.13.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.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.24.0: + version "4.28.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.0.tgz#9cefece0a386a17a3cd3d22ebf67b9deca1b5929" + integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ== + dependencies: + baseline-browser-mapping "^2.8.25" + caniuse-lite "^1.0.30001754" + electron-to-chromium "^1.5.249" + node-releases "^2.0.27" + update-browserslist-db "^1.1.4" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bound@^1.0.2, call-bound@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001754: + version "1.0.30001756" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz#fe80104631102f88e58cad8aa203a2c3e5ec9ebd" + integrity sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.1: + 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" + +chokidar@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== + dependencies: + readdirp "^4.0.1" + +chrome-trace-event@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.14: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + +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== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +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" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.3.4, debug@^4.3.5: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +debug@~4.3.1, debug@~4.3.2, 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" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +diff@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" + integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ee-first@1.1.1: + version "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.5.249: + version "1.5.259" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.259.tgz#d4393167ec14c5a046cebaec3ddf3377944ce965" + integrity sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encodeurl@~1.0.2: + version "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.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.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/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.7.2" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.17.1" + +enhanced-resolve@^5.17.2: + version "5.18.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" + integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.2.tgz#22a5ed2fd7ce0cbcff1d1474cf4909a44bdb6e85" + integrity sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + punycode "^1.4.1" + safe-regex-test "^1.1.0" + +envinfo@^7.14.0: + version "7.20.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.20.0.tgz#3fd9de69fb6af3e777a017dfa033676368d67dd7" + integrity sha512-+zUomDcLXsVkQ37vUqWBvQwLaLlj8eZPSi61llaEFAVBY5mhcXdaSw1pSJVl4yTYD5g/gEfpNl28YYk4IPvrrg== + +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +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== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +escalade@^3.1.1, 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: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +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== + +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.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" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + 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" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.7: + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== + +follow-redirects@^1.0.0: + version "1.15.11" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" + integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== + +foreground-child@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + +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== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +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" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "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@^10.4.5: + version "10.5.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" + integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +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.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + 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" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +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== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +import-local@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +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" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.16.1: + 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: + hasown "^2.0.2" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" + integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== + dependencies: + call-bound "^1.0.2" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +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" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +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" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +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.2.10" + +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 "^9.0.3" + webpack-merge "^4.1.5" + +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" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.7.2" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + 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.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-2.1.0.tgz#6cd4b0f0dc3baea163929c8638155b8d19c55a74" + integrity sha512-NAJhiNB84tnvJ5EQx7iER3GWw7rsTZkX9HVHZpe7E3dDBD/dhTzqgSwNU3MfQjniy2rB04bP24WM9Z32ntUWRg== + dependencies: + format-util "^1.0.5" + +loader-runner@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +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== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.4.1: + version "6.9.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6" + integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.5" + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5: + 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.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@11.7.1: + version "11.7.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.7.1.tgz#91948fecd624fb4bd154ed260b7e1ad3910d7c7a" + integrity sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A== + dependencies: + browser-stdout "^1.3.1" + chokidar "^4.0.1" + debug "^4.3.5" + diff "^7.0.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^10.4.5" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^9.0.5" + ms "^2.1.3" + picocolors "^1.1.1" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^9.2.0" + yargs "^17.7.2" + yargs-parser "^21.1.1" + yargs-unparser "^2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +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== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "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.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +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" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" + integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +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.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" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.20.0: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rfdc@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" + integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + is-regex "^1.2.1" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^4.3.0, schema-utils@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== + 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" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.0.6: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +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.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.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.6.0" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + +source-map-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +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: + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@0.5.21, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +streamroller@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.5.tgz#1263182329a45def1ffaef58d31b15d13d2ee7ff" + integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" + integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== + dependencies: + ansi-regex "^6.0.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@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + 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" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== + +terser-webpack-plugin@^5.3.11: + 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.25" + jest-worker "^27.4.5" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" + +terser@^5.31.1: + version "5.44.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.1.tgz#e391e92175c299b8c284ad6ded609e37303b0a9c" + integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.15.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +tmp@^0.2.1: + version "0.2.5" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" + integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +ua-parser-js@^0.7.30: + version "0.7.41" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.41.tgz#9f6dee58c389e8afababa62a4a2dc22edb69a452" + integrity sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg== + +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "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.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" + integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@^1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +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@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" + integrity sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw== + dependencies: + "@discoveryjs/json-ext" "^0.6.1" + "@webpack-cli/configtest" "^3.0.1" + "@webpack-cli/info" "^3.0.1" + "@webpack-cli/serve" "^3.0.1" + colorette "^2.0.14" + commander "^12.1.0" + cross-spawn "^7.0.3" + envinfo "^7.14.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^6.0.1" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" + integrity sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.1" + +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== + +webpack@5.100.2: + version "5.100.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.100.2.tgz#e2341facf9f7de1d702147c91bcb65b693adf9e8" + integrity sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw== + dependencies: + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.24.0" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.17.2" + 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.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 "^4.3.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.11" + watchpack "^2.4.1" + webpack-sources "^3.3.3" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +workerpool@^9.2.0: + version "9.3.4" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-9.3.4.tgz#f6c92395b2141afd78e2a889e80cb338fe9fca41" + integrity sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +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.2: + 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-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +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== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/projects/build.gradle.kts b/projects/build.gradle.kts deleted file mode 100644 index 26a71b2..0000000 --- a/projects/build.gradle.kts +++ /dev/null @@ -1,55 +0,0 @@ -plugins { - kotlin("jvm") version libs.versions.kotlin.get() - alias(libs.plugins.testLogger) - alias(libs.plugins.kover) -} - -subprojects { - apply { - plugin(rootProject.libs.plugins.kover.pluginId) - plugin(rootProject.libs.plugins.testLogger.pluginId) - } - - kotlin { - jvmToolchain(17) - compilerOptions { - freeCompilerArgs = listOf("-Xjsr305=strict", "-Xskip-metadata-version-check") - allWarningsAsErrors = true - } - } - - kover { - reports { - filters { - excludes { - packages("com.trendyol.kediatr.testing") - } - } - } - } - - dependencies { - implementation(rootProject.libs.kotlinx.coroutines.core) - kover(this@subprojects) - } - - dependencies { - testImplementation(rootProject.libs.kotlinx.coroutines.test) - testImplementation(rootProject.libs.kotest.assertions.core) - testImplementation(rootProject.libs.kotest.assertions.table) - testImplementation(rootProject.libs.kotest.framework.engine) - testImplementation(rootProject.libs.kotest.runner.junit5) - } - - tasks.test { - useJUnitPlatform() - testlogger { - setTheme("mocha") - showStandardStreams = true - } - reports { - junitXml.required.set(true) - html.required.set(true) - } - } -} diff --git a/projects/kediatr-core/build.gradle.kts b/projects/kediatr-core/build.gradle.kts index 2dee25a..2f89c5c 100644 --- a/projects/kediatr-core/build.gradle.kts +++ b/projects/kediatr-core/build.gradle.kts @@ -1,26 +1,42 @@ plugins { - `java-test-fixtures` + kotlin("multiplatform") } -val testFixturesImplementation: Configuration by configurations.getting { - extendsFrom(configurations.implementation.get()) -} +kotlin { + jvm() -dependencies { - testFixturesImplementation(libs.kotest.assertions.core) - testFixturesImplementation(libs.kotest.runner.junit5) - testFixturesImplementation(junitLibs.junitJupiterApi) - testFixturesImplementation(libs.kotlinx.coroutines.test) - testFixturesRuntimeOnly(junitLibs.junitJupiterEngine) -} + js(IR) { + browser() + nodejs() + } -kotlin { - jvmToolchain(11) -} + iosArm64() + iosX64() + iosSimulatorArm64() + + macosArm64() + macosX64() + + linuxX64() + linuxArm64() + + mingwX64() -val javaComponent = components["java"] as AdhocComponentWithVariants -javaComponent.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() } -javaComponent.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() } -afterEvaluate { - javaComponent.withVariantsFromConfiguration(configurations["testFixturesSourcesElements"]) { skip() } + sourceSets { + commonMain { + dependencies { + implementation(libs.kotlinx.coroutines.core) + } + } + jvmTest { + dependencies { + implementation(projects.projects.kediatrTesting) + implementation(libs.kotest.assertions.core) + implementation(libs.kotest.framework.engine) + implementation(libs.kotlinx.coroutines.test) + implementation(libs.kotest.runner.junit5) + implementation(kotlin("test")) + } + } + } } diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CachedRegistry.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/CachedRegistry.kt similarity index 91% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CachedRegistry.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/CachedRegistry.kt index 2350d03..ba8d388 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CachedRegistry.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/CachedRegistry.kt @@ -1,8 +1,6 @@ -@file:Suppress("UNCHECKED_CAST") - package com.trendyol.kediatr -import java.util.concurrent.ConcurrentHashMap +import kotlin.reflect.KClass /** * A caching wrapper around the Registry interface that improves performance by caching resolved handlers. @@ -24,6 +22,7 @@ import java.util.concurrent.ConcurrentHashMap * @see Registry * @see RegistryImpl */ +@Suppress("UNCHECKED_CAST") internal class CachedRegistry( private val delegate: Registry ) : Registry { @@ -31,13 +30,13 @@ internal class CachedRegistry( * Cache for request handlers. Key is the request class, value is the resolved handler. * Uses ConcurrentHashMap for thread-safe access without explicit synchronization. */ - private val requestHandlerCache = ConcurrentHashMap, RequestHandler<*, *>>() + private val requestHandlerCache = createConcurrentMap, RequestHandler<*, *>>() /** * Cache for notification handlers. Key is the notification class, value is the collection of handlers. * Uses ConcurrentHashMap for thread-safe access without explicit synchronization. */ - private val notificationHandlerCache = ConcurrentHashMap, Collection>>() + private val notificationHandlerCache = createConcurrentMap, Collection>>() /** * Cache for pipeline behaviors. Since pipeline behaviors apply to all requests, @@ -63,8 +62,8 @@ internal class CachedRegistry( * @throws HandlerNotFoundException if no handler is found for the request type */ override fun , TResult> resolveHandler( - classOfRequest: Class - ): RequestHandler = requestHandlerCache.computeIfAbsent(classOfRequest) { + classOfRequest: KClass + ): RequestHandler = requestHandlerCache.getOrPut(classOfRequest) { delegate.resolveHandler(classOfRequest) } as RequestHandler @@ -84,8 +83,8 @@ internal class CachedRegistry( * @return The cached or newly resolved collection of notification handlers */ override fun resolveNotificationHandlers( - classOfNotification: Class - ): Collection> = notificationHandlerCache.computeIfAbsent(classOfNotification) { + classOfNotification: KClass + ): Collection> = notificationHandlerCache.getOrPut(classOfNotification) { delegate.resolveNotificationHandlers(classOfNotification) } as Collection> diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Container.kt similarity index 69% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Container.kt index b2b597d..2da0629 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Container.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Internal container class that manages the registration and storage of handlers and pipeline behaviors. * @@ -27,13 +29,13 @@ internal class Container( * Map storing request handlers where the key is the request class and the value is the request provider. * Each request type should have exactly one handler. */ - val requestHandlerMap = HashMap, RequestProvider, *>>>() + val requestHandlerMap = HashMap, RequestProvider, *>>>() /** * Map storing notification handlers where the key is the notification class and the value is a list of providers. * Multiple handlers can be registered for the same notification type. */ - val notificationMap = HashMap, MutableList>>>() + val notificationMap = HashMap, MutableList>>>() /** * Set storing all pipeline behavior providers. Pipeline behaviors are applied to all requests. @@ -43,10 +45,20 @@ internal class Container( init { registerFor, *>, Request<*>>(dependencyProvider) { key, value -> if (requestHandlerMap.containsKey(key)) { + // We need to instantiate the existing handler to get its class name? + // Or just keep the provider? RequestProvider stores the type. + // RequestProvider is private field 'type'. We can't access it easily. + // But we can call get(). + // But get() creates an instance. + // Let's try to improve the error message if possible, or just accept simpleName of existing handler. + + // Wait, we can't easily get the type from RequestProvider because 'type' is private. + // But we can change RequestProvider to expose 'type'. + // Or just instantiate it. + error( - "Multiple handlers registered for request type: ${key.name}" + - "\nExisting handler: ${requestHandlerMap[key]!!.get().javaClass.name}" + - "\nDuplicate handler: ${value.name}" + "Multiple handlers registered for request type: ${key.simpleName}" + + "\nDuplicate handler: ${value.simpleName}" ) } requestHandlerMap[key] = RequestProvider(dependencyProvider, value) @@ -56,7 +68,7 @@ internal class Container( registerFor, Notification>(dependencyProvider) { key, value -> notificationMap .getOrPut(key) { mutableListOf() } - .add(NotificationProvider(dependencyProvider, value as Class>)) + .add(NotificationProvider(dependencyProvider, value as KClass>)) } // Register pipeline behaviors - applied to all requests diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/DependencyProvider.kt similarity index 89% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/DependencyProvider.kt index e19cbfa..188abf1 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/DependencyProvider.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Dependency provider interface for resolving handler instances and discovering subtypes. * @@ -23,7 +25,7 @@ interface DependencyProvider { * @return A single instance of the specified type * @throws Exception if the instance cannot be resolved or multiple instances are found */ - fun getSingleInstanceOf(clazz: Class): T + fun getSingleInstanceOf(clazz: KClass): T /** * Gets all subtypes of the specified class. @@ -36,5 +38,5 @@ interface DependencyProvider { * @param clazz The class object representing the base type * @return A collection of all classes that extend or implement the specified type */ - fun getSubTypesOf(clazz: Class): Collection> + fun getSubTypesOf(clazz: KClass): Collection> } diff --git a/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Dispatchers.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Dispatchers.kt new file mode 100644 index 0000000..d635760 --- /dev/null +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Dispatchers.kt @@ -0,0 +1,9 @@ +package com.trendyol.kediatr + +import kotlinx.coroutines.CoroutineDispatcher + +/** + * Platform-specific default dispatcher for I/O operations + */ +expect val DefaultDispatcher: CoroutineDispatcher + diff --git a/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt new file mode 100644 index 0000000..31c5068 --- /dev/null +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt @@ -0,0 +1,69 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass + +/** + * Dependency provider implementation that uses a map to resolve dependencies. + * + * This is a simple, map-based dependency provider that can be used for testing + * or scenarios where you want to manually configure handlers without a full + * dependency injection framework. It stores handler instances in a HashMap + * and resolves them by their class type. + * + * @param handlerMap A map that contains the handlers where the key is the handler class + * and the value is the handler instance + * @see DependencyProvider + * @see Mediator + */ +@Suppress("UNCHECKED_CAST") +class HandlerRegistryProvider( + private val handlerMap: Map, Any> +) : DependencyProvider { + /** + * Gets a single instance of the specified class from the handler map. + * + * @param T The type of instance to resolve + * @param clazz The class object representing the type to resolve + * @return The handler instance from the map + * @throws ClassCastException if the stored instance cannot be cast to the requested type + * @throws NullPointerException if no handler is found for the specified class + */ + override fun getSingleInstanceOf(clazz: KClass): T = handlerMap[clazz] as T + + /** + * Gets all subtypes of the specified class from the handler map. + * + * This method searches through all registered handlers and returns those that + * are compatible with the specified base class or interface. It supports + * complex type hierarchies including generic interfaces and inheritance chains. + * + * @param T The base type to find subtypes for + * @param clazz The class object representing the base type + * @return A collection of all classes that extend or implement the specified type + */ + override fun getSubTypesOf(clazz: KClass): Collection> = handlerMap.keys + .filter { ReflectionUtils.isAssignableFrom(clazz, it) } + .map { it as KClass } + + companion object { + /** + * Creates a mediator instance with the given handlers using a mapping dependency provider. + * + * This is a convenient factory method for creating a mediator with a predefined set of handlers. + * It's particularly useful for testing scenarios or simple applications that don't require + * a full dependency injection framework. + * + * @param handlers The handlers to be used by the mediator. Can include any combination of + * RequestHandler, NotificationHandler, and PipelineBehavior instances + * @return A configured mediator instance ready for use + * @see RequestHandler + * @see NotificationHandler + * @see PipelineBehavior + */ + fun createMediator(handlers: List = emptyList()): Mediator { + val provider = HandlerRegistryProvider(handlers.associateBy { it::class }) + val mediator = Mediator.build(provider) + return mediator + } + } +} diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Mediator.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Mediator.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/MediatorImpl.kt similarity index 92% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/MediatorImpl.kt index e1e6416..4409b1c 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/MediatorImpl.kt @@ -31,7 +31,7 @@ internal class MediatorImpl( */ override suspend fun , TResponse> send( request: TRequest - ): TResponse = handle(request) { registry.resolveHandler(it.javaClass).handle(it) } + ): TResponse = handle(request) { registry.resolveHandler(it::class as kotlin.reflect.KClass).handle(it) } /** * Publishes a notification using the specified publish strategy. @@ -43,7 +43,7 @@ internal class MediatorImpl( override suspend fun publish( notification: T, publishStrategy: PublishStrategy - ) = handle(notification) { publishStrategy.publish(notification, registry.resolveNotificationHandlers(notification.javaClass)) } + ) = handle(notification) { publishStrategy.publish(notification, registry.resolveNotificationHandlers(notification::class as kotlin.reflect.KClass)) } /** * Executes the message through the pipeline of behaviors. diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/NotificationHandler.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/NotificationHandler.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/NotificationProvider.kt similarity index 95% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/NotificationProvider.kt index 3fa7d6f..5fc62a6 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/NotificationProvider.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Internal provider class for creating notification handler instances with dependency injection support. * @@ -17,7 +19,7 @@ package com.trendyol.kediatr */ internal class NotificationProvider>( private val dependencyProvider: DependencyProvider, - private val type: Class + private val type: KClass ) { /** * Creates and returns a new instance of the notification handler. diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PipelineBehavior.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PipelineBehavior.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PipelineProvider.kt similarity index 95% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PipelineProvider.kt index bae06d2..8d3f16c 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PipelineProvider.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Internal provider class for creating pipeline behavior instances with dependency injection support. * @@ -17,7 +19,7 @@ package com.trendyol.kediatr */ internal class PipelineProvider( private val dependencyProvider: DependencyProvider, - private val type: Class + private val type: KClass ) { /** * Creates and returns a new instance of the pipeline behavior. diff --git a/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Platform.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Platform.kt new file mode 100644 index 0000000..633000f --- /dev/null +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Platform.kt @@ -0,0 +1,3 @@ +package com.trendyol.kediatr + +expect fun createConcurrentMap(): MutableMap diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PublishStrategies.kt similarity index 97% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PublishStrategies.kt index fb43b3f..e2ee58c 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/PublishStrategies.kt @@ -10,12 +10,12 @@ interface PublishStrategy { * @param T The type of notification to publish * @param notification The notification instance to publish * @param notificationHandlers Collection of handlers that will process the notification - * @param dispatcher The coroutine dispatcher to use for execution (defaults to Dispatchers.IO) + * @param dispatcher The coroutine dispatcher to use for execution (defaults to platform-specific DefaultDispatcher) */ suspend fun publish( notification: T, notificationHandlers: Collection>, - dispatcher: CoroutineDispatcher = Dispatchers.IO + dispatcher: CoroutineDispatcher = DefaultDispatcher ) companion object { diff --git a/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/ReflectionUtils.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/ReflectionUtils.kt new file mode 100644 index 0000000..db158a1 --- /dev/null +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/ReflectionUtils.kt @@ -0,0 +1,16 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass + +public expect object ReflectionUtils { + fun isAbstract(kClass: KClass<*>): Boolean + fun isAssignableFrom(superType: KClass, subType: KClass<*>): Boolean + fun getSuperclass(kClass: KClass<*>): KClass<*>? + + /** + * Finds the generic parameter type of the handler interface implemented by handlerClass. + * E.g. if handlerClass implements RequestHandler, and handlerInterface is RequestHandler, + * this returns MyRequest. + */ + fun getHandlerParameterType(handlerClass: KClass<*>, handlerInterface: KClass<*>): KClass<*>? +} diff --git a/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registrar.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registrar.kt new file mode 100644 index 0000000..68f9977 --- /dev/null +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registrar.kt @@ -0,0 +1,48 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass + +/** + * Abstract base class that provides handler registration functionality. + * + * This class contains the core logic for discovering and registering handlers from a dependency provider. + * It uses ReflectionUtils to analyze handler implementations and extract the types they handle. + * + * @see Container + * @see DependencyProvider + */ +@Suppress("UNCHECKED_CAST") +internal abstract class Registrar { + /** + * Registers handlers that handle a specific parameter type (used for requests and notifications). + */ + protected inline fun registerFor( + dependencyProvider: DependencyProvider, + noinline registrar: (key: KClass, value: KClass) -> Unit + ) { + val handlerInterface = THandler::class + dependencyProvider.getSubTypesOf(handlerInterface) + .filter { !ReflectionUtils.isAbstract(it) } + .forEach { handler -> + val paramType = ReflectionUtils.getHandlerParameterType(handler, handlerInterface) + if (paramType != null) { + registrar(paramType as KClass, handler as KClass) + } + } + } + + /** + * Registers handlers that don't require parameter type mapping (used for pipeline behaviors). + */ + protected inline fun registerFor( + dependencyProvider: DependencyProvider, + noinline registrar: (value: KClass) -> Unit + ) { + dependencyProvider.getSubTypesOf(T::class) + .forEach { handler -> + if (!ReflectionUtils.isAbstract(handler)) { + registrar(handler) + } + } + } +} diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registry.kt similarity index 94% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registry.kt index 506fa27..2a0bb37 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/Registry.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Registry interface for resolving handlers and pipeline behaviors. * @@ -27,7 +29,7 @@ internal interface Registry { * @throws HandlerNotFoundException if no handler is found for the request type * @throws IllegalStateException if multiple handlers are found for the request type */ - fun , TResult> resolveHandler(classOfRequest: Class): RequestHandler + fun , TResult> resolveHandler(classOfRequest: KClass): RequestHandler /** * Resolves all notification handlers for the specified notification type. @@ -40,7 +42,7 @@ internal interface Registry { * @return A collection of all notification handlers for the specified notification type */ fun resolveNotificationHandlers( - classOfNotification: Class + classOfNotification: KClass ): Collection> /** diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RegistryImpl.kt similarity index 89% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RegistryImpl.kt index efed790..8dc3967 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RegistryImpl.kt @@ -2,6 +2,8 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Default implementation of the Registry interface. * @@ -45,10 +47,10 @@ internal class RegistryImpl( * @throws HandlerNotFoundException if no handler is found for the request type or its base types */ override fun , TResult> resolveHandler( - classOfRequest: Class + classOfRequest: KClass ): RequestHandler { val handler = registry.requestHandlerMap[classOfRequest]?.get() - ?: registry.requestHandlerMap[baseClassOrItself(classOfRequest, Request::class.java)]?.get() + ?: registry.requestHandlerMap[baseClassOrItself(classOfRequest, Request::class)]?.get() ?: throw HandlerNotFoundException( requestType = classOfRequest, availableHandlers = registry.requestHandlerMap.keys.toList() @@ -69,9 +71,9 @@ internal class RegistryImpl( * @return A collection of all notification handlers that can process the specified notification type */ override fun resolveNotificationHandlers( - classOfNotification: Class + classOfNotification: KClass ): Collection> = registry.notificationMap - .filter { (k, _) -> k.isAssignableFrom(classOfNotification) } + .filter { (k, _) -> ReflectionUtils.isAssignableFrom(k, classOfNotification) } .flatMap { (_, v) -> v.map { it.get() as NotificationHandler } } /** @@ -114,11 +116,11 @@ internal class RegistryImpl( * returns [clazz]. */ private fun baseClassOrItself( - clazz: Class<*>, - clazzWanted: Class<*> - ): Class<*> = - generateSequence(clazz) { it.superclass } // ↪ generate the chain: clazz, clazz.superclass, clazz.superclass.superclass, … - .filter { clazzWanted.isAssignableFrom(it) } // ↪ keep only those that actually "implement/extend" clazzWanted + clazz: KClass<*>, + clazzWanted: KClass<*> + ): KClass<*> = + generateSequence(clazz) { ReflectionUtils.getSuperclass(it) } // ↪ generate the chain: clazz, clazz.superclass, clazz.superclass.superclass, … + .filter { ReflectionUtils.isAssignableFrom(clazzWanted, it) } // ↪ keep only those that actually "implement/extend" clazzWanted .lastOrNull() // ↪ pick the *last* (farthest‐up) match ?: clazz // ↪ if none matched, return the original clazz } diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestHandler.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestHandler.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestHandler.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestHandler.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestHandlerDelegate.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestHandlerDelegate.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestHandlerDelegate.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestHandlerDelegate.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestProvider.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestProvider.kt similarity index 94% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestProvider.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestProvider.kt index b904a8e..7985e9b 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RequestProvider.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/RequestProvider.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Internal provider class for creating request handler instances with dependency injection support. * @@ -15,7 +17,7 @@ package com.trendyol.kediatr */ internal class RequestProvider>( private val dependencyProvider: DependencyProvider, - private val type: Class + private val type: KClass ) { /** * Creates and returns a new instance of the request handler. diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/exceptions.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/exceptions.kt similarity index 91% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/exceptions.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/exceptions.kt index 3321a3f..84455fb 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/exceptions.kt +++ b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/exceptions.kt @@ -1,5 +1,7 @@ package com.trendyol.kediatr +import kotlin.reflect.KClass + /** * Exception thrown when no handler is found for a specific request type. * @@ -13,12 +15,12 @@ package com.trendyol.kediatr * @see DependencyProvider */ class HandlerNotFoundException( - val requestType: Class<*>, - val availableHandlers: List> + val requestType: KClass<*>, + val availableHandlers: List> ) : Exception() { override val message: String get() = buildString { - appendLine("Handler not found for ${requestType.typeName}") + appendLine("Handler not found for ${requestType.simpleName}") appendLine("Available handlers: ${availableHandlers.map { it.simpleName }}") } } diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/messages.kt b/projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/messages.kt similarity index 100% rename from projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/messages.kt rename to projects/kediatr-core/src/commonMain/kotlin/com/trendyol/kediatr/messages.kt diff --git a/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Dispatchers.js.kt b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Dispatchers.js.kt new file mode 100644 index 0000000..32989e0 --- /dev/null +++ b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Dispatchers.js.kt @@ -0,0 +1,7 @@ +package com.trendyol.kediatr + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +actual val DefaultDispatcher: CoroutineDispatcher = Dispatchers.Default + diff --git a/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Platform.js.kt b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Platform.js.kt new file mode 100644 index 0000000..ba4b17f --- /dev/null +++ b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/Platform.js.kt @@ -0,0 +1,7 @@ +package com.trendyol.kediatr + +actual fun createConcurrentMap(): MutableMap { + // JavaScript is single-threaded, so a regular mutableMapOf is sufficient + return mutableMapOf() +} + diff --git a/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/ReflectionUtils.js.kt b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/ReflectionUtils.js.kt new file mode 100644 index 0000000..01e4bf8 --- /dev/null +++ b/projects/kediatr-core/src/jsMain/kotlin/com/trendyol/kediatr/ReflectionUtils.js.kt @@ -0,0 +1,31 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass + +public actual object ReflectionUtils { + actual fun isAbstract(kClass: KClass<*>): Boolean { + // JS reflection is limited, we assume classes passed here are not abstract + return false + } + + actual fun isAssignableFrom(superType: KClass, subType: KClass<*>): Boolean { + // Check if subType is the same as superType + if (superType == subType) return true + + // For JS platforms, we have limited reflection capabilities + // This is a simplified implementation + return false + } + + actual fun getSuperclass(kClass: KClass<*>): KClass<*>? { + // Kotlin/JS has limited reflection support + return null + } + + actual fun getHandlerParameterType(handlerClass: KClass<*>, handlerInterface: KClass<*>): KClass<*>? { + // Kotlin/JS doesn't support full generic type reflection + // This functionality requires manual registration + return null + } +} + diff --git a/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Dispatchers.jvm.kt b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Dispatchers.jvm.kt new file mode 100644 index 0000000..86645c0 --- /dev/null +++ b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Dispatchers.jvm.kt @@ -0,0 +1,7 @@ +package com.trendyol.kediatr + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +actual val DefaultDispatcher: CoroutineDispatcher = Dispatchers.IO + diff --git a/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Platform.jvm.kt b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Platform.jvm.kt new file mode 100644 index 0000000..fbf12f0 --- /dev/null +++ b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/Platform.jvm.kt @@ -0,0 +1,4 @@ +package com.trendyol.kediatr +import java.util.concurrent.ConcurrentHashMap + +actual fun createConcurrentMap(): MutableMap = ConcurrentHashMap() diff --git a/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/ReflectionUtils.jvm.kt b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/ReflectionUtils.jvm.kt new file mode 100644 index 0000000..568160d --- /dev/null +++ b/projects/kediatr-core/src/jvmMain/kotlin/com/trendyol/kediatr/ReflectionUtils.jvm.kt @@ -0,0 +1,78 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass +import java.lang.reflect.Modifier +import java.lang.reflect.ParameterizedType +import java.lang.reflect.TypeVariable + +public actual object ReflectionUtils { + actual fun isAbstract(kClass: KClass<*>): Boolean { + return Modifier.isAbstract(kClass.java.modifiers) + } + + actual fun isAssignableFrom(superType: KClass, subType: KClass<*>): Boolean { + return superType.java.isAssignableFrom(subType.java) + } + + actual fun getSuperclass(kClass: KClass<*>): KClass<*>? { + return kClass.java.superclass?.kotlin + } + + actual fun getHandlerParameterType(handlerClass: KClass<*>, handlerInterface: KClass<*>): KClass<*>? { + val handlerJava = handlerClass.java + val interfaceJava = handlerInterface.java + + if (!interfaceJava.isAssignableFrom(handlerJava)) return null + + return findParameterType(handlerJava, interfaceJava)?.kotlin + } + + private fun findParameterType(handler: Class<*>, targetInterface: Class<*>): Class<*>? { + // Check directly implemented interfaces + handler.genericInterfaces + .filterIsInstance() + .filter { + val raw = it.rawType as Class<*> + targetInterface.isAssignableFrom(raw) + } + .forEach { + return extractParameterFromRegistrarLogic(it) + } + + // Check superclass + val genericSuperclass = handler.genericSuperclass + if (genericSuperclass is ParameterizedType) { + val inheritedHandler = genericSuperclass.rawType as Class<*> + if (targetInterface.isAssignableFrom(inheritedHandler)) { + return extractParameterFromRegistrarLogic(genericSuperclass) + } + } else if (genericSuperclass is Class<*>) { + if (targetInterface.isAssignableFrom(genericSuperclass)) { + return findParameterType(genericSuperclass, targetInterface) + } + } + + return null + } + + private fun extractParameterFromRegistrarLogic(genericInterface: ParameterizedType): Class<*> { + return when (val typeArgument = genericInterface.actualTypeArguments[0]) { + is ParameterizedType -> { + typeArgument.rawType as Class<*> + } + + is TypeVariable<*> -> { + val rawType = (genericInterface.rawType as Class<*>) + if (rawType.genericInterfaces.isNotEmpty()) { + extractParameterFromRegistrarLogic(rawType.genericInterfaces[0] as ParameterizedType) + } else { + rawType + } + } + + else -> { + typeArgument as Class<*> + } + } + } +} diff --git a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt similarity index 93% rename from projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt rename to projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt index da69b39..bf74e0b 100644 --- a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt +++ b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryPerformanceTest.kt @@ -36,7 +36,7 @@ class CachedRegistryPerformanceTest : AnotherPingHandler() ) - val provider = HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>) + val provider = HandlerRegistryProvider(handlers.associateBy { it::class }) val uncachedRegistry = RegistryImpl(provider) val cachedRegistry = CachedRegistry(uncachedRegistry) @@ -44,27 +44,27 @@ class CachedRegistryPerformanceTest : // Warm up both registries repeat(100) { - uncachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) - cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) + uncachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) + cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) } // Benchmark uncached registry val uncachedTime = measureTimeMillis { repeat(iterations) { - uncachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) - uncachedRegistry.resolveNotificationHandlers(PingForInherited::class.java) - uncachedRegistry.resolveNotificationHandlers(ExtendedPing::class.java) - uncachedRegistry.resolveNotificationHandlers(Ping::class.java) + uncachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) + uncachedRegistry.resolveNotificationHandlers(PingForInherited::class) + uncachedRegistry.resolveNotificationHandlers(ExtendedPing::class) + uncachedRegistry.resolveNotificationHandlers(Ping::class) } } // Benchmark cached registry val cachedTime = measureTimeMillis { repeat(iterations) { - cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) - cachedRegistry.resolveNotificationHandlers(PingForInherited::class.java) - cachedRegistry.resolveNotificationHandlers(ExtendedPing::class.java) - cachedRegistry.resolveNotificationHandlers(Ping::class.java) + cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) + cachedRegistry.resolveNotificationHandlers(PingForInherited::class) + cachedRegistry.resolveNotificationHandlers(ExtendedPing::class) + cachedRegistry.resolveNotificationHandlers(Ping::class) } } @@ -91,7 +91,7 @@ class CachedRegistryPerformanceTest : ThirdPipelineBehaviour() ) - val provider = HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>) + val provider = HandlerRegistryProvider(handlers.associateBy { it::class }) val uncachedRegistry = RegistryImpl(provider) val cachedRegistry = CachedRegistry(uncachedRegistry) @@ -145,7 +145,7 @@ class CachedRegistryPerformanceTest : LoggingPipelineBehavior() ) - val provider = HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>) + val provider = HandlerRegistryProvider(handlers.associateBy { it::class }) val cachedRegistry = CachedRegistry(RegistryImpl(provider)) // Act & Assert @@ -156,9 +156,9 @@ class CachedRegistryPerformanceTest : initialStats.pipelineBehaviorCacheSize shouldBe 2 // Populate caches - cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) - cachedRegistry.resolveHandler(TestCommandForInheritance::class.java) - cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) + cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) + cachedRegistry.resolveHandler(TestCommandForInheritance::class) + cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) cachedRegistry.getPipelineBehaviors() val finalStats = cachedRegistry.getCacheStatistics() diff --git a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt similarity index 85% rename from projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt rename to projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt index 0dbad7c..b6168b3 100644 --- a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt +++ b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/CachedRegistryTest.kt @@ -15,12 +15,12 @@ class CachedRegistryTest : // Arrange val testHandler = TestRequestHandlerWithoutInjection() val handlers = listOf(testHandler) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act - val firstCall = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) - val secondCall = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) + val firstCall = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) + val secondCall = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) // Assert firstCall shouldBeSameInstanceAs secondCall @@ -31,12 +31,12 @@ class CachedRegistryTest : val commandHandler = TestRequestHandlerWithoutInjection() val inheritedHandler = TestInheritedRequestHandlerForSpecificCommand() val handlers = listOf(commandHandler, inheritedHandler) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act - val resolvedCommandHandler = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) - val resolvedInheritedHandler = cachedRegistry.resolveHandler(TestCommandForInheritance::class.java) + val resolvedCommandHandler = cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) + val resolvedInheritedHandler = cachedRegistry.resolveHandler(TestCommandForInheritance::class) // Assert resolvedCommandHandler shouldNotBe resolvedInheritedHandler @@ -44,20 +44,20 @@ class CachedRegistryTest : should("propagate exceptions from underlying registry") { // Arrange - empty registry will throw HandlerNotFoundException - val baseRegistry = RegistryImpl(HandlerRegistryProvider(hashMapOf())) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(emptyMap())) val cachedRegistry = CachedRegistry(baseRegistry) // Act & Assert var exceptionCount = 0 try { - cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) + cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) } catch (_: HandlerNotFoundException) { exceptionCount++ } // Verify exception is not cached - should throw again try { - cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class.java) + cachedRegistry.resolveHandler(TestCommandForWithoutInjection::class) } catch (e: HandlerNotFoundException) { exceptionCount++ } @@ -71,12 +71,12 @@ class CachedRegistryTest : // Arrange val notificationHandler = Handler1ForNotificationOfMultipleHandlers() val handlers = listOf(notificationHandler) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act - val firstCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) - val secondCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) + val firstCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) + val secondCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) // Assert firstCall shouldBeSameInstanceAs secondCall @@ -84,12 +84,12 @@ class CachedRegistryTest : should("cache empty collections for notifications with no handlers") { // Arrange - empty registry will return empty collection - val baseRegistry = RegistryImpl(HandlerRegistryProvider(hashMapOf())) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(emptyMap())) val cachedRegistry = CachedRegistry(baseRegistry) // Act - val firstCall = cachedRegistry.resolveNotificationHandlers(TestNotification::class.java) - val secondCall = cachedRegistry.resolveNotificationHandlers(TestNotification::class.java) + val firstCall = cachedRegistry.resolveNotificationHandlers(TestNotification::class) + val secondCall = cachedRegistry.resolveNotificationHandlers(TestNotification::class) // Assert firstCall shouldBeSameInstanceAs secondCall @@ -101,12 +101,12 @@ class CachedRegistryTest : val handler1 = Handler1ForNotificationOfMultipleHandlers() val handler2 = Handler2ForNotificationOfMultipleHandlers() val handlers = listOf(handler1, handler2) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act - val firstCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) - val secondCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class.java) + val firstCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) + val secondCall = cachedRegistry.resolveNotificationHandlers(NotificationForMultipleHandlers::class) // Assert firstCall shouldBeSameInstanceAs secondCall @@ -119,7 +119,7 @@ class CachedRegistryTest : // Arrange val pipelineBehavior = ExceptionPipelineBehavior() val handlers = listOf(pipelineBehavior) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act @@ -135,7 +135,7 @@ class CachedRegistryTest : val behavior1 = ExceptionPipelineBehavior() val behavior2 = LoggingPipelineBehavior() val handlers = listOf(behavior1, behavior2) - val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>)) + val baseRegistry = RegistryImpl(HandlerRegistryProvider(handlers.associateBy { it::class })) val cachedRegistry = CachedRegistry(baseRegistry) // Act diff --git a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/MediatorTests.kt similarity index 94% rename from projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt rename to projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/MediatorTests.kt index bbc7c34..0f2761e 100644 --- a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt +++ b/projects/kediatr-core/src/jvmTest/commonTest/kotlin/com/trendyol/kediatr/MediatorTests.kt @@ -91,8 +91,7 @@ class MediatorTests : MediatorUseCases() { } // Assert - exception.message shouldBe "Multiple handlers registered for request type: com.trendyol.kediatr.testing.CommandWithMultipleHandlers\n" + - "Existing handler: com.trendyol.kediatr.testing.FirstHandlerForCommand\n" + - "Duplicate handler: com.trendyol.kediatr.testing.SecondHandlerForCommand" + exception.message shouldBe "Multiple handlers registered for request type: CommandWithMultipleHandlers\n" + + "Duplicate handler: SecondHandlerForCommand" } } diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt deleted file mode 100644 index 909fc9b..0000000 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/HandlerRegistryProvider.kt +++ /dev/null @@ -1,146 +0,0 @@ -@file:Suppress("UNCHECKED_CAST") - -package com.trendyol.kediatr - -import java.lang.reflect.ParameterizedType - -/** - * Dependency provider implementation that uses a map to resolve dependencies. - * - * This is a simple, map-based dependency provider that can be used for testing - * or scenarios where you want to manually configure handlers without a full - * dependency injection framework. It stores handler instances in a HashMap - * and resolves them by their class type. - * - * Example usage: - * ```kotlin - * val handlers = listOf( - * MyRequestHandler(), - * MyNotificationHandler(), - * LoggingPipelineBehavior() - * ) - * val mediator = HandlerRegistryProvider.createMediator(handlers) - * ``` - * - * @param handlerMap A map that contains the handlers where the key is the handler class - * and the value is the handler instance - * @see DependencyProvider - * @see Mediator - */ -class HandlerRegistryProvider( - private val handlerMap: HashMap, Any> -) : DependencyProvider { - /** - * Gets a single instance of the specified class from the handler map. - * - * @param T The type of instance to resolve - * @param clazz The class object representing the type to resolve - * @return The handler instance from the map - * @throws ClassCastException if the stored instance cannot be cast to the requested type - * @throws NullPointerException if no handler is found for the specified class - */ - override fun getSingleInstanceOf(clazz: Class): T = handlerMap[clazz] as T - - /** - * Gets all subtypes of the specified class from the handler map. - * - * This method searches through all registered handlers and returns those that - * are compatible with the specified base class or interface. It supports - * complex type hierarchies including generic interfaces and inheritance chains. - * - * @param T The base type to find subtypes for - * @param clazz The class object representing the base type - * @return A collection of all classes that extend or implement the specified type - */ - override fun getSubTypesOf(clazz: Class): Collection> = handlerMap.keys - .filter { isCompatibleType(it, clazz) } - .map { it as Class } - - /** - * Determines if a handler class is compatible with the specified interface or base class. - * - * This method performs sophisticated type checking that handles: - * - Direct class inheritance and interface implementation - * - Generic interface implementations (e.g., RequestHandler) - * - Inheritance chains with generic interfaces - * - Complex type hierarchies - * - * @param T The target type to check compatibility against - * @param handler The handler class to check - * @param interfaceOrBaseClass The interface or base class to check compatibility with - * @return true if the handler is compatible with the specified type, false otherwise - */ - private fun isCompatibleType( - handler: Class<*>, - interfaceOrBaseClass: Class - ): Boolean = when { - // Direct assignability check (handles direct inheritance and interface implementation) - interfaceOrBaseClass.isAssignableFrom(handler) -> true - - // Check if handler directly implements the generic interface - handler.genericInterfaces - .filterIsInstance() - .any { it.rawType == interfaceOrBaseClass } -> true - - // Check inheritance chain for generic interface implementations - else -> when (val superclass = handler.genericSuperclass) { - is ParameterizedType -> { - val inheritedHandler = superclass.rawType as Class<*> - inheritedHandler.genericInterfaces - .filterIsInstance() - .any { it.rawType == interfaceOrBaseClass } - } - - is Class<*> -> { - interfaceOrBaseClass.isAssignableFrom(superclass) - } - - else -> { - false - } - } - } - - companion object { - /** - * Creates a mediator instance with the given handlers using a mapping dependency provider. - * - * This is a convenient factory method for creating a mediator with a predefined set of handlers. - * It's particularly useful for testing scenarios or simple applications that don't require - * a full dependency injection framework. - * - * The handlers list can contain: - * - RequestHandler implementations for queries and commands - * - NotificationHandler implementations - * - PipelineBehavior implementations - * - * Example: - * ```kotlin - * val handlers = listOf( - * GetUserRequestHandler(), - * CreateUserRequestHandler(), - * UserCreatedNotificationHandler(), - * LoggingPipelineBehavior() - * ) - * val mediator = HandlerRegistryProvider.createMediator(handlers) - * - * // Use the mediator - * val user = mediator.send(GetUserQuery(123)) - * mediator.send(CreateUserCommand("John Doe")) - * mediator.publish(UserCreatedNotification(user.id)) - * ``` - * - * @param handlers The handlers to be used by the mediator. Can include any combination of - * RequestHandler, NotificationHandler, and PipelineBehavior instances - * @return A configured mediator instance ready for use - * @see RequestHandler - * @see NotificationHandler - * @see PipelineBehavior - */ - fun createMediator(handlers: List = emptyList()): Mediator { - val provider = HandlerRegistryProvider(handlers.associateBy { it.javaClass } as HashMap, Any>) - val mediator = Mediator.build(provider) - return mediator - } - } -} diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt deleted file mode 100644 index 1198aeb..0000000 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt +++ /dev/null @@ -1,162 +0,0 @@ -package com.trendyol.kediatr - -import java.lang.reflect.* - -/** - * Abstract base class that provides handler registration functionality. - * - * This class contains the core logic for discovering and registering handlers from a dependency provider. - * It uses reflection to analyze handler implementations and extract the types they handle, then - * registers them appropriately. The registration process supports complex type hierarchies including - * generic interfaces, inheritance chains, and parameterized types. - * - * The Registrar is used by the Container class to automatically discover and register: - * - RequestHandler implementations for queries and commands - * - NotificationHandler implementations - * - PipelineBehavior implementations - * - * @see Container - * @see DependencyProvider - */ -@Suppress("UNCHECKED_CAST") -internal abstract class Registrar { - /** - * Registers handlers that handle a specific parameter type (used for requests and notifications). - * - * This method discovers all implementations of the specified handler type from the dependency provider - * and registers them with their corresponding parameter types. It's used for handlers that process - * specific message types (requests, notifications). - * - * @param THandler The type of handler to register (e.g., RequestHandler, NotificationHandler) - * @param TParameter The type of parameter the handler processes (e.g., Request, Notification) - * @param dependencyProvider The dependency provider to discover handlers from - * @param registrar The callback function to register each handler with its parameter type - */ - protected inline fun registerFor( - dependencyProvider: DependencyProvider, - registrar: (key: Class, value: Class) -> Unit - ) = dependencyProvider - .getSubTypesOf(THandler::class.java) - .filter { Modifier.isAbstract(it.modifiers).not() } - .forEach { - registerFor(it) { key, value -> - registrar(key as Class, value as Class) - } - } - - /** - * Registers a specific handler class with its parameter type. - * - * This method analyzes the handler class using reflection to determine what parameter types - * it can handle. It examines generic interfaces and inheritance chains to extract the - * appropriate parameter types and register the handler for each one. - * - * @param THandler The type of handler being registered - * @param TParameter The type of parameter the handler processes - * @param handler The specific handler class to register - * @param registrar The callback function to register the handler with its parameter type - */ - protected inline fun registerFor( - handler: Class<*>, - registrar: (key: Class<*>, value: Class<*>) -> Unit - ) { - val interfaceOrBaseClass = THandler::class.java - if (!interfaceOrBaseClass.isAssignableFrom(handler)) return - - // Register handlers based on directly implemented generic interfaces - handler.genericInterfaces - .filterIsInstance() - .map { extractParameter(it) } - .forEach { registrar(it, handler) } - - // Handle inheritance chains where handlers inherit from base classes - when (handler.genericSuperclass) { - is ParameterizedType -> { - val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*> - inheritedHandler.genericInterfaces - .filterIsInstance() - .map { extractParameter(handler.genericSuperclass as ParameterizedType) } - .forEach { registrar(it, handler) } - } - - is Class<*> -> { - val inheritedHandler = handler.genericSuperclass as Class<*> - if (interfaceOrBaseClass.isAssignableFrom(inheritedHandler)) { - inheritedHandler.genericInterfaces - .filterIsInstance() - .map { extractParameter(it) } - .forEach { registrar(it, handler) } - } - } - } - } - - /** - * Registers handlers that don't require parameter type mapping (used for pipeline behaviors). - * - * This method discovers all implementations of the specified type from the dependency provider - * and registers them directly without parameter type extraction. It's used for pipeline behaviors - * which apply to all requests regardless of their specific type. - * - * @param T The type of handler to register (e.g., PipelineBehavior) - * @param dependencyProvider The dependency provider to discover handlers from - * @param registrar The callback function to register each handler - */ - protected inline fun registerFor( - dependencyProvider: DependencyProvider, - registrar: (value: Class) -> Unit - ) = dependencyProvider.getSubTypesOf(T::class.java).forEach { handler -> - registerFor(handler) { value -> registrar(value as Class) } - } - - /** - * Registers a specific handler class without parameter type mapping. - * - * This method simply checks if the handler class is assignable to the target type - * and registers it if compatible. Used for simple registration scenarios. - * - * @param T The type of handler being registered - * @param handler The specific handler class to register - * @param registrar The callback function to register the handler - */ - protected inline fun registerFor( - handler: Class<*>, - registrar: (value: Class<*>) -> Unit - ) { - val interfaceOrBaseClass = T::class.java - if (!interfaceOrBaseClass.isAssignableFrom(handler)) return - registrar(handler) - } - - /** - * Extracts the parameter type from a generic interface using reflection. - * - * This method analyzes parameterized types to extract the actual type arguments, - * handling various scenarios including: - * - Direct parameterized types (e.g., RequestHandler) - * - Type variables with bounds - * - Nested generic types - * - Inheritance chains with generic interfaces - * - * @param genericInterface The parameterized type to extract the parameter from - * @return The extracted parameter class - */ - protected fun extractParameter(genericInterface: ParameterizedType): Class<*> = - when (val typeArgument = genericInterface.actualTypeArguments[0]) { - is ParameterizedType -> { - typeArgument.rawType as Class<*> - } - - is TypeVariable<*> -> { - val rawType = (genericInterface.rawType as Class<*>) - when { - rawType.genericInterfaces.any() -> extractParameter(rawType.genericInterfaces[0] as ParameterizedType) - else -> rawType - } - } - - else -> { - typeArgument as Class<*> - } - } -} diff --git a/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Dispatchers.native.kt b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Dispatchers.native.kt new file mode 100644 index 0000000..32989e0 --- /dev/null +++ b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Dispatchers.native.kt @@ -0,0 +1,7 @@ +package com.trendyol.kediatr + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +actual val DefaultDispatcher: CoroutineDispatcher = Dispatchers.Default + diff --git a/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Platform.native.kt b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Platform.native.kt new file mode 100644 index 0000000..1de6ac2 --- /dev/null +++ b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/Platform.native.kt @@ -0,0 +1,19 @@ +package com.trendyol.kediatr + +import kotlin.native.concurrent.ThreadLocal + +@ThreadLocal +private object ConcurrentMapStorage { + val maps = mutableMapOf>() + private var nextId = 0 + + fun createMap(): MutableMap { + @Suppress("UNCHECKED_CAST") + return mutableMapOf() + } +} + +actual fun createConcurrentMap(): MutableMap { + return ConcurrentMapStorage.createMap() +} + diff --git a/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/ReflectionUtils.native.kt b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/ReflectionUtils.native.kt new file mode 100644 index 0000000..005b209 --- /dev/null +++ b/projects/kediatr-core/src/nativeMain/kotlin/com/trendyol/kediatr/ReflectionUtils.native.kt @@ -0,0 +1,41 @@ +package com.trendyol.kediatr + +import kotlin.reflect.KClass + +public actual object ReflectionUtils { + actual fun isAbstract(kClass: KClass<*>): Boolean { + // Native reflection is limited, we assume classes passed here are not abstract + // This is a simplification for native platforms + return false + } + + actual fun isAssignableFrom(superType: KClass, subType: KClass<*>): Boolean { + // Check if subType is the same as superType or inherits from it + if (superType == subType) return true + + // For native platforms, we have limited reflection capabilities + // This is a simplified implementation + var current: KClass<*>? = subType + while (current != null) { + if (current == superType) return true + // Native Kotlin doesn't have full reflection for superclass traversal + // This is a limitation of Kotlin/Native + current = null + } + return false + } + + actual fun getSuperclass(kClass: KClass<*>): KClass<*>? { + // Kotlin/Native has limited reflection support + // We cannot reliably get superclass information + return null + } + + actual fun getHandlerParameterType(handlerClass: KClass<*>, handlerInterface: KClass<*>): KClass<*>? { + // Kotlin/Native doesn't support full generic type reflection + // This functionality requires manual registration or code generation + // For now, return null to indicate this feature is not available on native platforms + return null + } +} + diff --git a/projects/kediatr-koin-starter/build.gradle.kts b/projects/kediatr-koin-starter/build.gradle.kts index 6ac5a5b..47b3be0 100644 --- a/projects/kediatr-koin-starter/build.gradle.kts +++ b/projects/kediatr-koin-starter/build.gradle.kts @@ -1,11 +1,40 @@ -dependencies { - api(projects.projects.kediatrCore) - implementation(libs.org.reflections) - implementation(libs.koin.core) +plugins { + kotlin("multiplatform") } -dependencies { - testImplementation(testFixtures(projects.projects.kediatrCore)) - testImplementation(libs.koin.test) - testImplementation(libs.koin.test.junit5) +kotlin { + jvm() + + js(IR) { + browser() + nodejs() + } + + iosArm64() + iosX64() + iosSimulatorArm64() + + macosArm64() + macosX64() + + linuxX64() + linuxArm64() + + mingwX64() + + sourceSets { + commonMain { + dependencies { + api(projects.projects.kediatrCore) + implementation(libs.koin.core) + } + } + jvmTest { + dependencies { + implementation(projects.projects.kediatrTesting) + implementation(libs.koin.test) + implementation(libs.koin.test.junit5) + } + } + } } diff --git a/projects/kediatr-koin-starter/src/commonMain/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt b/projects/kediatr-koin-starter/src/commonMain/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt new file mode 100644 index 0000000..5ac4deb --- /dev/null +++ b/projects/kediatr-koin-starter/src/commonMain/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt @@ -0,0 +1,44 @@ +@file:Suppress("UNCHECKED_CAST") + +package com.trendyol.kediatr.koin + +import com.trendyol.kediatr.* +import org.koin.core.Koin +import org.koin.core.annotation.KoinInternalApi +import org.koin.mp.KoinPlatformTools +import kotlin.reflect.KClass + +@OptIn(KoinInternalApi::class) +class KediatRKoinProvider : DependencyProvider { + private val koin: Koin = KoinPlatformTools.defaultContext().get() + private val subTypes: List> + get() { + val instances = koin.instanceRegistry.instances + if (instances.isEmpty()) { + error("Koin instances are empty! Koin: $koin. Make sure beans are loaded.") + } + return instances + .map { it.value.beanDefinition } + .fold(mutableListOf>()) { acc, beanDefinition -> + acc.also { + it.add(beanDefinition.primaryType) + it.addAll(beanDefinition.secondaryTypes) + } + }.distinct() + } + + override fun getSingleInstanceOf(clazz: KClass): T = koin.get(clazz) + + override fun getSubTypesOf(clazz: KClass): Collection> { + val allTypes = subTypes + return allTypes + .filter { ReflectionUtils.isAssignableFrom(clazz, it) } + .map { it as KClass } + } +} + +class KediatRKoin { + companion object { + fun getMediator() = Mediator.build(KediatRKoinProvider()) + } +} diff --git a/projects/kediatr-koin-starter/src/test/kotlin/com/trendyol/kediatr/koin/MediatorTests.kt b/projects/kediatr-koin-starter/src/jvmTest/kotlin/com/trendyol/kediatr/koin/MediatorTests.kt similarity index 100% rename from projects/kediatr-koin-starter/src/test/kotlin/com/trendyol/kediatr/koin/MediatorTests.kt rename to projects/kediatr-koin-starter/src/jvmTest/kotlin/com/trendyol/kediatr/koin/MediatorTests.kt diff --git a/projects/kediatr-koin-starter/src/main/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt b/projects/kediatr-koin-starter/src/main/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt deleted file mode 100644 index 673e678..0000000 --- a/projects/kediatr-koin-starter/src/main/kotlin/com/trendyol/kediatr/koin/KediatRKoinProvider.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("UNCHECKED_CAST") - -package com.trendyol.kediatr.koin - -import com.trendyol.kediatr.* -import org.koin.core.Koin -import org.koin.core.annotation.KoinInternalApi -import org.koin.java.KoinJavaComponent.getKoin -import kotlin.reflect.KClass - -@OptIn(KoinInternalApi::class) -class KediatRKoinProvider : DependencyProvider { - private val koin: Koin = getKoin() - private val subTypes: List> - get() = koin - .instanceRegistry.instances - .map { it.value.beanDefinition } - .fold(mutableListOf>()) { acc, beanDefinition -> - acc.also { - it.add(beanDefinition.primaryType) - it.addAll(beanDefinition.secondaryTypes) - } - }.distinct() - - override fun getSingleInstanceOf(clazz: Class): T = koin.get(clazz.kClass()) - - override fun getSubTypesOf(clazz: Class): Collection> = subTypes - .filter { clazz.isAssignableFrom(it.java) } - .map { it.java as Class } - - private fun Class.kClass(): KClass = (this as Class<*>).kotlin -} - -class KediatRKoin { - companion object { - fun getMediator() = Mediator.build(KediatRKoinProvider()) - } -} diff --git a/projects/kediatr-quarkus-starter/build.gradle.kts b/projects/kediatr-quarkus-starter/build.gradle.kts index 703626d..4f26619 100644 --- a/projects/kediatr-quarkus-starter/build.gradle.kts +++ b/projects/kediatr-quarkus-starter/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { } dependencies { - testImplementation(testFixtures(projects.projects.kediatrCore)) + testImplementation(projects.projects.kediatrTesting) testImplementation(libs.quarkus.junit5) } diff --git a/projects/kediatr-quarkus-starter/src/main/kotlin/com/trendyol/kediatr/quarkus/KediatRBeanProvider.kt b/projects/kediatr-quarkus-starter/src/main/kotlin/com/trendyol/kediatr/quarkus/KediatRBeanProvider.kt index d75332a..862f83f 100644 --- a/projects/kediatr-quarkus-starter/src/main/kotlin/com/trendyol/kediatr/quarkus/KediatRBeanProvider.kt +++ b/projects/kediatr-quarkus-starter/src/main/kotlin/com/trendyol/kediatr/quarkus/KediatRBeanProvider.kt @@ -3,13 +3,16 @@ package com.trendyol.kediatr.quarkus import com.trendyol.kediatr.* import io.quarkus.runtime.Startup import jakarta.enterprise.context.ApplicationScoped +import kotlin.reflect.KClass class KediatRBeanProvider( private val resolver: QuarkusTypeResolver ) : DependencyProvider { - override fun getSingleInstanceOf(clazz: Class): T = resolver.resolveOrThrow(clazz) + override fun getSingleInstanceOf(clazz: KClass): T = resolver.resolveOrThrow(clazz.java) - override fun getSubTypesOf(clazz: Class): Collection> = resolver.resolveTypesOrEmpty(clazz) + override fun getSubTypesOf(clazz: KClass): Collection> = resolver + .resolveTypesOrEmpty(clazz.java) + .map { it.kotlin as KClass } } @ApplicationScoped diff --git a/projects/kediatr-spring-boot-2x-starter/build.gradle.kts b/projects/kediatr-spring-boot-2x-starter/build.gradle.kts index e1d3a86..c39defa 100644 --- a/projects/kediatr-spring-boot-2x-starter/build.gradle.kts +++ b/projects/kediatr-spring-boot-2x-starter/build.gradle.kts @@ -4,10 +4,6 @@ dependencies { } dependencies { - testImplementation(testFixtures(projects.projects.kediatrCore)) + testImplementation(projects.projects.kediatrTesting) testImplementation(libs.spring.boot.get2x().starter.test) } - -kotlin { - jvmToolchain(11) -} diff --git a/projects/kediatr-spring-boot-2x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt b/projects/kediatr-spring-boot-2x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt index e7068e7..91f493d 100644 --- a/projects/kediatr-spring-boot-2x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt +++ b/projects/kediatr-spring-boot-2x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt @@ -4,15 +4,16 @@ package com.trendyol.kediatr.spring import com.trendyol.kediatr.DependencyProvider import org.springframework.context.ApplicationContext +import kotlin.reflect.KClass class KediatRSpringBeanProvider( private val applicationContext: ApplicationContext ) : DependencyProvider { - override fun getSingleInstanceOf(clazz: Class): T = applicationContext.getBean(clazz) + override fun getSingleInstanceOf(clazz: KClass): T = applicationContext.getBean(clazz.java) - override fun getSubTypesOf( - clazz: Class - ): Collection> = applicationContext - .getBeanNamesForType(clazz) - .map { applicationContext.getType(it) as Class } + override fun getSubTypesOf( + clazz: KClass + ): Collection> = applicationContext + .getBeanNamesForType(clazz.java) + .map { applicationContext.getType(it)!!.kotlin as KClass } } diff --git a/projects/kediatr-spring-boot-3x-starter/build.gradle.kts b/projects/kediatr-spring-boot-3x-starter/build.gradle.kts index 57eae1a..ab4d518 100644 --- a/projects/kediatr-spring-boot-3x-starter/build.gradle.kts +++ b/projects/kediatr-spring-boot-3x-starter/build.gradle.kts @@ -4,6 +4,6 @@ dependencies { } dependencies { - testImplementation(testFixtures(projects.projects.kediatrCore)) + testImplementation(projects.projects.kediatrTesting) testImplementation(libs.spring.boot.get3x().starter.test) } diff --git a/projects/kediatr-spring-boot-3x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt b/projects/kediatr-spring-boot-3x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt index e7068e7..91f493d 100644 --- a/projects/kediatr-spring-boot-3x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt +++ b/projects/kediatr-spring-boot-3x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt @@ -4,15 +4,16 @@ package com.trendyol.kediatr.spring import com.trendyol.kediatr.DependencyProvider import org.springframework.context.ApplicationContext +import kotlin.reflect.KClass class KediatRSpringBeanProvider( private val applicationContext: ApplicationContext ) : DependencyProvider { - override fun getSingleInstanceOf(clazz: Class): T = applicationContext.getBean(clazz) + override fun getSingleInstanceOf(clazz: KClass): T = applicationContext.getBean(clazz.java) - override fun getSubTypesOf( - clazz: Class - ): Collection> = applicationContext - .getBeanNamesForType(clazz) - .map { applicationContext.getType(it) as Class } + override fun getSubTypesOf( + clazz: KClass + ): Collection> = applicationContext + .getBeanNamesForType(clazz.java) + .map { applicationContext.getType(it)!!.kotlin as KClass } } diff --git a/projects/kediatr-spring-boot-4x-starter/build.gradle.kts b/projects/kediatr-spring-boot-4x-starter/build.gradle.kts index 5a62290..c08dc1b 100644 --- a/projects/kediatr-spring-boot-4x-starter/build.gradle.kts +++ b/projects/kediatr-spring-boot-4x-starter/build.gradle.kts @@ -4,6 +4,6 @@ dependencies { } dependencies { - testImplementation(testFixtures(projects.projects.kediatrCore)) + testImplementation(projects.projects.kediatrTesting) testImplementation(libs.spring.boot.get4x().starter.test) } diff --git a/projects/kediatr-spring-boot-4x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt b/projects/kediatr-spring-boot-4x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt index dc27fc6..98ce7e0 100644 --- a/projects/kediatr-spring-boot-4x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt +++ b/projects/kediatr-spring-boot-4x-starter/src/main/kotlin/com/trendyol/kediatr/spring/KediatRSpringBeanProvider.kt @@ -4,18 +4,19 @@ package com.trendyol.kediatr.spring import com.trendyol.kediatr.DependencyProvider import org.springframework.context.ApplicationContext +import kotlin.reflect.KClass class KediatRSpringBeanProvider( private val applicationContext: ApplicationContext ) : DependencyProvider { - override fun getSingleInstanceOf(clazz: Class): T = applicationContext - .getBeanNamesForType(clazz) + override fun getSingleInstanceOf(clazz: KClass): T = applicationContext + .getBeanNamesForType(clazz.java) .single() .let { applicationContext.getBean(it) as T } - override fun getSubTypesOf( - clazz: Class - ): Collection> = applicationContext - .getBeanNamesForType(clazz) - .map { applicationContext.getType(it) as Class } + override fun getSubTypesOf( + clazz: KClass + ): Collection> = applicationContext + .getBeanNamesForType(clazz.java) + .map { applicationContext.getType(it)!!.kotlin as KClass } } diff --git a/projects/kediatr-testing/build.gradle.kts b/projects/kediatr-testing/build.gradle.kts new file mode 100644 index 0000000..a8cdd05 --- /dev/null +++ b/projects/kediatr-testing/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + kotlin("jvm") +} + +dependencies { + api(projects.projects.kediatrCore) + api(kotlin("test-common")) + api(kotlin("test-annotations-common")) + api(kotlin("test-junit5")) + implementation(libs.kotest.assertions.core) + implementation(libs.kotlinx.coroutines.test) +} + diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt b/projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt similarity index 98% rename from projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt rename to projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt index f31bc02..d39c5f2 100644 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt +++ b/projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/MediatorUseCases.kt @@ -9,7 +9,7 @@ import io.kotest.matchers.longs.* import io.kotest.matchers.string.shouldContain import kotlinx.coroutines.* import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.* +import kotlin.test.Test abstract class MediatorUseCases : MediatorTestConvention() { @Test @@ -32,7 +32,7 @@ abstract class MediatorUseCases : MediatorTestConvention() { testMediator.send(TestNonExistCommand()) } - exception.message shouldContain "Handler not found for ${TestNonExistCommand::class.java.typeName}" + exception.message shouldContain "Handler not found for ${TestNonExistCommand::class.simpleName}" exception.message shouldContain "Available handlers: " } @@ -42,7 +42,7 @@ abstract class MediatorUseCases : MediatorTestConvention() { testMediator.send(NonExistCommandWithResult()) } - exception.message shouldContain "Handler not found for ${NonExistCommandWithResult::class.java.typeName}" + exception.message shouldContain "Handler not found for ${NonExistCommandWithResult::class.simpleName}" exception.message shouldContain "Available handlers: " } @@ -67,7 +67,7 @@ abstract class MediatorUseCases : MediatorTestConvention() { @Test fun command_that_fails_should_throw_related_exception_when_it_is_routed() = runTest { val act = suspend { testMediator.send(TestCommandThatFailsWithException()) } - assertThrows { act() } + shouldThrow { act() } } @Test @@ -76,7 +76,7 @@ abstract class MediatorUseCases : MediatorTestConvention() { testMediator.send(NonExistQuery()) } - exception.message shouldContain "Handler not found for ${NonExistQuery::class.java.typeName}" + exception.message shouldContain "Handler not found for ${NonExistQuery::class.simpleName}" exception.message shouldContain "Available handlers: " } @@ -109,12 +109,12 @@ abstract class MediatorUseCases : MediatorTestConvention() { val command = TestCommandForInheritanceWithFallback.TestCommandInherited1("id") testMediator.send(command) command.invocationCount().get() shouldBe 1 - command.whereItWasInvokedFrom() shouldContain TestCommandForInheritanceWithFallbackHandlerHandler::class.java.name + command.whereItWasInvokedFrom() shouldContain TestCommandForInheritanceWithFallbackHandlerHandler::class.simpleName!! val command2 = TestCommandForInheritanceWithFallback.TestCommandInherited2("id") testMediator.send(command2) command2.invocationCount().get() shouldBe 1 - command2.whereItWasInvokedFrom() shouldContain TestRequestHandlerForCommandInherited2::class.java.name + command2.whereItWasInvokedFrom() shouldContain TestRequestHandlerForCommandInherited2::class.simpleName!! } @Test @@ -154,7 +154,7 @@ abstract class MediatorUseCases : MediatorTestConvention() { testMediator.send(TestNonExistCommand()) } - exception.message shouldContain "Handler not found for ${TestNonExistCommand::class.java.typeName}" + exception.message shouldContain "Handler not found for ${TestNonExistCommand::class.simpleName}" exception.message shouldContain "Available handlers: " } diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt b/projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/convention.kt similarity index 100% rename from projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt rename to projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/convention.kt diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/models.kt b/projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/models.kt similarity index 99% rename from projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/models.kt rename to projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/models.kt index cbc9126..b22f3ae 100644 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/models.kt +++ b/projects/kediatr-testing/src/main/kotlin/com/trendyol/kediatr/testing/models.kt @@ -647,14 +647,14 @@ sealed class TestCommandForInheritanceWithFallback : class TestCommandForInheritanceWithFallbackHandlerHandler : RequestHandler.Unit { override suspend fun handle(request: TestCommandForInheritanceWithFallback) { request.incrementInvocationCount() - request.invokedFrom(javaClass.name) + request.invokedFrom(this::class.simpleName!!) } } class TestRequestHandlerForCommandInherited2 : RequestHandler.Unit { override suspend fun handle(request: TestCommandForInheritanceWithFallback.TestCommandInherited2) { request.incrementInvocationCount() - request.invokedFrom(javaClass.name) + request.invokedFrom(this::class.simpleName!!) } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 176a7a7..2bf3d97 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,7 @@ import dev.aga.gradle.versioncatalogs.GeneratorConfig rootProject.name = "kediatR" include( "projects:kediatr-core", + "projects:kediatr-testing", "projects:kediatr-koin-starter", "projects:kediatr-quarkus-starter", "projects:kediatr-spring-boot-2x-starter", @@ -40,4 +41,3 @@ dependencyResolutionManagement { } } } -