diff options
author | Robert Jaros <rjaros@finn.pl> | 2020-03-11 16:18:17 +0100 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2020-03-11 16:18:17 +0100 |
commit | 9e243a469ae6544e8cf523ad09b959f541c3f565 (patch) | |
tree | be9c7447e221af49180c9e98434df7f988b940b8 | |
parent | ec6084c42c13a621e17b17bd40d90b5c7879f0ec (diff) | |
download | kvision-9e243a469ae6544e8cf523ad09b959f541c3f565.tar.gz kvision-9e243a469ae6544e8cf523ad09b959f541c3f565.tar.bz2 kvision-9e243a469ae6544e8cf523ad09b959f541c3f565.zip |
Upgrade to Kotlin 1.3.70 + other dependencies (Coroutinse, Serialization, Spring Boot)
Major refactoring of build architecture.
255 files changed, 4115 insertions, 2558 deletions
diff --git a/bintray.gradle b/bintray.gradle deleted file mode 100644 index f55e4aa5..00000000 --- a/bintray.gradle +++ /dev/null @@ -1,24 +0,0 @@ -bintray { - user = findProperty('buser') - key = findProperty('bkey') - pkg { - repo = 'kotlin' - name = "${project.name}" - licenses = ['MIT'] - vcsUrl = "https://github.com/rjaros/kvision.git" - version { - name = "${project.version}" - desc = 'Object oriented web framework for Kotlin/JS' - released = new Date() - vcsTag = project.version - } - } - filesSpec { - from "${project.buildDir}/libs/" - into "pl/treksoft/${project.name}/${project.version}" - } -} - -bintrayUpload { - dependsOn "generatePomFileForMavenProjectPublication" -} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index dda5105b..00000000 --- a/build.gradle +++ /dev/null @@ -1,262 +0,0 @@ -buildscript { - ext.production = (findProperty('prod') ?: 'false') == 'true' - - repositories { - jcenter() - maven { url = "https://dl.bintray.com/kotlin/kotlin-eap" } - maven { url = "https://plugins.gradle.org/m2/" } - maven { url = "https://bintray.com/kotlin/kotlin-eap/dokka" } - maven { url = "https://kotlin.bintray.com/kotlinx" } - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" - classpath "org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}" - classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:${frontendPluginVersion}" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokkaVersion}" - classpath "io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}" - } -} - -plugins { - id "com.jfrog.bintray" version "1.7.3" - id "io.gitlab.arturbosch.detekt" version "1.0.0-RC14" -} - -configure(allprojects - project(':kvision-modules') - project(':kvision-tools')) { - repositories { - jcenter() - mavenCentral() - maven { url = "https://dl.bintray.com/kotlin/kotlin-eap" } - maven { url = 'https://kotlin.bintray.com/kotlinx' } - maven { url = 'https://dl.bintray.com/gbaldeck/kotlin' } - maven { url = 'https://dl.bintray.com/rjaros/kotlin' } - maven { url = 'https://dl.bintray.com/kotlin/kotlin-js-wrappers' } - mavenLocal() - } -} - -configure(allprojects - project(':kvision-modules') - project(':kvision-tools') - project(":kvision-modules:kvision-base")) { - apply plugin: 'io.gitlab.arturbosch.detekt' - apply plugin: 'com.jfrog.bintray' - apply plugin: 'maven' - apply plugin: 'maven-publish' - apply from: rootProject.file('pom.gradle') - apply from: rootProject.file('bintray.gradle') - - afterEvaluate { - task sourceJar(type: Jar, dependsOn: classes) { - classifier 'sources' - from sourceSets.main.kotlin - duplicatesStrategy = "exclude" - } - } - - task emptyJar(type: Jar) { - classifier 'javadoc' - } - - tasks.build.dependsOn(['sourceJar', 'emptyJar']) - - detekt { - config = files(rootProject.projectDir.path + "/detekt.yml") - filters = ".*test.*,.*/resources/.*,.*/tmp/.*" - } - - publishing { - publications { - mavenProject(MavenPublication) { - from components.java - groupId project.group - artifactId project.name - version project.version - - artifact sourceJar { - classifier 'sources' - } - - artifact emptyJar { - classifier 'javadoc' - } - - withPom(pom) - } - } - } - - model { - tasks.generatePomFileForMavenProjectPublication { - destination = file("$buildDir/libs/${project.name}-${version}.pom") - } - } -} - -if (!project.gradle.startParameter.taskNames.contains("dokka")) { - apply plugin: 'kotlin-platform-js' - apply plugin: 'org.jetbrains.kotlin.frontend' -} else { - apply plugin: 'kotlin' -} -apply plugin: 'org.jetbrains.dokka' -apply plugin: 'kotlinx-serialization' - -dependencies { - if (!project.gradle.startParameter.taskNames.contains("dokka")) { - expectedBy project('kvision-modules:kvision-common-types') - compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion" - if (!project.gradle.startParameter.taskNames.contains("generatePomFileForMavenProjectPublication")) { - compile "org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion" - } - testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion" - } else { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - } - compile "com.github.snabbdom:snabbdom-kotlin:$snabbdomKotlinVersion" - compile "pl.treksoft:navigo-kotlin:$navigoKotlinVersion" - compile "pl.treksoft:jquery-kotlin:$jqueryKotlinVersion" -} - -if (!project.gradle.startParameter.taskNames.contains("dokka")) { - kotlinFrontend { - npm { - dependency("css-loader", "3.3.2") - dependency("style-loader", "1.0.1") - dependency("less", "3.10.3") - dependency("less-loader", "5.0.0") - dependency("imports-loader", "0.8.0") - dependency("uglifyjs-webpack-plugin", "2.2.0") - dependency("file-loader", "5.0.2") - dependency("url-loader", "3.0.0") - dependency("jquery", "3.4.1") - dependency("fecha", "3.0.3") - dependency("snabbdom", "0.7.4") - dependency("snabbdom-virtualize", "0.7.0") - dependency("jquery-resizable-dom", "0.35.0") - dependency("navigo", "7.1.2") - devDependency("karma", "4.4.1") - devDependency("karma-chrome-launcher", "3.1.0") - devDependency("karma-webpack", "4.0.2") - devDependency("qunit", "2.9.3") - } - - webpackBundle { - bundleName = "main" - contentPath = file('src/main/web') - mode = production ? "production" : "development" - } - karma { - plugins = ["karma-chrome-launcher"] - browsers = ["ChromeHeadless"] - } - define "PRODUCTION", production - - } -} - -dokka { - includes = ['Module.md'] - sourceDirs = files('kvision-modules/kvision-bootstrap/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-css/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-select/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-datetime/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-spinner/src/main/kotlin', - 'kvision-modules/kvision-richtext/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-upload/src/main/kotlin', - 'kvision-modules/kvision-handlebars/src/main/kotlin', - 'kvision-modules/kvision-i18n/src/main/kotlin', - 'kvision-modules/kvision-chart/src/main/kotlin', - 'kvision-modules/kvision-datacontainer/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-dialog/src/main/kotlin', - 'kvision-modules/kvision-fontawesome/src/main/kotlin', - 'kvision-modules/kvision-redux/src/main/kotlin', - 'kvision-modules/kvision-redux-kotlin/src/main/kotlin', - 'kvision-modules/kvision-maps/src/main/kotlin', - 'kvision-modules/kvision-moment/src/main/kotlin', - 'kvision-modules/kvision-tabulator/src/main/kotlin', - 'kvision-modules/kvision-pace/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-typeahead/src/main/kotlin', - 'kvision-modules/kvision-event-flow/src/main/kotlin', - 'kvision-modules/kvision-remote/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin', - 'kvision-modules/kvision-tabulator-remote/src/main/kotlin', - 'kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin', - 'kvision-modules/kvision-common/src/main/kotlin', - 'kvision-modules/kvision-common-types/src/main/kotlin', - 'kvision-modules/kvision-common-annotations/src/main/kotlin', - 'kvision-modules/kvision-server-javalin/src/main/kotlin', - 'kvision-modules/kvision-server-jooby/src/main/kotlin', - 'kvision-modules/kvision-server-ktor/src/main/kotlin', - 'kvision-modules/kvision-server-spring-boot/src/main/kotlin', - 'kvision-modules/kvision-cordova/src/main/kotlin', - 'kvision-modules/kvision-electron/src/main/kotlin', - 'kvision-modules/kvision-testutils/src/main/kotlin') - classpath = [new File("dokka/kvision-dokka-helper.jar")] - outputFormat = 'html' - outputDirectory = "$buildDir/kdoc" - reportUndocumented = false -} - -task testJar(type: Jar, dependsOn: testClasses) { - baseName = "${project.archivesBaseName}-test" - from sourceSets.test.output -} - -configurations { - tests -} - -artifacts { - tests testJar -} - -task cleanLibs(type: Delete) { - delete 'build/js', 'build/libs' -} - -if (project.gradle.startParameter.taskNames.contains("jar")) { - compileKotlin2Js.dependsOn 'cleanLibs' -} - -jar { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -if (!project.gradle.startParameter.taskNames.contains("dokka")) { - - compileKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' - } - - compileTestKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' - } - -} - -task copyResources(type: Copy) { - from "src/main/resources" - into file(buildDir.path + "/js") -} - -task copyResourcesForTests(type: Copy) { - from "src/main/resources" - into file(buildDir.path + "/js-tests/") -} - -if (!project.gradle.startParameter.taskNames.contains("dokka")) { - afterEvaluate { - tasks.getByName("webpack-bundle") { dependsOn(copyResources) } - tasks.getByName("webpack-run") { dependsOn(copyResources) } - tasks.getByName("test") { dependsOn(copyResources, copyResourcesForTests) } - tasks.getByName("karma-start") { dependsOn(copyResources, copyResourcesForTests) } - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..e0480fec --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,141 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + val kotlinVersion: String by System.getProperties() + id("kotlinx-serialization") version kotlinVersion + kotlin("js") + id("maven-publish") + val dokkaVersion: String by System.getProperties() + id("org.jetbrains.dokka") version dokkaVersion +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val snabbdomKotlinVersion: String by project +val navigoKotlinVersion: String by project +val jqueryKotlinVersion: String by project + +// Custom Properties +val webDir = file("src/main/web") + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(project(":kvision-modules:kvision-common-types")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("com.github.snabbdom:snabbdom-kotlin:$snabbdomKotlinVersion") + api("pl.treksoft:navigo-kotlin:$navigoKotlinVersion") + api("pl.treksoft:jquery-kotlin:$jqueryKotlinVersion") + implementation(npm("css-loader", "3.3.2")) + implementation(npm("style-loader", "1.0.1")) + implementation(npm("less", "3.10.3")) + implementation(npm("less-loader", "5.0.0")) + implementation(npm("imports-loader", "0.8.0")) + implementation(npm("uglifyjs-webpack-plugin", "2.2.0")) + implementation(npm("file-loader", "5.0.2")) + implementation(npm("url-loader", "3.0.0")) + implementation(npm("jquery", "3.4.1")) + implementation(npm("fecha", "3.0.3")) + implementation(npm("snabbdom", "0.7.4")) + implementation(npm("snabbdom-virtualize", "0.7.0")) + implementation(npm("jquery-resizable-dom", "0.35.0")) + implementation(npm("navigo", "7.1.2")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +fun copyResources() { + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision/kotlin") + } + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision/kotlin-dce") + } +} + +tasks { + getByName("JsJar", Jar::class) { + from("${project.buildDir}/js/packages/kvision/package.json") + } + getByName("compileTestKotlinJs") { + doLast { + copyResources() + } + } + getByName("processDceKotlinJs") { + doLast { + copyResources() + } + } + val dokka by getting(org.jetbrains.dokka.gradle.DokkaTask::class) { + outputFormat = "html" + outputDirectory = "$buildDir/kdoc" + subProjects = listOf( + "kvision-bootstrap", + "kvision-bootstrap-css", + "kvision-bootstrap-datetime", + "kvision-bootstrap-dialog", + "kvision-bootstrap-select", + "kvision-bootstrap-select-remote", + "kvision-bootstrap-spinner", + "kvision-bootstrap-typeahead", + "kvision-bootstrap-typeahead-remote", + "kvision-bootstrap-upload", + "kvision-common-annotations", + "kvision-common-remote", + "kvision-common-types", + "kvision-chart", + "kvision-cordova", + "kvision-datacontainer", + "kvision-electron", + "kvision-event-flow", + "kvision-fontawesome", + "kvision-handlebars", + "kvision-i18n", + "kvision-maps", + "kvision-moment", + "kvision-pace", + "kvision-redux", + "kvision-redux-kotlin", + "kvision-richtext", + "kvision-tabulator", + "kvision-tabulator-remote", + "kvision-server-javalin" + ) + multiplatform { + val js by creating { + includes = listOf("Module.md") + reportUndocumented = false + } + } + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 00000000..5d2c5a5d --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + `kotlin-dsl` +} + +repositories { + jcenter() + mavenLocal() +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.70") + implementation(gradleApi()) +} diff --git a/buildSrc/src/main/kotlin/Shared.kt b/buildSrc/src/main/kotlin/Shared.kt new file mode 100644 index 00000000..b72e7663 --- /dev/null +++ b/buildSrc/src/main/kotlin/Shared.kt @@ -0,0 +1,121 @@ +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPom +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.repositories +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget + +fun Project.repositories() { + repositories { + mavenCentral() + jcenter() + maven { url = uri("https://dl.bintray.com/kotlin/kotlin-eap") } + maven { url = uri("https://kotlin.bintray.com/kotlinx") } + maven { url = uri("https://dl.bintray.com/kotlin/kotlin-js-wrappers") } + maven { + url = uri("https://dl.bintray.com/gbaldeck/kotlin") + metadataSources { + mavenPom() + artifact() + } + } + maven { url = uri("https://dl.bintray.com/rjaros/kotlin") } + mavenLocal() + } +} + +fun KotlinJsProjectExtension.kotlinJsTargets() { + target { + val isProductionBuild = project.extra.get("production") as Boolean + kotlinJsTargets(isProductionBuild) + } +} + +fun KotlinMultiplatformExtension.kotlinJsTargets() { + js { + val isProductionBuild = project.extra.get("production") as Boolean + kotlinJsTargets(isProductionBuild) + } +} + +private fun KotlinJsTarget.kotlinJsTargets(isProductionBuild: Boolean) { + compilations.all { + kotlinOptions { + moduleKind = "umd" + sourceMap = !isProductionBuild + if (!isProductionBuild) { + sourceMapEmbedSources = "always" + } + } + } + browser { + testTask { + useKarma { + useChromeHeadless() + } + } + } +} + +fun KotlinMultiplatformExtension.kotlinJvmTargets() { + jvm { + compilations.all { + kotlinOptions { + jvmTarget = "1.8" + freeCompilerArgs = listOf("-Xjsr305=strict") + } + } + } +} + +fun MavenPom.defaultPom() { + name.set("KVision") + description.set("Object oriented web framework for Kotlin/JS") + url.set("https://github.com/rjaros/kvision") + licenses { + license { + name.set("MIT") + url.set("https://opensource.org/licenses/MIT") + } + } + developers { + developer { + id.set("rjaros") + name.set("Robert Jaros") + organization.set("Treksoft") + organizationUrl.set("http://www.treksoft.pl") + } + } + scm { + url.set("https://github.com/rjaros/kvision.git") + connection.set("scm:git:git://github.com/rjaros/kvision.git") + developerConnection.set("scm:git:git://github.com/rjaros/kvision.git") + } +} + +fun Project.setupPublication() { + plugins.apply("maven-publish") + + extensions.getByType<PublishingExtension>().run { + publications.withType<MavenPublication>().all { + pom { + defaultPom() + } + } + + repositories { + maven { + url = uri("https://api.bintray.com/maven/rjaros/kotlin/${project.name}/;publish=0;override=1") + credentials { + username = findProperty("buser")?.toString() + password = findProperty("bkey")?.toString() + } + } + } + } +} diff --git a/detekt.yml b/detekt.yml deleted file mode 100644 index 14960490..00000000 --- a/detekt.yml +++ /dev/null @@ -1,538 +0,0 @@ -build: - maxIssues: 10 - weights: - # complexity: 2 - # LongParameterList: 1 - # style: 1 - # comments: 1 - -processors: - active: true - exclude: - # - 'FunctionCountProcessor' - # - 'PropertyCountProcessor' - # - 'ClassCountProcessor' - # - 'PackageCountProcessor' - # - 'KtFileCountProcessor' - -console-reports: - active: true - exclude: - # - 'ProjectStatisticsReport' - # - 'ComplexityReport' - # - 'NotificationReport' - # - 'FindingsReport' - # - 'BuildFailureReport' - -comments: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - CommentOverPrivateFunction: - active: false - CommentOverPrivateProperty: - active: false - EndOfSentenceFormat: - active: false - endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$) - UndocumentedPublicClass: - active: false - searchInNestedClass: true - searchInInnerClass: true - searchInInnerObject: true - searchInInnerInterface: true - UndocumentedPublicFunction: - active: false - -complexity: - active: true - ComplexCondition: - active: true - threshold: 4 - ComplexInterface: - active: false - threshold: 10 - includeStaticDeclarations: false - ComplexMethod: - active: true - threshold: 10 - ignoreSingleWhenExpression: false - ignoreSimpleWhenEntries: false - LabeledExpression: - active: false - ignoredLabels: "" - LargeClass: - active: true - threshold: 600 - LongMethod: - active: false - threshold: 60 - LongParameterList: - active: false - threshold: 6 - ignoreDefaultParameters: false - MethodOverloading: - active: false - threshold: 6 - NestedBlockDepth: - active: true - threshold: 4 - StringLiteralDuplication: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - threshold: 3 - ignoreAnnotation: true - excludeStringsWithLessThan5Characters: true - ignoreStringsRegex: '$^' - TooManyFunctions: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - thresholdInFiles: 11 - thresholdInClasses: 11 - thresholdInInterfaces: 11 - thresholdInObjects: 11 - thresholdInEnums: 11 - ignoreDeprecated: false - ignorePrivate: false - ignoreOverridden: false - -empty-blocks: - active: true - EmptyCatchBlock: - active: true - allowedExceptionNameRegex: "^(_|(ignore|expected).*)" - EmptyClassBlock: - active: true - EmptyDefaultConstructor: - active: true - EmptyDoWhileBlock: - active: true - EmptyElseBlock: - active: true - EmptyFinallyBlock: - active: true - EmptyForBlock: - active: true - EmptyFunctionBlock: - active: true - ignoreOverriddenFunctions: false - EmptyIfBlock: - active: true - EmptyInitBlock: - active: true - EmptyKtFile: - active: true - EmptySecondaryConstructor: - active: true - EmptyWhenBlock: - active: true - EmptyWhileBlock: - active: true - -exceptions: - active: true - ExceptionRaisedInUnexpectedLocation: - active: false - methodNames: 'toString,hashCode,equals,finalize' - InstanceOfCheckForException: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - NotImplementedDeclaration: - active: false - PrintStackTrace: - active: false - RethrowCaughtException: - active: false - ReturnFromFinally: - active: false - SwallowedException: - active: false - ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException' - ThrowingExceptionFromFinally: - active: false - ThrowingExceptionInMain: - active: false - ThrowingExceptionsWithoutMessageOrCause: - active: false - exceptions: 'IllegalArgumentException,IllegalStateException,IOException' - ThrowingNewInstanceOfSameException: - active: false - TooGenericExceptionCaught: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - exceptionNames: - - ArrayIndexOutOfBoundsException - - Error - - Exception - - IllegalMonitorStateException - - NullPointerException - - IndexOutOfBoundsException - - RuntimeException - - Throwable - allowedExceptionNameRegex: "^(_|(ignore|expected).*)" - TooGenericExceptionThrown: - active: true - exceptionNames: - - Error - - Exception - - Throwable - - RuntimeException - -formatting: - active: true - android: false - autoCorrect: true - ChainWrapping: - active: true - autoCorrect: true - CommentSpacing: - active: true - autoCorrect: true - Filename: - active: true - FinalNewline: - active: true - autoCorrect: true - ImportOrdering: - active: false - Indentation: - active: true - autoCorrect: true - indentSize: 4 - continuationIndentSize: 4 - MaximumLineLength: - active: true - maxLineLength: 120 - ModifierOrdering: - active: true - autoCorrect: true - NoBlankLineBeforeRbrace: - active: true - autoCorrect: true - NoConsecutiveBlankLines: - active: true - autoCorrect: true - NoEmptyClassBody: - active: true - autoCorrect: true - NoItParamInMultilineLambda: - active: false - NoLineBreakAfterElse: - active: true - autoCorrect: true - NoLineBreakBeforeAssignment: - active: true - autoCorrect: true - NoMultipleSpaces: - active: true - autoCorrect: true - NoSemicolons: - active: true - autoCorrect: true - NoTrailingSpaces: - active: true - autoCorrect: true - NoUnitReturn: - active: true - autoCorrect: true - NoUnusedImports: - active: true - autoCorrect: true - NoWildcardImports: - active: true - autoCorrect: true - PackageName: - active: true - autoCorrect: true - ParameterListWrapping: - active: true - autoCorrect: true - indentSize: 4 - SpacingAroundColon: - active: true - autoCorrect: true - SpacingAroundComma: - active: true - autoCorrect: true - SpacingAroundCurly: - active: true - autoCorrect: true - SpacingAroundKeyword: - active: true - autoCorrect: true - SpacingAroundOperators: - active: true - autoCorrect: true - SpacingAroundParens: - active: true - autoCorrect: true - SpacingAroundRangeOperator: - active: true - autoCorrect: true - StringTemplate: - active: true - autoCorrect: true - -naming: - active: true - ClassNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - classPattern: '[A-Z$][a-zA-Z0-9$]*' - ConstructorParameterNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - parameterPattern: '[a-z][A-Za-z0-9]*' - privateParameterPattern: '[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - EnumNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' - ForbiddenClassName: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - forbiddenName: '' - FunctionMaxLength: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - maximumFunctionNameLength: 30 - FunctionMinLength: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - minimumFunctionNameLength: 3 - FunctionNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' - excludeClassPattern: '$^' - ignoreOverridden: true - FunctionParameterNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - parameterPattern: '[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - ignoreOverriddenFunctions: true - InvalidPackageDeclaration: - active: false - rootPackage: '' - MatchingDeclarationName: - active: true - MemberNameEqualsClassName: - active: false - ignoreOverriddenFunction: true - ObjectPropertyNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - constantPattern: '[A-Za-z][_A-Za-z0-9]*' - propertyPattern: '[A-Za-z][_A-Za-z0-9]*' - privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' - PackageNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$' - TopLevelPropertyNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - constantPattern: '[A-Z][_A-Z0-9]*' - propertyPattern: '[A-Za-z][_A-Za-z0-9]*' - privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' - VariableMaxLength: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - maximumVariableNameLength: 64 - VariableMinLength: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - minimumVariableNameLength: 1 - VariableNaming: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - variablePattern: '[a-z][A-Za-z0-9]*' - privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - ignoreOverridden: true - -performance: - active: true - ArrayPrimitive: - active: false - ForEachOnRange: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - SpreadOperator: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - UnnecessaryTemporaryInstantiation: - active: true - -potential-bugs: - active: true - DuplicateCaseInWhenExpression: - active: true - EqualsAlwaysReturnsTrueOrFalse: - active: false - EqualsWithHashCodeExist: - active: true - ExplicitGarbageCollectionCall: - active: true - InvalidRange: - active: false - IteratorHasNextCallsNextMethod: - active: false - IteratorNotThrowingNoSuchElementException: - active: false - LateinitUsage: - active: false - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - excludeAnnotatedProperties: "" - ignoreOnClassesPattern: "" - MissingWhenCase: - active: false - RedundantElseInWhen: - active: false - UnconditionalJumpStatementInLoop: - active: false - UnreachableCode: - active: true - UnsafeCallOnNullableType: - active: false - UnsafeCast: - active: false - UselessPostfixExpression: - active: false - WrongEqualsTypeParameter: - active: false - -style: - active: true - CollapsibleIfStatements: - active: false - DataClassContainsFunctions: - active: false - conversionFunctionPrefix: 'to' - DataClassShouldBeImmutable: - active: false - EqualsNullCall: - active: false - EqualsOnSignatureLine: - active: false - ExplicitItLambdaParameter: - active: false - ExpressionBodySyntax: - active: false - includeLineWrapping: false - ForbiddenComment: - active: true - values: 'TODO:,FIXME:,STOPSHIP:' - ForbiddenImport: - active: false - imports: '' - ForbiddenVoid: - active: false - ignoreOverridden: false - FunctionOnlyReturningConstant: - active: false - ignoreOverridableFunction: true - excludedFunctions: 'describeContents' - LoopWithTooManyJumpStatements: - active: false - maxJumpCount: 1 - MagicNumber: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - ignoreNumbers: '-1,0,1,2' - ignoreHashCodeFunction: true - ignorePropertyDeclaration: false - ignoreConstantDeclaration: true - ignoreCompanionObjectPropertyDeclaration: true - ignoreAnnotation: false - ignoreNamedArgument: true - ignoreEnums: false - ignoreRanges: false - MandatoryBracesIfStatements: - active: false - MaxLineLength: - active: true - maxLineLength: 120 - excludePackageStatements: true - excludeImportStatements: true - excludeCommentStatements: false - MayBeConst: - active: false - ModifierOrder: - active: true - NestedClassesVisibility: - active: false - NewLineAtEndOfFile: - active: true - NoTabs: - active: false - OptionalAbstractKeyword: - active: true - OptionalUnit: - active: false - OptionalWhenBraces: - active: false - PreferToOverPairSyntax: - active: false - ProtectedMemberInFinalClass: - active: false - RedundantVisibilityModifierRule: - active: false - ReturnCount: - active: true - max: 2 - excludedFunctions: "equals" - excludeLabeled: false - excludeReturnFromLambda: true - SafeCast: - active: true - SerialVersionUIDInSerializableClass: - active: false - SpacingBetweenPackageAndImports: - active: false - ThrowsCount: - active: true - max: 2 - TrailingWhitespace: - active: false - UnderscoresInNumericLiterals: - active: false - acceptableDecimalLength: 5 - UnnecessaryAbstractClass: - active: false - excludeAnnotatedClasses: "dagger.Module" - UnnecessaryApply: - active: false - UnnecessaryInheritance: - active: false - UnnecessaryLet: - active: false - UnnecessaryParentheses: - active: false - UntilInsteadOfRangeTo: - active: false - UnusedImports: - active: false - UnusedPrivateClass: - active: false - UnusedPrivateMember: - active: false - allowedNames: "(_|ignored|expected|serialVersionUID)" - UseCheckOrError: - active: false - UseDataClass: - active: false - excludeAnnotatedClasses: "" - UseRequire: - active: false - UselessCallOnNotNull: - active: false - UtilityClassWithPublicConstructor: - active: false - VarCouldBeVal: - active: false - WildcardImport: - active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" - excludeImports: 'java.util.*,kotlinx.android.synthetic.*' diff --git a/dokka/kvision-dokka-helper.jar b/dokka/kvision-dokka-helper.jar Binary files differdeleted file mode 100644 index 3c8e3adf..00000000 --- a/dokka/kvision-dokka-helper.jar +++ /dev/null diff --git a/gradle.properties b/gradle.properties index be865b3b..5f8b2b42 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,27 +1,22 @@ group=pl.treksoft version=3.0.1 -kotlinVersion=1.3.61 +systemProp.kotlinVersion=1.3.70 javaVersion=1.8 -coroutinesVersion=1.3.3 -serializationVersion=0.14.0 -frontendPluginVersion=0.0.45 -dokkaVersion=0.9.18 -detektVersion=1.0.0-RC14 -junitVersion=4.12 +coroutinesVersion=1.3.4 +serializationVersion=0.20.0 +systemProp.dokkaVersion=0.10.1 joobyVersion=2.6.1 -springBootVersion=2.2.4.RELEASE +springBootVersion=2.2.5.RELEASE ktorVersion=1.3.1 javalinVersion=3.7.0 guiceVersion=4.2.2 -dependencyManagementPluginVersion=1.0.8.RELEASE -jacksonModuleKotlinVersion=2.10.2 -springDataRelationalVersion=1.1.4.RELEASE +jacksonModuleKotlinVersion=2.10.3 +springDataRelationalVersion=1.1.5.RELEASE jqueryKotlinVersion=0.0.4 snabbdomKotlinVersion=0.1.1 navigoKotlinVersion=0.0.3 nodeKtVersion=0.1.0 -kotlinReduxVersion=4.0.0-pre.90-kotlin-1.3.61 -reduxKotlinVersion=0.3.1 +kotlinReduxVersion=4.0.0-pre.93-kotlin-1.3.70 +reduxKotlinVersion=0.3.2 reduxKotlinThunkVersion=0.2.9 -mpaptRuntimeVersion=0.8.3 -autoServiceVersion=1.0-rc6 +mpaptRuntimeVersion=0.8.4 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differindex 94336fca..cc4fdc29 100644 --- a/gradle/wrapper/gradle-wrapper.jar +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae45383b..84a90661 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -109,8 +125,8 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` @@ -138,19 +154,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +175,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f9553162..9618d8d9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/kvision-modules/kvision-base/build.gradle b/kvision-modules/kvision-base/build.gradle deleted file mode 100644 index 51970a40..00000000 --- a/kvision-modules/kvision-base/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'kotlin-platform-js' - -dependencies { - compile rootProject - compile project(path: ":", configuration: "tests") - testCompile rootProject -} diff --git a/kvision-modules/kvision-bootstrap-css/build.gradle b/kvision-modules/kvision-bootstrap-css/build.gradle deleted file mode 100644 index d18cfc13..00000000 --- a/kvision-modules/kvision-bootstrap-css/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap", "4.4.1") - } - -} diff --git a/kvision-modules/kvision-bootstrap-css/build.gradle.kts b/kvision-modules/kvision-bootstrap-css/build.gradle.kts new file mode 100644 index 00000000..d9df96e0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("bootstrap", "4.4.1")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-bootstrap-css/package.json.d/project.info b/kvision-modules/kvision-bootstrap-css/package.json.d/project.info deleted file mode 100644 index b990974a..00000000 --- a/kvision-modules/kvision-bootstrap-css/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Bootstrap CSS module" -} diff --git a/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js index 32a7c4d0..35b28e6a 100644 --- a/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js @@ -1,4 +1,3 @@ config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); -config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-bootstrap-css/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-bootstrap-datetime/build.gradle b/kvision-modules/kvision-bootstrap-datetime/build.gradle deleted file mode 100644 index 54902008..00000000 --- a/kvision-modules/kvision-bootstrap-datetime/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("pc-bootstrap4-datetimepicker", "4.17.50") - } - -} diff --git a/kvision-modules/kvision-bootstrap-datetime/build.gradle.kts b/kvision-modules/kvision-bootstrap-datetime/build.gradle.kts new file mode 100644 index 00000000..f2340ad9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("pc-bootstrap4-datetimepicker", "4.17.50")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info deleted file mode 100644 index 3d332806..00000000 --- a/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Datetime module" -} diff --git a/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-dialog/build.gradle b/kvision-modules/kvision-bootstrap-dialog/build.gradle deleted file mode 100644 index 652d14d6..00000000 --- a/kvision-modules/kvision-bootstrap-dialog/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile project(":kvision-modules:kvision-bootstrap") - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} diff --git a/kvision-modules/kvision-bootstrap-dialog/build.gradle.kts b/kvision-modules/kvision-bootstrap-dialog/build.gradle.kts new file mode 100644 index 00000000..1065b02a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/build.gradle.kts @@ -0,0 +1,44 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +// Versions +val coroutinesVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api(project(":kvision-modules:kvision-bootstrap")) + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info deleted file mode 100644 index 416cd4a7..00000000 --- a/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Dialog module" -} diff --git a/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-select-remote/build.gradle b/kvision-modules/kvision-bootstrap-select-remote/build.gradle deleted file mode 100644 index 7a4dc8fa..00000000 --- a/kvision-modules/kvision-bootstrap-select-remote/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile project(":kvision-modules:kvision-bootstrap-select") - compile project(":kvision-modules:kvision-remote") -} diff --git a/kvision-modules/kvision-bootstrap-select-remote/build.gradle.kts b/kvision-modules/kvision-bootstrap-select-remote/build.gradle.kts new file mode 100644 index 00000000..e7b28ac8 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/build.gradle.kts @@ -0,0 +1,74 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api(project(":kvision-modules:kvision-bootstrap-select")) + api(project(":kvision-modules:kvision-common-remote")) + compileOnly(project(":kvision-modules:kvision-server-javalin")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +fun copyResources() { + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin") + } + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin-dce") + } + copy { + from("${rootProject.projectDir}/kvision-modules/kvision-bootstrap-select/src/main/resources") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin") + } + copy { + from("${rootProject.projectDir}/kvision-modules/kvision-bootstrap-select/src/main/resources") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin-dce") + } +} + +tasks { + getByName("compileTestKotlinJs") { + doLast { + copyResources() + } + } + getByName("processDceKotlinJs") { + doLast { + copyResources() + } + } +} diff --git a/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info deleted file mode 100644 index 5685d581..00000000 --- a/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Select remote addon module" -} diff --git a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt index 6092fd93..e7fd384c 100644 --- a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.await import kotlinx.coroutines.launch import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.list +import kotlinx.serialization.builtins.list import kotlinx.serialization.stringify import org.w3c.dom.get import pl.treksoft.kvision.core.Container @@ -53,7 +53,7 @@ external fun decodeURIComponent(encodedURI: String): String * @param preload preload all options from remote data source * @param classes a set of CSS class names */ -@UseExperimental(ImplicitReflectionSerializer::class) +@OptIn(ImplicitReflectionSerializer::class) open class SelectRemoteInput<T : Any>( serviceManager: KVServiceManager<T>, function: suspend T.(String?, String?, String?) -> List<RemoteOption>, diff --git a/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-select/build.gradle b/kvision-modules/kvision-bootstrap-select/build.gradle deleted file mode 100644 index 01ec3ad0..00000000 --- a/kvision-modules/kvision-bootstrap-select/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-select", "1.13.12") - dependency("ajax-bootstrap-select", "1.4.5") - } - -} diff --git a/kvision-modules/kvision-bootstrap-select/build.gradle.kts b/kvision-modules/kvision-bootstrap-select/build.gradle.kts new file mode 100644 index 00000000..1db76c5d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/build.gradle.kts @@ -0,0 +1,68 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("bootstrap-select", "1.13.12")) + implementation(npm("ajax-bootstrap-select", "1.4.5")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +fun copyResources() { + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin") + } + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin-dce") + } +} + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } + getByName("compileTestKotlinJs") { + doLast { + copyResources() + } + } + getByName("processDceKotlinJs") { + doLast { + copyResources() + } + } +} diff --git a/kvision-modules/kvision-bootstrap-select/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info deleted file mode 100644 index 80e675b0..00000000 --- a/kvision-modules/kvision-bootstrap-select/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Select module" -} diff --git a/kvision-modules/kvision-bootstrap-select/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-select/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-bootstrap-spinner/build.gradle b/kvision-modules/kvision-bootstrap-spinner/build.gradle deleted file mode 100644 index 0c3a2940..00000000 --- a/kvision-modules/kvision-bootstrap-spinner/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-touchspin", "4.2.5") - } - -} diff --git a/kvision-modules/kvision-bootstrap-spinner/build.gradle.kts b/kvision-modules/kvision-bootstrap-spinner/build.gradle.kts new file mode 100644 index 00000000..19453b54 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("bootstrap-touchspin", "4.2.5")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info deleted file mode 100644 index fb0c7956..00000000 --- a/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Spinner module" -} diff --git a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle b/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle deleted file mode 100644 index cab403d5..00000000 --- a/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile project(":kvision-modules:kvision-bootstrap-typeahead") - compile project(":kvision-modules:kvision-remote") -} diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle.kts b/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle.kts new file mode 100644 index 00000000..a94b0ce9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle.kts @@ -0,0 +1,42 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api(project(":kvision-modules:kvision-bootstrap-typeahead")) + api(project(":kvision-modules:kvision-common-remote")) + compileOnly(project(":kvision-modules:kvision-server-javalin")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info deleted file mode 100644 index 15dc8333..00000000 --- a/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Typeahead remote addon module" -} diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt index e56468d1..42412ae4 100644 --- a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt @@ -22,8 +22,8 @@ package pl.treksoft.kvision.form.text import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.list -import kotlinx.serialization.serializer +import kotlinx.serialization.builtins.list +import kotlinx.serialization.builtins.serializer import kotlinx.serialization.stringify import org.w3c.dom.get import pl.treksoft.kvision.core.Container @@ -46,7 +46,7 @@ import kotlin.browser.window * @param value text input value * @param classes a set of CSS class names */ -@UseExperimental(ImplicitReflectionSerializer::class) +@OptIn(ImplicitReflectionSerializer::class) open class TypeaheadRemoteInput<T : Any>( serviceManager: KVServiceManager<T>, function: suspend T.(String?, String?) -> List<String>, diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-typeahead/build.gradle b/kvision-modules/kvision-bootstrap-typeahead/build.gradle deleted file mode 100644 index e9162b54..00000000 --- a/kvision-modules/kvision-bootstrap-typeahead/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("eam_bootstrap-3-typeahead", "0.0.2") - } - -} diff --git a/kvision-modules/kvision-bootstrap-typeahead/build.gradle.kts b/kvision-modules/kvision-bootstrap-typeahead/build.gradle.kts new file mode 100644 index 00000000..a5fbfaf9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("eam_bootstrap-3-typeahead", "0.0.2")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-bootstrap-typeahead/package.json.d/project.info b/kvision-modules/kvision-bootstrap-typeahead/package.json.d/project.info deleted file mode 100644 index a212d31d..00000000 --- a/kvision-modules/kvision-bootstrap-typeahead/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Typeahead module" -} diff --git a/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-typeahead/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-bootstrap-upload/build.gradle b/kvision-modules/kvision-bootstrap-upload/build.gradle deleted file mode 100644 index 208e1e21..00000000 --- a/kvision-modules/kvision-bootstrap-upload/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} - -kotlinFrontend { - - npm { - dependency("bootstrap-fileinput", "5.0.8") - } - -} diff --git a/kvision-modules/kvision-bootstrap-upload/build.gradle.kts b/kvision-modules/kvision-bootstrap-upload/build.gradle.kts new file mode 100644 index 00000000..4fcaa183 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/build.gradle.kts @@ -0,0 +1,71 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +val coroutinesVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(project(":kvision-modules:kvision-common-types")) + api(rootProject) + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + implementation(npm("bootstrap-fileinput", "5.0.8")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +fun copyResources() { + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin") + } + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin-dce") + } +} + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } + getByName("compileTestKotlinJs") { + doLast { + copyResources() + } + } + getByName("processDceKotlinJs") { + doLast { + copyResources() + } + } +} diff --git a/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info deleted file mode 100644 index d789d81b..00000000 --- a/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Upload module" -} diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js index a5c7b5da..653ca21f 100644 --- a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js @@ -1,6 +1,9 @@ config.module.rules.push( { - test: /\.(jpe?g|png|gif)$/i, - loader: 'file-loader' + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, } -);
\ No newline at end of file +); diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-bootstrap/build.gradle b/kvision-modules/kvision-bootstrap/build.gradle deleted file mode 100644 index 3d964668..00000000 --- a/kvision-modules/kvision-bootstrap/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("popper.js", "1.16.1") - dependency("bootstrap", "4.4.1") - dependency("awesome-bootstrap-checkbox", "1.0.1") - dependency("element-resize-event", "3.0.3") - } - -} diff --git a/kvision-modules/kvision-bootstrap/build.gradle.kts b/kvision-modules/kvision-bootstrap/build.gradle.kts new file mode 100644 index 00000000..bed8be05 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/build.gradle.kts @@ -0,0 +1,49 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("popper.js", "1.16.1")) + implementation(npm("bootstrap", "4.4.1")) + implementation(npm("awesome-bootstrap-checkbox", "1.0.1")) + implementation(npm("element-resize-event", "3.0.3")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-bootstrap/package.json.d/project.info b/kvision-modules/kvision-bootstrap/package.json.d/project.info deleted file mode 100644 index e77a0f47..00000000 --- a/kvision-modules/kvision-bootstrap/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Bootstrap module" -} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt index 44c0a243..36967e2b 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -216,6 +216,7 @@ open class TabPanel( } content.remove(content.getChildren()[index]) activeIndex = content.activeIndex + @Suppress("UnsafeCastFromDynamic") this@TabPanel.dispatchEvent("tabChange", obj { detail = obj { data = activeIndex } }) return this } diff --git a/kvision-modules/kvision-bootstrap/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap/webpack.config.d/bootstrap.js index 32a7c4d0..35b28e6a 100644 --- a/kvision-modules/kvision-bootstrap/webpack.config.d/bootstrap.js +++ b/kvision-modules/kvision-bootstrap/webpack.config.d/bootstrap.js @@ -1,4 +1,3 @@ config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); -config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-bootstrap/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-bootstrap/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-bootstrap/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-bootstrap/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-chart/build.gradle b/kvision-modules/kvision-chart/build.gradle deleted file mode 100644 index cc5d9506..00000000 --- a/kvision-modules/kvision-chart/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("chart.js", "2.9.3") - } - -} diff --git a/kvision-modules/kvision-chart/build.gradle.kts b/kvision-modules/kvision-chart/build.gradle.kts new file mode 100644 index 00000000..78c4ef43 --- /dev/null +++ b/kvision-modules/kvision-chart/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("chart.js", "2.9.3")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-chart/package.json.d/project.info b/kvision-modules/kvision-chart/package.json.d/project.info deleted file mode 100644 index 4b4a6303..00000000 --- a/kvision-modules/kvision-chart/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Chart module" -} diff --git a/kvision-modules/kvision-chart/webpack.config.d/bootstrap.js b/kvision-modules/kvision-chart/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-chart/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-chart/webpack.config.d/file.js b/kvision-modules/kvision-chart/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-chart/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-common-annotations/build.gradle b/kvision-modules/kvision-common-annotations/build.gradle deleted file mode 100644 index f62cd411..00000000 --- a/kvision-modules/kvision-common-annotations/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'kotlin-platform-common' -apply plugin: 'kotlinx-serialization' - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion" -} diff --git a/kvision-modules/kvision-common-annotations/build.gradle.kts b/kvision-modules/kvision-common-annotations/build.gradle.kts new file mode 100644 index 00000000..9ada6145 --- /dev/null +++ b/kvision-modules/kvision-common-annotations/build.gradle.kts @@ -0,0 +1,49 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("maven-publish") +} + +repositories() + +// Versions +val serializationVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-common-annotations" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-common-annotations/src/main/kotlin/pl/treksoft/kvision/annotations/Annotations.kt b/kvision-modules/kvision-common-annotations/src/commonMain/kotlin/pl/treksoft/kvision/annotations/Annotations.kt index 22cf570b..22cf570b 100644 --- a/kvision-modules/kvision-common-annotations/src/main/kotlin/pl/treksoft/kvision/annotations/Annotations.kt +++ b/kvision-modules/kvision-common-annotations/src/commonMain/kotlin/pl/treksoft/kvision/annotations/Annotations.kt diff --git a/kvision-modules/kvision-common-remote/build.gradle b/kvision-modules/kvision-common-remote/build.gradle deleted file mode 100644 index af3703e6..00000000 --- a/kvision-modules/kvision-common-remote/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -apply plugin: 'kotlin-platform-common' -apply plugin: 'kotlinx-serialization' - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion" - testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlinVersion" - testCompile "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlinVersion" -} diff --git a/kvision-modules/kvision-common-remote/build.gradle.kts b/kvision-modules/kvision-common-remote/build.gradle.kts new file mode 100644 index 00000000..a7daa88e --- /dev/null +++ b/kvision-modules/kvision-common-remote/build.gradle.kts @@ -0,0 +1,57 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val serializationVersion: String by project +val coroutinesVersion: String by project +val jacksonModuleKotlinVersion: String by project +val jqueryKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + implementation("pl.treksoft:jquery-kotlin:$jqueryKotlinVersion") + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-common-remote" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/JsonRpc.kt b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/JsonRpc.kt index d82189a0..d82189a0 100644 --- a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/JsonRpc.kt +++ b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/JsonRpc.kt diff --git a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceMgr.kt index 1d37ae51..2d68f1d0 100644 --- a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceMgr.kt @@ -19,29 +19,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package pl.treksoft.kvision.types -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.math.BigDecimal +package pl.treksoft.kvision.remote -actual typealias Decimal = BigDecimal - -class BigDecimalSerializer : JsonSerializer<BigDecimal>() { - @Throws(IOException::class) - override fun serialize(value: BigDecimal, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeNumber(value.toDouble()) - } -} - -class BigDecimalDeserializer : JsonDeserializer<BigDecimal>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): BigDecimal? { - return p.doubleValue.toBigDecimal() - } +@Suppress("unused") +interface KVServiceMgr<T : Any> { + fun getCalls(): Map<String, Pair<String, HttpMethod>> } diff --git a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteTypes.kt b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/RemoteTypes.kt index 62b2354b..d96aa30c 100644 --- a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteTypes.kt +++ b/kvision-modules/kvision-common-remote/src/commonMain/kotlin/pl/treksoft/kvision/remote/RemoteTypes.kt @@ -23,6 +23,14 @@ package pl.treksoft.kvision.remote import kotlinx.serialization.Serializable +enum class HttpMethod { + GET, + POST, + PUT, + DELETE, + OPTIONS +} + class ServiceException(message: String) : Exception(message) @Serializable diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/CallAgent.kt index 9110d4df..6c1e629c 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/CallAgent.kt @@ -52,7 +52,7 @@ open class CallAgent { * @param method a HTTP method * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) @Suppress("UnsafeCastFromDynamic", "ComplexMethod") fun jsonRpcCall( url: String, diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt index 86d90e4c..62657b3d 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVRemoteAgent.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.list +import kotlinx.serialization.builtins.list import kotlinx.serialization.serializer import kotlinx.serialization.stringify import kotlin.reflect.KClass @@ -39,8 +39,11 @@ import kotlin.reflect.KClass * Client side agent for JSON-RPC remote calls. */ @Suppress("LargeClass", "TooManyFunctions") -@UseExperimental(ImplicitReflectionSerializer::class, ExperimentalCoroutinesApi::class) -open class KVRemoteAgent<T : Any>(val serviceManager: KVServiceManager<T>) : RemoteAgent { +@OptIn( + ImplicitReflectionSerializer::class, ExperimentalCoroutinesApi::class +) +open class KVRemoteAgent<T : Any>(val serviceManager: KVServiceMgr<T>) : + RemoteAgent { val callAgent = CallAgent() @@ -394,7 +397,13 @@ open class KVRemoteAgent<T : Any>(val serviceManager: KVServiceManager<T>) : Rem val requestJob = launch { for (par1 in requestChannel) { val param = serialize(par1) - val str = JSON.plain.stringify(JsonRpcRequest(0, url, listOf(param))) + val str = JSON.plain.stringify( + JsonRpcRequest( + 0, + url, + listOf(param) + ) + ) if (!socket.sendOrFalse(str)) break } responseJob.cancel() @@ -464,7 +473,13 @@ open class KVRemoteAgent<T : Any>(val serviceManager: KVServiceManager<T>) : Rem val requestJob = launch { for (par1 in requestChannel) { val param = serialize(par1) - val str = JSON.plain.stringify(JsonRpcRequest(0, url, listOf(param))) + val str = JSON.plain.stringify( + JsonRpcRequest( + 0, + url, + listOf(param) + ) + ) if (!socket.sendOrFalse(str)) break } responseJob.cancel() diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt index 1fb90507..fba6356c 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt @@ -23,25 +23,17 @@ package pl.treksoft.kvision.remote import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.KSerializer -import kotlinx.serialization.internal.BooleanSerializer -import kotlinx.serialization.internal.ByteSerializer -import kotlinx.serialization.internal.CharSerializer -import kotlinx.serialization.internal.DoubleSerializer -import kotlinx.serialization.internal.FloatSerializer -import kotlinx.serialization.internal.IntSerializer -import kotlinx.serialization.internal.LongSerializer -import kotlinx.serialization.internal.ShortSerializer -import kotlinx.serialization.internal.StringSerializer -import kotlinx.serialization.list +import kotlinx.serialization.builtins.list +import kotlinx.serialization.builtins.serializer import kotlinx.serialization.serializer import pl.treksoft.kvision.types.JsonDateSerializer import pl.treksoft.kvision.types.toStringInternal import kotlin.js.Date import kotlin.reflect.KClass -internal class NotStandardTypeException(type: String) : Exception("Not a standard type: $type!") +class NotStandardTypeException(type: String) : Exception("Not a standard type: $type!") -internal class NotEnumTypeException : Exception("Not the Enum type!") +class NotEnumTypeException : Exception("Not the Enum type!") /** * Interface for client side agent for JSON-RPC remote calls. @@ -52,7 +44,7 @@ interface RemoteAgent { * @suppress * Internal function */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) @Suppress("ComplexMethod", "TooGenericExceptionCaught", "NestedBlockDepth") fun trySerialize(kClass: KClass<Any>, value: Any): String { return if (value is List<*>) { @@ -60,34 +52,34 @@ interface RemoteAgent { when { value[0] is String -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(StringSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(String.serializer().list as KSerializer<Any>, value) value[0] is Date -> @Suppress("UNCHECKED_CAST") JSON.plain.stringify(JsonDateSerializer.list as KSerializer<Any>, value) value[0] is Int -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(IntSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Int.serializer().list as KSerializer<Any>, value) value[0] is Long -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(LongSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Long.serializer().list as KSerializer<Any>, value) value[0] is Boolean -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(BooleanSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Boolean.serializer().list as KSerializer<Any>, value) value[0] is Float -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(FloatSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Float.serializer().list as KSerializer<Any>, value) value[0] is Double -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(DoubleSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Double.serializer().list as KSerializer<Any>, value) value[0] is Char -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(CharSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Char.serializer().list as KSerializer<Any>, value) value[0] is Short -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(ShortSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Short.serializer().list as KSerializer<Any>, value) value[0] is Byte -> @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(ByteSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(Byte.serializer().list as KSerializer<Any>, value) value[0] is Enum<*> -> "[" + value.joinToString(",") { "\"$it\"" } + "]" else -> try { @Suppress("UNCHECKED_CAST") @@ -99,7 +91,7 @@ interface RemoteAgent { } catch (e: Throwable) { try { @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(StringSerializer.list as KSerializer<Any>, value) + JSON.plain.stringify(String.serializer().list as KSerializer<Any>, value) } catch (e: Throwable) { value.toString() } @@ -132,14 +124,14 @@ interface RemoteAgent { @Suppress("UNCHECKED_CAST", "ComplexMethod") fun <RET> deserialize(value: String, jsType: String): RET { return when (jsType) { - "String" -> JSON.plain.parse(StringSerializer, value) as RET - "Number" -> JSON.plain.parse(DoubleSerializer, value) as RET - "Long" -> JSON.plain.parse(LongSerializer, value) as RET - "Boolean" -> JSON.plain.parse(BooleanSerializer, value) as RET - "BoxedChar" -> JSON.plain.parse(CharSerializer, value) as RET - "Short" -> JSON.plain.parse(ShortSerializer, value) as RET + "String" -> JSON.plain.parse(String.serializer(), value) as RET + "Number" -> JSON.plain.parse(Double.serializer(), value) as RET + "Long" -> JSON.plain.parse(Long.serializer(), value) as RET + "Boolean" -> JSON.plain.parse(Boolean.serializer(), value) as RET + "BoxedChar" -> JSON.plain.parse(Char.serializer(), value) as RET + "Short" -> JSON.plain.parse(Short.serializer(), value) as RET "Date" -> JSON.plain.parse(JsonDateSerializer, value) as RET - "Byte" -> JSON.plain.parse(ByteSerializer, value) as RET + "Byte" -> JSON.plain.parse(Byte.serializer(), value) as RET else -> throw NotStandardTypeException(jsType) } } @@ -151,14 +143,14 @@ interface RemoteAgent { @Suppress("UNCHECKED_CAST", "ComplexMethod") fun <RET> deserializeList(value: String, jsType: String): List<RET> { return when (jsType) { - "String" -> JSON.plain.parse(StringSerializer.list, value) as List<RET> - "Number" -> JSON.plain.parse(DoubleSerializer.list, value) as List<RET> - "Long" -> JSON.plain.parse(LongSerializer.list, value) as List<RET> - "Boolean" -> JSON.plain.parse(BooleanSerializer.list, value) as List<RET> - "BoxedChar" -> JSON.plain.parse(CharSerializer.list, value) as List<RET> - "Short" -> JSON.plain.parse(ShortSerializer.list, value) as List<RET> + "String" -> JSON.plain.parse(String.serializer().list, value) as List<RET> + "Number" -> JSON.plain.parse(Double.serializer().list, value) as List<RET> + "Long" -> JSON.plain.parse(Long.serializer().list, value) as List<RET> + "Boolean" -> JSON.plain.parse(Boolean.serializer().list, value) as List<RET> + "BoxedChar" -> JSON.plain.parse(Char.serializer().list, value) as List<RET> + "Short" -> JSON.plain.parse(Short.serializer().list, value) as List<RET> "Date" -> JSON.plain.parse(JsonDateSerializer.list, value) as List<RET> - "Byte" -> JSON.plain.parse(ByteSerializer.list, value) as List<RET> + "Byte" -> JSON.plain.parse(Byte.serializer().list, value) as List<RET> else -> throw NotStandardTypeException(jsType) } } @@ -171,7 +163,7 @@ interface RemoteAgent { fun tryDeserializeEnum(kClass: KClass<Any>, value: String): Any { return try { if (kClass.asDynamic().jClass.`$metadata$`.interfaces[0].name == "Enum") { - findEnumValue(kClass, JSON.plain.parse(StringSerializer, value)) ?: throw NotEnumTypeException() + findEnumValue(kClass, JSON.plain.parse(String.serializer(), value)) ?: throw NotEnumTypeException() } else { throw NotEnumTypeException() } @@ -188,8 +180,8 @@ interface RemoteAgent { fun tryDeserializeEnumList(kClass: KClass<Any>, value: String): List<Any> { return try { if (kClass.asDynamic().jClass.`$metadata$`.interfaces[0].name == "Enum") { - JSON.plain.parse(StringSerializer.list, value).map { - findEnumValue(kClass, JSON.plain.parse(StringSerializer, it)) ?: throw NotEnumTypeException() + JSON.plain.parse(String.serializer().list, value).map { + findEnumValue(kClass, JSON.plain.parse(String.serializer(), it)) ?: throw NotEnumTypeException() } } else { throw NotEnumTypeException() diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Security.kt index fd2b5cb0..fd2b5cb0 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Security.kt diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Socket.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Socket.kt index f668d57a..f668d57a 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Socket.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Socket.kt diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Utils.kt index 465fbf59..98fbaea8 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Utils.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/remote/Utils.kt @@ -49,7 +49,7 @@ object JSON { val plain = Json(context = serializersModuleOf(Date::class, JsonDateSerializer)) val nonstrict = Json( - configuration = JsonConfiguration.Stable.copy(strictMode = false), + configuration = JsonConfiguration.Stable.copy(ignoreUnknownKeys = true), context = serializersModuleOf(Date::class, JsonDateSerializer) ) diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/types/Date.kt index 78370a70..715eab6c 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ b/kvision-modules/kvision-common-remote/src/jsMain/kotlin/pl/treksoft/kvision/types/Date.kt @@ -25,32 +25,22 @@ import kotlinx.serialization.Decoder import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialDescriptor -import kotlinx.serialization.internal.SerialClassDescImpl import kotlin.js.Date import kotlin.math.absoluteValue -actual typealias LocalDateTime = Date - -actual typealias LocalDate = Date - -actual typealias LocalTime = Date - -actual typealias OffsetDateTime = Date - -actual typealias OffsetTime = Date /** * JSON date serializer. */ internal object JsonDateSerializer : KSerializer<Date> { - override val descriptor: SerialDescriptor = SerialClassDescImpl("kotlin.js.Date") + override val descriptor: SerialDescriptor = SerialDescriptor("kotlin.js.Date") override fun deserialize(decoder: Decoder): Date { return decoder.decodeString().toDateInternal() } - override fun serialize(encoder: Encoder, obj: Date) { - encoder.encodeString(obj.toStringInternal()) + override fun serialize(encoder: Encoder, value: Date) { + encoder.encodeString(value.toStringInternal()) } } @@ -77,7 +67,11 @@ internal fun String.toDateInternal(): Date { dt[0].toInt(), dt[1].toInt() - 1, dt[2].toInt(), - if (utcCheck) { dt[3].toInt() } else { dt[3].toInt() - sign * dt[6].toInt() }, + if (utcCheck) { + dt[3].toInt() + } else { + dt[3].toInt() - sign * dt[6].toInt() + }, dt[4].toInt(), ds[0].toInt(), if (ds.size == 2) ds[1].toInt() else 0 diff --git a/kvision-modules/kvision-common-types/build.gradle b/kvision-modules/kvision-common-types/build.gradle deleted file mode 100644 index f62cd411..00000000 --- a/kvision-modules/kvision-common-types/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'kotlin-platform-common' -apply plugin: 'kotlinx-serialization' - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion" -} diff --git a/kvision-modules/kvision-common-types/build.gradle.kts b/kvision-modules/kvision-common-types/build.gradle.kts new file mode 100644 index 00000000..fec5f5cf --- /dev/null +++ b/kvision-modules/kvision-common-types/build.gradle.kts @@ -0,0 +1,52 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val serializationVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-common-types" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/Date.kt index 3e7152a1..3e7152a1 100644 --- a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/Date.kt diff --git a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/Decimal.kt index 26d64654..26d64654 100644 --- a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/Decimal.kt diff --git a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/KFile.kt b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/KFile.kt index ce4adca4..ce4adca4 100644 --- a/kvision-modules/kvision-common-types/src/main/kotlin/pl/treksoft/kvision/types/KFile.kt +++ b/kvision-modules/kvision-common-types/src/commonMain/kotlin/pl/treksoft/kvision/types/KFile.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-common-types/src/jsMain/kotlin/pl/treksoft/kvision/types/Date.kt index 1d37ae51..82e913fe 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-common-types/src/jsMain/kotlin/pl/treksoft/kvision/types/Date.kt @@ -21,27 +21,16 @@ */ package pl.treksoft.kvision.types -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.math.BigDecimal +import kotlin.js.Date -actual typealias Decimal = BigDecimal +const val KV_DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH:mm:ss" -class BigDecimalSerializer : JsonSerializer<BigDecimal>() { - @Throws(IOException::class) - override fun serialize(value: BigDecimal, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeNumber(value.toDouble()) - } -} +actual typealias LocalDateTime = Date -class BigDecimalDeserializer : JsonDeserializer<BigDecimal>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): BigDecimal? { - return p.doubleValue.toBigDecimal() - } -} +actual typealias LocalDate = Date + +actual typealias LocalTime = Date + +actual typealias OffsetDateTime = Date + +actual typealias OffsetTime = Date diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-common-types/src/jsMain/kotlin/pl/treksoft/kvision/types/Decimal.kt index d1c0366e..d1c0366e 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-common-types/src/jsMain/kotlin/pl/treksoft/kvision/types/Decimal.kt diff --git a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-common-types/src/jvmMain/kotlin/pl/treksoft/kvision/types/Date.kt index 61f8ba58..61f8ba58 100644 --- a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ b/kvision-modules/kvision-common-types/src/jvmMain/kotlin/pl/treksoft/kvision/types/Date.kt diff --git a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-common-types/src/jvmMain/kotlin/pl/treksoft/kvision/types/Decimal.kt index 1d37ae51..1d37ae51 100644 --- a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-common-types/src/jvmMain/kotlin/pl/treksoft/kvision/types/Decimal.kt diff --git a/kvision-modules/kvision-cordova/build.gradle b/kvision-modules/kvision-cordova/build.gradle deleted file mode 100644 index 4aaef76d..00000000 --- a/kvision-modules/kvision-cordova/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} diff --git a/kvision-modules/kvision-cordova/build.gradle.kts b/kvision-modules/kvision-cordova/build.gradle.kts new file mode 100644 index 00000000..f31fb11e --- /dev/null +++ b/kvision-modules/kvision-cordova/build.gradle.kts @@ -0,0 +1,43 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +// Versions +val coroutinesVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-cordova/webpack.config.d/bootstrap.js b/kvision-modules/kvision-cordova/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-cordova/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-cordova/webpack.config.d/file.js b/kvision-modules/kvision-cordova/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-cordova/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-datacontainer/build.gradle b/kvision-modules/kvision-datacontainer/build.gradle deleted file mode 100644 index 6779c309..00000000 --- a/kvision-modules/kvision-datacontainer/build.gradle +++ /dev/null @@ -1 +0,0 @@ -apply from: "../shared.gradle" diff --git a/kvision-modules/kvision-datacontainer/build.gradle.kts b/kvision-modules/kvision-datacontainer/build.gradle.kts new file mode 100644 index 00000000..ed57bd2e --- /dev/null +++ b/kvision-modules/kvision-datacontainer/build.gradle.kts @@ -0,0 +1,39 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-datacontainer/package.json.d/project.info b/kvision-modules/kvision-datacontainer/package.json.d/project.info deleted file mode 100644 index 86ea568f..00000000 --- a/kvision-modules/kvision-datacontainer/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision DataContainer module" -} diff --git a/kvision-modules/kvision-datacontainer/webpack.config.d/bootstrap.js b/kvision-modules/kvision-datacontainer/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-datacontainer/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-datacontainer/webpack.config.d/file.js b/kvision-modules/kvision-datacontainer/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-datacontainer/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-electron/build.gradle b/kvision-modules/kvision-electron/build.gradle deleted file mode 100644 index 8716dd65..00000000 --- a/kvision-modules/kvision-electron/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -apply plugin: 'kotlin-platform-js' -apply plugin: 'kotlinx-serialization' - -task cleanLibs(type: Delete) { - delete 'build/js', 'build/libs' -} - -if (project.gradle.startParameter.taskNames.contains("jar")) { - compileKotlin2Js.dependsOn 'cleanLibs' -} - -jar { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -compileKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -compileTestKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" - compile "me.kgustave:node-kt:$nodeKtVersion" -} diff --git a/kvision-modules/kvision-electron/build.gradle.kts b/kvision-modules/kvision-electron/build.gradle.kts new file mode 100644 index 00000000..6cd8beff --- /dev/null +++ b/kvision-modules/kvision-electron/build.gradle.kts @@ -0,0 +1,43 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +// Versions +val nodeKtVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api("me.kgustave:node-kt:$nodeKtVersion") + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-electron/webpack.config.d/bootstrap.js b/kvision-modules/kvision-electron/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-electron/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-electron/webpack.config.d/css.js b/kvision-modules/kvision-electron/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-electron/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-electron/webpack.config.d/file.js b/kvision-modules/kvision-electron/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-electron/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-event-flow/build.gradle b/kvision-modules/kvision-event-flow/build.gradle deleted file mode 100644 index 4aaef76d..00000000 --- a/kvision-modules/kvision-event-flow/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} diff --git a/kvision-modules/kvision-event-flow/build.gradle.kts b/kvision-modules/kvision-event-flow/build.gradle.kts new file mode 100644 index 00000000..f31fb11e --- /dev/null +++ b/kvision-modules/kvision-event-flow/build.gradle.kts @@ -0,0 +1,43 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +// Versions +val coroutinesVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-event-flow/package.json.d/project.info b/kvision-modules/kvision-event-flow/package.json.d/project.info deleted file mode 100644 index f9d34fd1..00000000 --- a/kvision-modules/kvision-event-flow/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision event flow module" -} diff --git a/kvision-modules/kvision-event-flow/src/main/kotlin/pl/treksoft/kvision/event/EventFlow.kt b/kvision-modules/kvision-event-flow/src/main/kotlin/pl/treksoft/kvision/event/EventFlow.kt index 3a93d2a5..f9556e62 100644 --- a/kvision-modules/kvision-event-flow/src/main/kotlin/pl/treksoft/kvision/event/EventFlow.kt +++ b/kvision-modules/kvision-event-flow/src/main/kotlin/pl/treksoft/kvision/event/EventFlow.kt @@ -29,7 +29,7 @@ import org.w3c.dom.events.Event import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.core.onEvent -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) inline fun <reified T : Widget> T.eventFlow(event: String): Flow<Pair<T, Event>> = callbackFlow { val id = onEvent { this.asDynamic()[event] = { e: Event -> @@ -41,7 +41,7 @@ inline fun <reified T : Widget> T.eventFlow(event: String): Flow<Pair<T, Event>> } } -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) inline val <reified T : Widget> T.clickFlow: Flow<T> get() = callbackFlow { val id = onEvent { @@ -54,7 +54,7 @@ inline val <reified T : Widget> T.clickFlow: Flow<T> } } -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) inline val <reified T : Widget> T.inputFlow: Flow<T> get() = callbackFlow { val id = onEvent { @@ -67,7 +67,7 @@ inline val <reified T : Widget> T.inputFlow: Flow<T> } } -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) inline val <reified T : Widget> T.changeFlow: Flow<T> get() = callbackFlow { val id = onEvent { diff --git a/kvision-modules/kvision-event-flow/webpack.config.d/bootstrap.js b/kvision-modules/kvision-event-flow/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-event-flow/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-event-flow/webpack.config.d/file.js b/kvision-modules/kvision-event-flow/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-event-flow/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-fontawesome/build.gradle b/kvision-modules/kvision-fontawesome/build.gradle deleted file mode 100644 index 3df8b70e..00000000 --- a/kvision-modules/kvision-fontawesome/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("@fortawesome/fontawesome-free", "5.12.0") - } - -} diff --git a/kvision-modules/kvision-fontawesome/build.gradle.kts b/kvision-modules/kvision-fontawesome/build.gradle.kts new file mode 100644 index 00000000..31231570 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("@fortawesome/fontawesome-free", "5.12.0")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-fontawesome/package.json.d/project.info b/kvision-modules/kvision-fontawesome/package.json.d/project.info deleted file mode 100644 index 0801ee7b..00000000 --- a/kvision-modules/kvision-fontawesome/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Font Awesome module" -} diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js index 32a7c4d0..35b28e6a 100644 --- a/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js @@ -1,4 +1,3 @@ config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); -config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/file.js b/kvision-modules/kvision-fontawesome/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-handlebars/build.gradle b/kvision-modules/kvision-handlebars/build.gradle deleted file mode 100644 index 5a62036c..00000000 --- a/kvision-modules/kvision-handlebars/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("handlebars", "4.7.2") - dependency("handlebars-loader", "1.7.1") - } - -} diff --git a/kvision-modules/kvision-handlebars/build.gradle.kts b/kvision-modules/kvision-handlebars/build.gradle.kts new file mode 100644 index 00000000..a5e3dbbf --- /dev/null +++ b/kvision-modules/kvision-handlebars/build.gradle.kts @@ -0,0 +1,47 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("handlebars", "4.7.2")) + implementation(npm("handlebars-loader", "1.7.1")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-handlebars/package.json.d/project.info b/kvision-modules/kvision-handlebars/package.json.d/project.info deleted file mode 100644 index fd5bb305..00000000 --- a/kvision-modules/kvision-handlebars/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Handlebars module" -} diff --git a/kvision-modules/kvision-handlebars/webpack.config.d/bootstrap.js b/kvision-modules/kvision-handlebars/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-handlebars/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-handlebars/webpack.config.d/css.js b/kvision-modules/kvision-handlebars/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-handlebars/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-handlebars/webpack.config.d/file.js b/kvision-modules/kvision-handlebars/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-handlebars/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-i18n/build.gradle b/kvision-modules/kvision-i18n/build.gradle deleted file mode 100644 index a2b6d3f8..00000000 --- a/kvision-modules/kvision-i18n/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("jed", "1.1.1") - } - -} diff --git a/kvision-modules/kvision-i18n/build.gradle.kts b/kvision-modules/kvision-i18n/build.gradle.kts new file mode 100644 index 00000000..80a20619 --- /dev/null +++ b/kvision-modules/kvision-i18n/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("jed", "1.1.1")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-i18n/package.json.d/project.info b/kvision-modules/kvision-i18n/package.json.d/project.info deleted file mode 100644 index cefa5d1f..00000000 --- a/kvision-modules/kvision-i18n/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision i18n module" -} diff --git a/kvision-modules/kvision-i18n/webpack.config.d/bootstrap.js b/kvision-modules/kvision-i18n/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-i18n/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-i18n/webpack.config.d/file.js b/kvision-modules/kvision-i18n/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-i18n/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-maps/build.gradle b/kvision-modules/kvision-maps/build.gradle deleted file mode 100644 index f87287f3..00000000 --- a/kvision-modules/kvision-maps/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("leaflet", "1.6.0") - } - -} diff --git a/kvision-modules/kvision-maps/build.gradle.kts b/kvision-modules/kvision-maps/build.gradle.kts new file mode 100644 index 00000000..143f0515 --- /dev/null +++ b/kvision-modules/kvision-maps/build.gradle.kts @@ -0,0 +1,49 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +val coroutinesVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + implementation(npm("leaflet", "1.6.0")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-maps/package.json.d/project.info b/kvision-modules/kvision-maps/package.json.d/project.info deleted file mode 100644 index d737fd1c..00000000 --- a/kvision-modules/kvision-maps/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision maps module" -} diff --git a/kvision-modules/kvision-maps/webpack.config.d/bootstrap.js b/kvision-modules/kvision-maps/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-maps/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-maps/webpack.config.d/file.js b/kvision-modules/kvision-maps/webpack.config.d/file.js index a5c7b5da..653ca21f 100644 --- a/kvision-modules/kvision-maps/webpack.config.d/file.js +++ b/kvision-modules/kvision-maps/webpack.config.d/file.js @@ -1,6 +1,9 @@ config.module.rules.push( { - test: /\.(jpe?g|png|gif)$/i, - loader: 'file-loader' + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, } -);
\ No newline at end of file +); diff --git a/kvision-modules/kvision-moment/build.gradle b/kvision-modules/kvision-moment/build.gradle deleted file mode 100644 index 4325a38a..00000000 --- a/kvision-modules/kvision-moment/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("moment", "2.24.0") - } - -} diff --git a/kvision-modules/kvision-moment/build.gradle.kts b/kvision-modules/kvision-moment/build.gradle.kts new file mode 100644 index 00000000..31193544 --- /dev/null +++ b/kvision-modules/kvision-moment/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("moment", "2.24.0")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-moment/package.json.d/project.info b/kvision-modules/kvision-moment/package.json.d/project.info deleted file mode 100644 index c68b247f..00000000 --- a/kvision-modules/kvision-moment/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Moment module" -} diff --git a/kvision-modules/kvision-moment/webpack.config.d/bootstrap.js b/kvision-modules/kvision-moment/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-moment/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-moment/webpack.config.d/css.js b/kvision-modules/kvision-moment/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-moment/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-moment/webpack.config.d/file.js b/kvision-modules/kvision-moment/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-moment/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-pace/build.gradle b/kvision-modules/kvision-pace/build.gradle deleted file mode 100644 index 47b3c704..00000000 --- a/kvision-modules/kvision-pace/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("pace-progressbar", "1.0.9") - } - -}
\ No newline at end of file diff --git a/kvision-modules/kvision-pace/build.gradle.kts b/kvision-modules/kvision-pace/build.gradle.kts new file mode 100644 index 00000000..2bfd7dd4 --- /dev/null +++ b/kvision-modules/kvision-pace/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("pace-progressbar", "1.0.9")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-pace/package.json.d/project.info b/kvision-modules/kvision-pace/package.json.d/project.info deleted file mode 100644 index 98d48a0f..00000000 --- a/kvision-modules/kvision-pace/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Pace module" -} diff --git a/kvision-modules/kvision-pace/webpack.config.d/bootstrap.js b/kvision-modules/kvision-pace/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-pace/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-pace/webpack.config.d/file.js b/kvision-modules/kvision-pace/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-pace/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-redux-kotlin/build.gradle b/kvision-modules/kvision-redux-kotlin/build.gradle deleted file mode 100644 index 0b00ddd8..00000000 --- a/kvision-modules/kvision-redux-kotlin/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile ("org.reduxkotlin:redux-kotlin-js:$reduxKotlinVersion") - compile ("org.reduxkotlin:redux-kotlin-thunk-js:$reduxKotlinThunkVersion") -} diff --git a/kvision-modules/kvision-redux-kotlin/build.gradle.kts b/kvision-modules/kvision-redux-kotlin/build.gradle.kts new file mode 100644 index 00000000..993eaff6 --- /dev/null +++ b/kvision-modules/kvision-redux-kotlin/build.gradle.kts @@ -0,0 +1,45 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +// Versions +val reduxKotlinVersion: String by project +val reduxKotlinThunkVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api("org.reduxkotlin:redux-kotlin-js:$reduxKotlinVersion") + api("org.reduxkotlin:redux-kotlin-thunk-js:$reduxKotlinThunkVersion") + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-redux-kotlin/package.json.d/project.info b/kvision-modules/kvision-redux-kotlin/package.json.d/project.info deleted file mode 100644 index d36f4db0..00000000 --- a/kvision-modules/kvision-redux-kotlin/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Redux Kotlin module" -} diff --git a/kvision-modules/kvision-redux-kotlin/webpack.config.d/bootstrap.js b/kvision-modules/kvision-redux-kotlin/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-redux-kotlin/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-redux-kotlin/webpack.config.d/file.js b/kvision-modules/kvision-redux-kotlin/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-redux-kotlin/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-redux/build.gradle b/kvision-modules/kvision-redux/build.gradle deleted file mode 100644 index d7ed852c..00000000 --- a/kvision-modules/kvision-redux/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile ("org.jetbrains:kotlin-redux:$kotlinReduxVersion") { - exclude group: "org.jetbrains.kotlinx", module: "kotlinx-html-js" - } -} - -kotlinFrontend { - - npm { - dependency("redux", "4.0.5") - dependency("redux-thunk", "2.3.0") - } - -} diff --git a/kvision-modules/kvision-redux/build.gradle.kts b/kvision-modules/kvision-redux/build.gradle.kts new file mode 100644 index 00000000..15e65cf2 --- /dev/null +++ b/kvision-modules/kvision-redux/build.gradle.kts @@ -0,0 +1,52 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +val kotlinReduxVersion: String by project + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api("org.jetbrains:kotlin-redux:$kotlinReduxVersion") { + exclude("org.jetbrains.kotlinx", "kotlinx-html-js") + } + implementation(npm("redux", "4.0.5")) + implementation(npm("redux-thunk", "2.3.0")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-redux/package.json.d/project.info b/kvision-modules/kvision-redux/package.json.d/project.info deleted file mode 100644 index f4189f6f..00000000 --- a/kvision-modules/kvision-redux/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Redux module" -} diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt index 474206fc..2c6cb1e9 100644 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt +++ b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt @@ -80,7 +80,12 @@ class ReduxStore<S : Any, A : RAction>( }, initialState, @Suppress("SpreadOperator") - KVManagerRedux.compose(KVManagerRedux.applyMiddleware(KVManagerRedux.reduxThunk, *middlewares), rEnhancer()) + (KVManagerRedux.compose( + KVManagerRedux.applyMiddleware<S, RAction, WrapperAction, Any, Any>( + KVManagerRedux.reduxThunk, + *middlewares + ), rEnhancer() + )).asDynamic() ) } diff --git a/kvision-modules/kvision-redux/webpack.config.d/bootstrap.js b/kvision-modules/kvision-redux/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-redux/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-redux/webpack.config.d/file.js b/kvision-modules/kvision-redux/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-redux/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-remote/build.gradle b/kvision-modules/kvision-remote/build.gradle deleted file mode 100644 index e5cac713..00000000 --- a/kvision-modules/kvision-remote/build.gradle +++ /dev/null @@ -1,38 +0,0 @@ -apply plugin: 'kotlin-platform-js' -apply plugin: 'kotlinx-serialization' - -task cleanLibs(type: Delete) { - delete 'build/js', 'build/libs' -} - -if (project.gradle.startParameter.taskNames.contains("jar")) { - compileKotlin2Js.dependsOn 'cleanLibs' -} - -jar { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -compileKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -compileTestKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -dependencies { - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion" - compile "pl.treksoft:jquery-kotlin:$jqueryKotlinVersion" -} diff --git a/kvision-modules/kvision-richtext/build.gradle b/kvision-modules/kvision-richtext/build.gradle deleted file mode 100644 index 75b2c1a1..00000000 --- a/kvision-modules/kvision-richtext/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("trix", "1.2.2") - } - -} diff --git a/kvision-modules/kvision-richtext/build.gradle.kts b/kvision-modules/kvision-richtext/build.gradle.kts new file mode 100644 index 00000000..b52b398d --- /dev/null +++ b/kvision-modules/kvision-richtext/build.gradle.kts @@ -0,0 +1,67 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("trix", "1.2.2")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +fun copyResources() { + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin") + } + copy { + from("$buildDir/processedResources/Js/main") + into("${rootProject.buildDir}/js/packages/kvision-${project.name}/kotlin-dce") + } +} + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } + getByName("compileTestKotlinJs") { + doLast { + copyResources() + } + } + getByName("processDceKotlinJs") { + doLast { + copyResources() + } + } +} diff --git a/kvision-modules/kvision-richtext/package.json.d/project.info b/kvision-modules/kvision-richtext/package.json.d/project.info deleted file mode 100644 index 856dc500..00000000 --- a/kvision-modules/kvision-richtext/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision RichText module" -} diff --git a/kvision-modules/kvision-richtext/webpack.config.d/bootstrap.js b/kvision-modules/kvision-richtext/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-richtext/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-richtext/webpack.config.d/file.js b/kvision-modules/kvision-richtext/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-richtext/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-richtext/webpack.config.d/jquery.js b/kvision-modules/kvision-richtext/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/kvision-modules/kvision-richtext/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-richtext/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/kvision-modules/kvision-server-javalin/build.gradle b/kvision-modules/kvision-server-javalin/build.gradle deleted file mode 100644 index 4664b5d9..00000000 --- a/kvision-modules/kvision-server-javalin/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'kotlinx-serialization' - -dependencies { - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutinesVersion" - compile "io.javalin:javalin:$javalinVersion" - compile "com.google.inject:guice:$guiceVersion" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - testCompile project(":kvision-modules:kvision-common-types") - testCompile project(":kvision-modules:kvision-common-remote") - testCompile project(":kvision-modules:kvision-common-annotations") -} - -compileKotlin { - targetCompatibility = javaVersion - sourceCompatibility = javaVersion - kotlinOptions { - jvmTarget = javaVersion - } -} diff --git a/kvision-modules/kvision-server-javalin/build.gradle.kts b/kvision-modules/kvision-server-javalin/build.gradle.kts new file mode 100644 index 00000000..daaae81c --- /dev/null +++ b/kvision-modules/kvision-server-javalin/build.gradle.kts @@ -0,0 +1,69 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val javalinVersion: String by project +val guiceVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + api(project(":kvision-modules:kvision-common-annotations")) + api(project(":kvision-modules:kvision-common-types")) + api(project(":kvision-modules:kvision-common-remote")) + api(project(":kvision-modules:kvision-common-remote")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + } + } + val jvmMain by getting { + dependsOn(commonMain) + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutinesVersion") + api("io.javalin:javalin:$javalinVersion") + api("com.google.inject:guice:$guiceVersion") + api("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-server-javalin" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-javalin/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index 71c7d641..19da13c0 100644 --- a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-javalin/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -19,20 +19,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + package pl.treksoft.kvision.remote import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.SendChannel import kotlin.reflect.KClass -enum class HttpMethod { - GET, - POST, - PUT, - DELETE, - OPTIONS -} - /** * Multiplatform service manager. */ diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-javalin/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index aaf63153..23da6ac5 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-javalin/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -28,7 +28,7 @@ import kotlin.reflect.KClass /** * Multiplatform service manager. */ -actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>) { +actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>): KVServiceMgr<T> { protected val calls: MutableMap<String, Pair<String, HttpMethod>> = mutableMapOf() var counter: Int = 0 @@ -155,6 +155,6 @@ actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KCl /** * Returns the map of defined paths. */ - fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls + override fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls } diff --git a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt index aef6e2f2..aef6e2f2 100644 --- a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt +++ b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt diff --git a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index ffb2936b..e6428524 100644 --- a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -54,7 +54,7 @@ import kotlin.reflect.KClass * Multiplatform service manager for Javalin. */ @Suppress("LargeClass", "TooManyFunctions") -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) { companion object { diff --git a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt index e44cc46f..e44cc46f 100644 --- a/kvision-modules/kvision-server-javalin/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt +++ b/kvision-modules/kvision-server-javalin/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt diff --git a/kvision-modules/kvision-server-jooby/build.gradle b/kvision-modules/kvision-server-jooby/build.gradle deleted file mode 100644 index 4d2823e2..00000000 --- a/kvision-modules/kvision-server-jooby/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -apply plugin: "io.spring.dependency-management" -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'kotlinx-serialization' - -dependencyManagement { - imports { - mavenBom "io.jooby:jooby-bom:${joobyVersion}" - } -} - -dependencies { - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" - compile "io.jooby:jooby-netty" - compile "io.jooby:jooby-guice" - compile "io.jooby:jooby-jackson" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:${jacksonModuleKotlinVersion}" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - testCompile project(":kvision-modules:kvision-common-types") - testCompile project(":kvision-modules:kvision-common-remote") - testCompile project(":kvision-modules:kvision-common-annotations") -} - -compileKotlin { - targetCompatibility = javaVersion - sourceCompatibility = javaVersion - kotlinOptions { - jvmTarget = javaVersion - } -} diff --git a/kvision-modules/kvision-server-jooby/build.gradle.kts b/kvision-modules/kvision-server-jooby/build.gradle.kts new file mode 100644 index 00000000..329a6d19 --- /dev/null +++ b/kvision-modules/kvision-server-jooby/build.gradle.kts @@ -0,0 +1,68 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val joobyVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + api(project(":kvision-modules:kvision-common-annotations")) + api(project(":kvision-modules:kvision-common-types")) + api(project(":kvision-modules:kvision-common-remote")) + api(project(":kvision-modules:kvision-common-remote")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + } + } + val jvmMain by getting { + dependsOn(commonMain) + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("io.jooby:jooby-netty:$joobyVersion") + api("io.jooby:jooby-guice:$joobyVersion") + api("io.jooby:jooby-jackson:$joobyVersion") + api("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-server-jooby" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-server-jooby/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-jooby/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..19da13c0 --- /dev/null +++ b/kvision-modules/kvision-server-jooby/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +expect open class KVServiceManager<T : Any>(serviceClass: KClass<T>) { + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) + + /** + * Binds a given function of the receiver as a web socket connection + * @param function a function of the receiver + */ + protected inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? = null + ) +} diff --git a/kvision-modules/kvision-server-jooby/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-jooby/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..23da6ac5 --- /dev/null +++ b/kvision-modules/kvision-server-jooby/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>): KVServiceMgr<T> { + + protected val calls: MutableMap<String, Pair<String, HttpMethod>> = mutableMapOf() + var counter: Int = 0 + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod, route: String? + ) { + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, + reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected actual inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", HttpMethod.POST) + } + + /** + * Binds a given web socket connetion with a function of the receiver. + * @param function a function of the receiver + * @param route a web socket route + */ + protected actual inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kvws/$routeDef", HttpMethod.POST) + } + + /** + * Returns the map of defined paths. + */ + override fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls + +} diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt index 2245e92b..2245e92b 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt +++ b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index 4e44162f..6bc2a73a 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -54,7 +54,7 @@ import kotlin.reflect.KClass * Multiplatform service manager for Jooby. */ @Suppress("LargeClass", "TooManyFunctions") -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) { companion object { diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt index 06955a07..06955a07 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt +++ b/kvision-modules/kvision-server-jooby/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt deleted file mode 100644 index 61f8ba58..00000000 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.types - -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import java.time.OffsetDateTime -import java.time.OffsetTime -import java.time.format.DateTimeFormatter -import java.time.format.DateTimeParseException - -actual typealias LocalDateTime = LocalDateTime - -actual typealias LocalDate = LocalDate - -actual typealias LocalTime = LocalTime - -actual typealias OffsetDateTime = OffsetDateTime - -actual typealias OffsetTime = OffsetTime - -fun String.toDateTimeF(): LocalDateTime = LocalDateTime.parse(this) - -fun String.toDateF(): LocalDate = LocalDate.parse(this) - -fun String.toTimeF(): LocalTime = LocalTime.parse(this) - -fun String.toOffsetDateTimeF(): OffsetDateTime = OffsetDateTime.parse(this) - -fun String.toOffsetTimeF(): OffsetTime = OffsetTime.parse(this) - -fun LocalDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - -fun LocalDate.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE) - -fun LocalTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_TIME) - -fun OffsetDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - -fun OffsetTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_TIME) - -class LocalDateTimeSerializer : JsonSerializer<LocalDateTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDateTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDateTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalDateSerializer : JsonSerializer<LocalDate>() { - @Throws(IOException::class) - override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atStartOfDay().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateDeserializer : JsonDeserializer<LocalDate>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDate? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDate.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalTimeSerializer : JsonSerializer<LocalTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalTimeDeserializer : JsonDeserializer<LocalTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class OffsetDateTimeSerializer : JsonSerializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetDateTimeDeserializer : JsonDeserializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetDateTime? { - val str = p.text - return try { - OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} - -class OffsetTimeSerializer : JsonSerializer<OffsetTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetTimeDeserializer : JsonDeserializer<OffsetTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetTime? { - val str = p.text - return try { - OffsetTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt deleted file mode 100644 index 1d37ae51..00000000 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.types - -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.math.BigDecimal - -actual typealias Decimal = BigDecimal - -class BigDecimalSerializer : JsonSerializer<BigDecimal>() { - @Throws(IOException::class) - override fun serialize(value: BigDecimal, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeNumber(value.toDouble()) - } -} - -class BigDecimalDeserializer : JsonDeserializer<BigDecimal>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): BigDecimal? { - return p.doubleValue.toBigDecimal() - } -} diff --git a/kvision-modules/kvision-server-ktor/build.gradle b/kvision-modules/kvision-server-ktor/build.gradle deleted file mode 100644 index 20e21f6d..00000000 --- a/kvision-modules/kvision-server-ktor/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'kotlinx-serialization' - -dependencies { - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" - compile "io.ktor:ktor-server-core:$ktorVersion" - compile "io.ktor:ktor-jackson:$ktorVersion" - compile "io.ktor:ktor-websockets:$ktorVersion" - compile "com.google.inject:guice:$guiceVersion" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - testCompile project(":kvision-modules:kvision-common-types") - testCompile project(":kvision-modules:kvision-common-remote") - testCompile project(":kvision-modules:kvision-common-annotations") -} - -compileKotlin { - targetCompatibility = javaVersion - sourceCompatibility = javaVersion - kotlinOptions { - jvmTarget = javaVersion - } -} diff --git a/kvision-modules/kvision-server-ktor/build.gradle.kts b/kvision-modules/kvision-server-ktor/build.gradle.kts new file mode 100644 index 00000000..e9825289 --- /dev/null +++ b/kvision-modules/kvision-server-ktor/build.gradle.kts @@ -0,0 +1,70 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val ktorVersion: String by project +val guiceVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + api(project(":kvision-modules:kvision-common-annotations")) + api(project(":kvision-modules:kvision-common-types")) + api(project(":kvision-modules:kvision-common-remote")) + api(project(":kvision-modules:kvision-common-remote")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + } + } + val jvmMain by getting { + dependsOn(commonMain) + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("io.ktor:ktor-server-core:$ktorVersion") + api("io.ktor:ktor-jackson:$ktorVersion") + api("io.ktor:ktor-websockets:$ktorVersion") + api("com.google.inject:guice:$guiceVersion") + api("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-server-ktor" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-server-ktor/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-ktor/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..19da13c0 --- /dev/null +++ b/kvision-modules/kvision-server-ktor/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +expect open class KVServiceManager<T : Any>(serviceClass: KClass<T>) { + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) + + /** + * Binds a given function of the receiver as a web socket connection + * @param function a function of the receiver + */ + protected inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? = null + ) +} diff --git a/kvision-modules/kvision-server-ktor/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-ktor/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..23da6ac5 --- /dev/null +++ b/kvision-modules/kvision-server-ktor/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>): KVServiceMgr<T> { + + protected val calls: MutableMap<String, Pair<String, HttpMethod>> = mutableMapOf() + var counter: Int = 0 + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod, route: String? + ) { + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, + reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected actual inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", HttpMethod.POST) + } + + /** + * Binds a given web socket connetion with a function of the receiver. + * @param function a function of the receiver + * @param route a web socket route + */ + protected actual inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kvws/$routeDef", HttpMethod.POST) + } + + /** + * Returns the map of defined paths. + */ + override fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls + +} diff --git a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt b/kvision-modules/kvision-server-ktor/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt index 11959ea0..11959ea0 100644 --- a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/remote/KVModules.kt +++ b/kvision-modules/kvision-server-ktor/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVModules.kt diff --git a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-ktor/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index 276ee9a6..d516f2b3 100644 --- a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-ktor/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -64,7 +64,7 @@ import kotlin.reflect.KClass * Multiplatform service manager for Ktor. */ @KtorExperimentalAPI -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) @Suppress("LargeClass", "TooManyFunctions") actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) { diff --git a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/types/Date.kt deleted file mode 100644 index 61f8ba58..00000000 --- a/kvision-modules/kvision-server-ktor/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.types - -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import java.time.OffsetDateTime -import java.time.OffsetTime -import java.time.format.DateTimeFormatter -import java.time.format.DateTimeParseException - -actual typealias LocalDateTime = LocalDateTime - -actual typealias LocalDate = LocalDate - -actual typealias LocalTime = LocalTime - -actual typealias OffsetDateTime = OffsetDateTime - -actual typealias OffsetTime = OffsetTime - -fun String.toDateTimeF(): LocalDateTime = LocalDateTime.parse(this) - -fun String.toDateF(): LocalDate = LocalDate.parse(this) - -fun String.toTimeF(): LocalTime = LocalTime.parse(this) - -fun String.toOffsetDateTimeF(): OffsetDateTime = OffsetDateTime.parse(this) - -fun String.toOffsetTimeF(): OffsetTime = OffsetTime.parse(this) - -fun LocalDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - -fun LocalDate.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE) - -fun LocalTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_TIME) - -fun OffsetDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - -fun OffsetTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_TIME) - -class LocalDateTimeSerializer : JsonSerializer<LocalDateTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDateTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDateTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalDateSerializer : JsonSerializer<LocalDate>() { - @Throws(IOException::class) - override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atStartOfDay().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateDeserializer : JsonDeserializer<LocalDate>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDate? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDate.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalTimeSerializer : JsonSerializer<LocalTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalTimeDeserializer : JsonDeserializer<LocalTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class OffsetDateTimeSerializer : JsonSerializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetDateTimeDeserializer : JsonDeserializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetDateTime? { - val str = p.text - return try { - OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} - -class OffsetTimeSerializer : JsonSerializer<OffsetTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetTimeDeserializer : JsonDeserializer<OffsetTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetTime? { - val str = p.text - return try { - OffsetTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} diff --git a/kvision-modules/kvision-server-spring-boot/build.gradle b/kvision-modules/kvision-server-spring-boot/build.gradle deleted file mode 100644 index c46a38b1..00000000 --- a/kvision-modules/kvision-server-spring-boot/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'kotlinx-serialization' - -repositories { - mavenCentral() - jcenter() - maven { url = "https://dl.bintray.com/kotlin/kotlin-eap" } - maven { url = 'https://kotlin.bintray.com/kotlinx' } - maven { url = 'https://dl.bintray.com/rjaros/kotlin' } - maven { url = "https://repo.spring.io/milestone" } -} - -dependencies { - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - compile "org.springframework.boot:spring-boot-starter:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-webflux:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-security:$springBootVersion" - compile "org.springframework.data:spring-data-relational:$springDataRelationalVersion" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:${jacksonModuleKotlinVersion}" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - testCompile project(":kvision-modules:kvision-common-types") - testCompile project(":kvision-modules:kvision-common-remote") - testCompile project(":kvision-modules:kvision-common-annotations") -} - -compileKotlin { - kotlinOptions { - freeCompilerArgs = ["-Xjsr305=strict"] - jvmTarget = "1.8" - } -} diff --git a/kvision-modules/kvision-server-spring-boot/build.gradle.kts b/kvision-modules/kvision-server-spring-boot/build.gradle.kts new file mode 100644 index 00000000..d24073d4 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/build.gradle.kts @@ -0,0 +1,72 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val springBootVersion: String by project +val springDataRelationalVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + api(project(":kvision-modules:kvision-common-annotations")) + api(project(":kvision-modules:kvision-common-types")) + api(project(":kvision-modules:kvision-common-remote")) + api(project(":kvision-modules:kvision-common-remote")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + } + } + val jvmMain by getting { + dependsOn(commonMain) + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("stdlib-jdk7")) + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion") + api("org.springframework.boot:spring-boot-starter:$springBootVersion") + api("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion") + api("org.springframework.boot:spring-boot-starter-security:$springBootVersion") + api("org.springframework.data:spring-data-relational:$springDataRelationalVersion") + api("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-server-spring-boot" + pom { + defaultPom() + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt index 3fb82d2e..67fb1de1 100644 --- a/kvision-modules/kvision-common-remote/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt +++ b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt @@ -21,10 +21,10 @@ */ package pl.treksoft.kvision.remote -@UseExperimental(ExperimentalMultiplatform::class) +@OptIn(ExperimentalMultiplatform::class) @OptionalExpectation expect annotation class Id() -@UseExperimental(ExperimentalMultiplatform::class) +@OptIn(ExperimentalMultiplatform::class) @OptionalExpectation expect annotation class Transient() diff --git a/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..19da13c0 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +expect open class KVServiceManager<T : Any>(serviceClass: KClass<T>) { + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) + + /** + * Binds a given function of the receiver as a web socket connection + * @param function a function of the receiver + */ + protected inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? = null + ) +} diff --git a/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..23da6ac5 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision.remote + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>): KVServiceMgr<T> { + + protected val calls: MutableMap<String, Pair<String, HttpMethod>> = mutableMapOf() + var counter: Int = 0 + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod, route: String? + ) { + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given route with a function of the receiver. + * @param function a function of the receiver + * @param method a HTTP method + * @param route a route + */ + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, + reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, + method: HttpMethod, route: String? + ) { + if (method == HttpMethod.GET) + throw UnsupportedOperationException("GET method is only supported for methods without parameters") + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected actual inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", HttpMethod.POST) + } + + /** + * Binds a given web socket connetion with a function of the receiver. + * @param function a function of the receiver + * @param route a web socket route + */ + protected actual inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? + ) { + val routeDef = "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kvws/$routeDef", HttpMethod.POST) + } + + /** + * Returns the map of defined paths. + */ + override fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls + +} diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt index 7de82631..7de82631 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt index 42c4107d..42c4107d 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index 2ee939ef..4c1d8e6a 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -53,7 +53,7 @@ import kotlin.reflect.KClass /** * Multiplatform service manager for Spring Boot. */ -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) @Suppress("LargeClass", "TooManyFunctions") actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) { diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt index 2c74e611..3c0e4e99 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt @@ -63,7 +63,9 @@ class KVWebSocketHandler( }.first() } - @UseExperimental(ExperimentalCoroutinesApi::class, FlowPreview::class) + @OptIn( + ExperimentalCoroutinesApi::class, FlowPreview::class + ) override fun handle(session: WebSocketSession): Mono<Void> { val handler = getHandler(session) val responseChannel = Channel<String>() diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Security.kt index 7a9084dc..7a9084dc 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Security.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt index 63c5a9d1..63c5a9d1 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/resources/META-INF/spring.factories b/kvision-modules/kvision-server-spring-boot/src/jvmMain/resources/META-INF/spring.factories index 01084666..01084666 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/resources/META-INF/spring.factories +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/resources/META-INF/spring.factories diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt deleted file mode 100644 index 61f8ba58..00000000 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.types - -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import java.io.IOException -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import java.time.OffsetDateTime -import java.time.OffsetTime -import java.time.format.DateTimeFormatter -import java.time.format.DateTimeParseException - -actual typealias LocalDateTime = LocalDateTime - -actual typealias LocalDate = LocalDate - -actual typealias LocalTime = LocalTime - -actual typealias OffsetDateTime = OffsetDateTime - -actual typealias OffsetTime = OffsetTime - -fun String.toDateTimeF(): LocalDateTime = LocalDateTime.parse(this) - -fun String.toDateF(): LocalDate = LocalDate.parse(this) - -fun String.toTimeF(): LocalTime = LocalTime.parse(this) - -fun String.toOffsetDateTimeF(): OffsetDateTime = OffsetDateTime.parse(this) - -fun String.toOffsetTimeF(): OffsetTime = OffsetTime.parse(this) - -fun LocalDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - -fun LocalDate.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE) - -fun LocalTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_TIME) - -fun OffsetDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - -fun OffsetTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_TIME) - -class LocalDateTimeSerializer : JsonSerializer<LocalDateTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDateTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDateTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalDateSerializer : JsonSerializer<LocalDate>() { - @Throws(IOException::class) - override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atStartOfDay().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalDateDeserializer : JsonDeserializer<LocalDate>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDate? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalDate.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class LocalTimeSerializer : JsonSerializer<LocalTime>() { - @Throws(IOException::class) - override fun serialize(value: LocalTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class LocalTimeDeserializer : JsonDeserializer<LocalTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalTime? { - val str = p.text - try { - @Suppress("MagicNumber") - return LocalTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - return null - } - } -} - -class OffsetDateTimeSerializer : JsonSerializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetDateTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetDateTimeDeserializer : JsonDeserializer<OffsetDateTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetDateTime? { - val str = p.text - return try { - OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} - -class OffsetTimeSerializer : JsonSerializer<OffsetTime>() { - @Throws(IOException::class) - override fun serialize(value: OffsetTime, gen: JsonGenerator, provider: SerializerProvider) { - try { - val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - gen.writeString(s) - } catch (e: DateTimeParseException) { - System.err.println(e) - gen.writeString("") - } - } -} - -class OffsetTimeDeserializer : JsonDeserializer<OffsetTime>() { - @Throws(IOException::class) - override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetTime? { - val str = p.text - return try { - OffsetTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } catch (e: DateTimeParseException) { - System.err.println(e) - null - } - } -} diff --git a/kvision-modules/kvision-tabulator-remote/build.gradle b/kvision-modules/kvision-tabulator-remote/build.gradle deleted file mode 100644 index d498e275..00000000 --- a/kvision-modules/kvision-tabulator-remote/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile project(":kvision-modules:kvision-tabulator") - compile project(":kvision-modules:kvision-remote") -} diff --git a/kvision-modules/kvision-tabulator-remote/build.gradle.kts b/kvision-modules/kvision-tabulator-remote/build.gradle.kts new file mode 100644 index 00000000..e6beb1c5 --- /dev/null +++ b/kvision-modules/kvision-tabulator-remote/build.gradle.kts @@ -0,0 +1,42 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + api(project(":kvision-modules:kvision-tabulator")) + api(project(":kvision-modules:kvision-common-remote")) + compileOnly(project(":kvision-modules:kvision-server-javalin")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-tabulator-remote/package.json.d/project.info b/kvision-modules/kvision-tabulator-remote/package.json.d/project.info deleted file mode 100644 index c6af34cc..00000000 --- a/kvision-modules/kvision-tabulator-remote/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Tabulator remote addon module" -} diff --git a/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt b/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt index b413066e..c9e8e208 100644 --- a/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt +++ b/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt @@ -49,7 +49,7 @@ import kotlin.browser.window * @param types a set of table types * @param classes a set of CSS class names */ -@UseExperimental(ImplicitReflectionSerializer::class) +@OptIn(ImplicitReflectionSerializer::class) open class TabulatorRemote<T : Any, E : Any>( serviceManager: KVServiceManager<E>, function: suspend E.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<T>, @@ -72,12 +72,14 @@ open class TabulatorRemote<T : Any, E : Any>( options.ajaxRequestFunc = { _, _, params -> val page = params.page val size = params.size + @Suppress("UnsafeCastFromDynamic") val filters = if (params.filters != null) { kotlin.js.JSON.stringify(params.filters) } else { null } + @Suppress("UnsafeCastFromDynamic") val sorters = if (params.sorters != null) { kotlin.js.JSON.stringify(params.sorters) @@ -85,6 +87,7 @@ open class TabulatorRemote<T : Any, E : Any>( null } val state = stateFunction?.invoke() + @Suppress("UnsafeCastFromDynamic") val data = JSON.plain.stringify(JsonRpcRequest(0, url, listOf(page, size, filters, sorters, state))) callAgent.remoteCall(url, data, method = HttpMethod.valueOf(method.name)).then { r: dynamic -> diff --git a/kvision-modules/kvision-tabulator-remote/webpack.config.d/bootstrap.js b/kvision-modules/kvision-tabulator-remote/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-tabulator-remote/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-tabulator-remote/webpack.config.d/file.js b/kvision-modules/kvision-tabulator-remote/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-tabulator-remote/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-tabulator/build.gradle b/kvision-modules/kvision-tabulator/build.gradle deleted file mode 100644 index 4ac457b1..00000000 --- a/kvision-modules/kvision-tabulator/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("tabulator-tables", "4.5.3") - } - -} diff --git a/kvision-modules/kvision-tabulator/build.gradle.kts b/kvision-modules/kvision-tabulator/build.gradle.kts new file mode 100644 index 00000000..289483f3 --- /dev/null +++ b/kvision-modules/kvision-tabulator/build.gradle.kts @@ -0,0 +1,46 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("tabulator-tables", "4.5.3")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") + } +} diff --git a/kvision-modules/kvision-tabulator/package.json.d/project.info b/kvision-modules/kvision-tabulator/package.json.d/project.info deleted file mode 100644 index 19e574ef..00000000 --- a/kvision-modules/kvision-tabulator/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Tabulator module" -} diff --git a/kvision-modules/kvision-tabulator/webpack.config.d/bootstrap.js b/kvision-modules/kvision-tabulator/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-tabulator/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-tabulator/webpack.config.d/file.js b/kvision-modules/kvision-tabulator/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-tabulator/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-testutils/build.gradle b/kvision-modules/kvision-testutils/build.gradle deleted file mode 100644 index ad0ffd2e..00000000 --- a/kvision-modules/kvision-testutils/build.gradle +++ /dev/null @@ -1,61 +0,0 @@ -apply plugin: 'kotlin-platform-js' - -task cleanLibs(type: Delete) { - delete 'build/js', 'build/libs' -} - -if (project.gradle.startParameter.taskNames.contains("jar")) { - compileKotlin2Js.dependsOn 'cleanLibs' -} - -jar { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -task testJar(type: Jar, dependsOn: testClasses) { - baseName = "${project.archivesBaseName}" - classifier = "tests" - from sourceSets.test.output -} - -configurations { - tests -} - -artifacts { - tests testJar -} - -publishing { - publications { - mavenProject(MavenPublication) { - artifact testJar { - classifier 'tests' - } - } - } -} - -compileKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -compileTestKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion" - if (!project.gradle.startParameter.taskNames.contains("generatePomFileForMavenProjectPublication")) { - compile project(":kvision-modules:kvision-base") - } else { - compile rootProject - } -} diff --git a/kvision-modules/kvision-testutils/build.gradle.kts b/kvision-modules/kvision-testutils/build.gradle.kts new file mode 100644 index 00000000..efd29e1b --- /dev/null +++ b/kvision-modules/kvision-testutils/build.gradle.kts @@ -0,0 +1,48 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.test.get().kotlin) +} + +val testJar by tasks.registering(Jar::class) { + dependsOn("testClasses") + archiveClassifier.set("tests") + from(tasks["compileTestKotlinJs"].outputs) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + artifact(tasks["testJar"]) { + classifier = "tests" + } + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-modules/kvision-testutils/webpack.config.d/bootstrap.js b/kvision-modules/kvision-testutils/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-testutils/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-testutils/webpack.config.d/css.js b/kvision-modules/kvision-testutils/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-testutils/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-testutils/webpack.config.d/file.js b/kvision-modules/kvision-testutils/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-testutils/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/shared.gradle b/kvision-modules/shared.gradle deleted file mode 100644 index f6ee1509..00000000 --- a/kvision-modules/shared.gradle +++ /dev/null @@ -1,77 +0,0 @@ -apply plugin: 'kotlin-platform-js' -apply plugin: 'org.jetbrains.kotlin.frontend' -apply plugin: 'kotlinx-serialization' - -kotlinFrontend { - - npm { - devDependency("karma", "4.4.1") - devDependency("karma-chrome-launcher", "3.1.0") - devDependency("karma-webpack", "4.0.2") - devDependency("qunit", "2.9.3") - } - - webpackBundle { - bundleName = "main" - contentPath = file('src/main/web') - mode = production ? "production" : "development" - } - - define "PRODUCTION", production - - karma { - plugins = ["karma-chrome-launcher"] - browsers = ["ChromeHeadless"] - } -} - - -dependencies { - if (!project.gradle.startParameter.taskNames.contains("generatePomFileForMavenProjectPublication")) { - compile project(":kvision-modules:kvision-base") - } else { - compile rootProject - } -} - -task cleanLibs(type: Delete) { - delete 'build/js', 'build/libs' -} - -if (project.gradle.startParameter.taskNames.contains("jar")) { - compileKotlin2Js.dependsOn 'cleanLibs' -} - -jar { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -compileKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -compileTestKotlin2Js { - kotlinOptions.metaInfo = true - kotlinOptions.outputFile = "$project.buildDir.path/js-tests/${project.name}-tests.js" - kotlinOptions.sourceMap = !production - kotlinOptions.moduleKind = 'umd' -} - -task copyResources(type: Copy) { - from "src/main/resources" - into file(buildDir.path + "/js") -} - -task copyResourcesForTests(type: Copy) { - from "src/main/resources" - into file(buildDir.path + "/js-tests/") -} - -afterEvaluate { - tasks.getByName("webpack-bundle") { dependsOn(copyResources) } - tasks.getByName("webpack-run") { dependsOn(copyResources) } - tasks.getByName("karma-start") { dependsOn(copyResources, copyResourcesForTests) } -} diff --git a/kvision-tools/kvision-compiler-plugin/build.gradle b/kvision-tools/kvision-compiler-plugin/build.gradle deleted file mode 100644 index 3b00300c..00000000 --- a/kvision-tools/kvision-compiler-plugin/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: "kotlin-kapt" -apply plugin: "maven" - -dependencies { - compile "de.jensklingenberg:mpapt-runtime:$mpaptRuntimeVersion" - expectedBy project(":kvision-modules:kvision-common-annotations") - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - compileOnly "org.jetbrains.kotlin:kotlin-compiler-embeddable" - compileOnly "com.google.auto.service:auto-service:$autoServiceVersion" - kapt "com.google.auto.service:auto-service:$autoServiceVersion" -} - -kapt { - includeCompileClasspath = false -} diff --git a/kvision-tools/kvision-compiler-plugin/build.gradle.kts b/kvision-tools/kvision-compiler-plugin/build.gradle.kts new file mode 100644 index 00000000..c27127d8 --- /dev/null +++ b/kvision-tools/kvision-compiler-plugin/build.gradle.kts @@ -0,0 +1,33 @@ +plugins { + kotlin("jvm") + id("maven-publish") +} + +val mpaptRuntimeVersion: String by project + +repositories() + +dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("de.jensklingenberg:mpapt-runtime:$mpaptRuntimeVersion") + compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable") +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/annotations/Annotations.kt index d1c0366e..22cf570b 100644 --- a/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/annotations/Annotations.kt @@ -19,6 +19,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package pl.treksoft.kvision.types +package pl.treksoft.kvision.annotations -actual typealias Decimal = Double +@Target(AnnotationTarget.CLASS) +annotation class KVService diff --git a/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/plugin/CommonComponentRegistrar.kt b/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/plugin/CommonComponentRegistrar.kt index c71dbce8..07a4ddad 100644 --- a/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/plugin/CommonComponentRegistrar.kt +++ b/kvision-tools/kvision-compiler-plugin/src/main/kotlin/pl/treksoft/kvision/plugin/CommonComponentRegistrar.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.plugin -import com.google.auto.service.AutoService import de.jensklingenberg.mpapt.common.MpAptProject import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.com.intellij.mock.MockProject @@ -30,7 +29,6 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension -@AutoService(ComponentRegistrar::class) open class CommonComponentRegistrar : ComponentRegistrar { override fun registerProjectComponents( diff --git a/kvision-tools/kvision-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/kvision-tools/kvision-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar new file mode 100644 index 00000000..60c3da5e --- /dev/null +++ b/kvision-tools/kvision-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar @@ -0,0 +1 @@ +pl.treksoft.kvision.plugin.CommonComponentRegistrar diff --git a/kvision-tools/kvision-gradle-plugin/build.gradle b/kvision-tools/kvision-gradle-plugin/build.gradle deleted file mode 100644 index 7b2d0f33..00000000 --- a/kvision-tools/kvision-gradle-plugin/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: "java-gradle-plugin" -apply plugin: "kotlin-kapt" -apply plugin: "maven" - -gradlePlugin { - plugins { - simplePlugin { - id = "pl.treksoft.kvision" - implementationClass = "pl.treksoft.kvision.gradle.KVisionGradlePlugin" - } - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - compile "org.jetbrains.kotlin:kotlin-gradle-plugin-api:$kotlinVersion" - compileOnly "com.google.auto.service:auto-service:$autoServiceVersion" - kapt "com.google.auto.service:auto-service:$autoServiceVersion" -} diff --git a/kvision-tools/kvision-gradle-plugin/build.gradle.kts b/kvision-tools/kvision-gradle-plugin/build.gradle.kts new file mode 100644 index 00000000..a4cc5abb --- /dev/null +++ b/kvision-tools/kvision-gradle-plugin/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + kotlin("jvm") + id("java-gradle-plugin") + id("maven-publish") +} + +val kotlinVersion: String by System.getProperties() +val autoServiceVersion: String by project + +repositories() + +gradlePlugin { + plugins { + isAutomatedPublishing = false + create("simplePlugin") { + id = "pl.treksoft.kvision" + implementationClass = "pl.treksoft.kvision.gradle.KVisionGradlePlugin" + } + } +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:$kotlinVersion") +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() diff --git a/kvision-tools/kvision-gradle-plugin/src/main/kotlin/pl/treksoft/kvision/gradle/KVisionGradleSubplugin.kt b/kvision-tools/kvision-gradle-plugin/src/main/kotlin/pl/treksoft/kvision/gradle/KVisionGradleSubplugin.kt index 76bab0c0..59e2f202 100644 --- a/kvision-tools/kvision-gradle-plugin/src/main/kotlin/pl/treksoft/kvision/gradle/KVisionGradleSubplugin.kt +++ b/kvision-tools/kvision-gradle-plugin/src/main/kotlin/pl/treksoft/kvision/gradle/KVisionGradleSubplugin.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.gradle -import com.google.auto.service.AutoService import org.gradle.api.Project import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions @@ -30,7 +29,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact import org.jetbrains.kotlin.gradle.plugin.SubpluginOption -@AutoService(KotlinGradleSubplugin::class) class KVisionGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> { override fun apply( project: Project, diff --git a/kvision-tools/kvision-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/kvision-tools/kvision-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin new file mode 100644 index 00000000..82f481b9 --- /dev/null +++ b/kvision-tools/kvision-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin @@ -0,0 +1 @@ +pl.treksoft.kvision.gradle.KVisionGradleSubplugin diff --git a/pom.gradle b/pom.gradle deleted file mode 100644 index 3deafa50..00000000 --- a/pom.gradle +++ /dev/null @@ -1,33 +0,0 @@ -def pomConfig = { - licenses { - license { - name "MIT" - url "https://opensource.org/licenses/MIT" - distribution "repo" - } - } - developers { - developer { - id "rjaros" - name "Robert Jaros" - organization "Treksoft" - organizationUrl "http://www.treksoft.pl" - } - } - - scm { - url "https://github.com/rjaros/kvision.git" - } -} - -def withPom = { pom -> - pom.withXml { - def root = asNode() - root.appendNode('name', project.name) - root.appendNode('description', 'Object oriented web framework for Kotlin/JS') - root.appendNode('url', 'https://github.com/rjaros/kvision') - root.children().last() + pomConfig - } -} - -ext.withPom = withPom diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 4f16117f..00000000 --- a/settings.gradle +++ /dev/null @@ -1,40 +0,0 @@ -rootProject.name = 'kvision' - -include 'kvision-modules:kvision-base', - 'kvision-modules:kvision-common-annotations', - 'kvision-modules:kvision-common-remote', - 'kvision-modules:kvision-common-types', - 'kvision-modules:kvision-bootstrap', - 'kvision-modules:kvision-bootstrap-css', - 'kvision-modules:kvision-bootstrap-datetime', - 'kvision-modules:kvision-bootstrap-spinner', - 'kvision-modules:kvision-bootstrap-upload', - 'kvision-modules:kvision-bootstrap-select', - 'kvision-modules:kvision-bootstrap-select-remote', - 'kvision-modules:kvision-bootstrap-dialog', - 'kvision-modules:kvision-bootstrap-typeahead', - 'kvision-modules:kvision-bootstrap-typeahead-remote', - 'kvision-modules:kvision-richtext', - 'kvision-modules:kvision-handlebars', - 'kvision-modules:kvision-i18n', - 'kvision-modules:kvision-chart', - 'kvision-modules:kvision-datacontainer', - 'kvision-modules:kvision-fontawesome', - 'kvision-modules:kvision-redux', - 'kvision-modules:kvision-redux-kotlin', - 'kvision-modules:kvision-tabulator', - 'kvision-modules:kvision-maps', - 'kvision-modules:kvision-moment', - 'kvision-modules:kvision-pace', - 'kvision-modules:kvision-event-flow', - 'kvision-modules:kvision-remote', - 'kvision-modules:kvision-tabulator-remote', - 'kvision-modules:kvision-server-javalin', - 'kvision-modules:kvision-server-jooby', - 'kvision-modules:kvision-server-ktor', - 'kvision-modules:kvision-server-spring-boot', - 'kvision-modules:kvision-electron', - 'kvision-modules:kvision-cordova', - 'kvision-modules:kvision-testutils', - 'kvision-tools:kvision-compiler-plugin', - 'kvision-tools:kvision-gradle-plugin' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..44f424da --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,58 @@ +pluginManagement { + repositories { + mavenCentral() + jcenter() + maven { url = uri("https://plugins.gradle.org/m2/") } + maven { url = uri("https://dl.bintray.com/kotlin/kotlin-eap") } + maven { url = uri("https://kotlin.bintray.com/kotlinx") } + maven { url = uri("https://dl.bintray.com/rjaros/kotlin") } + mavenLocal() + } + resolutionStrategy { + eachPlugin { + when { + requested.id.id == "kotlinx-serialization" -> useModule("org.jetbrains.kotlin:kotlin-serialization:${requested.version}") + } + } + } +} +rootProject.name = "kvision" + +include( + "kvision-modules:kvision-common-annotations", + "kvision-modules:kvision-common-types", + "kvision-modules:kvision-common-remote", + "kvision-modules:kvision-bootstrap", + "kvision-modules:kvision-bootstrap-css", + "kvision-modules:kvision-bootstrap-datetime", + "kvision-modules:kvision-bootstrap-dialog", + "kvision-modules:kvision-bootstrap-select", + "kvision-modules:kvision-bootstrap-select-remote", + "kvision-modules:kvision-bootstrap-spinner", + "kvision-modules:kvision-bootstrap-typeahead", + "kvision-modules:kvision-bootstrap-typeahead-remote", + "kvision-modules:kvision-bootstrap-upload", + "kvision-modules:kvision-chart", + "kvision-modules:kvision-cordova", + "kvision-modules:kvision-datacontainer", + "kvision-modules:kvision-electron", + "kvision-modules:kvision-event-flow", + "kvision-modules:kvision-fontawesome", + "kvision-modules:kvision-handlebars", + "kvision-modules:kvision-i18n", + "kvision-modules:kvision-maps", + "kvision-modules:kvision-moment", + "kvision-modules:kvision-pace", + "kvision-modules:kvision-redux", + "kvision-modules:kvision-redux-kotlin", + "kvision-modules:kvision-richtext", + "kvision-modules:kvision-tabulator", + "kvision-modules:kvision-tabulator-remote", + "kvision-modules:kvision-server-javalin", + "kvision-modules:kvision-server-jooby", + "kvision-modules:kvision-server-ktor", + "kvision-modules:kvision-server-spring-boot", + "kvision-modules:kvision-testutils", + "kvision-tools:kvision-compiler-plugin", + "kvision-tools:kvision-gradle-plugin" +) diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt index 0ba694eb..1cd41e7d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt @@ -46,15 +46,15 @@ external fun require(name: String): dynamic object KVManager { init { try { - require("kvision-bootstrap-css").pl.treksoft.kvision.KVManagerBootstrapCss + require("kvision-kvision-bootstrap-css").pl.treksoft.kvision.KVManagerBootstrapCss } catch (e: Throwable) { } try { - require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap + require("kvision-kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap } catch (e: Throwable) { } try { - require("kvision-fontawesome").pl.treksoft.kvision.KVManagerFontAwesome + require("kvision-kvision-fontawesome").pl.treksoft.kvision.KVManagerFontAwesome } catch (e: Throwable) { } require("./css/style.css") diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index 918d0ad0..c03316ab 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -355,7 +355,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component * } * } */ - @Suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST", "UnsafeCastFromDynamic") open fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Int { val handlerCounter = listenerCounter++ val blockAsWidget = block as SnOn<Widget>.() -> Unit diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt index 5e49e1b4..3eb94f64 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt @@ -21,19 +21,22 @@ */ package pl.treksoft.kvision.form +import kotlinx.serialization.DynamicObjectParser import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.KSerializer -import kotlinx.serialization.Mapper +import kotlinx.serialization.builtins.list import kotlinx.serialization.modules.serializersModuleOf import kotlinx.serialization.serializer import pl.treksoft.kvision.i18n.I18n.trans import pl.treksoft.kvision.types.DateSerializer import pl.treksoft.kvision.types.KFile import pl.treksoft.kvision.types.toStringF +import pl.treksoft.kvision.utils.JSON.toObj import kotlin.js.Date import kotlin.js.Json import kotlin.reflect.KClass import kotlin.reflect.KProperty1 +import kotlin.js.JSON as NativeJSON /** * Internal data class containing form field parameters. @@ -46,27 +49,6 @@ internal data class FieldParams<in F : FormControl>( ) /** - * A wrapper for a Map with a custom containsKey method implementation. - * Used with kotlinx.serialization Mapper. - */ -private class FormMapWrapper<out V>(private val map: Map<String, V>) : Map<String, V> { - override fun equals(other: Any?): Boolean = map == other - override fun hashCode(): Int = map.hashCode() - override fun toString(): String = map.toString() - override val size: Int get() = map.size - override fun isEmpty(): Boolean = map.isEmpty() - override fun containsKey(key: String): Boolean = - if (key.indexOf('.') != -1) map.containsKey(key) else - !(map.containsKey("$key.time") || map.containsKey("$key.size")) - - override fun containsValue(value: @UnsafeVariance V): Boolean = map.containsValue(value) - override fun get(key: String): V? = map[key] - override val keys: Set<String> get() = map.keys - override val values: Collection<V> get() = map.values - override val entries: Set<Map.Entry<String, V>> get() = map.entries -} - -/** * The form definition class. Can be used directly or indirectly inside a [FormPanel]. * * @constructor Creates a form with a given modelFactory function @@ -89,36 +71,26 @@ class Form<K : Any>( init { modelFactory = { - val map = it.flatMap { entry -> - when (entry.value) { + val json = js("{}") + it.forEach { (key, value) -> + val v = when (value) { is Date -> { - listOf(entry.key to (entry.value as? Date)?.toStringF()) + value.toStringF() } is List<*> -> { @Suppress("UNCHECKED_CAST") - (entry.value as? List<KFile>)?.let { list -> - listOf(entry.key to entry.value, "${entry.key}.size" to list.size) + - list.mapIndexed { index, kFile -> - listOf( - "${entry.key}.$index.name" to kFile.name, - "${entry.key}.$index.size" to kFile.size, - "${entry.key}.$index.content" to kFile.content - ) - }.flatten() - } ?: listOf() + ((value as? List<KFile>)?.toObj(KFile.serializer().list)) } - else -> listOf(entry.key to entry.value) + else -> value } - }.toMap() + json[key] = v + } val serializersModule = if (customSerializers == null) { serializersModuleOf(Date::class, DateSerializer) } else { serializersModuleOf(customSerializers + (Date::class to DateSerializer)) } - Mapper(context = serializersModule).unmapNullable( - serializer, - FormMapWrapper(map) - ) + DynamicObjectParser(serializersModule).parse(json, serializer) } } @@ -315,7 +287,7 @@ class Form<K : Any>( } else { serializersModuleOf(customSerializers + (Date::class to DateSerializer)) } - return JSON.parse( + return NativeJSON.parse( kotlinx.serialization.json.Json(context = serializersModule).stringify( serializer, getData() @@ -361,7 +333,7 @@ class Form<K : Any>( } companion object { - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified K : Any> create( panel: FormPanel<K>? = null, customSerializers: Map<KClass<*>, KSerializer<*>>? = null, diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index ba144137..8f918a97 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -114,34 +114,42 @@ open class FormPanel<K : Any>( * HTTP method. */ var method by refreshOnUpdate(method) + /** * The URL address to send data. */ var action by refreshOnUpdate(action) + /** * The form encoding type. */ var enctype by refreshOnUpdate(enctype) + /** * The form name. */ var name: String? by refreshOnUpdate() + /** * The form target. */ var target: FormTarget? by refreshOnUpdate() + /** * Determines if the form is not validated. */ var novalidate: Boolean? by refreshOnUpdate() + /** * Determines if the form should have autocomplete. */ var autocomplete: Boolean? by refreshOnUpdate() + /** * Determines if the form is condensed. */ var condensed by refreshOnUpdate(condensed) + /** * Horizontal form layout ratio. */ @@ -155,6 +163,7 @@ open class FormPanel<K : Any>( set(value) { form.validatorMessage = value } + /** * Validation function. */ @@ -178,6 +187,7 @@ open class FormPanel<K : Any>( */ @Suppress("LeakingThis") val form = Form(this, serializer, customSerializers) + /** * @suppress * Internal property. @@ -459,7 +469,7 @@ open class FormPanel<K : Any>( companion object { - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified K : Any> create( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, type: FormType? = null, condensed: Boolean = false, diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Template.kt b/src/main/kotlin/pl/treksoft/kvision/html/Template.kt index 7b5b26a5..b9e165ef 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Template.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Template.kt @@ -66,7 +66,7 @@ fun <K> Template.setData(obj: K, serializer: SerializationStrategy<K>) { /** * Extension function to set serializable object as a template data. */ -@UseExperimental(ImplicitReflectionSerializer::class) +@OptIn(ImplicitReflectionSerializer::class) inline fun <reified K : Any> Template.setData(obj: K) { this.setData(obj, K::class.serializer()) } diff --git a/src/main/kotlin/pl/treksoft/kvision/rest/RestClient.kt b/src/main/kotlin/pl/treksoft/kvision/rest/RestClient.kt index b1ab97b6..9011c780 100644 --- a/src/main/kotlin/pl/treksoft/kvision/rest/RestClient.kt +++ b/src/main/kotlin/pl/treksoft/kvision/rest/RestClient.kt @@ -180,7 +180,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any> call( url: String, data: dynamic = null, @@ -201,7 +201,7 @@ open class RestClient { * @param beforeSend a function to set request parameters * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified V : Any> call( url: String, data: V, @@ -230,7 +230,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <T : Any, reified V : Any> call( url: String, data: V, @@ -263,7 +263,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any, V : Any> call( url: String, serializer: SerializationStrategy<V>, @@ -295,7 +295,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the result */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any, reified V : Any> call( url: String, data: V, @@ -470,7 +470,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the response */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any> request( url: String, data: dynamic = null, @@ -491,7 +491,7 @@ open class RestClient { * @param beforeSend a function to set request parameters * @return a promise of the response */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified V : Any> request( url: String, data: V, @@ -520,7 +520,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the response */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <T : Any, reified V : Any> request( url: String, data: V, @@ -553,7 +553,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the response */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any, V : Any> request( url: String, serializer: SerializationStrategy<V>, @@ -585,7 +585,7 @@ open class RestClient { * @param transform a function to transform the result of the call * @return a promise of the response */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any, reified V : Any> request( url: String, data: V, diff --git a/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/src/main/kotlin/pl/treksoft/kvision/types/Date.kt index 889d26fc..74bcc28d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/types/Date.kt +++ b/src/main/kotlin/pl/treksoft/kvision/types/Date.kt @@ -25,22 +25,9 @@ import kotlinx.serialization.Decoder import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialDescriptor -import kotlinx.serialization.internal.SerialClassDescImpl import pl.treksoft.kvision.KVManager import kotlin.js.Date -const val KV_DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH:mm:ss" - -actual typealias LocalDateTime = Date - -actual typealias LocalDate = Date - -actual typealias LocalTime = Date - -actual typealias OffsetDateTime = Date - -actual typealias OffsetTime = Date - /** * Extension function to convert String to Date with a given date format. * @param format date/time format @@ -63,7 +50,7 @@ fun Date.toStringF(format: String = KV_DEFAULT_DATE_FORMAT): String { } object DateSerializer : KSerializer<Date> { - override val descriptor: SerialDescriptor = SerialClassDescImpl("kotlin.js.Date") + override val descriptor: SerialDescriptor = SerialDescriptor("kotlin.js.Date") override fun deserialize(decoder: Decoder): Date { val str = decoder.decodeString() @@ -74,7 +61,7 @@ object DateSerializer : KSerializer<Date> { } } - override fun serialize(encoder: Encoder, obj: Date) { - encoder.encodeString(obj.toStringF()) + override fun serialize(encoder: Encoder, value: Date) { + encoder.encodeString(value.toStringF()) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt b/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt index 8dd8a504..4d951028 100644 --- a/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt +++ b/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt @@ -38,14 +38,14 @@ object JSON { val plain = Json(context = serializersModuleOf(Date::class, DateSerializer)) val nonstrict = Json( - configuration = JsonConfiguration.Stable.copy(strictMode = false), + configuration = JsonConfiguration.Stable.copy(ignoreUnknownKeys = true), context = serializersModuleOf(Date::class, DateSerializer) ) /** * An extension function to convert Serializable object to JS dynamic object */ - @UseExperimental(ImplicitReflectionSerializer::class) + @OptIn(ImplicitReflectionSerializer::class) inline fun <reified T : Any> T.toObj(): dynamic { return this.toObj(T::class.serializer()) } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/FormSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/FormSpec.kt index de875c67..5bc4cc95 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/FormSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/FormSpec.kt @@ -43,7 +43,6 @@ data class DataForm2( val d: String? = null ) - @Suppress("CanBeParameter") class FormSpec : SimpleSpec { diff --git a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt index ed3a5347..a3ac9d66 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt @@ -35,7 +35,7 @@ class ImageSpec : DomSpec { fun render() { run { val root = Root("test", fixed = true) - val res = require("./img/placeholder.png") + val res = require("img/placeholder.png") @Suppress("UnsafeCastFromDynamic") val image = Image(res, "Image", true, ImageShape.ROUNDED, true) root.add(image) diff --git a/src/test/resources/css/style.css b/src/test/resources/css/style.css new file mode 100644 index 00000000..cae50162 --- /dev/null +++ b/src/test/resources/css/style.css @@ -0,0 +1,445 @@ +.splitpanel-vertical { + display: flex; + flex-direction: row; + overflow: auto; +} + +.splitpanel-vertical > *:first-child { + max-width: calc(100% - 9px); +} + +.splitpanel-vertical > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-vertical > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitpanel-horizontal { + display: flex; + flex-direction: column; + overflow: auto; +} + +.splitpanel-horizontal > *:first-child { + max-height: calc(100% - 9px); +} + +.splitpanel-horizontal > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-horizontal > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitter-vertical { + flex: 0 0 auto; + width: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; + cursor: col-resize; +} + +.splitter-horizontal { + flex: 0 0 auto; + height: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; + cursor: row-resize; +} + +.trix-control { + overflow-y: auto; +} + +trix-toolbar .trix-button-group { + margin-bottom: 3px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { + border: 1px solid #ccc; + border-radius: 4px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.tabulator-row .tabulator-cell.tabulator-editing { + border-right: 1px solid #1d68cd !important; + padding: 2px !important; +} + +.input-group.date.is-invalid~.invalid-feedback { + display: block; +} + +.input-group.date { + padding-left: 0px; + padding-right: 0px; +} + +.bootstrap-select .dropdown-toggle.btn-default:focus { + outline: none !important; +} + +.bootstrap-select .dropdown-toggle::after { + margin-left: -1em !important; +} + +.select-parent.text-danger>.invalid-feedback { + display: block; +} +.select-parent.text-danger>div.form-control>button.form-control { + border-color: #dc3545; +} + +.form-inline .bootstrap-select .form-control { + min-width: 200px; +} + +label.required-label::after { + content: " *"; + color: #dc3545; +} + +.kv-spinner-btn-none .input-group-btn-vertical { + display: none; +} + +.kv-spinner-btn-none .form-control { + border-radius: 4px !important; +} + +.kv-spinner > span { + display: inline-block; + width: 100%; +} + +.input-group.kv-spinner { + padding-left: 0px; + padding-right: 0px; +} + +.kv-spinner.is-invalid~.invalid-feedback { + display: block; +} + +.kv-radiogroup-inline label.control-label { + vertical-align: top; + margin-right: .75rem; + margin-bottom: 0px; +} +.row.kv-radiogroup-inline label.control-label { + margin-right: 0px; +} + +.row.kv-radiogroup-inline .kv-radiogroup-container, .row.kv-radiogroup .kv-radiogroup-container { + margin-left: -15px; +} + +.kv-radiogroup-inline .kv-radiogroup-container { + display: inline-flex; +} + +.kv-radiogroup-container.is-invalid~.invalid-feedback { + display: block; +} + +.form-check { + padding-left: 0.5rem; +} + +.form-check-input.form-control-sm, .form-check-input.form-control-lg { + height: inherit; +} + +.form-check-inline { + margin-left: 3px; +} + +.form-check-inline.form-check { + padding-left: 0px; +} + +.form-horizontal.container-fluid { + width: inherit; +} + +.form-inline .form-group { + margin-right: 6px; +} + +.form-inline .form-group .control-label { + margin-right: 6px; +} + +.form-inline .form-check.form-group { + margin-left: 6px; +} + +.kv-form-condensed .form-group { + margin-bottom: 0.5rem; +} + +.kv-window.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5); + box-shadow: 0 5px 15px rgba(0,0,0,.5); + border-radius: 0px; +} + +.kv-window .modal-header { + height: 40px; + padding: 5px 15px 5px 15px; + align-items: center; +} + +.kv-window .modal-header button.close { + width: 24px; + height: 24px; + margin: 0px; + padding: 0px; +} + +.kv-window .modal-header .modal-title { + white-space: nowrap; +} + +.kv-window .modal-header .window-icon { + margin-right: 6px; +} + +.kv-window .kv-window-icons-container { + display: flex; +} + +.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { + padding: 5px 8px; +} + +.file-drop-zone.clickable:hover { + border: 1px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 1px solid #5acde2; +} + +.nav.tabs-top { + flex-wrap: nowrap; +} + +ul.tabs-top { + overflow-x: auto; + overflow-y: hidden; + display: flex; +} + +ul.tabs-top > li { + float:none; + flex-shrink: 0; +} + +.kv-tab-close { + margin-left: 10px; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: 0.2; +} + +.kv-tab-close:hover, .kv-tab-close:focus { + cursor: pointer; + filter: alpha(opacity=50); + opacity: 0.5; +} + +select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent none no-repeat; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); + background-position: right center; + cursor: pointer; +} + +.abc-checkbox input[type="checkbox"]:checked+label::after, +.abc-checkbox input[type="radio"]:checked+label::after { + font-family: "Font Awesome 5 Pro", "Font Awesome 5 Free"; + content: "\f00c"; + font-weight: 900; +} + +.abc-checkbox label::before { + top: 0px; +} +.abc-checkbox label::after { + top: 0px; +} + +.abc-radio label::before { + top: 0px; +} + +.abc-radio label::after { + top: 3px; +} + +.abc-checkbox.form-check-inline label::before { + top: 2px; +} + +.abc-checkbox.form-check-inline label::after { + top: 2px; +} + +.abc-radio.form-check-inline label::before { + top: 2px; +} + +.abc-radio.form-check-inline label::after { + top: 5px; +} + +.abc-checkbox label.col-form-label-lg::before { + top: 10px; +} +.abc-checkbox label.col-form-label-lg::after { + top: 10px; +} + +.abc-radio label.col-form-label-lg::before { + top: 10px; +} + +.abc-radio label.col-form-label-lg::after { + top: 13px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::after { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::after { + top: 18px; +} + +/*! + * bootstrap-vertical-tabs - v1.2.2 + * https://dbtek.github.io/bootstrap-vertical-tabs + * 2016-12-02 + * Copyright (c) 2016 İsmail Demirbilek + * License: MIT + */ +.nav-tabs.tabs-left, .nav-tabs.tabs-right { + border-bottom: none; + padding-top: 2px; +} +.nav-tabs.tabs-left { + border-right: 1px solid #dee2e6; +} +.nav-tabs.tabs-right { + border-left: 1px solid #dee2e6; +} +.nav-tabs.tabs-left>li.nav-item, .nav-tabs.tabs-right>li.nav-item { + float: none; + margin-bottom: 2px; +} +.nav-tabs.tabs-left>li.nav-item { + margin-right: -1px; +} +.nav-tabs.tabs-right>li.nav-item { + margin-left: -1px; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:focus { + border-bottom-color: #dee2e6; + border-right-color: transparent; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:focus { + border-bottom: 1px solid #dee2e6; + border-left-color: transparent; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link { + border-radius: 4px 0 0 4px; + margin-right: 0; + display:block; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link { + border-radius: 0 4px 4px 0; + margin-right: 0; +} + +.kv-focus { + border-radius: 0.25rem; + outline-width: 0px; + box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25); +} + +.kv-focus .kv-fileinput-caption { + border-color: #80bdff; +} + +.modal-dialog .modal-footer { + flex-wrap: wrap; +} + +.modal-dialog .modal-footer>button { + margin-top: 5px; +} + +.kv_fieldset { + border: 1px solid #dee2e6; + border-radius: 0.25rem; + padding-left: 1rem; + padding-right: 1rem; +} + +.kv_fieldset legend { + border: 1px solid #dee2e6; + border-radius: 0.25rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: bold; + padding: 3px 10px 3px 10px; + width: auto; +} + +form fieldset.kv_fieldset { + padding-top: 5px; + margin-bottom: 8px; +} + +form[class~="form-horizontal"] fieldset.kv_fieldset { + padding-left: 1.1rem; + padding-right: 2rem; + margin-right: -15px; + margin-left: -15px; +} + +form[class~="form-horizontal"] div.form-group { + align-items: center; +} + +ul.typeahead > li.active > a { + text-decoration: none; + background-color: #f8f9fa; +} diff --git a/src/test/resources/img/placeholder.png b/src/test/resources/img/placeholder.png new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/test/resources/img/placeholder.png diff --git a/webpack.config.d/bootstrap.js b/webpack.config.d/bootstrap.js index 32a7c4d0..35b28e6a 100644 --- a/webpack.config.d/bootstrap.js +++ b/webpack.config.d/bootstrap.js @@ -1,4 +1,3 @@ config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); -config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/webpack.config.d/file.js b/webpack.config.d/file.js index a5c7b5da..653ca21f 100644 --- a/webpack.config.d/file.js +++ b/webpack.config.d/file.js @@ -1,6 +1,9 @@ config.module.rules.push( { - test: /\.(jpe?g|png|gif)$/i, - loader: 'file-loader' + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, } -);
\ No newline at end of file +); diff --git a/webpack.config.d/jed.js b/webpack.config.d/jed.js index a6d18464..9a970dd0 100644 --- a/webpack.config.d/jed.js +++ b/webpack.config.d/jed.js @@ -1,3 +1,7 @@ -config.plugins.push(new webpack.ProvidePlugin({ - Jed: "jed" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + Jed: "jed" + })); +})(); diff --git a/webpack.config.d/jquery.js b/webpack.config.d/jquery.js index bf5a1a20..e6c6b219 100644 --- a/webpack.config.d/jquery.js +++ b/webpack.config.d/jquery.js @@ -1,5 +1,9 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/webpack.config.d/moment.js b/webpack.config.d/moment.js index e8db2ea0..94d91914 100644 --- a/webpack.config.d/moment.js +++ b/webpack.config.d/moment.js @@ -1,4 +1,12 @@ -config.plugins.push(new webpack.ProvidePlugin({ - moment: "moment", - "window.moment": "moment" -})); +;(function() { + const webpack = require('webpack') + try { + const moment = require("moment"); + + config.plugins.push(new webpack.ProvidePlugin({ + moment: "moment", + "window.moment": "moment" + })); + } catch (e) { + } +})(); diff --git a/webpack.config.d/webpack.js b/webpack.config.d/webpack.js new file mode 100644 index 00000000..d627c368 --- /dev/null +++ b/webpack.config.d/webpack.js @@ -0,0 +1 @@ +config.resolve.modules.push("../../processedResources/Js/main"); |