Skip to content

Commit

Permalink
Merge pull request #266 from modelix/feature/js-model-client
Browse files Browse the repository at this point in the history
Feature/js model client
  • Loading branch information
odzhychko authored Oct 27, 2023
2 parents 1c2622e + e14d15f commit 8e1e388
Show file tree
Hide file tree
Showing 6 changed files with 548 additions and 0 deletions.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ modelix-mps-buildtools = { id = "org.modelix.mps.build-tools", version = "1.1.0"
dokka = {id = "org.jetbrains.dokka", version = "1.9.10"}
node = {id = "com.github.node-gradle.node", version = "7.0.1"}
detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.1" }
npm-publish = { id = "dev.petuska.npm.publish", version = "3.4.1" }

[versions]
kotlin = "1.9.10"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023.
*
* 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
*
* http://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.
*/

package org.modelix.kotlin.utils

/**
* Marks an API as unstable.
*
* @param reason Describes why the feature is experimental.
* @param intendedFinalization Describes when this API is intended to be finalized or removed.
*/
@RequiresOptIn(message = "This API is experimental. It may be changed in the future without notice.")
@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY,
AnnotationTarget.ANNOTATION_CLASS,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.TYPEALIAS,
)
annotation class UnstableModelixFeature(
val reason: String,
val intendedFinalization: String,
)
83 changes: 83 additions & 0 deletions model-client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id("com.diffplug.spotless")
`java-library`
jacoco
alias(libs.plugins.npm.publish)
}

java {
Expand Down Expand Up @@ -34,6 +35,8 @@ kotlin {
}
}
}
binaries.library()
generateTypeScriptDefinitions()
useCommonJs()
}
@Suppress("UNUSED_VARIABLE", "KotlinRedundantDiagnosticSuppress")
Expand Down Expand Up @@ -86,6 +89,7 @@ kotlin {
}
}
val jsMain by getting {
languageSettings.optIn("kotlin.js.ExperimentalJsExport")
dependencies {
implementation(kotlin("stdlib-js"))
implementation(npm("uuid", "^8.3.0"))
Expand Down Expand Up @@ -128,3 +132,82 @@ spotless {
)
}
}

val productionLibraryByKotlinOutputDirectory = layout.buildDirectory.dir("compileSync/js/main/productionLibrary/kotlin")
val preparedProductionLibraryOutputDirectory = layout.buildDirectory.dir("npmPublication")

val patchTypesScriptInProductionLibrary = tasks.register("patchTypesScriptInProductionLibrary") {
dependsOn("compileProductionLibraryKotlinJs")
inputs.dir(productionLibraryByKotlinOutputDirectory)
outputs.dir(preparedProductionLibraryOutputDirectory)
outputs.cacheIf { true }
doLast {
// Delete old data
delete {
delete(preparedProductionLibraryOutputDirectory)
}

// Copy over library create by Kotlin
copy {
from(productionLibraryByKotlinOutputDirectory)
into(preparedProductionLibraryOutputDirectory)
}

// Add correct TypeScript imports and mark exports as experimental.
val typescriptDeclaration =
preparedProductionLibraryOutputDirectory.get().file("modelix.core-model-client.d.ts").asFile
val originalTypescriptDeclarationContent = typescriptDeclaration.readLines()
val experimentalDeclaration = """
/**
* @experimental This feature is expected to be finalized with https://issues.modelix.org/issue/MODELIX-500.
*/
""".trimIndent()
typescriptDeclaration.writer().use {
it.appendLine("""import { INodeJS } from "@modelix/ts-model-api";""")
.appendLine()
for (line in originalTypescriptDeclarationContent) {
// Only mark the parts of the client (`org.modelix.model.client2`) experimental.
// Reported declarations from `org.modelix.model.api` should not be annotated as experimental.
if (line.startsWith("export declare namespace org.modelix.model.client2")) {
it.appendLine(experimentalDeclaration)
}
it.appendLine(line)
}
}
}
}

npmPublish {
registries {
register("itemis-npm-open") {
uri.set("https://artifacts.itemis.cloud/repository/npm-open")
System.getenv("NODE_AUTH_TOKEN").takeIf { !it.isNullOrBlank() }?.let {
authToken.set(it)
}
}
}
packages {
named("js") {
files {
// The files need to be set manually because we patch
// the JS/TS produces by `compileProductionLibraryKotlinJs`
// with the `patchTypesScriptInProductionLibrary` task
setFrom(patchTypesScriptInProductionLibrary)
}
packageJson {
name.set("@modelix/model-client")
homepage.set("https://modelix.org/")
repository {
type.set("git")
url.set("https://github.com/modelix/modelix.core.git")
directory.set(project.name)
}
}
dependencies {
// The model client NPM package uses the types from this @modelix/ts-model-api
normal("@modelix/ts-model-api", rootProject.version.toString())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2023.
*
* 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
*
* http://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.
*/

package org.modelix.model.client2

import INodeJS
import org.modelix.kotlin.utils.UnstableModelixFeature

@UnstableModelixFeature(
reason = "The overarching task https://issues.modelix.org/issue/MODELIX-500 is in development.",
intendedFinalization = "The client is intended to be finalized when the overarching task is finished.",
)
@JsExport
sealed interface ChangeJS {
val node: INodeJS
}

@UnstableModelixFeature(
reason = "The overarching task https://issues.modelix.org/issue/MODELIX-500 is in development.",
intendedFinalization = "The client is intended to be finalized when the overarching task is finished.",
)
@JsExport
data class PropertyChanged(override val node: INodeJS, val role: String) : ChangeJS

@UnstableModelixFeature(
reason = "The overarching task https://issues.modelix.org/issue/MODELIX-500 is in development.",
intendedFinalization = "The client is intended to be finalized when the overarching task is finished.",
)
@JsExport
data class ChildrenChanged(override val node: INodeJS, val role: String?) : ChangeJS

@UnstableModelixFeature(
reason = "The overarching task https://issues.modelix.org/issue/MODELIX-500 is in development.",
intendedFinalization = "The client is intended to be finalized when the overarching task is finished.",
)
@JsExport
data class ReferenceChanged(override val node: INodeJS, val role: String) : ChangeJS

@UnstableModelixFeature(
reason = "The overarching task https://issues.modelix.org/issue/MODELIX-500 is in development.",
intendedFinalization = "The client is intended to be finalized when the overarching task is finished.",
)
@JsExport
data class ContainmentChanged(override val node: INodeJS) : ChangeJS
Loading

0 comments on commit 8e1e388

Please sign in to comment.