Skip to content

Commit 325aef9

Browse files
authored
Split Vulnerability and Save platforms (#2862)
* Split Vulnerability and Save platforms
1 parent b516684 commit 325aef9

304 files changed

Lines changed: 20434 additions & 215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build_and_test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
'save-backend',
5353
'save-orchestrator',
5454
'save-frontend',
55+
'save-cosv-frontend',
5556
'save-preprocessor',
5657
'test-utils',
5758
'save-api',
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Cosv-Frontend-LocalRun" type="GradleRunConfiguration" factoryName="Gradle">
3+
<ExternalSystemSettings>
4+
<option name="executionName" />
5+
<option name="externalProjectPath" value="$PROJECT_DIR$" />
6+
<option name="externalSystemIdString" value="GRADLE" />
7+
<option name="scriptParameters" value="--continuous" />
8+
<option name="taskDescriptions">
9+
<list />
10+
</option>
11+
<option name="taskNames">
12+
<list>
13+
<option value="save-cosv-frontend:run" />
14+
</list>
15+
</option>
16+
<option name="vmOptions" />
17+
</ExternalSystemSettings>
18+
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
19+
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
20+
<DebugAllEnabled>false</DebugAllEnabled>
21+
<method v="2" />
22+
</configuration>
23+
</component>

save-cosv-frontend/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# COSV Frontend
2+
3+
### Building
4+
* For IR usage see https://github.com/JetBrains/kotlin-wrappers#experimental-ir-backend
5+
6+
To run frontend locally, use `./gradlew :save-cosv-frontend:browserDevelopmentRun --continuous` or `./gradlew :save-cosv-frontend:browserProductionRun --continuous`.
7+
8+
To pack distribution, use `./gradlew :save-cosv-frontend:browserDevelopmentWebpack` and `./gradlew :save-cosv-frontend:browserProductionWebpack`.
9+
10+
save-backend consumes frontend distribution as a dependency. Frontend distribution is copied and included in spring boot resources.
11+
12+
### `nginx` [configuration](../save-frontend-common/README.md)
13+
14+
### `webpack-dev-server` [configuration for no `api-gateway` run](../save-frontend-common/README.md)
15+
16+
### [Using OAuth with a local deployment (`api-gateway` on)](../save-frontend-common/README.md)
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
2+
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
3+
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
4+
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
5+
6+
@Suppress("DSL_SCOPE_VIOLATION", "RUN_IN_SCRIPT") // https://github.com/gradle/gradle/issues/22797
7+
plugins {
8+
kotlin("js")
9+
id("com.saveourtool.save.buildutils.build-frontend-image-configuration")
10+
id("com.saveourtool.save.buildutils.code-quality-convention")
11+
id("com.saveourtool.save.buildutils.save-cloud-version-file-configuration")
12+
alias(libs.plugins.kotlin.plugin.serialization)
13+
}
14+
15+
rootProject.plugins.withType<NodeJsRootPlugin> {
16+
rootProject.the<NodeJsRootExtension>().nodeVersion = "16.13.1"
17+
}
18+
19+
dependencies {
20+
implementation(projects.saveCloudCommon)
21+
implementation(projects.saveFrontendCommon)
22+
23+
implementation(enforcedPlatform(libs.kotlin.wrappers.bom))
24+
implementation("org.jetbrains.kotlin-wrappers:kotlin-react")
25+
implementation("org.jetbrains.kotlin-wrappers:kotlin-extensions")
26+
implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom")
27+
implementation("org.jetbrains.kotlin-wrappers:kotlin-react-router-dom")
28+
implementation("org.jetbrains.kotlin-wrappers:kotlin-tanstack-react-table")
29+
implementation("org.jetbrains.kotlin-wrappers:kotlin-mui-icons")
30+
implementation("org.jetbrains.kotlin-wrappers:kotlin-mui")
31+
implementation("io.github.petertrr:kotlin-multiplatform-diff-js:0.4.0")
32+
33+
implementation(libs.save.common)
34+
implementation(libs.kotlinx.coroutines.core)
35+
implementation(libs.kotlinx.serialization.json)
36+
implementation(libs.kotlinx.datetime)
37+
implementation(libs.ktor.http)
38+
}
39+
40+
val distributionsDirName = "distributions"
41+
42+
kotlin {
43+
js(IR) {
44+
// as for `-pre.148-kotlin-1.4.21`, react-table gives errors with IR
45+
browser {
46+
distribution(
47+
Action {
48+
// TODO: need to remove this overriding
49+
outputDirectory = layout.buildDirectory.dir(distributionsDirName)
50+
}
51+
)
52+
testTask {
53+
useKarma {
54+
when (properties["save.profile"]) {
55+
"dev" -> {
56+
useChrome()
57+
// useFirefox()
58+
}
59+
null -> useChromeHeadless()
60+
}
61+
}
62+
}
63+
commonWebpackConfig {
64+
cssSupport {
65+
enabled.set(true)
66+
}
67+
}
68+
}
69+
// kotlin-wrapper migrates to commonjs and missed @JsNonModule annotations
70+
// https://github.com/JetBrains/kotlin-wrappers/issues/1935
71+
useCommonJs()
72+
binaries.executable() // already default for LEGACY, but explicitly needed for IR
73+
sourceSets.all {
74+
languageSettings.apply {
75+
optIn("kotlin.RequiresOptIn")
76+
optIn("kotlinx.serialization.ExperimentalSerializationApi")
77+
optIn("kotlin.js.ExperimentalJsExport")
78+
}
79+
}
80+
sourceSets["main"].dependencies {
81+
compileOnly(devNpm("sass", "^1.43.0"))
82+
compileOnly(devNpm("sass-loader", "^12.0.0"))
83+
compileOnly(devNpm("style-loader", "^3.3.1"))
84+
compileOnly(devNpm("css-loader", "^6.5.0"))
85+
compileOnly(devNpm("file-loader", "^6.2.0"))
86+
// https://getbootstrap.com/docs/4.0/getting-started/webpack/#importing-precompiled-sass
87+
compileOnly(devNpm("postcss-loader", "^6.2.1"))
88+
compileOnly(devNpm("postcss", "^8.2.13"))
89+
// See https://stackoverflow.com/a/72828500; newer versions are supported only for Bootstrap 5.2+
90+
compileOnly(devNpm("autoprefixer", "10.4.5"))
91+
compileOnly(devNpm("webpack-bundle-analyzer", "^4.5.0"))
92+
compileOnly(devNpm("mini-css-extract-plugin", "^2.6.0"))
93+
compileOnly(devNpm("html-webpack-plugin", "^5.5.0"))
94+
95+
// web-specific dependencies
96+
implementation(npm("@fortawesome/fontawesome-svg-core", "^1.2.36"))
97+
implementation(npm("@fortawesome/free-solid-svg-icons", "5.15.3"))
98+
implementation(npm("@fortawesome/free-brands-svg-icons", "5.15.3"))
99+
implementation(npm("@fortawesome/react-fontawesome", "^0.1.16"))
100+
implementation(npm("devicon", "^2.15.1"))
101+
implementation(npm("animate.css", "^4.1.1"))
102+
implementation(npm("react-scroll-motion", "^0.3.0"))
103+
implementation(npm("react-spinners", "0.13.0"))
104+
implementation(npm("react-tsparticles", "1.42.1"))
105+
implementation(npm("tsparticles", "2.1.3"))
106+
implementation(npm("jquery", "3.6.0"))
107+
// BS5: implementation(npm("@popperjs/core", "2.11.0"))
108+
implementation(npm("popper.js", "1.16.1"))
109+
// BS5: implementation(npm("bootstrap", "5.0.1"))
110+
implementation(npm("react-calendar", "^3.8.0"))
111+
implementation(npm("bootstrap", "^4.6.0"))
112+
implementation(npm("react", "^18.0.0"))
113+
implementation(npm("react-dom", "^18.0.0"))
114+
implementation(npm("react-modal", "^3.0.0"))
115+
implementation(npm("os-browserify", "^0.3.0"))
116+
implementation(npm("path-browserify", "^1.0.1"))
117+
implementation(npm("react-minimal-pie-chart", "^8.2.0"))
118+
implementation(npm("lodash.debounce", "^4.0.8"))
119+
implementation(npm("react-markdown", "^8.0.3"))
120+
implementation(npm("rehype-highlight", "^5.0.2"))
121+
implementation(npm("react-ace", "^10.1.0"))
122+
implementation(npm("react-avatar-image-cropper", "^1.4.2"))
123+
implementation(npm("react-circle", "^1.1.1"))
124+
implementation(npm("react-diff-viewer-continued", "^3.2.6"))
125+
implementation(npm("react-json-view", "^1.21.3"))
126+
implementation(npm("multi-range-slider-react", "^2.0.5"))
127+
// react-sigma
128+
implementation(npm("@react-sigma/core", "^3.1.0"))
129+
implementation(npm("sigma", "^2.4.0"))
130+
implementation(npm("graphology", "^0.25.1"))
131+
implementation(npm("graphology-layout", "^0.6.1"))
132+
implementation(npm("graphology-layout-forceatlas2", "^0.10.1"))
133+
implementation(npm("@react-sigma/layout-core", "^3.1.0"))
134+
implementation(npm("@react-sigma/layout-random", "^3.1.0"))
135+
implementation(npm("@react-sigma/layout-circular", "^3.1.0"))
136+
implementation(npm("@react-sigma/layout-forceatlas2", "^3.1.0"))
137+
implementation(npm("react-graph-viz-engine", "^0.1.0"))
138+
implementation(npm("cytoscape", "^3.25.0"))
139+
// translation
140+
implementation(npm("i18next", "^23.4.5"))
141+
implementation(npm("react-i18next", "^13.2.0"))
142+
implementation(npm("i18next-http-backend", "^2.2.2"))
143+
implementation(npm("js-cookie", "^3.0.5"))
144+
// transitive dependencies with explicit version ranges required for security reasons
145+
compileOnly(devNpm("minimist", "^1.2.6"))
146+
compileOnly(devNpm("async", "^2.6.4"))
147+
compileOnly(devNpm("follow-redirects", "^1.14.8"))
148+
}
149+
sourceSets["test"].dependencies {
150+
implementation(kotlin("test-js"))
151+
implementation(devNpm("jsdom", "^19.0.0"))
152+
implementation(devNpm("global-jsdom", "^8.4.0"))
153+
implementation(devNpm("@testing-library/react", "^13.2.0"))
154+
implementation(devNpm("@testing-library/user-event", "^14.0.0"))
155+
implementation(devNpm("karma-mocha-reporter", "^2.0.0"))
156+
implementation(devNpm("istanbul-instrumenter-loader", "^3.0.1"))
157+
implementation(devNpm("karma-coverage-istanbul-reporter", "^3.0.3"))
158+
implementation(devNpm("msw", "^0.40.0"))
159+
}
160+
}
161+
}
162+
163+
rootProject.plugins.withType(NodeJsRootPlugin::class.java) {
164+
rootProject.the<NodeJsRootExtension>().versions.apply {
165+
// workaround for continuous work of WebPack: (https://github.com/webpack/webpack-cli/issues/2990)
166+
webpackCli.version = "4.9.0"
167+
webpackDevServer.version = "^4.9.0"
168+
// override default version from KGP for security reasons
169+
karma.version = "^6.3.14"
170+
mocha.version = "^9.2.0"
171+
}
172+
}
173+
// store yarn.lock in the root directory
174+
rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension> {
175+
lockFileDirectory = rootProject.projectDir
176+
}
177+
178+
val mswScriptTargetPath = file("${rootProject.buildDir}/js/packages/${rootProject.name}-${project.name}-test/node_modules").absolutePath
179+
val mswScriptTargetFile = "$mswScriptTargetPath/mockServiceWorker.js"
180+
@Suppress("GENERIC_VARIABLE_WRONG_DECLARATION")
181+
val installMwsScriptTaskProvider = tasks.register<Exec>("installMswScript") {
182+
dependsOn(":kotlinNodeJsSetup", ":kotlinNpmInstall", "packageJson")
183+
inputs.dir(mswScriptTargetPath)
184+
outputs.file(mswScriptTargetFile)
185+
// cd to directory where the generated package.json is located. This is required for correct operation of npm/npx
186+
workingDir("$rootDir/build/js")
187+
188+
val isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows
189+
val nodeJsEnv = NodeJsRootPlugin.apply(project.rootProject).requireConfigured()
190+
val nodeDir = nodeJsEnv.nodeDir
191+
val nodeBinDir = nodeJsEnv.nodeBinDir
192+
listOf(
193+
System.getenv("PATH"),
194+
nodeBinDir.absolutePath,
195+
)
196+
.filterNot { it.isNullOrEmpty() }
197+
.joinToString(separator = File.pathSeparator)
198+
.let { environment("PATH", it) }
199+
200+
if (!isWindows) {
201+
doFirst {
202+
// workaround, because `npx` is a symlink but symlinks are lost when Gradle unpacks archive
203+
exec {
204+
commandLine("ln", "-sf", "$nodeDir/lib/node_modules/npm/bin/npx-cli.js", "$nodeBinDir/npx")
205+
}
206+
exec {
207+
commandLine("ln", "-sf", "$nodeDir/lib/node_modules/npm/bin/npm-cli.js", "$nodeBinDir/npm")
208+
}
209+
exec {
210+
commandLine("ln", "-sf", "$nodeDir/lib/node_modules/corepack/dist/corepack.js", "$nodeBinDir/corepack")
211+
}
212+
}
213+
}
214+
215+
commandLine(
216+
nodeBinDir.resolve(if (isWindows) "npx.cmd" else "npx").canonicalPath,
217+
"msw",
218+
"init",
219+
mswScriptTargetPath,
220+
"--no-save",
221+
)
222+
}
223+
tasks.named<KotlinJsTest>("browserTest").configure {
224+
dependsOn(installMwsScriptTaskProvider)
225+
inputs.file(mswScriptTargetFile)
226+
}
227+
228+
tasks.withType<org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack> {
229+
// Since we inject timestamp into HTML file, we would like this task to always be re-run.
230+
inputs.property("Build timestamp", System.currentTimeMillis())
231+
doFirst {
232+
val additionalWebpackResources = fileTree("$buildDir/processedResources/js/main/") {
233+
include("scss/**")
234+
include("index.html")
235+
}
236+
copy {
237+
from(additionalWebpackResources)
238+
into("${rootProject.buildDir}/js/packages/${rootProject.name}-${project.name}")
239+
}
240+
}
241+
}
242+
243+
val distribution: Configuration by configurations.creating
244+
val distributionJarTask by tasks.registering(Jar::class) {
245+
dependsOn(":save-cosv-frontend:browserDistribution")
246+
archiveClassifier.set("distribution")
247+
from("$buildDir/$distributionsDirName") {
248+
into("static")
249+
exclude("scss")
250+
}
251+
from("$projectDir/nginx.conf") {
252+
into("")
253+
}
254+
}
255+
artifacts.add(distribution.name, distributionJarTask.get().archiveFile) {
256+
builtBy(distributionJarTask)
257+
}
258+
259+
detekt {
260+
config.setFrom(config.plus(file("detekt.yml")))
261+
}

save-cosv-frontend/detekt.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
style:
2+
MagicNumber:
3+
# There are a lot of magic number in UI code, so it's easier to just suppress the rule
4+
active: false
5+
naming:
6+
MatchingDeclarationName:
7+
# Because common pattern is RProps class and functional component in a single file, which triggers this rule
8+
active: false

0 commit comments

Comments
 (0)