From 0a52a55a9d25304149d4b8e4dfa29b4af3fe8965 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 17 Oct 2020 17:39:53 +0200 Subject: [PATCH] Add js sample (node and browser) --- build.gradle.kts | 3 +- buildSrc/build.gradle.kts | 6 +- buildSrc/src/main/kotlin/Deps.kt | 26 +++++- multiplatform-crypto/build.gradle.kts | 1 + sample/build.gradle.kts | 89 ++++++++++++++++++- .../com/ionspin/kotlin/crypto/sample/App.kt | 35 ++++++++ .../com/ionspin/kotlin/crypto/sample/Main.kt | 28 ++++++ sample/src/jsMain/resources/index.html | 12 +++ sample/webpack.config.d/devServer.config.js | 7 ++ 9 files changed, 198 insertions(+), 9 deletions(-) create mode 100644 sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/App.kt create mode 100644 sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/Main.kt create mode 100644 sample/src/jsMain/resources/index.html create mode 100644 sample/webpack.config.d/devServer.config.js diff --git a/build.gradle.kts b/build.gradle.kts index 7a49d0a..cdadcc4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,9 +15,8 @@ * */ - buildscript { - + repositories { mavenCentral() google() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2658b0f..409bfe9 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,7 +17,9 @@ plugins { + `java-gradle-plugin` `kotlin-dsl` + `kotlin-dsl-precompiled-script-plugins` } repositories { @@ -29,8 +31,8 @@ repositories { } dependencies { - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-rc") - implementation("com.android.tools.build:gradle:4.0.1") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10") + implementation("com.android.tools.build:gradle:4.0.2") } System.setProperty("PROJECT_PATH", project.projectDir.parentFile.toString()) diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index a29e32c..c468cae 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -23,7 +23,7 @@ object Versions { val dokkaPlugin = "1.4.0-rc" val taskTreePlugin = "1.5" - val kotlinBigNumVersion = "0.1.6-1.4.0-rc-SNAPSHOT" + val kotlinBigNumVersion = "0.2.2" val lazySodium = "4.3.1-SNAPSHOT" val jna = "5.5.0" @@ -64,15 +64,39 @@ object Deps { } object Js { + + object JsVersions { + val react = "16.13.1-pre.124-kotlin-1.4.10" + val reactNpm = "16.13.1" + val styled = "5.2.0-pre.124-kotlin-1.4.10" + val styledNpm = "1.0.0" + + } + val stdLib = "stdlib-js" val test = "test-js" val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.kotlinCoroutines}" val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}" + val ktorClient = "io.ktor:ktor-client-js:${Versions.ktor}" + val ktorClientSerialization = "io.ktor:ktor-client-serialization-js:${Versions.ktor}" + val ktorClientWebSockets = "io.ktor:ktor-client-websockets-js:${Versions.ktor}" + + object React { + val react = "org.jetbrains:kotlin-react:${JsVersions.react}" + val reactDom = "org.jetbrains:kotlin-react-dom:${JsVersions.react}" + val styled = "org.jetbrains:kotlin-styled:${JsVersions.styled}" + + } + object Npm { val libsodium = Pair("libsodium-wrappers-sumo", "0.7.8") //val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "0.7.8") + val reactPair = Pair("react", JsVersions.reactNpm) + val reactDomPair = Pair("react-dom", JsVersions.reactNpm) + val styledComponentsPair = Pair("styled-components", "5.2.0") + val inlineStylePrefixesPair = Pair("inline-style-prefixer", "6.0.0") } } diff --git a/multiplatform-crypto/build.gradle.kts b/multiplatform-crypto/build.gradle.kts index e75bc59..d458d71 100644 --- a/multiplatform-crypto/build.gradle.kts +++ b/multiplatform-crypto/build.gradle.kts @@ -49,6 +49,7 @@ val ideaActive = System.getProperty("idea.active") == "true" kotlin { val hostOsName = getHostOsName() + val bla =1 runningOnLinuxx86_64 { jvm() js { diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index ec6f87b..f418f36 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -25,9 +25,11 @@ plugins { id(PluginsDeps.kapt) id(PluginsDeps.androidApplication) id(PluginsDeps.kotlinAndroidExtensions) - id (PluginsDeps.mavenPublish) - id (PluginsDeps.signing) + id(PluginsDeps.mavenPublish) + id(PluginsDeps.signing) + } +org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolverPlugin.apply(project) val sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" val sonatypeSnapshots = "https://oss.sonatype.org/content/repositories/snapshots/" @@ -56,6 +58,9 @@ kotlin { jvm() js { browser { + webpackTask { + + } testTask { enabled = false //Until I sort out testing on travis useKarma { @@ -64,21 +69,21 @@ kotlin { } } nodejs { + testTask { useMocha() { timeout = "10s" } } } + binaries.executable() } android() linuxX64("linux") { - binaries { - executable { } } @@ -236,6 +241,27 @@ kotlin { val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) + implementation(Deps.Js.coroutines) +// implementation(Deps.Js.serialization) +// implementation(Deps.Js.ktorClient) +// implementation(Deps.Js.ktorClientSerialization) +// implementation(Deps.Js.ktorClientWebSockets) + // React + implementation(Deps.Js.React.react) + implementation(Deps.Js.React.reactDom) + implementation(npm(Deps.Js.Npm.reactPair.first, Deps.Js.Npm.reactPair.second)) + implementation(npm(Deps.Js.Npm.reactDomPair.first, Deps.Js.Npm.reactDomPair.second)) + + // Styled + implementation(Deps.Js.React.styled) + implementation(npm(Deps.Js.Npm.styledComponentsPair.first, Deps.Js.Npm.styledComponentsPair.second)) + implementation(npm(Deps.Js.Npm.inlineStylePrefixesPair.first, Deps.Js.Npm.inlineStylePrefixesPair.second)) + // Webpack ktor missing deps +// implementation(npm("text-encoding", "0.7.0")) +// implementation(npm("abort-controller", "3.0.0")) +// implementation(npm("bufferutil", "4.0.1")) +// implementation(npm("utf-8-validate", "5.0.2")) +// implementation(npm("fs")) } } val jsTest by getting { @@ -447,6 +473,61 @@ tasks { } +if (getHostOsName() == "macos") { + + val packForXcode by tasks.creating(Sync::class) { + val targetDir = File(buildDir, "xcode-frameworks") + + // / selecting the right configuration for the iOS + // / framework depending on the environment + // / variables set by Xcode build + val mode = System.getenv("CONFIGURATION") ?: "DEBUG" + val framework = kotlin.targets + .getByName("ios") + .binaries.getFramework(mode) + inputs.property("mode", mode) + dependsOn(framework.linkTask) + + from({ framework.outputDirectory }) + into(targetDir) + + // / generate a helpful ./gradlew wrapper with embedded Java path + doLast { + val gradlew = File(targetDir, "gradlew") + gradlew.writeText( + "#!/bin/bash\n" + + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n" + + "cd '${rootProject.rootDir}'\n" + + "./gradlew \$@\n" + ) + gradlew.setExecutable(true) + } + } + + tasks.getByName("build").dependsOn(packForXcode) +} + +fun org.jetbrains.kotlin.gradle.plugin.mpp.Executable.windowsResources(rcFileName: String) { + val taskName = linkTaskName.replaceFirst("link", "windres") + val inFile = compilation.defaultSourceSet.resources.sourceDirectories.singleFile.resolve(rcFileName) + val outFile = buildDir.resolve("processedResources/$taskName.res") + + val windresTask = tasks.create(taskName) { + val konanUserDir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" + val konanLlvmDir = "$konanUserDir/dependencies/msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1/bin" + + inputs.file(inFile) + outputs.file(outFile) + commandLine("$konanLlvmDir/windres", inFile, "-D_${buildType.name}", "-O", "coff", "-o", outFile) + environment("PATH", "$konanLlvmDir;${System.getenv("PATH")}") + + dependsOn(compilation.compileKotlinTask) + } + + linkTask.dependsOn(windresTask) + linkerOpts(outFile.toString()) +} + diff --git a/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/App.kt b/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/App.kt new file mode 100644 index 0000000..f626f89 --- /dev/null +++ b/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/App.kt @@ -0,0 +1,35 @@ +import com.ionspin.kotlin.crypto.hash.Hash +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlinx.css.br +import react.RBuilder +import react.RComponent +import react.RProps +import react.RState +import react.ReactElement +import react.dom.h1 + +external interface RAppState : RState { + var currentState: String +} + +external interface RAppProps : RProps { + +} + +class App(props: RAppProps) : RComponent(props) { + override fun RBuilder.render() { + val hash = Hash.sha512("123".encodeToUByteArray()) + h1 { + +"Hash (SHA512) of 123: ${hash.toHexString()}" + + } + } + +} + +fun RBuilder.app(handler: RAppProps.() -> Unit): ReactElement { + return child(App::class) { + this.attrs(handler) + } +} diff --git a/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/Main.kt b/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/Main.kt new file mode 100644 index 0000000..841f0c5 --- /dev/null +++ b/sample/src/jsMain/kotlin/com/ionspin/kotlin/crypto/sample/Main.kt @@ -0,0 +1,28 @@ + + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.hash.Hash +import com.ionspin.kotlin.crypto.util.LibsodiumRandom +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import react.dom.render +import kotlinx.browser.document +import kotlin.browser.window + +fun main() { + val runningOnNode = jsTypeOf(window) == "undefined" + if (!runningOnNode) { + LibsodiumInitializer.initializeWithCallback { + render(document.getElementById("root")) { + app { + + } + } + } + } else { + LibsodiumInitializer.initializeWithCallback { + val hash = Hash.sha512("123".encodeToUByteArray()) + println("Hash (SHA512) of 123: ${hash.toHexString()}") + } + } +} diff --git a/sample/src/jsMain/resources/index.html b/sample/src/jsMain/resources/index.html new file mode 100644 index 0000000..9f04a20 --- /dev/null +++ b/sample/src/jsMain/resources/index.html @@ -0,0 +1,12 @@ + + + + + Libsodium bindings sample app! + + + +
+ + + diff --git a/sample/webpack.config.d/devServer.config.js b/sample/webpack.config.d/devServer.config.js new file mode 100644 index 0000000..c4d84c0 --- /dev/null +++ b/sample/webpack.config.d/devServer.config.js @@ -0,0 +1,7 @@ +config.devServer = config.devServer || {} +config.devServer.port = 8081 +config.devServer.open = false +config.devServer.watchOptions = { + "aggregateTimeout": 1000, + "poll": 1000 +} \ No newline at end of file