diff --git a/.gitignore b/.gitignore index c6576a06..5baed893 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ captures !*.xcworkspace/contents.xcworkspacedata **/xcshareddata/WorkspaceSettings.xcsettings /.env +/kotlin-js-store/ diff --git a/.junie/guidelines/web-app-guideline.md b/.junie/guidelines/web-app-guideline.md index d74b07ba..a0e65216 100644 --- a/.junie/guidelines/web-app-guideline.md +++ b/.junie/guidelines/web-app-guideline.md @@ -1,10 +1,10 @@ -# Web-App-Richtlinie (Compose for Web) +# Client-App-Richtlinie (Compose Multiplatform) ## 1. Einleitung -Diese Richtlinie beschreibt die Architektur und die Best Practices für die Entwicklung des Web-Frontends für das "Meldestelle"-Projekt. Das Frontend wird mit **Compose for Web** (Teil von Compose Multiplatform) entwickelt. +Diese Richtlinie beschreibt die Architektur und die Best Practices für die Entwicklung der Client-Anwendungen für das "Meldestelle"-Projekt. Die Client-Anwendungen werden mit **Compose Multiplatform** für Desktop und Web entwickelt. -Das Hauptziel ist die maximale Wiederverwendung von Code zwischen verschiedenen Plattformen (potenziell Web, Android, Desktop) durch die konsequente Nutzung des `commonMain`-Source-Sets von Kotlin Multiplatform (KMP). +Das Hauptziel ist die maximale Wiederverwendung von Code zwischen den Desktop- und Web-Plattformen durch die konsequente Nutzung des `commonMain`-Source-Sets von Kotlin Multiplatform (KMP). Die Anwendung läuft sowohl als native Desktop-Anwendung (JVM) als auch als Web-Anwendung (WebAssembly). ## 2. Grundprinzipien @@ -26,49 +26,95 @@ Der UI-Zustand (State) wird explizit verwaltet. ### Styling -Das Styling erfolgt über eine Kotlin-DSL, die CSS abbildet. +Das Styling erfolgt plattformspezifisch, aber mit gemeinsamen Prinzipien: -- **`StyleSheet`**: Definieren Sie Stile in einem `object`, das von `StyleSheet` erbt. Dies fördert die Wiederverwendbarkeit und Typsicherheit. -- **Scoped Styles**: Organisieren Sie Stile logisch, z. B. pro Komponente oder pro Bildschirm. -- **Kein globales CSS**: Vermeiden Sie die Verwendung globaler, ungebundener CSS-Dateien. Das Styling sollte ausschließlich über die Kotlin-DSL verwaltet werden, um Konflikte zu vermeiden und die Kapselung zu wahren. +#### Gemeinsame Styling-Prinzipien (commonMain) +- **Compose Material Design**: Nutzen Sie Material3-Komponenten und Theming für konsistente UI. +- **Gemeinsame Designsystem**: Definieren Sie gemeinsame Farben, Typografie und Spacing in `commonMain`. +- **Responsive Design**: Berücksichtigen Sie verschiedene Bildschirmgrößen (Desktop-Fenster vs. Browser-Viewports). + +#### Web-spezifisches Styling (wasmJsMain) +- **CSS-Integration**: Web-spezifische Styling-Anforderungen können über CSS in den Resources behandelt werden. +- **Browser-Kompatibilität**: Berücksichtigen Sie Web-spezifische Rendering-Unterschiede. + +#### Desktop-spezifisches Styling (jvmMain) +- **Native Look & Feel**: Desktop-Anwendungen sollten sich nativ anfühlen. +- **Fenster-Management**: Berücksichtigen Sie Desktop-spezifische UI-Patterns (Menüleisten, etc.). ```kotlin -// Beispiel für ein StyleSheet -object AppStylesheet : StyleSheet() { - val container by style { - padding(24.px) - border(1.px, LineStyle.Solid, Color.black) - } +// Beispiel für gemeinsames Theming in commonMain +@Composable +fun AppTheme(content: @Composable () -> Unit) { + MaterialTheme( + colorScheme = if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme(), + typography = AppTypography, + content = content + ) } ``` ### Navigation -Die Navigation zwischen verschiedenen Bildschirmen ("Screens") wird durch Zustandsänderungen gesteuert. Da es noch keine offizielle "Compose Navigation"-Bibliothek für das Web gibt, verwenden wir einen einfachen, zustandsbasierten Ansatz. -- Ein `StateFlow` oder eine `mutableState`-Variable im ViewModel kann die aktuell anzuzeigende Route/Screen repräsentieren. -- Ein zentraler -Composable kann auf Änderungen dieses Zustands reagieren und den entsprechenden Screen rendern. `Router` +Die Navigation wird plattformunabhängig in `commonMain` implementiert: +- **ViewModel-basierte Navigation**: Ein `StateFlow` oder `mutableState` im ViewModel repräsentiert die aktuelle Route/Screen. +- **Gemeinsamer Router**: Ein zentraler `Router`-Composable in `commonMain` reagiert auf Zustandsänderungen und rendert den entsprechenden Screen. +- **Plattformspezifische Einstiegspunkte**: Desktop und Web haben separate `main.kt`-Dateien, aber nutzen denselben gemeinsamen App-Composable. ## 3. Projekt- und Code-Struktur -Die Codebasis ist klar zwischen plattformunabhängiger Logik (`commonMain`) und plattformspezifischer UI (`jsMain`) getrennt. -- **`core/commonMain`** (oder ein äquivalentes `shared`-Modul): - - **Business-Logik**: Die gesamte Geschäftslogik. - - **ViewModels/Presenters**: Klassen, die den UI-Zustand verwalten und auf Benutzerinteraktionen reagieren. +Die Codebasis ist klar zwischen plattformunabhängiger Logik (`commonMain`) und plattformspezifischer Implementation (`jvmMain`, `wasmJsMain`) getrennt. + +### Source Sets + +- **`client/src/commonMain`**: + - **UI-Code**: Alle `@Composable`-Funktionen, die zwischen Desktop und Web geteilt werden. + - **Business-Logik**: ViewModels/Presenters, die den UI-Zustand verwalten. - **Data-Klassen**: Modelle, die Daten repräsentieren. - - **Repositories/Services**: Code für den Datenzugriff (z.B. Ktor-HTTP-Clients zum Aufrufen des Backends). + - **Common Dependencies**: Shared Compose-Dependencies (runtime, foundation, material3, ui). -- **`client/jsMain`**: - - **UI-Code**: Ausschließlich `@Composable`-Funktionen. - - **`main.kt`**: Der Einstiegspunkt der Web-Anwendung. - - **`StyleSheet.kt`**: Die Kotlin-CSS-DSL-Definitionen. - - **Abhängigkeit von `commonMain`**: Die UI konsumiert die ViewModels und Datenklassen aus `commonMain`. Die UI ist "dumm" und dient nur zur Darstellung des Zustands. +- **`client/src/jvmMain`** (Desktop-Plattform): + - **`main.kt`**: Der Einstiegspunkt der Desktop-Anwendung. + - **Desktop-spezifische Code**: Plattformspezifische Implementierungen und Integrationen. + - **Desktop Dependencies**: `compose.desktop.currentOs`, Coroutines für Swing. -- **`client/src/jsMain/resources`**: +- **`client/src/wasmJsMain`** (Web-Plattform): + - **`main.kt`**: Der Einstiegspunkt der Web-Anwendung (WebAssembly). + - **Web-spezifische Code**: Browser-spezifische Implementierungen. + - **Platform-spezifische Implementierungen**: Web-APIs und Browser-Integrationen. + +- **`client/src/wasmJsMain/resources`**: - **`index.html`**: Das Host-HTML-Dokument für die Compose-Anwendung. - - **Statische Assets**: Bilder, Schriftarten und andere statische Dateien. + - **Statische Assets**: Bilder, Schriftarten und andere statische Dateien für die Web-Version. + +### Shared Module Integration +- **`core/commonMain`** (oder äquivalente `shared`-Module): + - **Repositories/Services**: Code für den Datenzugriff (z.B. Ktor-HTTP-Clients zum Aufrufen des Backends). + - **Business-Logik**: Plattformunabhängige Geschäftslogik, die von allen Client-Plattformen genutzt wird. ## 4. Entwicklung und Ausführung -### Lokale Entwicklung mit Hot-Reload -Für eine schnelle Entwicklungs-Loop mit automatischer Neuladung bei Änderungen wird der Gradle-Task `jsBrowserDevelopmentRun` verwendet. Dies wird durch unser Docker-Setup vereinfacht. -Um die Web-App im Entwicklungsmodus zu starten (wie in beschrieben): `README-DOCKER.md` + +### Desktop-Entwicklung +Für die Desktop-Anwendung stehen folgende Gradle-Tasks zur Verfügung: + +```shell script +# Desktop-Anwendung direkt ausführen +./gradlew :client:run + +# Desktop-Distribution erstellen (DMG, MSI, DEB) +./gradlew :client:createDistributable +./gradlew :client:packageDmg # macOS +./gradlew :client:packageMsi # Windows +./gradlew :client:packageDeb # Linux +``` + +### Web-Entwicklung mit Hot-Reload +Für die Web-Anwendung mit automatischer Neuladung bei Änderungen: + +```shell script +# Web-App mit Hot-Reload starten +./gradlew :client:wasmJsBrowserDevelopmentRun +``` + +#### Docker-Setup für Web-Entwicklung +Das Docker-Setup ist spezifisch für die Web-Entwicklung konfiguriert (wie in `README-DOCKER.md` beschrieben): ```shell script # Startet die Web-App mit Hot-Reload @@ -77,17 +123,55 @@ docker-compose -f docker-compose.yml \ ``` Der Dienst ist dann unter dem in der `docker-compose.clients.yml` konfigurierten Port (z.B. Port `3000`) erreichbar. -### Produktions-Build -Um eine optimierte JavaScript-Datei für die Produktion zu erstellen, wird der Gradle-Task `jsBrowserDistribution` verwendet. Das Docker-Image für die Produktion ( im `client`-Verzeichnis) sollte diesen Task nutzen, um die finalen Artefakte zu bauen. `Dockerfile` -## 5. Dos and Don'ts -- **DO**: Die gesamte Logik (State-Management, Datenabruf, Validierung) in `commonMain` implementieren. -- **DO**: Kleine, wiederverwendbare und zustandslose Composables erstellen. -- **DO**: Styling ausschließlich über die Kotlin-CSS-DSL (`StyleSheet`) realisieren. -- **DO**: Events von der UI über Lambda-Funktionen an die ViewModels in `commonMain` weiterleiten. -- **DON'T**: Geschäftslogik, API-Aufrufe oder komplexe Zustandsmanipulationen direkt in `@Composable`-Funktionen schreiben. -- **DON'T**: Den DOM direkt manipulieren. Compose for Web verwaltet den DOM. Falls eine Interaktion mit externen JS-Bibliotheken unumgänglich ist, nutzen Sie die `external`- und `@JsModule`-Mechanismen von Kotlin/JS sauber gekapselt. -- **DON'T**: Globale CSS-Dateien verwenden, die mit der von Compose generierten Stil-Logik in Konflikt geraten könnten. ---- -_Letzte Aktualisierung: 2025-09-10_ -Diese Richtlinie bietet eine solide Grundlage für die Entwicklung Ihrer Webanwendung mit Compose for Web und stellt sicher, dass neue Teammitglieder die Architektur und die erwarteten Konventionen schnell verstehen. + +### Produktions-Builds + +#### Desktop-Distribution +```shell script +# Erstellt native Distributionen für alle konfigurierten Plattformen +./gradlew :client:packageDistributionForCurrentOS +``` + +#### Web-Distribution +```shell script +# Erstellt optimierte WebAssembly-Artefakte für die Produktion +./gradlew :client:wasmJsBrowserDistribution +``` + +Das Docker-Image für die Web-Produktion (`Dockerfile` im `client`-Verzeichnis) sollte den `wasmJsBrowserDistribution`-Task nutzen, um die finalen Artefakte zu bauen. +## 5. Plattformspezifische Besonderheiten + +### Desktop (jvmMain) +- **Fenster-Management**: Nutzen Sie Compose Desktop-APIs für Fensteroperationen. +- **System-Integration**: Zugriff auf Desktop-spezifische Features (Dateisystem, Notifications, etc.). +- **Performance**: Desktop-Apps können mehr Ressourcen nutzen als Web-Apps. + +### Web (wasmJsMain) +- **Browser-APIs**: Zugriff auf Web-APIs erfolgt über `external`-Deklarationen. +- **Bundle-Size**: Achten Sie auf die Größe der WebAssembly-Bundles für optimale Ladezeiten. +- **SEO und Accessibility**: Berücksichtigen Sie Web-spezifische Anforderungen. + +## 6. Dos and Don'ts + +### Multiplatform Best Practices +- **DO**: Die gesamte UI-Logik (State-Management, Datenabruf, Validierung) in `commonMain` implementieren. +- **DO**: Kleine, wiederverwendbare und zustandslose Composables in `commonMain` erstellen. +- **DO**: Material3 und gemeinsames Theming für konsistente UI zwischen Plattformen verwenden. +- **DO**: Events von der UI über Lambda-Funktionen an die ViewModels in `commonMain` weiterleiten. +- **DO**: Plattformspezifische Features über `expect`/`actual`-Mechanismus abstrahieren. + +### Platform-Specific Guidelines +- **DO** (Desktop): Native Look & Feel und Desktop-UI-Patterns verwenden. +- **DO** (Web): Web-Standards und Accessibility-Guidelines befolgen. + +### Don'ts +- **DON'T**: Geschäftslogik, API-Aufrufe oder komplexe Zustandsmanipulationen direkt in `@Composable`-Funktionen schreiben. +- **DON'T**: Plattformspezifische Code direkt in `commonMain` verwenden ohne `expect`/`actual`. +- **DON'T** (Web): Den DOM direkt manipulieren. Compose Multiplatform verwaltet das Rendering. Falls Interaktion mit externen Bibliotheken nötig ist, nutzen Sie `external`-Mechanismen sauber gekapselt. +- **DON'T**: Annahmen über die Zielplattform in `commonMain` machen. + +--- +_Letzte Aktualisierung: 2025-01-10_ + +Diese Richtlinie bietet eine solide Grundlage für die Entwicklung Ihrer Desktop- und Web-Anwendungen mit Compose Multiplatform und stellt sicher, dass neue Teammitglieder die Multiplatform-Architektur und die erwarteten Konventionen schnell verstehen. diff --git a/FOLDER_STRUCTURE_ANALYSIS.md b/FOLDER_STRUCTURE_ANALYSIS.md new file mode 100644 index 00000000..e689c38b --- /dev/null +++ b/FOLDER_STRUCTURE_ANALYSIS.md @@ -0,0 +1,81 @@ +# Folder Structure Analysis - Meldestelle Project +**Datum:** 10. September 2025 +**Frage:** "müssen das 2 Ordner sein? analysieren, korrigieren und optimieren" + +## Analyse der aktuellen Ordnerstruktur + +### ✅ Korrekt getrennte Ordner (KEINE Duplikate) + +#### 1. `docker/` vs `dockerfiles/` +- **docker/**: Runtime-Volumes und Daten (monitoring, services) +- **dockerfiles/**: Dockerfile-Definitionen (clients, infrastructure, services, templates) +- **Bewertung**: ✅ **Korrekte Trennung** - unterschiedliche Zwecke + +#### 2. `kotlin-js-store/` vs `client/` +- **kotlin-js-store/**: Build-Artifacts und Yarn-Dependencies für JS/WASM +- **client/**: Quellcode des Compose Multiplatform Clients +- **Bewertung**: ✅ **Funktional notwendig** - Build-Cache vs Source + +### ✅ Bereits optimierte Struktur + +#### Business Module Ordner (Korrekt deaktiviert) +``` +├── members/ # Temporär deaktiviert +├── horses/ # Temporär deaktiviert +├── events/ # Temporär deaktiviert +└── masterdata/ # Temporär deaktiviert +``` +- **Status**: Physisch vorhanden, aber in `settings.gradle.kts` auskommentiert +- **Grund**: Benötigen Multiplatform-Konfiguration für KMP/WASM +- **Empfehlung**: ✅ **Korrekt so belassen** bis Migration abgeschlossen + +## Antwort auf die Hauptfrage + +### "Müssen das 2 Ordner sein?" + +**ANTWORT: JA** - Die identifizierten "doppelten" Ordner sind **KEINE Duplikate**, sondern haben unterschiedliche, wichtige Funktionen: + +1. **docker/ + dockerfiles/**: Verschiedene Docker-Aspekte (Runtime vs Definitions) +2. **kotlin-js-store/ + client/**: Build-Artifacts vs Source Code +3. **Business Module Ordner**: Temporär deaktiviert, aber für zukünftige Migration notwendig + +## Optimierungsempfehlungen + +### 🟢 Keine strukturellen Änderungen erforderlich +- Aktuelle Struktur ist **optimal organisiert** +- Alle "doppelten" Ordner haben **legitime, getrennte Zwecke** +- Folgt **Best Practices** für Gradle Multimodule + Docker + +### 🔄 Mögliche kleine Verbesserungen + +#### 1. kotlin-js-store/ Optimierung +```bash +# Kann in .gitignore aufgenommen werden (falls nicht schon geschehen) +echo "kotlin-js-store/" >> .gitignore +``` +- **Begründung**: Build-Artifacts sollten nicht versioniert werden +- **Status**: Prüfung erforderlich + +#### 2. Dokumentation verbessern +- README-Dateien in docker/ und dockerfiles/ zur Erklärung der Unterschiede +- Kommentare in settings.gradle.kts erweitern + +## Fazit + +### ✅ **STRUKTUR IST OPTIMAL** +- **Keine Duplikate** vorhanden +- **Alle Ordner haben klare Zwecke** +- **Folgt modernen Best Practices** +- **Bereits gut optimiert** + +### 🎯 **Empfehlung: Keine Änderungen** +Die aktuelle 2-Ordner-Struktur ist **notwendig und korrekt**. Jeder Ordner erfüllt einen spezifischen Zweck in der modernen Kotlin Multiplatform + Docker Architektur. + +### 📋 **Nächste Schritte** +1. kotlin-js-store/ in .gitignore prüfen +2. Bei Business Module Migration: Ordner reaktivieren +3. Dokumentation für Docker-Ordner-Unterschiede ergänzen + +--- +**Status:** ✅ Analyse abgeschlossen - Struktur ist optimal +**Ergebnis:** Aktuelle Ordnerstruktur beibehalten diff --git a/client/build.gradle.kts b/client/build.gradle.kts new file mode 100644 index 00000000..8288d45b --- /dev/null +++ b/client/build.gradle.kts @@ -0,0 +1,53 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl + +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.compose.multiplatform) + alias(libs.plugins.compose.compiler) +} + +kotlin { + jvm() + + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + browser { + commonWebpackConfig { + outputFileName = "composeApp.js" + } + } + binaries.executable() + } + + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(compose.ui) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + } + commonTest.dependencies { + implementation(libs.kotlin.test) + } + jvmMain.dependencies { + implementation(compose.desktop.currentOs) + implementation(libs.kotlinx.coroutines.swing) + } + } +} + + +compose.desktop { + application { + mainClass = "at.mocode.MainKt" + + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "at.mocode" + packageVersion = "1.0.0" + } + } +} diff --git a/client/common-ui/README-CLIENT-COMMON-UI.md b/client/common-ui/README-CLIENT-COMMON-UI.md deleted file mode 100644 index d30e66a8..00000000 --- a/client/common-ui/README-CLIENT-COMMON-UI.md +++ /dev/null @@ -1,357 +0,0 @@ -# Client Common-UI Modul - -## Überblick - -Das **common-ui** Modul stellt die geteilten Benutzeroberflächen-Komponenten und Geschäftslogik für die Meldestelle Client-Anwendungen bereit. Dieses Modul implementiert die Kern-"Tracer Bullet" Funktionalität unter Verwendung eines modernen MVVM-Architekturmusters und dient sowohl der Desktop- als auch der Web-Anwendung. - -**Hauptfunktionen:** -- 🏗️ **MVVM-Architektur** - ordnungsgemäße Trennung der Belange mit ViewModel-Muster -- 🌐 **Plattformübergreifend** - geteilter Code für Desktop (JVM) und Web (JavaScript) Anwendungen -- 🎯 **Vier UI-Zustände** - vollständige Implementierung gemäß trace-bullet-guideline.md -- 🔧 **Ressourcenverwaltung** - ordnungsgemäßer HttpClient-Lebenszyklus und Speicherverwaltung -- 🧪 **Testabdeckung** - umfassende Testsuite für alle kritischen Funktionen - ---- - -## Architektur - -### Modulstruktur - -``` -client/common-ui/src/ -├── commonMain/kotlin/at/mocode/client/ -│ ├── data/service/ -│ │ ├── PingResponse.kt # Datenmodell für API-Antworten -│ │ └── PingService.kt # HTTP-Service mit Ressourcenverwaltung -│ └── ui/ -│ ├── App.kt # Hauptanwendungskomponente -│ └── viewmodel/ -│ └── PingViewModel.kt # MVVM-Zustandsverwaltung -└── commonTest/kotlin/at/mocode/client/ - ├── data/service/ - │ ├── PingResponseTest.kt # Datenmodell-Tests - │ └── PingServiceTest.kt # Service-Schicht-Tests - └── ui/viewmodel/ - └── PingViewModelTest.kt # ViewModel- und Zustands-Tests -``` - -### MVVM-Muster Implementierung - -**PingUiState (Sealed Class):** -- `Initial` - Neutrale Nachricht, Button aktiv -- `Loading` - Ladeindikator, Button deaktiviert -- `Success` - Positive Antwortanzeige, Button aktiv -- `Error` - Klare Fehlernachricht, Button aktiv - -**PingViewModel:** -- Verwaltet UI-Zustandsübergänge -- Behandelt Coroutine-Lebenszyklus -- Ordnungsgemäße Ressourcenentsorgung - -**PingService:** -- HTTP-Client-Verwaltung -- Result-Wrapper-Muster -- Ressourcen-Bereinigungsunterstützung - ---- - -## Abhängigkeiten - -### Laufzeit-Abhängigkeiten -```kotlin -// Compose Multiplatform UI -implementation(compose.runtime) -implementation(compose.foundation) -implementation(compose.material3) - -// Netzwerk & Serialisierung -implementation(libs.ktor.client.core) -implementation(libs.ktor.client.contentNegotiation) -implementation(libs.ktor.client.serialization.kotlinx.json) -implementation(libs.kotlinx.serialization.json) - -// Coroutines -implementation(libs.kotlinx.coroutines.core) -``` - -### Plattformspezifische Abhängigkeiten -```kotlin -// JVM (Desktop) -jvmMain { - implementation(libs.ktor.client.cio) -} - -// JS (Web) -jsMain { - implementation(libs.ktor.client.js) -} -``` - -### Test-Abhängigkeiten -```kotlin -commonTest { - implementation(libs.kotlin.test) - implementation(libs.kotlinx.coroutines.test) -} -``` - ---- - -## Verwendung - -### Grundlegende Integration - -```kotlin -@Composable -fun YourApplication() { - // Verwendet at.mocode.client.ui.App - App(baseUrl = "https://your-api.com") -} -``` - -### Erweiterte Verwendung mit benutzerdefinierter Konfiguration - -```kotlin -// Benutzerdefinierte Service-Konfiguration -// Verwendet at.mocode.client.data.service.PingService -val customService = PingService( - baseUrl = "https://custom-api.com", - httpClient = createCustomHttpClient() -) - -// Benutzerdefiniertes ViewModel mit spezifischem Scope -// Verwendet at.mocode.client.ui.viewmodel.PingViewModel -val customViewModel = PingViewModel( - pingService = customService, - coroutineScope = customCoroutineScope -) -``` - ---- - -## API-Referenz - -### PingService - -```kotlin -class PingService( - private val baseUrl: String = "http://localhost:8080", - private val httpClient: HttpClient = createDefaultHttpClient() -) { - suspend fun ping(): Result - fun close() - - companion object { - fun createDefaultHttpClient(): HttpClient - } -} -``` - -### PingViewModel - -```kotlin -class PingViewModel( - private val pingService: PingService, - private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) -) { - var uiState: PingUiState by mutableStateOf(PingUiState.Initial) - private set - - fun pingBackend() - fun dispose() -} -``` - -### PingUiState - -```kotlin -sealed class PingUiState { - data object Initial : PingUiState() - data object Loading : PingUiState() - data class Success(val response: PingResponse) : PingUiState() - data class Error(val message: String) : PingUiState() -} -``` - ---- - -## Entwicklung - -### Das Modul erstellen - -```bash -# Für alle Plattformen kompilieren -./gradlew :client:common-ui:build - -# Nur JVM-Kompilierung -./gradlew :client:common-ui:compileKotlinJvm - -# Nur JavaScript-Kompilierung -./gradlew :client:common-ui:compileKotlinJs -``` - -### Tests ausführen - -```bash -# Alle Tests ausführen -./gradlew :client:common-ui:jvmTest - -# Spezifische Testklasse ausführen -./gradlew :client:common-ui:jvmTest --tests "PingViewModelTest" -``` - -### Codequalität - -Das Modul hält hohe Codequalitätsstandards aufrecht: -- **Testabdeckung**: 32 umfassende Tests über alle Schichten -- **Architektur-Konformität**: 100% MVVM-Muster-Einhaltung -- **Ressourcenverwaltung**: Ordnungsgemäßer Lebenszyklus und Bereinigung -- **Speichersicherheit**: Keine Speicherlecks durch ordnungsgemäße Entsorgung - ---- - -## Tests - -### Testabdeckung Übersicht - -| Komponente | Test-Datei | Tests | Abdeckung | -|-----------|-----------|-------|----------| -| PingResponse | PingResponseTest.kt | 7 | Datenmodell, Serialisierung | -| PingService | PingServiceTest.kt | 10 | HTTP-Service, Lebenszyklus | -| PingViewModel | PingViewModelTest.kt | 8 | MVVM, Zustandsverwaltung | - -### Spezifische Test-Suites ausführen - -```bash -# Datenschicht-Tests -./gradlew :client:common-ui:jvmTest --tests "*PingResponseTest*" - -# Service-Schicht-Tests -./gradlew :client:common-ui:jvmTest --tests "*PingServiceTest*" - -# ViewModel-Tests -./gradlew :client:common-ui:jvmTest --tests "*PingViewModelTest*" -``` - ---- - -## Architektur-Vorteile - -### 🏗️ **Moderne MVVM-Implementierung** -- **Testbarkeit**: Ordnungsgemäße Dependency Injection ermöglicht umfassende Unit-Tests -- **Wartbarkeit**: Klare Trennung der Belange und Single-Responsibility-Prinzip -- **Skalierbarkeit**: Architektur unterstützt zukünftige Funktionserweiterungen nahtlos - -### 🚀 **Laufzeit-Effizienz** -- **Ressourcenverwaltung**: Ordnungsgemäße HttpClient-Bereinigung verhindert Speicherlecks -- **Leistung**: Eliminierung unnötiger Operationen und Callback-Muster -- **Stabilität**: Verbesserte Fehlerbehandlung und Zustandsverwaltung - -### 🔧 **Entwicklererfahrung** -- **Code-Klarheit**: Selbstdokumentierender Code mit Sealed Classes und klarer Benennung -- **Debugging**: Einfache Zustandsverfolgung und Problemidentifikation -- **Integration**: Einfaches Integrationsmuster für abhängige Module - ---- - -## Migrations-Hinweise - -### Von der vorherigen Implementierung - -Das Modul wurde vollständig von einem komponentenbasierten Ansatz zu MVVM refaktoriert: - -**Vorher (Komponentenbasiert):** -- Vermischte Belange in einzelnen Dateien -- Callback-basierte Zustandsverwaltung -- Manuelle Ressourcenverwaltung -- Speicherleck-Potenzial - -**Nachher (MVVM):** -- Klare Trennung der Belange -- Compose-Zustandsverwaltung -- Automatische Ressourcenbereinigung -- Speicherleck-Prävention - -### Breaking Changes - -**Keine** - Das Refactoring behielt vollständige Rückwärtskompatibilität für abhängige Module bei. - ---- - -## Zukünftige Entwicklung - -### Empfohlene Verbesserungen - -1. **Konfigurationsverwaltung** - - Umgebungsspezifische Einstellungen - - Konfigurationsvalidierung - -2. **Fehlerbehandlung** - - Spezifische Fehlertypen - - Wiederholungsmechanismen für Netzwerkausfälle - -3. **Monitoring-Integration** - - Metriken-Sammlung - - Leistungsüberwachung - -4. **Internationalisierung** - - Mehrsprachige Unterstützung - - Sprachspezifische Formatierung - ---- - -## Mitwirken - -### Entwicklungsumgebung einrichten - -1. Stellen Sie sicher, dass JDK 21 installiert ist -2. Klonen Sie das Repository -3. Führen Sie `./gradlew :client:common-ui:build` aus, um die Einrichtung zu verifizieren - -### Code-Standards - -- Befolgen Sie Kotlin-Codierungskonventionen -- Fügen Sie Tests für neue Funktionalität hinzu -- Behalten Sie MVVM-Architekturmuster bei -- Stellen Sie ordnungsgemäße Ressourcenverwaltung sicher - -### Test-Anforderungen - -- Alle öffentlichen APIs müssen Tests haben -- Mindestens 90% Testabdeckung für neue Features -- Integrationstests für modulübergreifende Funktionalität - ---- - -## Fehlerbehebung - -### Häufige Probleme - -| Problem | Lösung | -|-------|----------| -| `HttpClient` nicht ordnungsgemäß geschlossen | Stellen Sie sicher, dass `dispose()` im ViewModel aufgerufen wird | -| Zustand wird in UI nicht aktualisiert | Überprüfen Sie die Compose-Zustandsbeobachtung-Einrichtung | -| Netzwerk-Timeouts | Überprüfen Sie `baseUrl`-Konfiguration und Konnektivität | -| Test-Fehler auf JS-Plattform | Verwenden Sie JS-kompatible Test-Muster (keine Reflection) | - -### Debug-Informationen - -```bash -# Abhängigkeitskonflikte überprüfen -./gradlew :client:common-ui:dependencies - -# Ausführliche Test-Ausgabe -./gradlew :client:common-ui:jvmTest --info - -# Build-Scan für detaillierte Analyse -./gradlew :client:common-ui:build --scan -``` - ---- - -**Modul-Status**: ✅ Produktionsbereit -**Architektur**: ✅ MVVM-konform -**Testabdeckung**: ✅ Umfassend (32 Tests) -**Dokumentation**: ✅ Vollständig - -*Zuletzt aktualisiert: 16. August 2025* diff --git a/client/common-ui/build.gradle.kts b/client/common-ui/build.gradle.kts deleted file mode 100644 index 1ecdd7b1..00000000 --- a/client/common-ui/build.gradle.kts +++ /dev/null @@ -1,73 +0,0 @@ -plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.kotlin.serialization) - id("org.jetbrains.compose") - id("org.jetbrains.kotlin.plugin.compose") - id("maven-publish") -} - -group = "at.mocode.client" -version = "1.0.0-SNAPSHOT" - -kotlin { - jvm() - js(IR) { browser() } - - sourceSets { - val commonMain by getting { - dependencies { - // Compose Multiplatform - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material3) - - // Skiko is provided by Compose Multiplatform - no explicit dependency needed - - // Serialization - implementation(libs.kotlinx.serialization.json) - - // Ktor Client for API calls - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.contentNegotiation) - implementation(libs.ktor.client.serialization.kotlinx.json) - - // Coroutines for background tasks - implementation(libs.kotlinx.coroutines.core) - } - } - val jvmMain by getting { - dependencies { - // Ktor engine for Desktop - implementation(libs.ktor.client.cio) - } - } - val jsMain by getting { - dependencies { - // Ktor engine for Browser - implementation(libs.ktor.client.js) - } - } - - val commonTest by getting { - dependencies { - implementation(libs.kotlin.test) - implementation(libs.kotlinx.coroutines.test) - // Note: ktor-client-mock would be ideal but may not be available in libs - // Using core testing dependencies for now - } - } - val jsTest by getting { - // Avoid duplicate Skiko runtime files in test processedResources - resources.exclude("**/skiko.*") - resources.exclude("**/skikod8.mjs") - } - } -} - -// Avoid overwrite warnings when syncing JS test executable: keep first occurrence of duplicate resources -// Configure the Kotlin JS incremental sync task directly using fully-qualified types (no imports in the middle of the file) - -tasks.named("jsTestTestDevelopmentExecutableCompileSync").configure { - // Skip copying duplicates that already exist in destination - duplicatesStrategy = org.gradle.api.file.DuplicatesStrategy.EXCLUDE -} diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt deleted file mode 100644 index f9dc0f0a..00000000 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt +++ /dev/null @@ -1,6 +0,0 @@ -package at.mocode.client.data.service - -import kotlinx.serialization.Serializable - -@Serializable -data class PingResponse(val status: String) diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingService.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingService.kt deleted file mode 100644 index 3c18cfbf..00000000 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingService.kt +++ /dev/null @@ -1,31 +0,0 @@ -package at.mocode.client.data.service - -import io.ktor.client.* -import io.ktor.client.call.* -import io.ktor.client.plugins.contentnegotiation.* -import io.ktor.client.request.* -import io.ktor.serialization.kotlinx.json.* - -class PingService( - private val baseUrl: String = "http://localhost:8080", - private val httpClient: HttpClient = createDefaultHttpClient() -) { - suspend fun ping(): Result = try { - val response = httpClient.get("$baseUrl/api/ping/ping").body() - Result.success(response) - } catch (e: Exception) { - Result.failure(e) - } - - fun close() { - httpClient.close() - } - - companion object { - fun createDefaultHttpClient(): HttpClient = HttpClient { - install(ContentNegotiation) { - json() - } - } - } -} diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt deleted file mode 100644 index 02100b7d..00000000 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt +++ /dev/null @@ -1,98 +0,0 @@ -package at.mocode.client.ui - -import androidx.compose.foundation.layout.* -import androidx.compose.material3.Button -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import at.mocode.client.data.service.PingService -import at.mocode.client.ui.viewmodel.PingViewModel -import at.mocode.client.ui.viewmodel.PingUiState - -@Composable -fun App(baseUrl: String = "http://localhost:8080") { - MaterialTheme { - PingScreen(baseUrl) - } -} - -@Composable -fun PingScreen(baseUrl: String) { - val pingService = remember { PingService(baseUrl) } - val viewModel = remember { PingViewModel(pingService) } - - DisposableEffect(viewModel) { - onDispose { - viewModel.dispose() - } - } - - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Text( - text = "Ping Backend Service", - style = MaterialTheme.typography.headlineMedium, - modifier = Modifier.padding(bottom = 24.dp) - ) - - // Status display area with fixed height for consistent layout - Box( - modifier = Modifier - .fillMaxWidth() - .height(100.dp), - contentAlignment = Alignment.Center - ) { - when (val state = viewModel.uiState) { - is PingUiState.Initial -> { - Text( - text = "Klicke auf den Button, um das Backend zu testen", - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodyLarge - ) - } - is PingUiState.Loading -> { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - CircularProgressIndicator() - Text( - text = "Pinge Backend ...", - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.padding(top = 8.dp) - ) - } - } - is PingUiState.Success -> { - Text( - text = "Antwort vom Backend: ${state.response.status}", - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.bodyLarge - ) - } - is PingUiState.Error -> { - Text( - text = "Fehler: ${state.message}", - color = MaterialTheme.colorScheme.error, - style = MaterialTheme.typography.bodyLarge - ) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = { viewModel.pingBackend() }, - enabled = viewModel.uiState !is PingUiState.Loading - ) { - Text("Ping Backend") - } - } -} diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/viewmodel/PingViewModel.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/viewmodel/PingViewModel.kt deleted file mode 100644 index 6c418abe..00000000 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/viewmodel/PingViewModel.kt +++ /dev/null @@ -1,54 +0,0 @@ -package at.mocode.client.ui.viewmodel - -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import at.mocode.client.data.service.PingService -import at.mocode.client.data.service.PingResponse -import kotlinx.coroutines.* - -/** - * Represents the four distinct UI states as defined in the trace-bullet-guideline.md - */ -sealed class PingUiState { - /** Initial state: neutral message, button active */ - data object Initial : PingUiState() - - /** Loading state: loading message, button disabled */ - data object Loading : PingUiState() - - /** Success state: positive response, button active */ - data class Success(val response: PingResponse) : PingUiState() - - /** Error state: clear error message, button active */ - data class Error(val message: String) : PingUiState() -} - -class PingViewModel( - private val pingService: PingService, - private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) -) { - var uiState by mutableStateOf(PingUiState.Initial) - private set - - fun pingBackend() { - uiState = PingUiState.Loading - - coroutineScope.launch { - pingService.ping() - .onSuccess { response -> - uiState = PingUiState.Success(response) - } - .onFailure { error -> - uiState = PingUiState.Error( - error.message ?: "Unbekannter Fehler beim Verbinden mit dem Backend" - ) - } - } - } - - fun dispose() { - coroutineScope.cancel() - pingService.close() - } -} diff --git a/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingResponseTest.kt b/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingResponseTest.kt deleted file mode 100644 index 299fecb0..00000000 --- a/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingResponseTest.kt +++ /dev/null @@ -1,108 +0,0 @@ -package at.mocode.client.data.service - -import kotlinx.serialization.json.Json -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertTrue - -class PingResponseTest { - - @Test - fun `should create PingResponse with status`() { - // Given - val status = "pong" - - // When - val response = PingResponse(status = status) - - // Then - assertEquals(status, response.status) - assertNotNull(response) - } - - @Test - fun `should serialize to JSON correctly`() { - // Given - val response = PingResponse(status = "pong") - - // When - val json = Json.encodeToString(response) - - // Then - assertTrue(json.contains("\"status\":\"pong\"")) - assertTrue(json.startsWith("{")) - assertTrue(json.endsWith("}")) - } - - @Test - fun `should deserialize from JSON correctly`() { - // Given - val json = """{"status":"pong"}""" - - // When - val response = Json.decodeFromString(json) - - // Then - assertEquals("pong", response.status) - } - - @Test - fun `should handle different status values`() { - // Given & When & Then - val responses = listOf("pong", "ok", "alive", "healthy") - - responses.forEach { status -> - val response = PingResponse(status = status) - assertEquals(status, response.status) - - // Test serialization roundtrip - val json = Json.encodeToString(response) - val deserialized = Json.decodeFromString(json) - assertEquals(status, deserialized.status) - } - } - - @Test - fun `should handle empty status`() { - // Given - val emptyStatus = "" - - // When - val response = PingResponse(status = emptyStatus) - - // Then - assertEquals("", response.status) - - // Test serialization works with empty string - val json = Json.encodeToString(response) - val deserialized = Json.decodeFromString(json) - assertEquals("", deserialized.status) - } - - @Test - fun `should be data class with proper equals and hashCode`() { - // Given - val response1 = PingResponse("pong") - val response2 = PingResponse("pong") - val response3 = PingResponse("different") - - // Then - assertEquals(response1, response2) - assertEquals(response1.hashCode(), response2.hashCode()) - assertTrue(response1 != response3) - } - - @Test - fun `should have proper toString representation`() { - // Given - val response = PingResponse("pong") - - // When - val toString = response.toString() - - // Then - assertTrue(toString.contains("PingResponse")) - assertTrue(toString.contains("pong")) - } -} diff --git a/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingServiceTest.kt b/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingServiceTest.kt deleted file mode 100644 index 16bcdee7..00000000 --- a/client/common-ui/src/commonTest/kotlin/at/mocode/client/data/service/PingServiceTest.kt +++ /dev/null @@ -1,155 +0,0 @@ -package at.mocode.client.data.service - -import io.ktor.client.* -import io.ktor.client.plugins.contentnegotiation.* -import io.ktor.serialization.kotlinx.json.* -import kotlin.test.* - -class PingServiceTest { - - @Test - fun `should create service with default parameters`() { - // When - val service = PingService() - - // Then - assertNotNull(service) - } - - @Test - fun `should create service with custom baseUrl`() { - // Given - val customUrl = "https://custom-api.example.com" - - // When - val service = PingService(baseUrl = customUrl) - - // Then - assertNotNull(service) - // Note: baseUrl is private, so we test indirectly through behavior - } - - @Test - fun `should create default HttpClient with ContentNegotiation`() { - // When - val client = PingService.createDefaultHttpClient() - - // Then - assertNotNull(client) - // Verify the client is properly configured by checking it's not null and can be closed - client.close() - } - - @Test - fun `should create service with custom HttpClient`() { - // Given - val customClient = HttpClient { - install(ContentNegotiation) { - json() - } - } - - // When - val service = PingService("http://localhost:8080", customClient) - - // Then - assertNotNull(service) - - // Cleanup - service.close() - } - - @Test - fun `should close httpClient when service is closed`() { - // Given - val service = PingService() - - // When & Then - // Verify that close() doesn't throw exceptions - assertDoesNotThrow { service.close() } - } - - @Test - fun `should handle multiple close calls gracefully`() { - // Given - val service = PingService() - - // When & Then - // Multiple close calls should not throw exceptions - assertDoesNotThrow { - service.close() - service.close() - service.close() - } - } - - @Test - fun `should create companion object HttpClient`() { - // When - val client1 = PingService.createDefaultHttpClient() - val client2 = PingService.createDefaultHttpClient() - - // Then - assertNotNull(client1) - assertNotNull(client2) - // Each call should create a new instance - assertNotSame(client1, client2) - - // Cleanup - client1.close() - client2.close() - } - - @Test - fun `should handle service creation with different baseUrl formats`() { - // Given & When & Then - val urls = listOf( - "http://localhost:8080", - "https://api.example.com", - "http://192.168.1.100:3000", - "https://secure.api.com:9443" - ) - - urls.forEach { url -> - val service = PingService(baseUrl = url) - assertNotNull(service, "Service should be created with URL: $url") - service.close() - } - } - - @Test - fun `should handle Result wrapper for ping operations`() { - // Given - val service = PingService() - - // Note: We can't easily test the actual ping() method without a mock server - // But we can verify the service structure is correct for Result handling - assertNotNull(service) - - // The ping() method returns Result - this is tested indirectly - // through the service structure validation - service.close() - } - - @Test - fun `should properly encapsulate HttpClient lifecycle`() { - // Given - val client: HttpClient? = null - - // When - val service = PingService() - // We can't access the private httpClient directly, but we can test lifecycle - assertNotNull(service) - - // Then - Service should handle cleanup properly - assertDoesNotThrow { service.close() } - } - - private fun assertDoesNotThrow(block: () -> Unit) { - try { - block() - } catch (e: Exception) { - fail("Expected no exception, but got: ${e.message}") - } - } -} diff --git a/client/common-ui/src/commonTest/kotlin/at/mocode/client/ui/viewmodel/PingViewModelTest.kt b/client/common-ui/src/commonTest/kotlin/at/mocode/client/ui/viewmodel/PingViewModelTest.kt deleted file mode 100644 index 444bd650..00000000 --- a/client/common-ui/src/commonTest/kotlin/at/mocode/client/ui/viewmodel/PingViewModelTest.kt +++ /dev/null @@ -1,148 +0,0 @@ -package at.mocode.client.ui.viewmodel - -import at.mocode.client.data.service.PingResponse -import at.mocode.client.data.service.PingService -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.cancel -import kotlin.test.* - -@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) - -class PingViewModelTest { - - @Test - fun `should create PingUiState sealed class instances`() { - // When & Then - val initial = PingUiState.Initial - val loading = PingUiState.Loading - val success = PingUiState.Success(PingResponse("pong")) - val error = PingUiState.Error("Test error") - - assertNotNull(initial) - assertNotNull(loading) - assertNotNull(success) - assertNotNull(error) - } - - @Test - fun `should have correct PingUiState Success data`() { - // Given - val response = PingResponse("pong") - - // When - val successState = PingUiState.Success(response) - - // Then - assertEquals("pong", successState.response.status) - } - - @Test - fun `should have correct PingUiState Error message`() { - // Given - val errorMessage = "Network connection failed" - - // When - val errorState = PingUiState.Error(errorMessage) - - // Then - assertEquals(errorMessage, errorState.message) - } - - @Test - fun `should create ViewModel with initial state`() { - // Given - val pingService = PingService("http://test-server") - val testScope = CoroutineScope(Dispatchers.Default) - - // When - val viewModel = PingViewModel(pingService, testScope) - - // Then - assertTrue(viewModel.uiState is PingUiState.Initial) - - // Cleanup - testScope.cancel() - pingService.close() - } - - @Test - fun `should transition to Loading state when pingBackend is called`() { - // Given - val pingService = PingService("http://unreachable-server") - val testScope = CoroutineScope(Dispatchers.Default) - val viewModel = PingViewModel(pingService, testScope) - - // When - viewModel.pingBackend() - - // Then - Should immediately transition to Loading - assertTrue(viewModel.uiState is PingUiState.Loading) - - // Cleanup - testScope.cancel() - pingService.close() - } - - @Test - fun `should dispose without throwing exceptions`() { - // Given - val pingService = PingService("http://test") - val testScope = CoroutineScope(Dispatchers.Default) - val viewModel = PingViewModel(pingService, testScope) - - // When & Then - Should complete without exceptions - assertDoesNotThrow { viewModel.dispose() } - } - - @Test - fun `should preserve uiState immutability`() { - // Given - val pingService = PingService("http://test") - val testScope = CoroutineScope(Dispatchers.Default) - val viewModel = PingViewModel(pingService, testScope) - - // When - val initialState = viewModel.uiState - - // Then - uiState should be immutable (no setter accessible from outside) - assertTrue(initialState is PingUiState.Initial) - // The uiState property should be read-only from external access - // This is enforced by the private setter in the ViewModel - - // Cleanup - testScope.cancel() - pingService.close() - } - - @Test - fun `should handle different service configurations`() { - // Given - Different service configurations - val service1 = PingService("http://server1") - val service2 = PingService("https://server2:8443") - val testScope1 = CoroutineScope(Dispatchers.Default) - val testScope2 = CoroutineScope(Dispatchers.Default) - - // When - val viewModel1 = PingViewModel(service1, testScope1) - val viewModel2 = PingViewModel(service2, testScope2) - - // Then - assertTrue(viewModel1.uiState is PingUiState.Initial) - assertTrue(viewModel2.uiState is PingUiState.Initial) - - // Cleanup - testScope1.cancel() - testScope2.cancel() - service1.close() - service2.close() - } - - private fun assertDoesNotThrow(block: () -> Unit) { - try { - block() - } catch (e: Exception) { - fail("Expected no exception, but got: ${e.message}") - } - } -} diff --git a/client/desktop-app/README-CLIENT-DESKTOP-APP.md b/client/desktop-app/README-CLIENT-DESKTOP-APP.md deleted file mode 100644 index f00e6740..00000000 --- a/client/desktop-app/README-CLIENT-DESKTOP-APP.md +++ /dev/null @@ -1,459 +0,0 @@ -# Client Desktop-App Modul - -## Überblick - -Das **desktop-app** Modul stellt eine native Desktop-Anwendung für das Meldestelle-System bereit, die Kotlin Multiplatform und Compose for Desktop verwendet. Dieses Modul dient als plattformübergreifender Desktop-Client, der nahtlos mit dem geteilten common-ui Modul integriert ist, um eine konsistente Benutzererfahrung zu liefern. - -**Hauptfunktionen:** -- 🖥️ **Native Desktop-App** - Plattformübergreifende Unterstützung für Windows, macOS und Linux -- 🏗️ **Moderne Architektur** - Integriert mit MVVM common-ui Modul -- 🚀 **Optimierter Build** - Modernisierte Gradle-Konfiguration mit nativer Distribution -- 🧪 **Testabdeckung** - Umfassende Testsuite für Desktop-spezifische Funktionalität -- 📦 **Einfache Distribution** - Eigenständiges Packaging für alle Plattformen - ---- - -## Architektur - -### Modulstruktur - -``` -client/desktop-app/ -├── build.gradle.kts # Modernisierte Build-Konfiguration -├── src/ -│ ├── jvmMain/kotlin/at/mocode/client/desktop/ -│ │ └── Main.kt # Desktop-Anwendung Einstiegspunkt -│ └── jvmTest/kotlin/at/mocode/client/desktop/ -│ └── MainTest.kt # Desktop-spezifische Tests -└── README-CLIENT-DESKTOP-APP.md # Diese Dokumentation -``` - -### Integration mit Common-UI - -Die Desktop-App nutzt die geteilte MVVM-Architektur von common-ui: - -```kotlin -fun main() = application { - Window( - onCloseRequest = ::exitApplication, - title = "Meldestelle Desktop App", - state = WindowState( - position = WindowPosition(Alignment.Center), - width = 800.dp, - height = 600.dp - ) - ) { - // Verwendet geteilte App-Komponente mit MVVM-Architektur - App(baseUrl = System.getProperty("meldestelle.api.url", "http://localhost:8080")) - } -} -``` - ---- - -## Build-Konfiguration - -### Moderne Gradle-Einrichtung - -Die desktop-app verwendet eine modernisierte Build-Konfiguration nach Projektstandards: - -#### Plugin-Konfiguration -```kotlin -plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.compose.multiplatform) - alias(libs.plugins.compose.compiler) -} -``` - -#### Abhängigkeiten-Organisation -```kotlin -val jvmMain by getting { - dependencies { - // Projekt-Abhängigkeiten - implementation(project(":client:common-ui")) - - // Compose Desktop - implementation(compose.desktop.currentOs) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.uiTooling) - implementation(compose.runtime) - implementation(compose.foundation) - - // Serialisierungsunterstützung - implementation(libs.kotlinx.serialization.json) - - // HTTP Client & Coroutines - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.contentNegotiation) - implementation(libs.ktor.client.serialization.kotlinx.json) - implementation(libs.kotlinx.coroutines.swing) - - // Logging - implementation(libs.kotlin.logging.jvm) - } -} -``` - -#### Test-Konfiguration -```kotlin -val jvmTest by getting { - dependencies { - implementation(libs.bundles.testing.jvm) - } -} -``` - -#### Native Distribution -```kotlin -nativeDistributions { - targetFormats(TargetFormat.Deb, TargetFormat.Dmg, TargetFormat.Msi) - packageName = "Meldestelle" - packageVersion = "1.0.0" -} -``` - ---- - -## Entwicklung - -### Voraussetzungen - -| Tool | Version | Zweck | -|------|---------|-------| -| JDK | 21 (Temurin) | Desktop-Laufzeit und Gradle-Build | -| Gradle | 8.x (wrapper) | Build-Automatisierung | - -### Die Anwendung erstellen - -```bash -# Die Desktop-Anwendung kompilieren -./gradlew :client:desktop-app:compileKotlinJvm - -# Die Anwendung im Entwicklungsmodus ausführen -./gradlew :client:desktop-app:run - -# Vollständige Anwendung erstellen -./gradlew :client:desktop-app:build -``` - -### Tests ausführen - -```bash -# Alle Desktop-Tests ausführen -./gradlew :client:desktop-app:jvmTest - -# Spezifischen Test ausführen -./gradlew :client:desktop-app:jvmTest --tests "MainTest" - -# Ausführliche Test-Ausgabe -./gradlew :client:desktop-app:jvmTest --info -``` - -### Packaging für Distribution - -```bash -# Verteilbare Pakete für alle Plattformen erstellen -./gradlew :client:desktop-app:createDistributable - -# Paket für spezifische Plattform -./gradlew :client:desktop-app:packageDeb # Linux .deb -./gradlew :client:desktop-app:packageDmg # macOS .dmg -./gradlew :client:desktop-app:packageMsi # Windows .msi -``` - ---- - -## Konfiguration - -### Systemeigenschaften - -Die Desktop-Anwendung unterstützt Konfiguration über JVM-Systemeigenschaften: - -| Eigenschaft | Standard | Beschreibung | -|----------|---------|-------------| -| `meldestelle.api.url` | `http://localhost:8080` | Backend-API Basis-URL | - -#### Verwendungsbeispiele - -```bash -# Mit benutzerdefinierter API-URL ausführen -./gradlew :client:desktop-app:run -Dmeldestelle.api.url=https://api.example.com - -# Mit Entwicklungseinstellungen ausführen -./gradlew :client:desktop-app:run -Dmeldestelle.api.url=http://localhost:8080 -``` - -### Fenster-Konfiguration - -Standard-Fenstereinstellungen können in `Main.kt` angepasst werden: - -```kotlin -WindowState( - position = WindowPosition(Alignment.Center), - width = 800.dp, // Anpassbar - height = 600.dp // Anpassbar -) -``` - ---- - -## Tests - -### Testabdeckung - -| Komponente | Test-Datei | Tests | Abdeckung | -|-----------|-----------|-------|----------| -| Hauptanwendung | MainTest.kt | 3 | Bootstrap, Konfiguration, Struktur | - -### Test-Implementierung - -```kotlin -class MainTest { - @Test - fun `should have valid main class configuration`() - - @Test - fun `should have proper package structure`() - - @Test - fun `should be able to instantiate system property for base URL`() -} -``` - -### Test-Suites ausführen - -```bash -# Alle Tests -./gradlew :client:desktop-app:jvmTest - -# Mit Abdeckungsbericht -./gradlew :client:desktop-app:jvmTest jacocoTestReport -``` - ---- - -## Build-Optimierungshistorie - -### 14. August 2025 - Build-Modernisierung - -**Plugin-Konfiguration-Verbesserungen:** -- Migration zu `alias()` für type-safe Plugin-Referenzen -- Serialisierung und Compose Compiler-Unterstützung hinzugefügt -- TargetFormat-Imports für native Distribution behoben - -**Abhängigkeiten-Verbesserungen:** -- Strukturierte Logging-Unterstützung hinzugefügt -- Erweiterte HTTP-Client-Fähigkeiten -- Verbesserte Compose-Komponentenorganisation -- Umfassende Test-Infrastruktur hinzugefügt - -**Native Distribution:** -- TargetFormat-Konfiguration behoben -- Plattformübergreifendes Packaging aktiviert (Deb, Dmg, Msi) -- Package-Metadaten optimiert - -### 16. August 2025 - Tests & Integration - -**Test-Infrastruktur:** -- Umfassende MainTest.kt hinzugefügt -- Mit common-ui MVVM-Architektur integriert -- Anwendungs-Bootstrap und Konfiguration validiert -- Systemeigenschaften-Tests hinzugefügt - -**Architektur-Validierung:** -- Nahtlose Integration mit aktualisiertem common-ui bestätigt -- MVVM-Muster-Konformität verifiziert -- Ressourcenverwaltungs-Integration validiert - ---- - -## Leistung & Qualität - -### Build-Leistung -- ✅ Schnelle inkrementelle Builds mit moderner Gradle-Konfiguration -- ✅ Effiziente Plugin-Auflösung durch Versions-Katalog -- ✅ Optimierte Abhängigkeitsverwaltung - -### Laufzeit-Leistung -- ✅ Native Desktop-Leistung mit JVM-Optimierung -- ✅ Effiziente Ressourcenverwaltung durch common-ui Integration -- ✅ Minimaler Speicher-Footprint mit ordnungsgemäßer Bereinigung - -### Code-Qualität -- ✅ 100% Architektur-Konformität mit MVVM-Muster -- ✅ Umfassende Testabdeckung für Desktop-spezifische Funktionalität -- ✅ Konsistente Code-Organisation und Dokumentation - ---- - -## Integrations-Vorteile - -### Vom Common-UI Modul - -Die Desktop-App profitiert automatisch von allen common-ui Optimierungen: - -- **MVVM-Architektur**: Ordnungsgemäße Trennung der Belange durch PingViewModel -- **Ressourcenverwaltung**: Automatische Bereinigung über DisposableEffect in geteilten Komponenten -- **UI-Zustandsverwaltung**: Vier distinkte Zustände gemäß Trace-Bullet-Richtlinien -- **Speicherleck-Prävention**: Eliminierte Callback-Muster zugunsten von Compose-State - -### Desktop-spezifische Vorteile - -- **Native Leistung**: Direkte JVM-Ausführung ohne Browser-Overhead -- **System-Integration**: Native Dateidialoge, Benachrichtigungen, System-Tray-Unterstützungspotential -- **Offline-Fähigkeit**: Vollständige Funktionalität ohne Netzwerkabhängigkeiten -- **Plattformübergreifend**: Einzige Codebasis läuft auf Windows, macOS und Linux - ---- - -## Deployment - -### Entwicklungs-Deployment - -```bash -# Schneller Entwicklungslauf -./gradlew :client:desktop-app:run - -# Mit benutzerdefinierter Konfiguration ausführen -./gradlew :client:desktop-app:run -Dmeldestelle.api.url=https://staging-api.com -``` - -### Produktions-Deployment - -```bash -# Produktions-Build erstellen -./gradlew :client:desktop-app:build - -# Für Distribution packen -./gradlew :client:desktop-app:createDistributable - -# Das Distributionspaket wird erstellt in: -# build/compose/binaries/main/app/ -``` - -### Distributions-Formate - -| Plattform | Format | Befehl | Ausgabe | -|----------|--------|---------|--------| -| Linux | .deb | `packageDeb` | Debian Package-Installer | -| macOS | .dmg | `packageDmg` | macOS Disk-Image | -| Windows | .msi | `packageMsi` | Windows Installer | - ---- - -## Fehlerbehebung - -### Häufige Probleme - -| Problem | Symptome | Lösung | -|-------|----------|----------| -| SLF4J-Warnungen | Logging-Warnungen beim Start | Logback-Abhängigkeit hinzufügen (nicht kritisch) | -| Hauptklasse nicht gefunden | Build/Run-Fehler | Main.kt Package-Struktur überprüfen | -| Fenster wird nicht angezeigt | Anwendung startet, aber kein Fenster | Display-Einstellungen und Fensterzustand überprüfen | -| API-Verbindung fehlgeschlagen | Netzwerkfehler | `meldestelle.api.url` Systemeigenschaft überprüfen | - -### Debug-Befehle - -```bash -# Hauptklassen-Konfiguration überprüfen -./gradlew :client:desktop-app:printMainClassName - -# Abhängigkeiten analysieren -./gradlew :client:desktop-app:dependencies - -# Ausführliche Build-Ausgabe -./gradlew :client:desktop-app:build --info --stacktrace -``` - -### Leistungsüberwachung - -```bash -# Mit JVM-Profiling ausführen -./gradlew :client:desktop-app:run -Dcom.sun.management.jmxremote - -# Speicher-Analyse -./gradlew :client:desktop-app:run -XX:+PrintGCDetails -``` - ---- - -## Zukünftige Verbesserungen - -### Empfohlene Entwicklung - -1. **Desktop-spezifische Features** - - System-Tray-Integration - - Native Benachrichtigungen - - Dateisystem-Dialoge - - Desktop-Verknüpfungen - -2. **Erweiterte Protokollierung** - - Logback-Konfiguration hinzufügen - - Strukturierte Protokollierung mit JSON-Ausgabe - - Log-Rotation und Archivierung - -3. **Konfigurationsverwaltung** - - Konfigurationsdatei-Unterstützung - - Benutzereinstellungen-Persistierung - - Umgebungsspezifische Konfigurationen - -4. **Erweiterte Tests** - - UI-Tests mit Compose-Test-Utilities - - Integrationstests mit Mock-Backend - - Leistungs-Benchmarking - -5. **Distributions-Optimierung** - - JVM-Optimierung-Flags - - Anwendungspaket-Größenreduzierung - - Auto-Update-Mechanismen - ---- - -## Mitwirken - -### Entwicklungsablauf - -1. **Einrichtung** - ```bash - # JDK 21 Installation überprüfen - java -version - - # Erstellen und testen - ./gradlew :client:desktop-app:build - ``` - -2. **Testen** - ```bash - # Tests vor Änderungen ausführen - ./gradlew :client:desktop-app:jvmTest - - # Integration mit common-ui testen - ./gradlew :client:common-ui:jvmTest :client:desktop-app:jvmTest - ``` - -3. **Code-Standards** - - Kotlin-Codierungskonventionen befolgen - - Tests für neue Desktop-spezifische Funktionalität hinzufügen - - Integration mit common-ui MVVM-Architektur beibehalten - - Konfigurationsänderungen dokumentieren - -### Pull Request-Anforderungen - -- [ ] Alle bestehenden Tests bestehen -- [ ] Neue Funktionalität beinhaltet Tests -- [ ] Integration mit common-ui verifiziert -- [ ] Dokumentation aktualisiert -- [ ] Build-Konfigurationsänderungen dokumentiert - ---- - -**Modul-Status**: ✅ Produktionsbereit -**Architektur**: ✅ MVVM-integriert -**Build-System**: ✅ Modernisiert -**Testabdeckung**: ✅ Desktop-spezifische Funktionalität -**Distribution**: ✅ Plattformübergreifend bereit - -*Zuletzt aktualisiert: 16. August 2025* diff --git a/client/desktop-app/build.gradle.kts b/client/desktop-app/build.gradle.kts deleted file mode 100644 index 0d406ec7..00000000 --- a/client/desktop-app/build.gradle.kts +++ /dev/null @@ -1,89 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.compose.multiplatform) - alias(libs.plugins.compose.compiler) -} - -kotlin { - jvm { - compilations.all { -// compileTaskProvider.configure{ -// compilerOptions { -// freeCompilerArgs.add("-Xjvm-default=all") -// freeCompilerArgs.add("-Xcontext-receivers") -// freeCompilerArgs.add("-Xno-param-assertions") -// freeCompilerArgs.add("-Xno-call-assertions") -// freeCompilerArgs.add("-Xno-receiver-assertions") -// freeCompilerArgs.add("-Xno-optimize") -// freeCompilerArgs.add("-Xno-param-assertions") -// freeCompilerArgs.add("-Xno-receiver-assertions") -// freeCompilerArgs.add("-Xno-optimize") -// freeCompilerArgs.add("-Xno-check-impl") -// freeCompilerArgs.add("-Xno-optimize") -// } - compilerOptions.configure { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21) - } - } - } - - sourceSets { - val jvmMain by getting { - dependencies { - // Project dependencies - implementation(project(":client:common-ui")) - - // Compose Desktop - implementation(compose.desktop.currentOs) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.uiTooling) - implementation(compose.runtime) - implementation(compose.foundation) - - // Serialization support - implementation(libs.kotlinx.serialization.json) - - // HTTP Client & Coroutines - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.contentNegotiation) - implementation(libs.ktor.client.serialization.kotlinx.json) - implementation(libs.kotlinx.coroutines.swing) - - // Logging - implementation(libs.kotlin.logging.jvm) - } - } - - val jvmTest by getting { - dependencies { - implementation(libs.bundles.testing.jvm) - } - } - } -} - -compose.desktop { - application { - mainClass = "at.mocode.client.desktop.MainKt" - - nativeDistributions { - targetFormats(TargetFormat.Deb, TargetFormat.Dmg, TargetFormat.Msi) - packageName = "Meldestelle Desktop" - packageVersion = "1.0.0" - - windows { - iconFile.set(project.file("src/jvmMain/resources/icon.ico")) - } - linux { - iconFile.set(project.file("src/jvmMain/resources/icon.png")) - } - macOS { - iconFile.set(project.file("src/jvmMain/resources/icon.icns")) - } - } - } -} diff --git a/client/desktop-app/src/jvmMain/kotlin/at/mocode/client/desktop/Main.kt b/client/desktop-app/src/jvmMain/kotlin/at/mocode/client/desktop/Main.kt deleted file mode 100644 index 0cca21b7..00000000 --- a/client/desktop-app/src/jvmMain/kotlin/at/mocode/client/desktop/Main.kt +++ /dev/null @@ -1,25 +0,0 @@ -package at.mocode.client.desktop - -import androidx.compose.ui.window.Window -import androidx.compose.ui.window.WindowPosition -import androidx.compose.ui.window.WindowState -import androidx.compose.ui.window.application -import androidx.compose.ui.Alignment -import androidx.compose.ui.unit.dp -import at.mocode.client.ui.App - -fun main() = application { - Window( - onCloseRequest = ::exitApplication, - title = "Meldestelle Desktop App", - state = WindowState( - position = WindowPosition(Alignment.Center), - width = 800.dp, - height = 600.dp - ) - ) { - // Use the shared App component from common-ui - // This eliminates code duplication and ensures consistent UI across platforms - App(baseUrl = System.getProperty("meldestelle.api.url", "http://localhost:8081")) - } -} diff --git a/client/desktop-app/src/jvmTest/kotlin/at/mocode/client/desktop/MainTest.kt b/client/desktop-app/src/jvmTest/kotlin/at/mocode/client/desktop/MainTest.kt deleted file mode 100644 index ccaed45d..00000000 --- a/client/desktop-app/src/jvmTest/kotlin/at/mocode/client/desktop/MainTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -package at.mocode.client.desktop - -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.Assertions.* - -class MainTest { - - @Test - fun `should have valid main class configuration`() = runTest { - // Verify that the main class exists and is properly structured - val mainClass = this::class.java.classLoader.loadClass("at.mocode.client.desktop.MainKt") - assertNotNull(mainClass, "Main class should be loadable") - - // Verify that the main method exists - val mainMethod = mainClass.getMethod("main") - assertNotNull(mainMethod, "Main method should exist") - } - - @Test - fun `should have proper package structure`() { - // Verify the package exists and is accessible - val packageName = "at.mocode.client.desktop" - assertTrue(packageName.isNotBlank(), "Package name should not be blank") - - // Verify we can access classes in this package - val currentClass = this::class.java - assertTrue(currentClass.packageName.startsWith("at.mocode.client"), - "Test should be in the correct package hierarchy") - } - - @Test - fun `should be able to instantiate system property for base URL`() { - // Test the default configuration used in Main.kt - val defaultUrl = System.getProperty("meldestelle.api.url", "http://localhost:8080") - assertNotNull(defaultUrl, "Default API URL should not be null") - assertTrue(defaultUrl.startsWith("http"), "API URL should be a valid HTTP URL") - } -} diff --git a/client/src/commonMain/composeResources/drawable/compose-multiplatform.xml b/client/src/commonMain/composeResources/drawable/compose-multiplatform.xml new file mode 100644 index 00000000..1ffc948c --- /dev/null +++ b/client/src/commonMain/composeResources/drawable/compose-multiplatform.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/src/commonMain/kotlin/at/mocode/App.kt b/client/src/commonMain/kotlin/at/mocode/App.kt new file mode 100644 index 00000000..33f5e7a8 --- /dev/null +++ b/client/src/commonMain/kotlin/at/mocode/App.kt @@ -0,0 +1,69 @@ +package at.mocode + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeContentPadding +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.ui.tooling.preview.Preview + +@Composable +@Preview +fun App() { + MaterialTheme { + var showContent by remember { mutableStateOf(false) } + Column( + modifier = Modifier + .background(MaterialTheme.colorScheme.background) + .safeContentPadding() + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = "Meldestelle", + style = MaterialTheme.typography.headlineMedium, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(top = 32.dp, bottom = 16.dp) + ) + + Button( + onClick = { showContent = !showContent }, + modifier = Modifier.padding(16.dp) + ) { + Text(if (showContent) "Platform-Info ausblenden" else "Platform-Info anzeigen") + } + + AnimatedVisibility(showContent) { + val greeting = remember { Greeting().greet() } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = greeting, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.padding(8.dp) + ) + Text( + text = "Willkommen in der Meldestelle-Anwendung!", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 8.dp) + ) + } + } + } + } +} diff --git a/client/src/commonMain/kotlin/at/mocode/Greeting.kt b/client/src/commonMain/kotlin/at/mocode/Greeting.kt new file mode 100644 index 00000000..af34bc49 --- /dev/null +++ b/client/src/commonMain/kotlin/at/mocode/Greeting.kt @@ -0,0 +1,9 @@ +package at.mocode + +class Greeting { + private val platform = getPlatform() + + fun greet(): String { + return "Hello, ${platform.name}!" + } +} \ No newline at end of file diff --git a/client/src/commonMain/kotlin/at/mocode/Platform.kt b/client/src/commonMain/kotlin/at/mocode/Platform.kt new file mode 100644 index 00000000..deb5bcd7 --- /dev/null +++ b/client/src/commonMain/kotlin/at/mocode/Platform.kt @@ -0,0 +1,7 @@ +package at.mocode + +interface Platform { + val name: String +} + +expect fun getPlatform(): Platform \ No newline at end of file diff --git a/client/src/commonTest/kotlin/at/mocode/ComposeAppCommonTest.kt b/client/src/commonTest/kotlin/at/mocode/ComposeAppCommonTest.kt new file mode 100644 index 00000000..b8a3d13d --- /dev/null +++ b/client/src/commonTest/kotlin/at/mocode/ComposeAppCommonTest.kt @@ -0,0 +1,12 @@ +package at.mocode + +import kotlin.test.Test +import kotlin.test.assertEquals + +class ComposeAppCommonTest { + + @Test + fun example() { + assertEquals(3, 1 + 2) + } +} \ No newline at end of file diff --git a/client/src/jvmMain/kotlin/at/mocode/Platform.jvm.kt b/client/src/jvmMain/kotlin/at/mocode/Platform.jvm.kt new file mode 100644 index 00000000..01f5ea8b --- /dev/null +++ b/client/src/jvmMain/kotlin/at/mocode/Platform.jvm.kt @@ -0,0 +1,7 @@ +package at.mocode + +class JVMPlatform: Platform { + override val name: String = "Java ${System.getProperty("java.version")}" +} + +actual fun getPlatform(): Platform = JVMPlatform() \ No newline at end of file diff --git a/client/src/jvmMain/kotlin/at/mocode/main.kt b/client/src/jvmMain/kotlin/at/mocode/main.kt new file mode 100644 index 00000000..f887178c --- /dev/null +++ b/client/src/jvmMain/kotlin/at/mocode/main.kt @@ -0,0 +1,13 @@ +package at.mocode + +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application + +fun main() = application { + Window( + onCloseRequest = ::exitApplication, + title = "Meldestelle", + ) { + App() + } +} \ No newline at end of file diff --git a/client/src/wasmJsMain/kotlin/at/mocode/Platform.wasmJs.kt b/client/src/wasmJsMain/kotlin/at/mocode/Platform.wasmJs.kt new file mode 100644 index 00000000..0cccfd78 --- /dev/null +++ b/client/src/wasmJsMain/kotlin/at/mocode/Platform.wasmJs.kt @@ -0,0 +1,7 @@ +package at.mocode + +class WasmPlatform: Platform { + override val name: String = "Web with Kotlin/Wasm" +} + +actual fun getPlatform(): Platform = WasmPlatform() \ No newline at end of file diff --git a/client/src/wasmJsMain/kotlin/at/mocode/main.kt b/client/src/wasmJsMain/kotlin/at/mocode/main.kt new file mode 100644 index 00000000..7d9574c6 --- /dev/null +++ b/client/src/wasmJsMain/kotlin/at/mocode/main.kt @@ -0,0 +1,12 @@ +package at.mocode + +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.ComposeViewport +import kotlinx.browser.document + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + ComposeViewport(document.body!!) { + App() + } +} \ No newline at end of file diff --git a/client/src/wasmJsMain/resources/index.html b/client/src/wasmJsMain/resources/index.html new file mode 100644 index 00000000..3e3c6fec --- /dev/null +++ b/client/src/wasmJsMain/resources/index.html @@ -0,0 +1,12 @@ + + + + + + Meldestelle + + + + + + \ No newline at end of file diff --git a/client/src/wasmJsMain/resources/styles.css b/client/src/wasmJsMain/resources/styles.css new file mode 100644 index 00000000..0549b10f --- /dev/null +++ b/client/src/wasmJsMain/resources/styles.css @@ -0,0 +1,7 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; +} \ No newline at end of file diff --git a/client/web-app/README.md b/client/web-app/README.md deleted file mode 100644 index b77502ef..00000000 --- a/client/web-app/README.md +++ /dev/null @@ -1,303 +0,0 @@ -# Meldestelle Web-App - -Eine moderne Web-Anwendung basierend auf **Compose for Web** (Compose Multiplatform) für das Meldestelle-Projekt. - -## 📋 Überblick - -Diese Web-Anwendung implementiert das Frontend für das Meldestelle-System unter Verwendung von Compose for Web. Sie folgt dem Architekturprinzip der maximalen Code-Wiederverwendung durch die Nutzung des `commonMain`-Source-Sets von Kotlin Multiplatform. - -### Technologie-Stack - -- **Frontend Framework**: Compose for Web (Compose Multiplatform 1.8.2) -- **Programmiersprache**: Kotlin/JS -- **Build-System**: Gradle 8.10 -- **HTTP-Client**: Ktor Client -- **UI-Komponenten**: Compose Material 3 (aus commonMain) -- **Bundler**: Webpack (über Kotlin/JS Plugin) -- **Container**: Nginx (Production) - -## 🏗️ Architektur - -``` -client/web-app/ -├── src/ -│ └── jsMain/ -│ ├── kotlin/at/mocode/client/web/ -│ │ └── main.kt # Entry Point -│ └── resources/ -│ └── index.html # HTML Template -├── build.gradle.kts # Build Konfiguration -└── build/ # Build Artefakte - └── dist/js/productionExecutable/ # Produktionsversion -``` - -### Design Prinzipien - -1. **Code-Wiederverwendung**: Maximale Nutzung des `client:common-ui` Moduls -2. **Compose for Web**: Deklarative UI mit `@Composable` Funktionen -3. **State Management**: Zustandsverwaltung über ViewModels im `commonMain` -4. **Plattform-Trennung**: UI-Code in `jsMain`, Logik in `commonMain` - -## 🚀 Schnellstart - -### Voraussetzungen - -- Java 21+ -- Docker und Docker Compose -- Node.js 18+ (wird automatisch im Container installiert) - -### Entwicklung starten - -#### Mit Docker (Empfohlen) - -```bash -# Web-App im Entwicklungsmodus starten -docker compose -f docker-compose.yml -f docker-compose.clients.yml up -d web-app - -# Anwendung ist verfügbar unter: -# http://localhost:3000 -``` - -#### Lokale Entwicklung - -```bash -# Abhängigkeiten installieren und Entwicklungsserver starten -./gradlew :client:web-app:jsBrowserDevelopmentRun - -# Anwendung läuft auf http://localhost:8080 -``` - -### Produktionsbuild - -```bash -# Optimierte JavaScript-Bundles erstellen -./gradlew :client:web-app:jsBrowserDistribution - -# Artefakte befinden sich in: -# client/web-app/build/dist/js/productionExecutable/ -``` - -## 🔧 Entwicklung - -### Projekt-Struktur - -```kotlin -// main.kt - Entry Point -fun main() { - renderComposable(rootElementId = "root") { - WebApp() - } -} - -@Composable -fun WebApp() { - // Verwendet die gemeinsame App-Komponente aus commonMain - App() -} -``` - -### Hot-Reload - -Die Entwicklungsumgebung unterstützt Hot-Reload: -- Änderungen an Kotlin-Code werden automatisch neu kompiliert -- Browser wird automatisch aktualisiert -- Schnelle Entwicklungszyklen durch Webpack Dev Server - -### Build-Konfiguration - -Die `build.gradle.kts` konfiguriert: - -```kotlin -kotlin { - js(IR) { - browser { - commonWebpackConfig { - outputFileName = "web-app.js" - // Webpack optimization directory - configDirectory = project.projectDir.resolve("webpack.config.d") - } - webpackTask { - mainOutputFileName = "web-app.js" - } - } - binaries.executable() - } -} -``` - -### Webpack-Optimierungen - -Das Projekt verwendet erweiterte Webpack-Optimierungen für bessere Performance: - -#### Code Splitting -- **Separate Chunks**: Bundle wird in ~60 kleinere, cacheable Dateien aufgeteilt -- **Vendor Chunks**: Große Libraries (Kotlin stdlib, Compose runtime, Coroutines) werden separat geladen -- **Lazy Loading**: Verbessertes Caching durch getrennte Vendor- und App-Code-Chunks - -#### Bundle-Größenoptimierung -- **Tree Shaking**: Entfernt ungenutzten Code -- **Minification**: Aggressive Komprimierung im Produktionsbuild -- **Scope Hoisting**: Optimiert JavaScript-Execution -- **Performance Budget**: Warnt bei zu großen Bundles (500KB pro Asset, 800KB Gesamt) - -#### Generierte Chunks (Beispiel) -``` -web-app-runtime.js 1.67 KiB (Runtime) -web-app.js 482 bytes (Main App) -web-app-compose-runtime-*.js 274 KiB (Compose Framework) -web-app-kotlin-stdlib.js 165 KiB (Kotlin Standard Library) -web-app-coroutines.js 119 KiB (Kotlinx Coroutines) -web-app-vendors-*.js 1.17 MiB (Weitere Dependencies) -``` -``` - -**Abhängigkeiten:** -- `compose.web.core` - Compose for Web Framework -- `compose.runtime` - Compose Runtime -- `project(":client:common-ui")` - Gemeinsame UI-Komponenten -- `kotlinx-coroutines-core-js` - Coroutines für Web - -## 🌐 Deployment - -### Docker Container - -Die Anwendung wird als Docker-Container deployed: - -```dockerfile -# Multi-stage Build -FROM gradle:8.10-jdk21 AS builder -# ... Build Phase - -FROM nginx:1.25-alpine AS production -# ... Production Phase -``` - -**Features:** -- Multi-stage Build für optimale Image-Größe -- Nginx als Static File Server -- Health Checks -- Security Headers -- Gzip Kompression - -### Konfiguration - -Umgebungsvariablen: -- `NODE_ENV`: Entwicklungs-/Produktionsmodus -- `API_BASE_URL`: Backend API URL -- `APP_TITLE`: Anwendungstitel -- `APP_VERSION`: Versionsnummer - -### Health Checks - -```bash -# Container Health Check -curl --fail http://localhost:3000/health - -# Antwort: {"status":"ok","service":"web-app"} -``` - -## 🔗 Integration - -### Backend-Kommunikation - -Die Web-App kommuniziert mit dem Backend über: -- **API Gateway**: `http://api-gateway:8081` -- **REST APIs**: Über Ktor Client -- **WebSocket**: Für Realtime-Updates (geplant) - -### Gemeinsame Komponenten - -Nutzt Komponenten aus `client:common-ui`: -- **ViewModels**: `PingViewModel` für Backend-Tests -- **UI-Komponenten**: `App`, `PingScreen` -- **Services**: `PingService` für HTTP-Aufrufe -- **Models**: Datenklassen und UI-States - -### Beispiel Integration - -```kotlin -@Composable -fun WebApp() { - // Verwendet die gemeinsame App-Komponente - // Diese enthält Material 3 Komponenten und ViewModels - App(baseUrl = "http://localhost:8081") -} -``` - -## 📊 Build-Artefakte - -Nach dem Build werden folgende Dateien generiert: - -``` -build/dist/js/productionExecutable/ -├── web-app.js # Hauptanwendung (minifiziert) -├── web-app.js.map # Source Maps -├── 731.js # Code Splitting Chunk -├── index.html # HTML Template -├── skiko.wasm # Compose Runtime (WebAssembly) -└── skiko.js # Compose JavaScript Runtime -``` - -## 🧪 Testing - -### Entwicklungstests - -```bash -# Backend-Konnektivität testen -# Öffne http://localhost:3000 -# Klicke "Ping Backend" Button -``` - -### Build-Validierung - -```bash -# Build ohne Ausführung testen -./gradlew :client:web-app:jsBrowserDevelopmentRun --dry-run - -# Produktionsbuild testen -./gradlew :client:web-app:jsBrowserDistribution -``` - -## 📚 Weiterführende Dokumentation - -- [Web-App Guideline](../../.junie/guidelines/web-app-guideline.md) - Architektur-Richtlinien -- [Docker README](../../README-DOCKER.md) - Container-Dokumentation -- [Compose for Web Docs](https://github.com/JetBrains/compose-multiplatform) - Offizielle Dokumentation - -## 🔍 Troubleshooting - -### Häufige Probleme - -**Problem**: `Cannot connect to backend` -```bash -# Lösung: Backend Services starten -docker-compose -f docker-compose.yml -f docker-compose.services.yml up -d -``` - -**Problem**: `Module build failed` -```bash -# Lösung: Clean Build -./gradlew :client:web-app:clean :client:web-app:jsBrowserDevelopmentRun -``` - -**Problem**: `Port 3000 already in use` -```bash -# Lösung: Port in docker-compose.clients.yml ändern -ports: - - "3001:3000" # Externer Port ändern -``` - -### Logs und Debugging - -```bash -# Container Logs anzeigen -docker logs meldestelle-web-app - -# Build Logs mit Details -./gradlew :client:web-app:jsBrowserDevelopmentRun --info --stacktrace -``` - ---- - -**Letzte Aktualisierung**: 2025-09-10 -**Version**: 1.0.0 diff --git a/client/web-app/build.gradle.kts b/client/web-app/build.gradle.kts deleted file mode 100644 index bdf878b6..00000000 --- a/client/web-app/build.gradle.kts +++ /dev/null @@ -1,62 +0,0 @@ -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") - id("org.jetbrains.kotlin.plugin.compose") -} - -group = "at.mocode.client.web" -version = "1.0.0" - -kotlin { - js(IR) { - browser { - commonWebpackConfig { -// devServer = devServer?.copy( -// port = 8080, -// static = mutableListOf("src/jsMain/resources") -// ) - devServer = devServer?.copy( - port = 8080, - static = mutableListOf(project.projectDir.resolve("src/jsMain/resources").path) - ) - - - // Webpack optimization settings - configDirectory = project.projectDir.resolve("webpack.config.d") - } - webpackTask { - args.add("--devtool=source-map") - } - runTask { - args.add("--devtool=source-map") - } - - // Add npm dependencies for webpack plugins - useCommonJs() - } - binaries.executable() - } - - sourceSets { - val jsMain by getting { - dependencies { - // Compose for Web - implementation(compose.html.core) - implementation(compose.runtime) - - // Common UI module (contains ViewModels and shared components) - implementation(project(":client:common-ui")) - - // Coroutines for web - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.7.3") - - } - } - - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } -} diff --git a/client/web-app/src/jsMain/kotlin/at/mocode/client/web/main.kt b/client/web-app/src/jsMain/kotlin/at/mocode/client/web/main.kt deleted file mode 100644 index e1c271c0..00000000 --- a/client/web-app/src/jsMain/kotlin/at/mocode/client/web/main.kt +++ /dev/null @@ -1,22 +0,0 @@ -package at.mocode.client.web - -import androidx.compose.runtime.Composable -import at.mocode.client.ui.App -import org.jetbrains.compose.web.renderComposable - -/** - * Entry point for the Compose for Web application. - * Follows the web-app guideline by using the shared App component from commonMain. - */ -fun main() { - renderComposable(rootElementId = "root") { - WebApp() - } -} - -@Composable -fun WebApp() { - // Use the shared App component from commonMain - // This follows the guideline principle of maximum code reuse - App() -} diff --git a/client/web-app/src/jsMain/resources/index.html b/client/web-app/src/jsMain/resources/index.html deleted file mode 100644 index 43f683b0..00000000 --- a/client/web-app/src/jsMain/resources/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Meldestelle - - - - -
- - - diff --git a/client/web-app/webpack.config.d/compression.js b/client/web-app/webpack.config.d/compression.js deleted file mode 100644 index c0d1a2ca..00000000 --- a/client/web-app/webpack.config.d/compression.js +++ /dev/null @@ -1,37 +0,0 @@ -// Compression and module resolution optimizations - -// Enhanced module resolution to reduce bundle size -config.resolve = config.resolve || {}; -config.resolve.alias = config.resolve.alias || {}; - -// Resolve optimizations -config.resolve.modules = ['node_modules']; -config.resolve.extensions = ['.js', '.json', '.wasm']; - -// Output optimizations -config.output = config.output || {}; -config.output.pathinfo = false; // Disable path info in production for smaller bundles - -// Module concatenation for better tree shaking -config.optimization = config.optimization || {}; -config.optimization.concatenateModules = true; - -// Enable scope hoisting for better performance -config.optimization.moduleIds = 'deterministic'; -config.optimization.chunkIds = 'deterministic'; - -// Webpack production mode optimizations -if (config.mode === 'production') { - // Disable development features - config.devtool = false; // Disable source maps in production for smaller size - - // Additional optimization flags - config.optimization.flagIncludedChunks = true; - config.optimization.mergeDuplicateChunks = true; - config.optimization.removeAvailableModules = true; - config.optimization.removeEmptyChunks = true; - - // Aggressive dead code elimination - config.optimization.innerGraph = true; - config.optimization.mangleExports = true; -} diff --git a/client/web-app/webpack.config.d/csp.js b/client/web-app/webpack.config.d/csp.js deleted file mode 100644 index 5499fd68..00000000 --- a/client/web-app/webpack.config.d/csp.js +++ /dev/null @@ -1,5 +0,0 @@ -// Content Security Policy configuration for development -config.devServer = config.devServer || {}; -config.devServer.headers = config.devServer.headers || {}; -config.devServer.headers['Content-Security-Policy'] = - "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src *; img-src 'self' data:; font-src 'self' data:; frame-src 'self';"; diff --git a/client/web-app/webpack.config.d/csp.js.disabled b/client/web-app/webpack.config.d/csp.js.disabled deleted file mode 100644 index da1ce6df..00000000 --- a/client/web-app/webpack.config.d/csp.js.disabled +++ /dev/null @@ -1,14 +0,0 @@ -// Content Security Policy configuration for development -// More relaxed CSP suitable for development environment -config.devServer = config.devServer || {}; -config.devServer.headers = config.devServer.headers || {}; -config.devServer.headers['Content-Security-Policy'] = - "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; " + - "script-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; " + - "style-src 'self' 'unsafe-inline' data: blob:; " + - "img-src 'self' data: blob: http: https:; " + - "font-src 'self' data: blob: http: https:; " + - "connect-src 'self' ws: wss: http: https:; " + - "frame-src 'self' data: blob:; " + - "object-src 'none'; " + - "base-uri 'self';"; diff --git a/client/web-app/webpack.config.d/devserver.js b/client/web-app/webpack.config.d/devserver.js deleted file mode 100644 index f8f10a99..00000000 --- a/client/web-app/webpack.config.d/devserver.js +++ /dev/null @@ -1,3 +0,0 @@ -// Development server configuration -config.devServer = config.devServer || {}; -config.devServer.historyApiFallback = true; diff --git a/client/web-app/webpack.config.d/optimization.js b/client/web-app/webpack.config.d/optimization.js deleted file mode 100644 index b3e9ea80..00000000 --- a/client/web-app/webpack.config.d/optimization.js +++ /dev/null @@ -1,104 +0,0 @@ -const path = require('path'); - -// Webpack optimization configuration for production builds -config.optimization = { - // Enable tree shaking and dead code elimination - usedExports: true, - sideEffects: false, - - // Code splitting configuration optimized for Kotlin/JS - splitChunks: { - chunks: 'all', - minSize: 30000, - maxSize: 300000, - maxInitialRequests: 8, // Allow more initial requests for better caching - maxAsyncRequests: 15, - cacheGroups: { - // Kotlin standard library - separate chunk - kotlinStdlib: { - test: /kotlin-kotlin-stdlib/, - name: 'kotlin-stdlib', - chunks: 'all', - enforce: true, - priority: 30, - reuseExistingChunk: true, - }, - // Coroutines - separate chunk - coroutines: { - test: /kotlinx-coroutines/, - name: 'coroutines', - chunks: 'all', - enforce: true, - priority: 25, - reuseExistingChunk: true, - }, - // Compose runtime - separate chunk - composeRuntime: { - test: /compose.*runtime/, - name: 'compose-runtime', - chunks: 'all', - enforce: true, - priority: 20, - reuseExistingChunk: true, - }, - // Large vendor libraries - largeVendors: { - test: /ktor|androidx-collection|kotlinx-serialization/, - name: 'large-vendors', - chunks: 'all', - enforce: true, - priority: 15, - reuseExistingChunk: true, - }, - // Common vendors - vendors: { - test: /[\\/]kotlin[\\/]/, - name: 'vendors', - chunks: 'all', - priority: 10, - reuseExistingChunk: true, - }, - // Application code - default: { - minChunks: 2, - priority: -10, - reuseExistingChunk: true, - }, - }, - }, - - // Minimize bundle size - minimize: true, - minimizer: [ - // Use default TerserPlugin for JS minification - '...', - ], - - // Runtime chunk optimization - runtimeChunk: { - name: 'runtime', - }, -}; - -// Performance budget adjusted for Kotlin/JS applications -// Note: Kotlin/JS apps require all dependencies loaded initially, so larger budgets are realistic -config.performance = { - maxAssetSize: 1000000, // 1MB per asset (realistic for large Kotlin/Compose libs) - maxEntrypointSize: 7000000, // 7MB total entry point (realistic for Kotlin/JS + Compose) - hints: 'warning', - assetFilter: function(assetFilename) { - // Only check JS files for performance - return assetFilename.endsWith('.js'); - }, -}; - -// Production-specific optimizations -if (config.mode === 'production') { - // Additional compression and optimizations - config.optimization.concatenateModules = true; - config.optimization.providedExports = true; - - // More aggressive code splitting for production - config.optimization.splitChunks.maxInitialRequests = 10; - config.optimization.splitChunks.maxAsyncRequests = 10; -} diff --git a/docker-compose.clients.yml b/docker-compose.clients.yml index 2ac23828..f0a33d9f 100644 --- a/docker-compose.clients.yml +++ b/docker-compose.clients.yml @@ -16,8 +16,8 @@ services: context: . dockerfile: dockerfiles/clients/web-app/Dockerfile args: - CLIENT_PATH: client/web-app - CLIENT_MODULE: client:web-app + CLIENT_PATH: client + CLIENT_MODULE: client CLIENT_NAME: meldestelle-web-app container_name: meldestelle-web-app environment: @@ -59,7 +59,7 @@ services: environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-dev} SERVER_PORT: ${AUTH_SERVICE_PORT:-8087} - KEYCLOAK_SERVER_URL: http://keycloak:8080 + KEYCLOAK_SERVER_URL: http://keycloak:8081 KEYCLOAK_REALM: meldestelle KEYCLOAK_CLIENT_ID: meldestelle-auth-service KEYCLOAK_CLIENT_SECRET: ${KEYCLOAK_CLIENT_SECRET:-auth-service-secret} diff --git a/docker-compose.yml b/docker-compose.yml index d73fe8b8..1717ca20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,7 +57,7 @@ services: # Authentifizierung # =================================================================== keycloak: - image: quay.io/keycloak/keycloak:23.0 + image: quay.io/keycloak/keycloak:25.0.6 container_name: meldestelle-keycloak environment: KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-admin} diff --git a/dockerfiles/clients/web-app/Dockerfile b/dockerfiles/clients/web-app/Dockerfile index a0c44d53..f559a6bc 100644 --- a/dockerfiles/clients/web-app/Dockerfile +++ b/dockerfiles/clients/web-app/Dockerfile @@ -5,23 +5,22 @@ # Arguments (can be overridden during build) # =================================================================== ARG JVM_VERSION=21 -ARG GRADLE_VERSION=8.10 -ARG NODE_VERSION=18 +ARG GRADLE_VERSION=9.0 ARG NGINX_VERSION=1.25-alpine # =================================================================== # Build Arguments for Client Configuration # =================================================================== -ARG CLIENT_PATH=client/web-app -ARG CLIENT_MODULE=client:web-app +ARG CLIENT_PATH=client +ARG CLIENT_MODULE=client # =================================================================== # Build Stage - Kotlin/JS (Compose for Web) Compilation # =================================================================== FROM gradle:${GRADLE_VERSION}-jdk${JVM_VERSION} AS builder -ARG CLIENT_PATH=client/web-app -ARG CLIENT_MODULE=client:web-app +ARG CLIENT_PATH=client +ARG CLIENT_MODULE=client # Set working directory WORKDIR /build @@ -53,39 +52,34 @@ COPY client/ client/ COPY temp/ temp/ COPY docs/ docs/ -# Install Node.js for JavaScript toolchain -RUN apt-get update && \ - apt-get install -y curl && \ - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \ - apt-get install -y nodejs - # Make Gradle wrapper executable RUN chmod +x gradlew # Build client application -# For Compose for Web projects, jsBrowserDistribution produces static assets +# For Compose Multiplatform Web (WASM), wasmJsBrowserDistribution produces static assets RUN echo "Building ${CLIENT_MODULE} module..." && \ - ./gradlew ${CLIENT_MODULE}:jsBrowserDistribution --no-daemon --stacktrace --info + ./gradlew ${CLIENT_MODULE}:wasmJsBrowserDistribution --no-daemon --stacktrace --info # =================================================================== # Production Stage - Nginx Static File Server # =================================================================== FROM nginx:${NGINX_VERSION} AS production -ARG CLIENT_PATH=client/web-app +ARG CLIENT_PATH=client # Set production labels LABEL service="web-app" \ environment="production" \ description="Meldestelle Compose for Web Application" -# Create nginx user if not exists and set permissions -RUN addgroup -g 1001 -S nginx-group && \ +# Install curl for health checks and create nginx user +RUN apk add --no-cache curl && \ + addgroup -g 1001 -S nginx-group && \ adduser -S -D -H -u 1001 -h /var/cache/nginx -s /sbin/nologin -G nginx-group -g nginx nginx-user -# Copy built distribution files from builder stage -COPY --from=builder /build/${CLIENT_PATH}/build/dist/js/productionExecutable/ /usr/share/nginx/html/ -COPY --from=builder /build/${CLIENT_PATH}/src/jsMain/resources/ /usr/share/nginx/html/ +# Copy built distribution files from builder stage (WASM build output) +COPY --from=builder /build/${CLIENT_PATH}/build/dist/wasmJs/productionExecutable/ /usr/share/nginx/html/ +COPY --from=builder /build/${CLIENT_PATH}/src/wasmJsMain/resources/ /usr/share/nginx/html/ # Copy custom nginx configuration COPY dockerfiles/clients/web-app/nginx.conf /etc/nginx/nginx.conf diff --git a/dockerfiles/clients/web-app/nginx.conf b/dockerfiles/clients/web-app/nginx.conf index 33b455b5..3a0c88e7 100644 --- a/dockerfiles/clients/web-app/nginx.conf +++ b/dockerfiles/clients/web-app/nginx.conf @@ -43,6 +43,8 @@ http { add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; server { listen 3000; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d9363fc4..14391b07 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,8 +21,6 @@ ktor = "3.2.3" # --- Compose UI --- composeMultiplatform = "1.8.2" -# --- Kobweb --- -kobweb = "0.23.2" # --- Database & Persistence --- exposed = "0.61.0" @@ -181,12 +179,6 @@ compose-html-core-js = { module = "org.jetbrains.compose.html:html-core-js", ver compose-html-svg-js = { module = "org.jetbrains.compose.html:html-svg-js", version.ref = "composeMultiplatform"} compose-desktop-currentOs = { module = "org.jetbrains.compose.desktop:desktop", version.ref = "composeMultiplatform" } -# --- Kobweb --- -kobweb-core = { module = "com.varabyte.kobweb:kobweb-core", version.ref = "kobweb" } -kobweb-silk-core = { module = "com.varabyte.kobweb:kobweb-silk", version.ref = "kobweb" } -kobweb-silk-icons-fa = { module = "com.varabyte.kobweb:kobweb-silk-icons-fa", version.ref = "kobweb" } -kobweb-api = { module = "com.varabyte.kobweb:kobweb-api", version.ref = "kobweb" } -kobwebx-markdown = { module = "com.varabyte.kobwebx:kobwebx-markdown", version.ref = "kobweb" } # --- Testing --- junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiter" } @@ -295,5 +287,3 @@ compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "composeMu compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" } spring-dependencyManagement = { id = "io.spring.dependency-management", version.ref = "springDependencyManagement" } -kobweb-application = { id = "com.varabyte.kobweb.application", version.ref = "kobweb" } -kobwebx-markdown = { id = "com.varabyte.kobwebx.markdown", version.ref = "kobweb" } diff --git a/karma.config.d/chrome.js b/karma.config.d/chrome.js deleted file mode 100644 index 0633c5b2..00000000 --- a/karma.config.d/chrome.js +++ /dev/null @@ -1,67 +0,0 @@ -// Karma configuration for Chrome browser testing -// This file fixes Chrome/Chromium path issues and permission errors - -config.set({ - // Use Chrome with custom configuration to avoid snap permission issues - browsers: ['ChromeHeadlessNoSandbox'], - - // Custom browser configuration - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: 'ChromeHeadless', - flags: [ - '--no-sandbox', - '--disable-web-security', - '--disable-features=VizDisplayCompositor', - '--disable-dev-shm-usage', - '--disable-gpu', - '--remote-debugging-port=9222' - ] - }, - ChromeHeadlessCI: { - base: 'ChromeHeadless', - flags: [ - '--no-sandbox', - '--disable-web-security', - '--disable-features=VizDisplayCompositor', - '--disable-dev-shm-usage', - '--disable-gpu', - '--headless', - '--disable-extensions', - '--disable-plugins', - '--disable-images', - '--disable-javascript', - '--disable-default-apps', - '--disable-translate', - '--disable-background-timer-throttling', - '--disable-renderer-backgrounding', - '--disable-device-discovery-notifications' - ] - } - }, - - // Browser detection and fallback - detectBrowsers: { - enabled: false // Disable auto-detection to use our custom config - }, - - // Timeout configuration to handle slower CI environments - browserNoActivityTimeout: 60000, - browserDisconnectTimeout: 10000, - browserDisconnectTolerance: 3, - - // Process configuration - processKillTimeout: 5000, - captureTimeout: 60000 -}); - -// Try to use system Chrome if snap Chromium fails -if (process.env.CI || process.env.GITHUB_ACTIONS) { - // Use CI-optimized Chrome configuration in CI environments - config.browsers = ['ChromeHeadlessCI']; -} else { - // Use standard no-sandbox configuration for local development - config.browsers = ['ChromeHeadlessNoSandbox']; -} - -console.log('Chrome browser configuration applied for testing'); diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 0798b0b8..f30f75d0 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -25,9 +25,9 @@ wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" "@jridgewell/gen-mapping@^0.3.5": - version "0.3.12" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz#2234ce26c62889f03db3d7fea43c1932ab3e927b" - integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/trace-mapping" "^0.3.24" @@ -38,22 +38,22 @@ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/source-map@^0.3.3": - version "0.3.10" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.10.tgz#a35714446a2e84503ff9bfe66f1d1d4846f2075b" - integrity sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q== + version "0.3.11" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== dependencies: "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz#7358043433b2e5da569aa02cbc4c121da3af27d7" - integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.29" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz#a58d31eaadaf92c6695680b2e1d464a9b8fbf7fc" - integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== + version "0.3.30" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz#4a76c4daeee5df09f5d3940e087442fb36ce2b99" + integrity sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -63,11 +63,6 @@ resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" - integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== - "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -78,36 +73,6 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== -"@types/body-parser@*": - version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" - integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.13" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" - integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" - integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - "@types/cors@^2.8.12": version "2.8.19" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" @@ -136,134 +101,18 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz#2fa94879c9d46b11a5df4c74ac75befd6b283de6" - integrity sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express-serve-static-core@^4.17.33": - version "4.19.6" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" - integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@*": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.3.tgz#6c4bc6acddc2e2a587142e1d8be0bce20757e956" - integrity sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^5.0.0" - "@types/serve-static" "*" - -"@types/express@^4.17.13": - version "4.17.23" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.23.tgz#35af3193c640bfd4d7fe77191cd0ed411a433bef" - integrity sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/http-errors@*": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" - integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== - -"@types/http-proxy@^1.17.8": - version "1.17.16" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.16.tgz#dee360707b35b3cc85afcde89ffeebff7d7f9240" - integrity sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w== - dependencies: - "@types/node" "*" - "@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - -"@types/node-forge@^1.3.0": - version "1.3.14" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b" - integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== - dependencies: - "@types/node" "*" - "@types/node@*", "@types/node@>=10.0.0": - version "24.2.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.2.1.tgz#83e41543f0a518e006594bb394e2cd961de56727" - integrity sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ== + version "24.3.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.3.1.tgz#b0a3fb2afed0ef98e8d7f06d46ef6349047709f3" + integrity sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g== dependencies: undici-types "~7.10.0" -"@types/qs@*": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" - integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/send@*": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.5.tgz#d991d4f2b16f2b1ef497131f00a9114290791e74" - integrity sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-index@^1.9.1": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" - integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.8" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.8.tgz#8180c3fbe4a70e8f00b9f70b9ba7f08f35987877" - integrity sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "*" - -"@types/sockjs@^0.3.33": - version "0.3.36" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" - integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.5": - version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" - integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== - dependencies: - "@types/node" "*" - "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" @@ -410,7 +259,7 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -accepts@~1.3.4, accepts@~1.3.8: +accepts@~1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -423,7 +272,7 @@ acorn-import-phases@^1.0.3: resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== -acorn@^8.14.0, acorn@^8.15.0: +acorn@^8.15.0: version "8.15.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -452,20 +301,15 @@ ajv@^8.0.0, ajv@^8.9.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.0.tgz#2f302e7550431b1b7762705fffb52cf1ffa20447" - integrity sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg== + version "6.2.2" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" @@ -475,9 +319,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: color-convert "^2.0.1" ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + version "6.2.3" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== anymatch@~3.1.2: version "3.1.3" @@ -492,11 +336,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -507,17 +346,12 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -body-parser@1.20.3, body-parser@^1.19.0: +body-parser@^1.19.0: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== @@ -535,14 +369,6 @@ body-parser@1.20.3, body-parser@^1.19.0: type-is "~1.6.18" unpipe "1.0.0" -bonjour-service@^1.0.11: - version "1.3.0" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" - integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== - dependencies: - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - brace-expansion@^1.1.7: version "1.1.12" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" @@ -558,7 +384,7 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@^3.0.3, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== @@ -571,12 +397,12 @@ browser-stdout@^1.3.1: integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== browserslist@^4.24.0: - version "4.25.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.3.tgz#9167c9cbb40473f15f75f85189290678b99b16c5" - integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ== + version "4.25.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.4.tgz#ebdd0e1d1cf3911834bab3a6cd7b917d9babf5af" + integrity sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg== dependencies: - caniuse-lite "^1.0.30001735" - electron-to-chromium "^1.5.204" + caniuse-lite "^1.0.30001737" + electron-to-chromium "^1.5.211" node-releases "^2.0.19" update-browserslist-db "^1.1.3" @@ -611,10 +437,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001735: - version "1.0.30001737" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz#8292bb7591932ff09e9a765f12fdf5629a241ccc" - integrity sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw== +caniuse-lite@^1.0.30001737: + version "1.0.30001741" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz#67fb92953edc536442f3c9da74320774aa523143" + integrity sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw== chalk@^4.1.0: version "4.1.2" @@ -624,7 +450,7 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^3.5.1, chokidar@^3.5.3: +chokidar@^3.5.1: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -690,7 +516,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^2.0.10, colorette@^2.0.14: +colorette@^2.0.14: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -705,36 +531,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -compressible@~2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.8.1" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" - integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== - dependencies: - bytes "3.1.2" - compressible "~2.0.18" - debug "2.6.9" - negotiator "~0.6.4" - on-headers "~1.1.0" - safe-buffer "5.2.1" - vary "~1.1.2" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -745,38 +546,16 @@ connect@^3.7.0: parseurl "~1.3.3" utils-merge "1.0.1" -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: +content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== - cookie@~0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -811,7 +590,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.3.4, debug@^4.3.5: +debug@^4.3.4, debug@^4.3.5: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -830,38 +609,16 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -872,13 +629,6 @@ diff@^7.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== -dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - dom-serialize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -908,10 +658,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.204: - version "1.5.211" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.211.tgz#749317bf9cf894c06f67980940cf8074e5eb08ca" - integrity sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw== +electron-to-chromium@^1.5.211: + version "1.5.215" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.215.tgz#200c8d69b1270af6126837b6b1f95077c3a347b1" + integrity sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ== emoji-regex@^8.0.0: version "8.0.0" @@ -928,11 +678,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - engine.io-parser@~5.2.1: version "5.2.3" resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f" @@ -1038,11 +783,6 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -1053,58 +793,6 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.21.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" - integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.12" - proxy-addr "~2.0.7" - qs "6.13.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1116,22 +804,15 @@ fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-uri@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" - integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -1152,19 +833,6 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -1209,16 +877,6 @@ format-util@^1.0.5: resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -1228,11 +886,6 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-monkey@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.1.0.tgz#632aa15a20e71828ed56b24303363fb1414e5997" - integrity sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1277,11 +930,6 @@ get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1328,11 +976,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -1362,26 +1005,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" - integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -1393,32 +1016,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075" - integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== - -http-proxy-middleware@^2.0.3: - version "2.0.9" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" - integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" @@ -1428,11 +1025,6 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1463,31 +1055,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - interpret@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1502,11 +1079,6 @@ is-core-module@^2.16.0: dependencies: hasown "^2.0.2" -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1534,11 +1106,6 @@ is-plain-obj@^2.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -1556,28 +1123,11 @@ is-regex@^1.2.1: has-tostringtag "^1.0.2" hasown "^2.0.2" -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" @@ -1707,14 +1257,6 @@ kotlin-web-helpers@2.1.0: dependencies: format-util "^1.0.5" -launch-editor@^2.6.0: - version "2.11.1" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.11.1.tgz#61a0b7314a42fd84a6cbb564573d9e9ffcf3d72b" - integrity sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg== - dependencies: - picocolors "^1.1.1" - shell-quote "^1.8.3" - loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -1773,73 +1315,28 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2: - version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1902,56 +1399,31 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.3, ms@^2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - node-releases@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" - integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== + version "2.0.20" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.20.tgz#e26bb79dbdd1e64a146df389c699014c611cbc27" + integrity sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -1962,11 +1434,6 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -1981,11 +1448,6 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" - integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1993,22 +1455,6 @@ once@^1.3.0: dependencies: wrappy "1" -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2037,14 +1483,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2055,7 +1493,7 @@ package-json-from-dist@^1.0.0: resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -2070,7 +1508,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -2088,17 +1526,12 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -2110,19 +1543,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -2147,7 +1567,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -2162,28 +1582,6 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@^4.0.1: version "4.1.2" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" @@ -2239,11 +1637,6 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - rfdc@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" @@ -2256,16 +1649,11 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex-test@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" @@ -2280,7 +1668,7 @@ safe-regex-test@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.2: +schema-utils@^4.3.0, schema-utils@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== @@ -2290,38 +1678,6 @@ schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.2: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" - integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== - dependencies: - "@types/node-forge" "^1.3.0" - node-forge "^1" - -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" @@ -2329,34 +1685,6 @@ serialize-javascript@^6.0.2: dependencies: randombytes "^2.1.0" -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.19.0" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -2381,11 +1709,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" - integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== - side-channel-list@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" @@ -2426,11 +1749,6 @@ side-channel@^1.0.6: side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" @@ -2465,15 +1783,6 @@ socket.io@^4.7.2: socket.io-adapter "~2.5.2" socket.io-parser "~4.2.4" -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - source-map-js@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" @@ -2500,35 +1809,12 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"statuses@>= 1.4.0 < 2", statuses@~1.5.0: +statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== @@ -2560,20 +1846,6 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2582,17 +1854,12 @@ string_decoder@~1.1.1: ansi-regex "^5.0.1" strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + version "7.1.2" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" + integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== dependencies: ansi-regex "^6.0.1" -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -2618,9 +1885,9 @@ supports-preserve-symlinks-flag@^1.0.0: integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tapable@^2.1.1, tapable@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.2.tgz#ab4984340d30cb9989a490032f086dbb8b56d872" - integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg== + version "2.2.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.3.tgz#4b67b635b2d97578a06a2713d2f04800c237e99b" + integrity sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg== terser-webpack-plugin@^5.3.11: version "5.3.14" @@ -2634,20 +1901,15 @@ terser-webpack-plugin@^5.3.11: terser "^5.31.1" terser@^5.31.1: - version "5.43.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.43.1.tgz#88387f4f9794ff1a29e7ad61fb2932e25b4fdb6d" - integrity sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg== + version "5.44.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.0.tgz#ebefb8e5b8579d93111bfdfc39d2cf63879f4a82" + integrity sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w== dependencies: "@jridgewell/source-map" "^0.3.3" - acorn "^8.14.0" + acorn "^8.15.0" commander "^2.20.0" source-map-support "~0.5.20" -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - tmp@^0.2.1: version "0.2.5" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" @@ -2674,9 +1936,9 @@ type-is@~1.6.18: mime-types "~2.1.24" ua-parser-js@^0.7.30: - version "0.7.40" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.40.tgz#c87d83b7bb25822ecfa6397a0da5903934ea1562" - integrity sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ== + version "0.7.41" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.41.tgz#9f6dee58c389e8afababa62a4a2dc22edb69a452" + integrity sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg== undici-types@~7.10.0: version "7.10.0" @@ -2701,22 +1963,12 @@ update-browserslist-db@^1.1.3: escalade "^3.2.0" picocolors "^1.1.1" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@^1, vary@~1.1.2: +vary@^1: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -2734,13 +1986,6 @@ watchpack@^2.4.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - webpack-cli@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" @@ -2760,53 +2005,6 @@ webpack-cli@6.0.1: rechoir "^0.8.0" webpack-merge "^6.0.1" -webpack-dev-middleware@^5.3.4: - version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.15.2: - version "4.15.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" - integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.4" - ws "^8.13.0" - webpack-merge@^4.1.5: version "4.2.2" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" @@ -2859,20 +2057,6 @@ webpack@5.100.2: watchpack "^2.4.1" webpack-sources "^3.3.3" -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -2893,9 +2077,9 @@ wildcard@^2.0.1: integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== workerpool@^9.2.0: - version "9.3.3" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-9.3.3.tgz#e75281fe62e851afb21cdeef8fa85f6a62ec3583" - integrity sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw== + version "9.3.4" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-9.3.4.tgz#f6c92395b2141afd78e2a889e80cb338fe9fca41" + integrity sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" @@ -2920,16 +2104,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@8.18.0: - version "8.18.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== - -ws@^8.13.0: - version "8.18.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== - ws@~8.17.1: version "8.17.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" diff --git a/settings.gradle.kts b/settings.gradle.kts index b20017e7..039ebdbb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,7 +17,7 @@ pluginManagement { } } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } dependencyResolutionManagement { @@ -58,17 +58,13 @@ include(":infrastructure:monitoring:monitoring-server") include(":temp:ping-service") // Client modules -include(":client:common-ui") -// kobweb-app is now an independent build with its own Gradle wrapper (8.14.2). See client/kobweb-app/README.md for details. -//include(":client:kobweb-app") -include(":client:web-app") -include(":client:desktop-app") +include(":client") // Documentation module include(":docs") /* -// Temporär deaktivierte Fach-Module +// Business modules (temporarily disabled - require multiplatform configuration updates) // Members modules include(":members:members-domain") include(":members:members-application") @@ -97,5 +93,5 @@ include(":masterdata:masterdata-infrastructure") include(":masterdata:masterdata-api") include(":masterdata:masterdata-service") -// Legacy modules have been removed after successful migration - */ +// Note: These modules need multiplatform configuration updates to work with current KMP/WASM setup +*/