From 546977fe86ccf9743cf661ce1f50104031b65f23 Mon Sep 17 00:00:00 2001 From: RTAkland Date: Sat, 17 Jan 2026 23:23:46 +0800 Subject: [PATCH] Add gradle plugin and fix authenticator --- .gitignore | 5 +- build.gradle.kts | 11 +-- core/build.gradle.kts | 67 ----------------- gradle.properties | 1 + serialization/build.gradle.kts | 5 -- settings.gradle.kts | 24 +++++- worker-core/build.gradle.kts | 75 +++++++++++++++++++ .../jsMain/kotlin/cn/rtast/cfworker/CORS.kt | 0 .../kotlin/cn/rtast/cfworker/HttpMethod.kt | 0 .../cn/rtast/cfworker/WorkerApplication.kt | 0 .../cn/rtast/cfworker/auth/AuthResult.kt | 0 .../kotlin/cn/rtast/cfworker/auth/AuthUtil.kt | 0 .../auth/credentials/BasicCredential.kt | 0 .../auth/credentials/BearerCredential.kt | 0 .../auth/credentials/HttpCredential.kt | 0 .../cfworker/auth/provider/Authenticator.kt | 4 +- .../auth/provider/BasicAuthenticator.kt | 0 .../auth/provider/BearerAuthenticator.kt | 0 .../kotlin/cn/rtast/cfworker/client/fetch.kt | 0 .../cn/rtast/cfworker/config/CORSConfig.kt | 0 .../jsMain/kotlin/cn/rtast/cfworker/main.kt | 10 +++ .../rtast/cfworker/response/ResponseUtil.kt | 0 .../cn/rtast/cfworker/route/RouteHandler.kt | 0 .../cn/rtast/cfworker/route/RouteUtil.kt | 0 .../cfworker/route/type/AbstractRoute.kt | 0 .../rtast/cfworker/route/type/RegexRoute.kt | 0 .../cn/rtast/cfworker/route/type/RouteType.kt | 0 .../rtast/cfworker/route/type/StringRoute.kt | 0 .../kotlin/cn/rtast/cfworker/util/Base64.kt | 0 .../cn/rtast/cfworker/util/ByteArray.kt | 0 .../websocket/WebsocketEventHandler.kt | 6 +- .../cfworker/websocket/WebsocketRoute.kt | 0 .../response/WebsocketResponseUtil.kt | 0 .../src/jsTest/kotlin/test/Test.kt | 0 {core => worker-core}/wrangler.template.toml | 0 worker-gradle-plugin/build.gradle.kts | 22 ++++++ .../plugin/KotlinCloudflareWorkerPlugin.kt | 75 +++++++++++++++++++ .../cn/rtast/cfworker/plugin/RunMode.kt | 12 +++ .../rtast/cfworker/plugin/WorkerExtension.kt | 25 +++++++ worker-serialization/build.gradle.kts | 10 +++ 40 files changed, 266 insertions(+), 86 deletions(-) delete mode 100644 core/build.gradle.kts delete mode 100644 serialization/build.gradle.kts create mode 100644 worker-core/build.gradle.kts rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/CORS.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/HttpMethod.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/WorkerApplication.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthResult.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthUtil.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BasicCredential.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BearerCredential.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/HttpCredential.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt (74%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BasicAuthenticator.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BearerAuthenticator.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/client/fetch.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/config/CORSConfig.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/main.kt (74%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/response/ResponseUtil.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteHandler.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteUtil.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/type/AbstractRoute.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RegexRoute.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RouteType.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/route/type/StringRoute.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/util/Base64.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/util/ByteArray.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt (93%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketRoute.kt (100%) rename {core => worker-core}/src/jsMain/kotlin/cn/rtast/cfworker/websocket/response/WebsocketResponseUtil.kt (100%) rename {core => worker-core}/src/jsTest/kotlin/test/Test.kt (100%) rename {core => worker-core}/wrangler.template.toml (100%) create mode 100644 worker-gradle-plugin/build.gradle.kts create mode 100644 worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/KotlinCloudflareWorkerPlugin.kt create mode 100644 worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/RunMode.kt create mode 100644 worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/WorkerExtension.kt create mode 100644 worker-serialization/build.gradle.kts diff --git a/.gitignore b/.gitignore index d915166..67c8dd5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ .kotlin/ build/ .gradle/ -/core/.dev.vars -/core/wrangler.toml +/worker-core/.dev.vars +/worker-core/wrangler.toml +/worker-plugin-test/wrangler.toml diff --git a/build.gradle.kts b/build.gradle.kts index c83027c..ccd18cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,22 +1,23 @@ plugins { + kotlin("jvm") version "2.2.21" apply false kotlin("multiplatform") version "2.2.21" apply false + kotlin("plugin.serialization") version "2.2.21" apply false id("maven-publish") } - - +val libVersion: String by extra allprojects { - group = "cn.rtast.kotlin-cfworker" - version = "1.0.2" + group = "kotlin-cloudflare-worker" + version = libVersion repositories { mavenCentral() + maven("https://repo.maven.rtast.cn/releases") } } subprojects { - apply(plugin = "org.jetbrains.kotlin.multiplatform") apply(plugin = "maven-publish") publishing { diff --git a/core/build.gradle.kts b/core/build.gradle.kts deleted file mode 100644 index 444ff87..0000000 --- a/core/build.gradle.kts +++ /dev/null @@ -1,67 +0,0 @@ -kotlin { - explicitApi() - js(IR) { nodejs { binaries.executable() } } - - sourceSets { - jsMain.dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") - } - - commonTest.dependencies { - implementation(kotlin("test")) - } - } -} - - -val wranglerRunDir: Provider = layout.buildDirectory.dir("wrangler-run") -tasks.register("prepareWranglerRun") { - group = "wrangler" - dependsOn("compileDevelopmentExecutableKotlinJs") - val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/developmentExecutable/kotlin") - from(buildOutputDir) - into(wranglerRunDir) -} - -val wranglerDev by tasks.registering(Exec::class) { - group = "wrangler" - workingDir = layout.buildDirectory.dir("wrangler-run").get().asFile.apply { mkdirs() } - doFirst { - val sourceDir = project.layout.projectDirectory - mapOf( - sourceDir.file("wrangler.toml").asFile to File(workingDir, "wrangler.toml"), - sourceDir.file(".dev.vars").asFile to File(workingDir, ".dev.vars"), - ).forEach { (s, d) -> s.copyTo(d, overwrite = true) } - } - commandLine( - if (System.getProperty("os.name").lowercase().contains("windows")) listOf( - "cmd", "/c", "wrangler dev --port 7071" - ) - else listOf("sh", "-c", "wrangler dev --port 7071") - ) - standardInput = System.`in` - isIgnoreExitValue = false -} - -val wranglerDeployDir: Provider = layout.buildDirectory.dir("wrangler-deploy") - .apply { get().asFile.deleteRecursively() } -val prepareProductionDeploy by tasks.registering(Copy::class) { - group = "wrangler" - dependsOn("compileProductionExecutableKotlinJs") - val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/productionExecutable/kotlin") - from(buildOutputDir) { exclude("*.map") } - into(wranglerDeployDir) - from(layout.projectDirectory.file("wrangler.toml")) - into(wranglerDeployDir) -} - -val wranglerDeploy by tasks.registering(Exec::class) { - group = "wrangler" - dependsOn(prepareProductionDeploy) - workingDir = layout.buildDirectory.dir("wrangler-deploy").get().asFile.apply { mkdirs() } - commandLine( - if (System.getProperty("os.name").lowercase().contains("windows")) listOf("cmd", "/c", "wrangler deploy") - else listOf("sh", "-c", "wrangler deploy") - ) - standardInput = System.`in` -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 7fc6f1f..61dd01d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ kotlin.code.style=official +libVersion=1.0.4 \ No newline at end of file diff --git a/serialization/build.gradle.kts b/serialization/build.gradle.kts deleted file mode 100644 index c9dd371..0000000 --- a/serialization/build.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -kotlin { - js(IR) { - nodejs { binaries.executable() } - } -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 0d65c7c..60ccc99 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,23 @@ -include(":core") -include(":serialization") +@file:Suppress("UnstableApiUsage") + +include(":worker-core") +include(":worker-serialization") +include(":worker-gradle-plugin") + +pluginManagement { + repositories { + mavenCentral() + mavenLocal() + maven("https://repo.maven.rtast.cn/releases") + } +} + +dependencyResolutionManagement { + repositories { + mavenCentral() + mavenLocal() + maven("https://repo.maven.rtast.cn/releases") + } +} + rootProject.name = "kotlin-cloudflare-worker" \ No newline at end of file diff --git a/worker-core/build.gradle.kts b/worker-core/build.gradle.kts new file mode 100644 index 0000000..259db7f --- /dev/null +++ b/worker-core/build.gradle.kts @@ -0,0 +1,75 @@ +plugins { + kotlin("multiplatform") + id("kotlin-cloudflare-worker") version "1.0.4" +} + +kotlin { + explicitApi() + js(IR) { nodejs { binaries.executable() } } + + sourceSets { + jsMain.dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") + } + + commonTest.dependencies { + implementation(kotlin("test")) + } + } +} + +wrangler { + wranglerFile = file("wrangler.toml") +} + +//val wranglerRunDir: Provider = layout.buildDirectory.dir("wrangler-run") +//tasks.register("prepareWranglerRun") { +// group = "wrangler" +// dependsOn("compileDevelopmentExecutableKotlinJs") +// val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/developmentExecutable/kotlin") +// from(buildOutputDir) +// into(wranglerRunDir) +//} +// +//val wranglerDev by tasks.registering(Exec::class) { +// group = "wrangler" +// workingDir = layout.buildDirectory.dir("wrangler-run").get().asFile.apply { mkdirs() } +// doFirst { +// val sourceDir = project.layout.projectDirectory +// mapOf( +// sourceDir.file("wrangler.toml").asFile to File(workingDir, "wrangler.toml"), +// sourceDir.file(".dev.vars").asFile to File(workingDir, ".dev.vars"), +// ).forEach { (s, d) -> s.copyTo(d, overwrite = true) } +// } +// commandLine( +// if (System.getProperty("os.name").lowercase().contains("windows")) listOf( +// "cmd", "/c", "wrangler dev --port 7071" +// ) +// else listOf("sh", "-c", "wrangler dev --port 7071") +// ) +// standardInput = System.`in` +// isIgnoreExitValue = false +//} +// +//val wranglerDeployDir: Provider = layout.buildDirectory.dir("wrangler-deploy") +// .apply { get().asFile.deleteRecursively() } +//val prepareProductionDeploy by tasks.registering(Copy::class) { +// group = "wrangler" +// dependsOn("compileProductionExecutableKotlinJs") +// val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/productionExecutable/kotlin") +// from(buildOutputDir) { exclude("*.map") } +// into(wranglerDeployDir) +// from(layout.projectDirectory.file("wrangler.toml")) +// into(wranglerDeployDir) +//} +// +//val wranglerDeploy by tasks.registering(Exec::class) { +// group = "wrangler" +// dependsOn(prepareProductionDeploy) +// workingDir = layout.buildDirectory.dir("wrangler-deploy").get().asFile.apply { mkdirs() } +// commandLine( +// if (System.getProperty("os.name").lowercase().contains("windows")) listOf("cmd", "/c", "wrangler deploy") +// else listOf("sh", "-c", "wrangler deploy") +// ) +// standardInput = System.`in` +//} \ No newline at end of file diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/CORS.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/CORS.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/CORS.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/CORS.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/HttpMethod.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/HttpMethod.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/HttpMethod.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/HttpMethod.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/WorkerApplication.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/WorkerApplication.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/WorkerApplication.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/WorkerApplication.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthResult.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthResult.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthResult.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthResult.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthUtil.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthUtil.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthUtil.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/AuthUtil.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BasicCredential.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BasicCredential.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BasicCredential.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BasicCredential.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BearerCredential.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BearerCredential.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BearerCredential.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/BearerCredential.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/HttpCredential.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/HttpCredential.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/HttpCredential.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/credentials/HttpCredential.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt similarity index 74% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt index cc712e6..6730ce0 100644 --- a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt +++ b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/Authenticator.kt @@ -8,6 +8,6 @@ import org.w3c.fetch.Request * An interface for authenticating * It's sealed */ -public sealed interface Authenticator { - public suspend fun authenticate(request: Request, credential: C?): AuthResult +public sealed interface Authenticator { + public suspend fun authenticate(request: Request, credential: @UnsafeVariance C?): AuthResult } \ No newline at end of file diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BasicAuthenticator.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BasicAuthenticator.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BasicAuthenticator.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BasicAuthenticator.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BearerAuthenticator.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BearerAuthenticator.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BearerAuthenticator.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/auth/provider/BearerAuthenticator.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/client/fetch.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/client/fetch.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/client/fetch.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/client/fetch.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/config/CORSConfig.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/config/CORSConfig.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/config/CORSConfig.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/config/CORSConfig.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt similarity index 74% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt index 3b5595d..fae984e 100644 --- a/core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt +++ b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/main.kt @@ -13,6 +13,9 @@ package cn.rtast.cfworker +import cn.rtast.cfworker.auth.AuthResult +import cn.rtast.cfworker.auth.provider.BearerAuthenticator +import cn.rtast.cfworker.client.Url import cn.rtast.cfworker.response.respondText import cn.rtast.cfworker.route.route import cn.rtast.cfworker.websocket.readText @@ -50,6 +53,13 @@ public fun handleRequest(request: Request): Promise = GlobalScope.prom onClose { } } + + route("/protected", setOf(HttpMethod.GET), BearerAuthenticator { request, credential -> + val name = request.Url.searchParams.get("name") + return@BearerAuthenticator if (name == "admin") AuthResult.OK else AuthResult.UNAUTHORIZED + }) { + respondText("Success") + } } return@promise server.handle(request) } diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/response/ResponseUtil.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/response/ResponseUtil.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/response/ResponseUtil.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/response/ResponseUtil.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteHandler.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteHandler.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteHandler.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteHandler.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteUtil.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteUtil.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteUtil.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/RouteUtil.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/AbstractRoute.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/AbstractRoute.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/AbstractRoute.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/AbstractRoute.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RegexRoute.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RegexRoute.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RegexRoute.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RegexRoute.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RouteType.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RouteType.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RouteType.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/RouteType.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/StringRoute.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/StringRoute.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/StringRoute.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/route/type/StringRoute.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/util/Base64.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/util/Base64.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/util/Base64.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/util/Base64.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/util/ByteArray.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/util/ByteArray.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/util/ByteArray.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/util/ByteArray.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt similarity index 93% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt index 3649b1b..b11b09c 100644 --- a/core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt +++ b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketEventHandler.kt @@ -28,7 +28,7 @@ import org.w3c.files.Blob public class WebsocketEventHandler(public val request: Request) { private var onMessageBlock: (suspend (MessageEvent) -> Unit)? = null private var onCloseBlock: (suspend (CloseEvent) -> Unit?)? = null - private var onOpenBlock: (suspend (Event) -> Unit)? = null + private var onOpenBlock: (suspend () -> Unit)? = null private var onErrorBlock: (suspend (Event) -> Unit)? = null private var requireUpgradeHeaderBlock: (suspend (Request) -> Response)? = { Response("Expected Upgrade: websocket", ResponseInit(426)) } @@ -46,7 +46,7 @@ public class WebsocketEventHandler(public val request: Request) { onCloseBlock = block } - public fun onOpen(block: suspend (Event) -> Unit) { + public fun onOpen(block: suspend () -> Unit) { onOpenBlock = block } @@ -66,9 +66,9 @@ public class WebsocketEventHandler(public val request: Request) { val server = pair[1] server.accept() clients.add(server) + GlobalScope.promise { onOpenBlock?.invoke() } server.addEventListener("message", { e: MessageEvent -> GlobalScope.promise { onMessageBlock?.invoke(e) } }) server.addEventListener("error", { e: Event -> GlobalScope.promise { onErrorBlock?.invoke(e) } }) - server.addEventListener("open", { e: Event -> GlobalScope.promise { onErrorBlock?.invoke(e) } }) server.addEventListener("close", { e: CloseEvent -> GlobalScope.promise { onCloseBlock?.invoke(e) diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketRoute.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketRoute.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketRoute.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/WebsocketRoute.kt diff --git a/core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/response/WebsocketResponseUtil.kt b/worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/response/WebsocketResponseUtil.kt similarity index 100% rename from core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/response/WebsocketResponseUtil.kt rename to worker-core/src/jsMain/kotlin/cn/rtast/cfworker/websocket/response/WebsocketResponseUtil.kt diff --git a/core/src/jsTest/kotlin/test/Test.kt b/worker-core/src/jsTest/kotlin/test/Test.kt similarity index 100% rename from core/src/jsTest/kotlin/test/Test.kt rename to worker-core/src/jsTest/kotlin/test/Test.kt diff --git a/core/wrangler.template.toml b/worker-core/wrangler.template.toml similarity index 100% rename from core/wrangler.template.toml rename to worker-core/wrangler.template.toml diff --git a/worker-gradle-plugin/build.gradle.kts b/worker-gradle-plugin/build.gradle.kts new file mode 100644 index 0000000..96d6ae2 --- /dev/null +++ b/worker-gradle-plugin/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + kotlin("jvm") + id("java-gradle-plugin") +} + +gradlePlugin { + website = "https://github.com/RTAkland/kotlin-cloudflare-worker" + vcsUrl = "https://github.com/RTAkland/kotlin-cloudflare-worker.git" + plugins { + create("kotlin-cloudflare-worker") { + id = "kotlin-cloudflare-worker" + displayName = "kotlin cloudflare worker" + description = "Kotlin cloudflare worker gradle plugin" + tags = listOf("tool", "tasks") + implementationClass = "cn.rtast.cfworker.plugin.KotlinCloudflareWorkerPlugin" + } + } +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.21") +} \ No newline at end of file diff --git a/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/KotlinCloudflareWorkerPlugin.kt b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/KotlinCloudflareWorkerPlugin.kt new file mode 100644 index 0000000..da76881 --- /dev/null +++ b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/KotlinCloudflareWorkerPlugin.kt @@ -0,0 +1,75 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/1/17 + */ + + +package cn.rtast.cfworker.plugin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.Exec +import java.io.File + +class KotlinCloudflareWorkerPlugin : Plugin { + override fun apply(target: Project) { + val extension = target.extensions.create("wrangler", WorkerExtension::class.java) + val layout = target.layout + val wranglerRunDir = layout.buildDirectory.dir("wrangler-run") + target.tasks.register("prepareWranglerRun", Copy::class.java) { + it.group = "wrangler" + it.dependsOn("compileDevelopmentExecutableKotlinJs") + val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/developmentExecutable/kotlin") + it.from(buildOutputDir) + it.into(wranglerRunDir) + } + target.tasks.register("wranglerDev", Exec::class.java) { exec -> + exec.group = "wrangler" + exec.workingDir = layout.buildDirectory.dir("wrangler-run").get().asFile.apply { mkdirs() } + exec.doFirst { + val sourceDir = target.layout.projectDirectory + mutableMapOf(extension.wranglerFile.get() to File(exec.workingDir, "wrangler.toml")).apply { + val envFile = sourceDir.file(".dev.vars").asFile + if (envFile.exists()) this[envFile] = File(exec.workingDir, ".dev.vars") + }.forEach { (s, d) -> s.copyTo(d, overwrite = true) } + } + exec.commandLine( + if (System.getProperty("os.name").lowercase().contains("windows")) listOf( + "cmd", "/c", "wrangler dev --port ${extension.port.get()}" + ) + else listOf("sh", "-c", "wrangler dev --port ${extension.port.get()}") + ) + exec.standardInput = System.`in` + exec.isIgnoreExitValue = false + } + + val wranglerDeployDir = layout.buildDirectory.dir("wrangler-deploy") + .apply { get().asFile.deleteRecursively() } + target.tasks.register("prepareProductionDeploy", Copy::class.java) { copy -> + copy.group = "wrangler" + copy.dependsOn("compileProductionExecutableKotlinJs") + val buildOutputDir = layout.buildDirectory.dir("compileSync/js/main/productionExecutable/kotlin") + copy.from(buildOutputDir) { it.exclude("*.map") } + copy.into(wranglerDeployDir) + copy.from(layout.projectDirectory.file("wrangler.toml")) + copy.into(wranglerDeployDir) + } + + target.tasks.register("wranglerDeploy", Exec::class.java) { + it.group = "wrangler" + it.dependsOn("prepareProductionDeploy") + it.workingDir = layout.buildDirectory.dir("wrangler-deploy").get().asFile.apply { mkdirs() } + it.commandLine( + if (System.getProperty("os.name").lowercase().contains("windows")) listOf( + "cmd", + "/c", + "wrangler deploy" + ) + else listOf("sh", "-c", "wrangler deploy") + ) + it.standardInput = System.`in` + } + } +} \ No newline at end of file diff --git a/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/RunMode.kt b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/RunMode.kt new file mode 100644 index 0000000..5c3b4fb --- /dev/null +++ b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/RunMode.kt @@ -0,0 +1,12 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/1/17 + */ + + +package cn.rtast.cfworker.plugin + +internal enum class RunMode { + Development, Production +} \ No newline at end of file diff --git a/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/WorkerExtension.kt b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/WorkerExtension.kt new file mode 100644 index 0000000..0a9a7f2 --- /dev/null +++ b/worker-gradle-plugin/src/main/kotlin/cn/rtast/cfworker/plugin/WorkerExtension.kt @@ -0,0 +1,25 @@ +/* + * Copyright © 2026 RTAkland + * Author: RTAkland + * Date: 2026/1/17 + */ + + +package cn.rtast.cfworker.plugin + +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import java.io.File + +abstract class WorkerExtension { + @get:Input + abstract val port: Property + + @get:Input + abstract val wranglerFile: Property + + init { + wranglerFile.convention(File("wrangler.toml")) + port.convention(7071) + } +} \ No newline at end of file diff --git a/worker-serialization/build.gradle.kts b/worker-serialization/build.gradle.kts new file mode 100644 index 0000000..d7213d7 --- /dev/null +++ b/worker-serialization/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + kotlin("multiplatform") + kotlin("plugin.serialization") +} + +kotlin { + js(IR) { + nodejs { binaries.executable() } + } +} \ No newline at end of file