diff --git a/packages/fs/package-lock.json b/packages/fs/package-lock.json
index 075b5291..a94de810 100644
--- a/packages/fs/package-lock.json
+++ b/packages/fs/package-lock.json
@@ -178,6 +178,7 @@
"integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~6.20.0"
}
@@ -934,6 +935,7 @@
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.editorconfig b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.editorconfig
deleted file mode 100644
index ebe51d3b..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.editorconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# EditorConfig is awesome: https://EditorConfig.org
-
-# top-most EditorConfig file
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = false
-insert_final_newline = false
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.gitignore b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.gitignore
deleted file mode 100644
index b2482031..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/.gitignore
+++ /dev/null
@@ -1,19 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/caches
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
-/.idea/navEditor.xml
-/.idea/assetWizardSettings.xml
-.DS_Store
-build
-/captures
-.externalNativeBuild
-.cxx
-local.properties
-key.properties
-
-/.tauri
-/tauri.settings.gradle
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/.gitignore b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/.gitignore
deleted file mode 100644
index 4008dd74..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/src/main/java/com/tauri/api/generated
-/src/main/jniLibs/**/*.so
-/src/main/assets/tauri.conf.json
-/tauri.build.gradle.kts
-/proguard-tauri.pro
-/tauri.properties
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/build.gradle.kts b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/build.gradle.kts
deleted file mode 100644
index f7047ca0..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/build.gradle.kts
+++ /dev/null
@@ -1,69 +0,0 @@
-import java.util.Properties
-
-plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
- id("rust")
-}
-
-val tauriProperties = Properties().apply {
- val propFile = file("tauri.properties")
- if (propFile.exists()) {
- propFile.inputStream().use { load(it) }
- }
-}
-
-android {
- compileSdk = 34
- namespace = "com.tauri.api"
- defaultConfig {
- manifestPlaceholders["usesCleartextTraffic"] = "false"
- applicationId = "com.tauri.api"
- minSdk = 24
- targetSdk = 34
- versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
- versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
- }
- buildTypes {
- getByName("debug") {
- manifestPlaceholders["usesCleartextTraffic"] = "true"
- isDebuggable = true
- isJniDebuggable = true
- isMinifyEnabled = false
- packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
- jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
- jniLibs.keepDebugSymbols.add("*/x86/*.so")
- jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
- }
- }
- getByName("release") {
- isMinifyEnabled = true
- proguardFiles(
- *fileTree(".") { include("**/*.pro") }
- .plus(getDefaultProguardFile("proguard-android-optimize.txt"))
- .toList().toTypedArray()
- )
- }
- }
- kotlinOptions {
- jvmTarget = "1.8"
- }
- buildFeatures {
- buildConfig = true
- }
-}
-
-rust {
- rootDirRel = "../../../"
-}
-
-dependencies {
- implementation("androidx.webkit:webkit:1.6.1")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.8.0")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.4")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
-}
-
-apply(from = "tauri.build.gradle.kts")
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/proguard-rules.pro b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/proguard-rules.pro
deleted file mode 100644
index 481bb434..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/AndroidManifest.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 8ebe7c4b..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/java/com/tauri/api/MainActivity.kt b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/java/com/tauri/api/MainActivity.kt
deleted file mode 100644
index 0a05f42b..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/java/com/tauri/api/MainActivity.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.tauri.api
-
-class MainActivity : TauriActivity()
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 2b068d11..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable/ic_launcher_background.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 07d5da9c..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/layout/activity_main.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 4fc24441..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 28f1aa11..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index 85d0c88a..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 28f1aa11..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 73e48dbf..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index 13dd2147..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index 73e48dbf..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 1d98044f..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
deleted file mode 100644
index a888b336..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 1d98044f..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 08183246..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index a2a838e7..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index 08183246..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index b18bceb6..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 3f8a57f3..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index b18bceb6..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values-night/themes.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values-night/themes.xml
deleted file mode 100644
index f0378527..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/colors.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/colors.xml
deleted file mode 100644
index f8c6127d..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
- #FF000000
- #FFFFFFFF
-
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/strings.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/strings.xml
deleted file mode 100644
index 6f4305e0..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
- Tauri API
- Tauri API
-
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/themes.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/themes.xml
deleted file mode 100644
index f0378527..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/xml/file_paths.xml b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/xml/file_paths.xml
deleted file mode 100644
index 782d63b9..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/app/src/main/res/xml/file_paths.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/build.gradle.kts b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/build.gradle.kts
deleted file mode 100644
index c5ef452a..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/build.gradle.kts
+++ /dev/null
@@ -1,22 +0,0 @@
-buildscript {
- repositories {
- google()
- mavenCentral()
- }
- dependencies {
- classpath("com.android.tools.build:gradle:8.5.1")
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25")
- }
-}
-
-allprojects {
- repositories {
- google()
- mavenCentral()
- }
-}
-
-tasks.register("clean").configure {
- delete("build")
-}
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/build.gradle.kts b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/build.gradle.kts
deleted file mode 100644
index 39e90b05..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/build.gradle.kts
+++ /dev/null
@@ -1,23 +0,0 @@
-plugins {
- `kotlin-dsl`
-}
-
-gradlePlugin {
- plugins {
- create("pluginsForCoolKids") {
- id = "rust"
- implementationClass = "RustPlugin"
- }
- }
-}
-
-repositories {
- google()
- mavenCentral()
-}
-
-dependencies {
- compileOnly(gradleApi())
- implementation("com.android.tools.build:gradle:8.5.1")
-}
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/BuildTask.kt b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/BuildTask.kt
deleted file mode 100644
index f9874825..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/BuildTask.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-import java.io.File
-import org.apache.tools.ant.taskdefs.condition.Os
-import org.gradle.api.DefaultTask
-import org.gradle.api.GradleException
-import org.gradle.api.logging.LogLevel
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.TaskAction
-
-open class BuildTask : DefaultTask() {
- @Input
- var rootDirRel: String? = null
- @Input
- var target: String? = null
- @Input
- var release: Boolean? = null
-
- @TaskAction
- fun assemble() {
- val executable = """pnpm""";
- try {
- runTauriCli(executable)
- } catch (e: Exception) {
- if (Os.isFamily(Os.FAMILY_WINDOWS)) {
- runTauriCli("$executable.cmd")
- } else {
- throw e;
- }
- }
- }
-
- fun runTauriCli(executable: String) {
- val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null")
- val target = target ?: throw GradleException("target cannot be null")
- val release = release ?: throw GradleException("release cannot be null")
- val args = listOf("tauri", "android", "android-studio-script");
-
- project.exec {
- workingDir(File(project.projectDir, rootDirRel))
- executable(executable)
- args(args)
- if (project.logger.isEnabled(LogLevel.DEBUG)) {
- args("-vv")
- } else if (project.logger.isEnabled(LogLevel.INFO)) {
- args("-v")
- }
- if (release) {
- args("--release")
- }
- args(listOf("--target", target))
- }.assertNormalExitValue()
- }
-}
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/RustPlugin.kt b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/RustPlugin.kt
deleted file mode 100644
index 4aa7fcaf..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/buildSrc/src/main/java/com/tauri/api/kotlin/RustPlugin.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-import com.android.build.api.dsl.ApplicationExtension
-import org.gradle.api.DefaultTask
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.configure
-import org.gradle.kotlin.dsl.get
-
-const val TASK_GROUP = "rust"
-
-open class Config {
- lateinit var rootDirRel: String
-}
-
-open class RustPlugin : Plugin {
- private lateinit var config: Config
-
- override fun apply(project: Project) = with(project) {
- config = extensions.create("rust", Config::class.java)
-
- val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
- val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList
-
- val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
- val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList
-
- val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")
-
- extensions.configure {
- @Suppress("UnstableApiUsage")
- flavorDimensions.add("abi")
- productFlavors {
- create("universal") {
- dimension = "abi"
- ndk {
- abiFilters += abiList
- }
- }
- defaultArchList.forEachIndexed { index, arch ->
- create(arch) {
- dimension = "abi"
- ndk {
- abiFilters.add(defaultAbiList[index])
- }
- }
- }
- }
- }
-
- afterEvaluate {
- for (profile in listOf("debug", "release")) {
- val profileCapitalized = profile.replaceFirstChar { it.uppercase() }
- val buildTask = tasks.maybeCreate(
- "rustBuildUniversal$profileCapitalized",
- DefaultTask::class.java
- ).apply {
- group = TASK_GROUP
- description = "Build dynamic library in $profile mode for all targets"
- }
-
- tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
-
- for (targetPair in targetsList.withIndex()) {
- val targetName = targetPair.value
- val targetArch = archList[targetPair.index]
- val targetArchCapitalized = targetArch.replaceFirstChar { it.uppercase() }
- val targetBuildTask = project.tasks.maybeCreate(
- "rustBuild$targetArchCapitalized$profileCapitalized",
- BuildTask::class.java
- ).apply {
- group = TASK_GROUP
- description = "Build dynamic library in $profile mode for $targetArch"
- rootDirRel = config.rootDirRel
- target = targetName
- release = profile == "release"
- }
-
- buildTask.dependsOn(targetBuildTask)
- tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
- targetBuildTask
- )
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle.properties b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle.properties
deleted file mode 100644
index 2a7ec695..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app"s APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
-android.useAndroidX=true
-# Kotlin code style for this project: "official" or "obsolete":
-kotlin.code.style=official
-# Enables namespacing of each library's R class so that its R class includes only the
-# resources declared in the library itself and none from the library's dependencies,
-# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
-android.nonFinalResIds=false
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.jar b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index e708b1c0..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 0df10d55..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Tue May 10 19:22:52 CST 2022
-distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
-distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew
deleted file mode 100644
index 4f906e0c..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env sh
-
-#
-# Copyright 2015 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-exec "$JAVACMD" "$@"
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew.bat b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew.bat
deleted file mode 100644
index 107acd32..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/gradlew.bat
+++ /dev/null
@@ -1,89 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/settings.gradle b/packages/kbot/gui/app/examples/api/src-tauri/gen/android/settings.gradle
deleted file mode 100644
index 39391166..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/android/settings.gradle
+++ /dev/null
@@ -1,3 +0,0 @@
-include ':app'
-
-apply from: 'tauri.settings.gradle'
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/.gitignore b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/.gitignore
deleted file mode 100644
index 6726e2f8..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-xcuserdata/
-build/
-Externals/
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png
deleted file mode 100644
index a6ac2a8c..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png
deleted file mode 100644
index 2869541f..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png
deleted file mode 100644
index 2869541f..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png
deleted file mode 100644
index cf265a45..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png
deleted file mode 100644
index 29c9746c..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png
deleted file mode 100644
index a4e68c8d..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png
deleted file mode 100644
index a4e68c8d..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png
deleted file mode 100644
index e4adcbce..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png
deleted file mode 100644
index 2869541f..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png
deleted file mode 100644
index a414e65b..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png
deleted file mode 100644
index a414e65b..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png
deleted file mode 100644
index a0807e5d..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
deleted file mode 100644
index 704c9291..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png
deleted file mode 100644
index a0807e5d..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png
deleted file mode 100644
index 2a9fbc26..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png
deleted file mode 100644
index 2cdf1848..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png
deleted file mode 100644
index 4723e4b4..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png
deleted file mode 100644
index f26fee45..00000000
Binary files a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png and /dev/null differ
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
deleted file mode 100644
index 90eea7ec..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "images" : [
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "AppIcon-20x20@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "AppIcon-20x20@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "AppIcon-29x29@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "AppIcon-29x29@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "AppIcon-40x40@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "AppIcon-40x40@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "AppIcon-60x60@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "AppIcon-60x60@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "AppIcon-20x20@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "AppIcon-20x20@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "AppIcon-29x29@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "AppIcon-29x29@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "AppIcon-40x40@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "AppIcon-40x40@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "AppIcon-76x76@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "AppIcon-76x76@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "83.5x83.5",
- "idiom" : "ipad",
- "filename" : "AppIcon-83.5x83.5@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "1024x1024",
- "idiom" : "ios-marketing",
- "filename" : "AppIcon-512@2x.png",
- "scale" : "1x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/Contents.json b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/Contents.json
deleted file mode 100644
index da4a164c..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/ExportOptions.plist b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/ExportOptions.plist
deleted file mode 100644
index 0428a171..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/ExportOptions.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- method
- debugging
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/LaunchScreen.storyboard b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/LaunchScreen.storyboard
deleted file mode 100644
index 81b5f90e..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/LaunchScreen.storyboard
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Podfile b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Podfile
deleted file mode 100644
index 24605d24..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Podfile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Uncomment the next line to define a global platform for your project
-
-target 'api_iOS' do
-platform :ios, '14.0'
- # Pods for api_iOS
-end
-
-target 'api_macOS' do
-platform :osx, '11.0'
- # Pods for api_macOS
-end
-
-# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile
-post_install do |installer|
- installer.pods_project.targets.each do |target|
- target.build_configurations.each do |config|
- config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
- config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET'
- end
- end
-end
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/bindings/bindings.h b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/bindings/bindings.h
deleted file mode 100644
index 51522007..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/bindings/bindings.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace ffi {
- extern "C" {
- void start_app();
- }
-}
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/main.mm b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/main.mm
deleted file mode 100644
index 7793a9d5..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/Sources/api/main.mm
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "bindings/bindings.h"
-
-int main(int argc, char * argv[]) {
- ffi::start_app();
- return 0;
-}
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.pbxproj b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.pbxproj
deleted file mode 100644
index 11be7126..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,469 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 54;
- objects = {
-
-/* Begin PBXBuildFile section */
- 3043432501C9BC2DB6B4CB95 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71EB788DE4662CFC0D97F567 /* CoreGraphics.framework */; };
- 328B4ADB3700C1873BEB7B10 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 90D3B673AFAB8D8AB561F616 /* main.mm */; };
- 6F379F15DA085785BA2624D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B7E79E23E646BA7968B457C /* Assets.xcassets */; };
- 832F9A55FEDEF3D807D8C40A /* libapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 248286BAA086BB1A5F98B2B2 /* libapp.a */; };
- 9AADB041D25772D04E543F15 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62601E25FA39E62BE119B74D /* Metal.framework */; };
- 9DDA3BE70DD0E4013973FE38 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6082E363D51372A7658C351 /* UIKit.framework */; };
- AC8BDC2C7A63FA3FDC5967F4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B2D1B108AE002010BDEC6D2 /* LaunchScreen.storyboard */; };
- AFA0CA286325FD7A34968CA2 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 384966E551417F94A02D2706 /* Security.framework */; };
- B60763BD194DFACA215EC7DA /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC377692DC31A070A0188C9D /* QuartzCore.framework */; };
- C6D80743F168BDF017B7769E /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 59CFE20DCF760BE67D9CE3D6 /* WebKit.framework */; };
- DFFF888045C8D9D9FB69E8FD /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 338E66700FD330B99D434DD7 /* MetalKit.framework */; };
- F86717F05E27C72C9FA1FB27 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 74A8FDFB350B966F5AAD4A24 /* assets */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 0E96CE07CD20273DD46BF325 /* main.rs */ = {isa = PBXFileReference; path = main.rs; sourceTree = ""; };
- 1C1AB1B414CA2795AFBEDDB9 /* tray.rs */ = {isa = PBXFileReference; path = tray.rs; sourceTree = ""; };
- 248286BAA086BB1A5F98B2B2 /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = ""; };
- 2F63E2AA460089BB58D40C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
- 338E66700FD330B99D434DD7 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
- 384966E551417F94A02D2706 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
- 4B2D1B108AE002010BDEC6D2 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
- 59CFE20DCF760BE67D9CE3D6 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
- 5AC703CEBA41A121596066F3 /* api_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = api_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 62601E25FA39E62BE119B74D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
- 6B7E79E23E646BA7968B457C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 71EB788DE4662CFC0D97F567 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
- 74A8FDFB350B966F5AAD4A24 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; };
- 785D025E9542F7E098BF22B5 /* lib.rs */ = {isa = PBXFileReference; path = lib.rs; sourceTree = ""; };
- 879941AE3DAA14534BBC6391 /* api_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = api_iOS.entitlements; sourceTree = ""; };
- 90D3B673AFAB8D8AB561F616 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; };
- B6082E363D51372A7658C351 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
- DC377692DC31A070A0188C9D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
- EC8C7948C50C3C9B5D96CB61 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = ""; };
- F835F52713CE8F029D5D252C /* cmd.rs */ = {isa = PBXFileReference; path = cmd.rs; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 11E18DCDB3ADFE87C18915EF /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 832F9A55FEDEF3D807D8C40A /* libapp.a in Frameworks */,
- 3043432501C9BC2DB6B4CB95 /* CoreGraphics.framework in Frameworks */,
- 9AADB041D25772D04E543F15 /* Metal.framework in Frameworks */,
- DFFF888045C8D9D9FB69E8FD /* MetalKit.framework in Frameworks */,
- B60763BD194DFACA215EC7DA /* QuartzCore.framework in Frameworks */,
- AFA0CA286325FD7A34968CA2 /* Security.framework in Frameworks */,
- 9DDA3BE70DD0E4013973FE38 /* UIKit.framework in Frameworks */,
- C6D80743F168BDF017B7769E /* WebKit.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 0677CEAF1F282F38CBA0F140 = {
- isa = PBXGroup;
- children = (
- 74A8FDFB350B966F5AAD4A24 /* assets */,
- 6B7E79E23E646BA7968B457C /* Assets.xcassets */,
- 4B2D1B108AE002010BDEC6D2 /* LaunchScreen.storyboard */,
- F2116A6428EED18BE2A07E2B /* api_iOS */,
- 86D903732E10FAC4D300E8DF /* Externals */,
- 7A9A7AC155D9E22E54D6D847 /* Sources */,
- CF9AA87D2F6E9C389B7AB70B /* src */,
- 10C9FC3FA3E12D6A4A67999D /* Frameworks */,
- 4AC51E67B71E27F15B02C5CD /* Products */,
- );
- sourceTree = "";
- };
- 07051859D6E2D8109C8FB128 /* bindings */ = {
- isa = PBXGroup;
- children = (
- EC8C7948C50C3C9B5D96CB61 /* bindings.h */,
- );
- path = bindings;
- sourceTree = "";
- };
- 10C9FC3FA3E12D6A4A67999D /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 71EB788DE4662CFC0D97F567 /* CoreGraphics.framework */,
- 248286BAA086BB1A5F98B2B2 /* libapp.a */,
- 62601E25FA39E62BE119B74D /* Metal.framework */,
- 338E66700FD330B99D434DD7 /* MetalKit.framework */,
- DC377692DC31A070A0188C9D /* QuartzCore.framework */,
- 384966E551417F94A02D2706 /* Security.framework */,
- B6082E363D51372A7658C351 /* UIKit.framework */,
- 59CFE20DCF760BE67D9CE3D6 /* WebKit.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 4AC51E67B71E27F15B02C5CD /* Products */ = {
- isa = PBXGroup;
- children = (
- 5AC703CEBA41A121596066F3 /* api_iOS.app */,
- );
- name = Products;
- sourceTree = "";
- };
- 7A9A7AC155D9E22E54D6D847 /* Sources */ = {
- isa = PBXGroup;
- children = (
- A3574F52DBC5463B9C3D043D /* api */,
- );
- path = Sources;
- sourceTree = "";
- };
- 86D903732E10FAC4D300E8DF /* Externals */ = {
- isa = PBXGroup;
- children = (
- );
- path = Externals;
- sourceTree = "";
- };
- A3574F52DBC5463B9C3D043D /* api */ = {
- isa = PBXGroup;
- children = (
- 90D3B673AFAB8D8AB561F616 /* main.mm */,
- 07051859D6E2D8109C8FB128 /* bindings */,
- );
- path = api;
- sourceTree = "";
- };
- CF9AA87D2F6E9C389B7AB70B /* src */ = {
- isa = PBXGroup;
- children = (
- F835F52713CE8F029D5D252C /* cmd.rs */,
- 785D025E9542F7E098BF22B5 /* lib.rs */,
- 0E96CE07CD20273DD46BF325 /* main.rs */,
- 1C1AB1B414CA2795AFBEDDB9 /* tray.rs */,
- );
- name = src;
- path = ../../src;
- sourceTree = "";
- };
- F2116A6428EED18BE2A07E2B /* api_iOS */ = {
- isa = PBXGroup;
- children = (
- 879941AE3DAA14534BBC6391 /* api_iOS.entitlements */,
- 2F63E2AA460089BB58D40C79 /* Info.plist */,
- );
- path = api_iOS;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 54DC6E273C78071F3BA12EF3 /* api_iOS */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 01CBC40275452376830D79B1 /* Build configuration list for PBXNativeTarget "api_iOS" */;
- buildPhases = (
- FF948951157DE71465B5BD5F /* Build Rust Code */,
- 71E73CC9AB5F1323EC1F6365 /* Sources */,
- CA2BEC44B6EDA1F21B6155CD /* Resources */,
- 11E18DCDB3ADFE87C18915EF /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = api_iOS;
- packageProductDependencies = (
- );
- productName = api_iOS;
- productReference = 5AC703CEBA41A121596066F3 /* api_iOS.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 9BC88C3717DA5D4B78A51C15 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- BuildIndependentTargetsInParallel = YES;
- LastUpgradeCheck = 1430;
- TargetAttributes = {
- 54DC6E273C78071F3BA12EF3 = {
- DevelopmentTeam = Q93MBH6S2F;
- };
- };
- };
- buildConfigurationList = 8FA67D0F928A09CD639137D1 /* Build configuration list for PBXProject "api" */;
- compatibilityVersion = "Xcode 14.0";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- Base,
- en,
- );
- mainGroup = 0677CEAF1F282F38CBA0F140;
- minimizedProjectReferenceProxies = 1;
- preferredProjectObjectVersion = 54;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 54DC6E273C78071F3BA12EF3 /* api_iOS */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- CA2BEC44B6EDA1F21B6155CD /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 6F379F15DA085785BA2624D4 /* Assets.xcassets in Resources */,
- AC8BDC2C7A63FA3FDC5967F4 /* LaunchScreen.storyboard in Resources */,
- F86717F05E27C72C9FA1FB27 /* assets in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- FF948951157DE71465B5BD5F /* Build Rust Code */ = {
- isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- );
- name = "Build Rust Code";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a",
- "$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "pnpm tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths \"${FRAMEWORK_SEARCH_PATHS:?}\" --header-search-paths \"${HEADER_SEARCH_PATHS:?}\" --gcc-preprocessor-definitions \"${GCC_PREPROCESSOR_DEFINITIONS:-}\" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 71E73CC9AB5F1323EC1F6365 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 328B4ADB3700C1873BEB7B10 /* main.mm in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- A83F70B4C02DD0222038C7F1 /* release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 14.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- MTL_FAST_MATH = YES;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SDKROOT = iphoneos;
- SWIFT_COMPILATION_MODE = wholemodule;
- SWIFT_OPTIMIZATION_LEVEL = "-O";
- SWIFT_VERSION = 5.0;
- };
- name = release;
- };
- B6AD77E490F315562F75D3D7 /* debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "$(inherited)",
- "DEBUG=1",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 14.0;
- MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
- MTL_FAST_MATH = YES;
- ONLY_ACTIVE_ARCH = YES;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
- };
- name = debug;
- };
- BF284FE6E7AE0C8DDCCE398B /* debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ARCHS = (
- arm64,
- );
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- DEVELOPMENT_TEAM = "Q93MBH6S2F";
- ENABLE_BITCODE = NO;
- "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "\".\"",
- );
- INFOPLIST_FILE = api_iOS/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- "LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
- "LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
- PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api;
- PRODUCT_NAME = "Tauri API";
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = arm64;
- };
- name = debug;
- };
- DB0E254D0FD84970B57F6410 /* release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ARCHS = (
- arm64,
- );
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- DEVELOPMENT_TEAM = "Q93MBH6S2F";
- ENABLE_BITCODE = NO;
- "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "\".\"",
- );
- INFOPLIST_FILE = api_iOS/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- "LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
- "LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
- PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api;
- PRODUCT_NAME = "Tauri API";
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = arm64;
- };
- name = release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 01CBC40275452376830D79B1 /* Build configuration list for PBXNativeTarget "api_iOS" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- BF284FE6E7AE0C8DDCCE398B /* debug */,
- DB0E254D0FD84970B57F6410 /* release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = debug;
- };
- 8FA67D0F928A09CD639137D1 /* Build configuration list for PBXProject "api" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- B6AD77E490F315562F75D3D7 /* debug */,
- A83F70B4C02DD0222038C7F1 /* release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = debug;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 9BC88C3717DA5D4B78A51C15 /* Project object */;
-}
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 919434a6..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
deleted file mode 100644
index ac90d5ac..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- BuildSystemType
- Original
- DisableBuildSystemDeprecationDiagnostic
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/xcshareddata/xcschemes/api_iOS.xcscheme b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/xcshareddata/xcschemes/api_iOS.xcscheme
deleted file mode 100644
index 2a9f5045..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api.xcodeproj/xcshareddata/xcschemes/api_iOS.xcscheme
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/Info.plist b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/Info.plist
deleted file mode 100644
index 7d35e702..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/Info.plist
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 2.0.0
- CFBundleVersion
- 2.0.0
- LSRequiresIPhoneOS
-
- UILaunchStoryboardName
- LaunchScreen
- UIRequiredDeviceCapabilities
-
- arm64
- metal
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- NSCameraUsageDescription
- Request camera access for WebRTC
- NSMicrophoneUsageDescription
- Request microphone access for WebRTC
- NSFaceIDUsageDescription
- Authenticate with biometrics
- NFCReaderUsageDescription
- Read and write to NFC tags for testing
-
-
\ No newline at end of file
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/api_iOS.entitlements b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/api_iOS.entitlements
deleted file mode 100644
index 0c67376e..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/api_iOS/api_iOS.entitlements
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/project.yml b/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/project.yml
deleted file mode 100644
index d789500e..00000000
--- a/packages/kbot/gui/app/examples/api/src-tauri/gen/apple/project.yml
+++ /dev/null
@@ -1,89 +0,0 @@
-name: api
-options:
- bundleIdPrefix: com.tauri.api
- deploymentTarget:
- iOS: 14.0
-fileGroups: [../../src]
-configs:
- debug: debug
- release: release
-settingGroups:
- app:
- base:
- PRODUCT_NAME: Tauri API
- PRODUCT_BUNDLE_IDENTIFIER: com.tauri.api
- DEVELOPMENT_TEAM: Q93MBH6S2F
-targetTemplates:
- app:
- type: application
- sources:
- - path: Sources
- scheme:
- environmentVariables:
- RUST_BACKTRACE: full
- RUST_LOG: info
- settings:
- groups: [app]
-targets:
- api_iOS:
- type: application
- platform: iOS
- sources:
- - path: Sources
- - path: Assets.xcassets
- - path: Externals
- - path: api_iOS
- - path: assets
- buildPhase: resources
- type: folder
- - path: LaunchScreen.storyboard
- info:
- path: api_iOS/Info.plist
- properties:
- LSRequiresIPhoneOS: true
- UILaunchStoryboardName: LaunchScreen
- UIRequiredDeviceCapabilities: [arm64, metal]
- UISupportedInterfaceOrientations:
- - UIInterfaceOrientationPortrait
- - UIInterfaceOrientationLandscapeLeft
- - UIInterfaceOrientationLandscapeRight
- UISupportedInterfaceOrientations~ipad:
- - UIInterfaceOrientationPortrait
- - UIInterfaceOrientationPortraitUpsideDown
- - UIInterfaceOrientationLandscapeLeft
- - UIInterfaceOrientationLandscapeRight
- CFBundleShortVersionString: 2.0.0
- CFBundleVersion: 2.0.0
- entitlements:
- path: api_iOS/api_iOS.entitlements
- scheme:
- environmentVariables:
- RUST_BACKTRACE: full
- RUST_LOG: info
- settings:
- base:
- ENABLE_BITCODE: false
- ARCHS: [arm64]
- VALID_ARCHS: arm64
- LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
- LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
- EXCLUDED_ARCHS[sdk=iphoneos*]: x86_64
- groups: [app]
- dependencies:
- - framework: libapp.a
- embed: false
- - sdk: CoreGraphics.framework
- - sdk: Metal.framework
- - sdk: MetalKit.framework
- - sdk: QuartzCore.framework
- - sdk: Security.framework
- - sdk: UIKit.framework
- - sdk: WebKit.framework
- preBuildScripts:
- - script: pnpm tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths "${FRAMEWORK_SEARCH_PATHS:?}" --header-search-paths "${HEADER_SEARCH_PATHS:?}" --gcc-preprocessor-definitions "${GCC_PREPROCESSOR_DEFINITIONS:-}" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}
- name: Build Rust Code
- basedOnDependencyAnalysis: false
- outputFiles:
- - $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a
- - $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a
\ No newline at end of file
diff --git a/packages/kbot/package-lock.json b/packages/kbot/package-lock.json
index 261f6c55..ff2426e9 100644
--- a/packages/kbot/package-lock.json
+++ b/packages/kbot/package-lock.json
@@ -155,6 +155,7 @@
"@polymech/fs": "file:../fs",
"@repo/typescript-config": "file:../typescript-config",
"@schemastore/package": "^0.0.10",
+ "ansi-regex": "^6.2.2",
"env-var": "^7.5.0",
"glob": "^10.4.5",
"js-yaml": "^4.1.0",
@@ -332,40 +333,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@bundled-es-modules/cookie": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz",
- "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "cookie": "^0.7.2"
- }
- },
- "node_modules/@bundled-es-modules/statuses": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz",
- "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "statuses": "^2.0.1"
- }
- },
- "node_modules/@bundled-es-modules/tough-cookie": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz",
- "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "dependencies": {
- "@types/tough-cookie": "^4.0.5",
- "tough-cookie": "^4.1.4"
- }
- },
"node_modules/@calebboyd/semaphore": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@calebboyd/semaphore/-/semaphore-1.3.1.tgz",
@@ -994,159 +961,6 @@
"dev": true,
"license": "BSD-3-Clause"
},
- "node_modules/@inquirer/confirm": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.6.tgz",
- "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@inquirer/core": "^10.1.7",
- "@inquirer/type": "^3.0.4"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/core": {
- "version": "10.1.7",
- "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.7.tgz",
- "integrity": "sha512-AA9CQhlrt6ZgiSy6qoAigiA1izOa751ugX6ioSjqgJ+/Gd+tEN/TORk5sUYNjXuHWfW0r1n/a6ak4u/NqHHrtA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@inquirer/figures": "^1.0.10",
- "@inquirer/type": "^3.0.4",
- "ansi-escapes": "^4.3.2",
- "cli-width": "^4.1.0",
- "mute-stream": "^2.0.0",
- "signal-exit": "^4.1.0",
- "wrap-ansi": "^6.2.0",
- "yoctocolors-cjs": "^2.1.2"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/core/node_modules/ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@inquirer/core/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
- "node_modules/@inquirer/core/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@inquirer/core/node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "optional": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@inquirer/core/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@inquirer/figures": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.10.tgz",
- "integrity": "sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@inquirer/type": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.4.tgz",
- "integrity": "sha512-2MNFrDY8jkFYc9Il9DgLsHhMzuHnOYM1+CUYVWbzu9oT0hC7V7EcYvdCKeoll/Fcci04A+ERZ9wcc7cQ8lTkIA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
"node_modules/@ioredis/commands": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
@@ -1341,25 +1155,6 @@
"integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==",
"license": "BSD-2-Clause"
},
- "node_modules/@mswjs/interceptors": {
- "version": "0.37.6",
- "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.6.tgz",
- "integrity": "sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@open-draft/deferred-promise": "^2.2.0",
- "@open-draft/logger": "^0.3.0",
- "@open-draft/until": "^2.0.0",
- "is-node-process": "^1.2.0",
- "outvariant": "^1.4.3",
- "strict-event-emitter": "^0.5.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1398,34 +1193,6 @@
"node": ">= 8"
}
},
- "node_modules/@open-draft/deferred-promise": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
- "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
- "node_modules/@open-draft/logger": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz",
- "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "is-node-process": "^1.2.0",
- "outvariant": "^1.4.0"
- }
- },
- "node_modules/@open-draft/until": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz",
- "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -1823,14 +1590,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/cookie": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
- "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@@ -1930,14 +1689,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/statuses": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz",
- "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/@types/tapable": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.12.tgz",
@@ -1945,14 +1696,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/tough-cookie": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
- "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/@types/turndown": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.5.tgz",
@@ -3638,17 +3381,6 @@
"node": ">=8"
}
},
- "node_modules/cli-width": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
- "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -3854,17 +3586,6 @@
"node": ">= 0.6"
}
},
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -5850,17 +5571,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/graphql": {
- "version": "16.10.0",
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz",
- "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
- }
- },
"node_modules/gtoken": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
@@ -5958,14 +5668,6 @@
"node": ">= 0.4"
}
},
- "node_modules/headers-polyfill": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz",
- "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
@@ -6242,14 +5944,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/is-node-process": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
- "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -7705,17 +7399,6 @@
"readable-stream": "^3.6.0"
}
},
- "node_modules/mute-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
- "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
"node_modules/mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
@@ -7965,18 +7648,6 @@
}
}
},
- "node_modules/node-gyp-build": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
- "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
- "license": "MIT",
- "optional": true,
- "bin": {
- "node-gyp-build": "bin.js",
- "node-gyp-build-optional": "optional.js",
- "node-gyp-build-test": "build-test.js"
- }
- },
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -8221,14 +7892,6 @@
"node": ">=4"
}
},
- "node_modules/outvariant": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
- "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/p-cancelable": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
@@ -8475,14 +8138,6 @@
"node": "20 || >=22"
}
},
- "node_modules/path-to-regexp": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
- "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -8715,20 +8370,6 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
- "node_modules/psl": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
- "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/lupomontero"
- }
- },
"node_modules/pump": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
@@ -8765,14 +8406,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -8986,14 +8619,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
@@ -9549,17 +9174,6 @@
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
"license": "MIT"
},
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/std-env": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
@@ -9567,14 +9181,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/strict-event-emitter": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
- "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"node_modules/strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -10220,23 +9826,6 @@
"node": ">=6"
}
},
- "node_modules/tough-cookie": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
- "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
- "dev": true,
- "license": "BSD-3-Clause",
- "optional": true,
- "dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -10993,20 +10582,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/type-fest": {
- "version": "4.35.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz",
- "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "optional": true,
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/typed-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
@@ -11138,17 +10713,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 4.0.0"
- }
- },
"node_modules/update-browserslist-db": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
@@ -11190,18 +10754,6 @@
"punycode": "^2.1.0"
}
},
- "node_modules/url-parse": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
"node_modules/url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
@@ -11912,20 +11464,6 @@
"node": ">=6"
}
},
- "node_modules/yoctocolors-cjs": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz",
- "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/zip-stream": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
diff --git a/packages/mail/dist-in/lib/imap/index.js b/packages/mail/dist-in/lib/imap/index.js
index 79ee0ed2..15df4e7d 100644
--- a/packages/mail/dist-in/lib/imap/index.js
+++ b/packages/mail/dist-in/lib/imap/index.js
@@ -43,16 +43,6 @@ export async function getMessagesFromInboxWithFilter(imapConfig, fromAddress, to
throw err;
}
}
-// Configuration for IMAP
-const imapConfig = {
- host: 'imap.example.com',
- port: 993,
- auth: {
- user: 'your_email@example.com',
- pass: 'your_password'
- },
- secure: true
-};
// Create a draft email
export const draft = async (subject, html, options) => {
const client = new ImapFlow(options);
@@ -81,4 +71,4 @@ export const draft = async (subject, html, options) => {
console.log('Connection ended.');
}
};
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2ltYXAvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQVVuQyxNQUFNLENBQUMsS0FBSyxVQUFVLDhCQUE4QixDQUFDLFVBQXVCLEVBQUUsV0FBb0IsRUFBRSxTQUFrQixFQUFFLE9BQWdCO0lBQ3RJLE1BQU0sTUFBTSxHQUFHLElBQUksUUFBUSxDQUFDO1FBQzFCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtRQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7UUFDckIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxHQUFHO1FBQ3RCLElBQUksRUFBRTtZQUNKLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtZQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVE7U0FDMUI7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFFMUIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFdkIsSUFBSSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELElBQUksQ0FBQztZQUNILE1BQU0sY0FBYyxHQUFRLEVBQUUsQ0FBQztZQUMvQixJQUFJLFdBQVc7Z0JBQUUsY0FBYyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7WUFDbkQsSUFBSSxTQUFTO2dCQUFFLGNBQWMsQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDO1lBQzdDLElBQUksT0FBTztnQkFBRSxjQUFjLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUU5QywwR0FBMEc7WUFDMUcsMkRBQTJEO1lBRTNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUVoRixJQUFJLEtBQUssRUFBRSxJQUFJLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7b0JBQ2hCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtvQkFDMUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2lCQUNsQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFFRCxNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLE9BQU8sQ0FBQztJQUVqQixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsTUFBTSxHQUFHLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQztBQUVELHlCQUF5QjtBQUN6QixNQUFNLFVBQVUsR0FBRztJQUNqQixJQUFJLEVBQUUsa0JBQWtCO0lBQ3hCLElBQUksRUFBRSxHQUFHO0lBQ1QsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFLHdCQUF3QjtRQUM5QixJQUFJLEVBQUUsZUFBZTtLQUN0QjtJQUNELE1BQU0sRUFBRSxJQUFJO0NBQ2IsQ0FBQztBQUVGLHVCQUF1QjtBQUN2QixNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsS0FBSyxFQUFFLE9BQWUsRUFBRSxJQUFZLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFcEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFdEIsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRWxDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsb0NBQW9DO2dCQUMxQyxPQUFPLEVBQUUsT0FBTzthQUNqQjtZQUNELE9BQU8sRUFBRSxJQUFJO1lBQ2IsR0FBRyxPQUFPO1NBQ1gsQ0FBQTtRQUVELDBDQUEwQztRQUMxQyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDekQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0IsTUFBTSxHQUFHLENBQUE7SUFDWCxDQUFDO1lBQVMsQ0FBQztRQUNULHVCQUF1QjtRQUN2QixNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbkMsQ0FBQztBQUNILENBQUMsQ0FBQSJ9
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2ltYXAvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQVVuQyxNQUFNLENBQUMsS0FBSyxVQUFVLDhCQUE4QixDQUFDLFVBQXVCLEVBQUUsV0FBb0IsRUFBRSxTQUFrQixFQUFFLE9BQWdCO0lBQ3RJLE1BQU0sTUFBTSxHQUFHLElBQUksUUFBUSxDQUFDO1FBQzFCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtRQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7UUFDckIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxHQUFHO1FBQ3RCLElBQUksRUFBRTtZQUNKLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtZQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVE7U0FDMUI7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFFMUIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFdkIsSUFBSSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELElBQUksQ0FBQztZQUNILE1BQU0sY0FBYyxHQUFRLEVBQUUsQ0FBQztZQUMvQixJQUFJLFdBQVc7Z0JBQUUsY0FBYyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7WUFDbkQsSUFBSSxTQUFTO2dCQUFFLGNBQWMsQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDO1lBQzdDLElBQUksT0FBTztnQkFBRSxjQUFjLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUU5QywwR0FBMEc7WUFDMUcsMkRBQTJEO1lBRTNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUVoRixJQUFJLEtBQUssRUFBRSxJQUFJLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7b0JBQ2hCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtvQkFDMUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2lCQUNsQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFFRCxNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLE9BQU8sQ0FBQztJQUVqQixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsTUFBTSxHQUFHLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQztBQUVELHVCQUF1QjtBQUN2QixNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsS0FBSyxFQUFFLE9BQWUsRUFBRSxJQUFZLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFcEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFdEIsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRWxDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsb0NBQW9DO2dCQUMxQyxPQUFPLEVBQUUsT0FBTzthQUNqQjtZQUNELE9BQU8sRUFBRSxJQUFJO1lBQ2IsR0FBRyxPQUFPO1NBQ1gsQ0FBQTtRQUVELDBDQUEwQztRQUMxQyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDekQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0IsTUFBTSxHQUFHLENBQUE7SUFDWCxDQUFDO1lBQVMsQ0FBQztRQUNULHVCQUF1QjtRQUN2QixNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbkMsQ0FBQztBQUNILENBQUMsQ0FBQSJ9
\ No newline at end of file
diff --git a/packages/mail/package-lock.json b/packages/mail/package-lock.json
index e443a16a..529b5222 100644
--- a/packages/mail/package-lock.json
+++ b/packages/mail/package-lock.json
@@ -25,7 +25,6 @@
"pm-mail": "dist-in/main.js"
},
"devDependencies": {
- "@vitest/coverage-v8": "^4.0.18",
"vitest": "^4.0.18"
},
"engines": {
@@ -132,66 +131,6 @@
"typescript-eslint": "^8.20.0"
}
},
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
- "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.28.6"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
- "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
- "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
@@ -634,16 +573,6 @@
"node": ">=18"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -651,17 +580,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
"node_modules/@pinojs/redact": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
@@ -1099,37 +1017,6 @@
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"license": "MIT"
},
- "node_modules/@vitest/coverage-v8": {
- "version": "4.0.18",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz",
- "integrity": "sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@bcoe/v8-coverage": "^1.0.2",
- "@vitest/utils": "4.0.18",
- "ast-v8-to-istanbul": "^0.3.10",
- "istanbul-lib-coverage": "^3.2.2",
- "istanbul-lib-report": "^3.0.1",
- "istanbul-reports": "^3.2.0",
- "magicast": "^0.5.1",
- "obug": "^2.1.1",
- "std-env": "^3.10.0",
- "tinyrainbow": "^3.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@vitest/browser": "4.0.18",
- "vitest": "4.0.18"
- },
- "peerDependenciesMeta": {
- "@vitest/browser": {
- "optional": true
- }
- }
- },
"node_modules/@vitest/expect": {
"version": "4.0.18",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz",
@@ -1286,18 +1173,6 @@
"node": ">=12"
}
},
- "node_modules/ast-v8-to-istanbul": {
- "version": "0.3.10",
- "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz",
- "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.31",
- "estree-walker": "^3.0.3",
- "js-tokens": "^9.0.1"
- }
- },
"node_modules/atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
@@ -1478,23 +1353,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/iconv-lite": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
@@ -1546,52 +1404,6 @@
"node": ">= 12"
}
},
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
- "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/js-tokens": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
- "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/libbase64": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.3.0.tgz",
@@ -1638,34 +1450,6 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
- "node_modules/magicast": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz",
- "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.28.5",
- "@babel/types": "^7.28.5",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
@@ -1899,19 +1683,6 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
- "node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/siginfo": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
@@ -2017,19 +1788,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/thread-stream": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.0.0.tgz",
diff --git a/packages/tasks/src/cad.ts b/packages/tasks/src/cad.ts
new file mode 100644
index 00000000..05512553
--- /dev/null
+++ b/packages/tasks/src/cad.ts
@@ -0,0 +1,69 @@
+import * as pMap from 'p-map'
+import * as path from 'path'
+import { isArray } from '@plastichub/core/primitives'
+import { convert as cadConvert } from '@plastichub/osr-cad/cad/sw-lib'
+import { SolidworkOptions } from '@plastichub/osr-cad'
+import { sanitize } from '@plastichub/osr-cad/sw_argv'
+import { resolve } from '@plastichub/osr-commons'
+
+import { logger } from '../src'
+import { option } from '../library'
+
+export interface ICadTask {
+ src: string | string[]
+ output: string
+ options: any
+}
+
+const create_cad_options = (src: string, dst: string, options: SolidworkOptions) => {
+ return { ...options, src, dst }
+}
+const convert = async (src, options, output) => {
+ const args = create_cad_options(src, output, options);
+ const syncArgs = sanitize({
+ ...args,
+ ...options
+ })
+ return cadConvert(syncArgs)
+}
+const convertFiles = async (items, options, output) => {
+ return (pMap as any)(items, async (s) => {
+ return convert(s, options, output)
+ }, {
+ concurrency: 1
+ })
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('cad', 'converts CAD files', function () {
+ const done = this.async()
+ const task_options = this.data.options || {}
+ const options: SolidworkOptions = {
+ ...this.data.options,
+ root: option('root', task_options, grunt, path.resolve('./')),
+ debug: option('debug', task_options, grunt),
+ verbose: option('verbose', task_options, grunt),
+ sw: option('sw', task_options, grunt),
+ swv: option('swv', task_options, grunt),
+ args: option('args', task_options, grunt),
+ dry: option('dry', task_options, grunt),
+ onNode: option('onNode', task_options, grunt),
+ cache: option('cache', task_options, grunt, true),
+ report: option('report', task_options, grunt),
+ configuration: option('configuration', task_options, grunt),
+ hidden: option('hidden', task_options, grunt),
+ quality: option('quality', task_options, grunt),
+ renderer: option('renderer', task_options, grunt),
+ view: option('view', task_options, grunt),
+ close: option('close', task_options, grunt, true),
+ logLevel: option('logLevel', task_options, grunt, 'warn')
+ }
+ let src: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+ src = src.map(f => (resolve(f)))
+ try {
+ convertFiles(src, options, this.data.output).then(done)
+ } catch (e) {
+ logger.error('Error converting files', e)
+ }
+ })
+}
\ No newline at end of file
diff --git a/packages/tasks/src/compile.ts b/packages/tasks/src/compile.ts
new file mode 100644
index 00000000..988b86af
--- /dev/null
+++ b/packages/tasks/src/compile.ts
@@ -0,0 +1,385 @@
+import * as path from 'path'
+import * as md5 from 'md5'
+import * as pMap from 'p-map'
+
+import { IOptions, ICompileOptions, compilerOptions } from '@plastichub/osrl/types'
+import { Engine as engine } from '@plastichub/osrl/Engine'
+import { parse } from '@plastichub/osrl/options'
+import { get_cached, set_cached } from '@plastichub/osr-cache/lib'
+import { OSR_CACHE, OSR_ROOT } from '@plastichub/osr-commons/config'
+
+import { isFile, resolve, substitute, pathInfo, pathInfoEx } from '@plastichub/osr-commons'
+
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as write } from '@plastichub/fs/write'
+import { sync as rm } from '@plastichub/fs/remove'
+import { taskOptions } from '../src/zod_schema'
+import { ICompileTaskOptions } from '../src/zod_types'
+import { logger } from '../src'
+import { option, gruntOptions } from '../library'
+
+import {
+ MODULE_NAME
+} from '../src/constants'
+
+import { TLogLevelName } from 'tslog'
+import { I18N_STORE } from '../src/config'
+
+const chokidar = require("chokidar")
+
+const lockMap = {}
+const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
+
+export type onCompileDone = (source: string, target: string, options: IOptions, content: string) => Promise
+
+export type ICompileTaskOptions2 = IOptions & {
+ watchContent?: boolean
+ debugWatch?: boolean
+ clear?: boolean
+ onCompile?: (options: IOptions) => Promise
+ onCompiled?: (source: string, target: string, content: string) => Promise
+ onCompileDone?: (source: string, target: string, options: IOptions, content: string) => Promise
+}
+
+export interface ICompileTaskData {
+ options: ICompileTaskOptions
+ src: string[]
+}
+
+export const createContent = async (file: string, _options: any) => {
+ if (!exists(file)) {
+ logger.error(`Source file ${file} not found`)
+ return false
+ }
+ const parts = path.parse(file)
+ const rel = path.relative(_options.root, file)
+ let output = _options.output
+ let outputInfo = pathInfo(_options.output)
+
+ const variables = {
+ root: _options.root || '.',
+ cwd: _options.cwd || path.resolve('.'),
+ ..._options.variables
+ }
+
+ if (!outputInfo.FILE_EXT) {
+ output = path.resolve(`${_options.output}/${path.parse(rel).dir}/${parts.name}.md`)
+ } else {
+ output = path.resolve(resolve(output, false, variables));
+ }
+
+ const defaults: any = {
+ language: _options.language,
+ debug: _options.debug,
+ profile: _options.profile,
+ output: output,
+ plugins: _options.plugins,
+ env: _options.env || 'library',
+ cwd: _options.cwd || path.resolve('.'),
+ source: file,
+ variables,
+ user: _options.user,
+ template: _options.template,
+ targetLanguage: _options.targetLanguage,
+ sourceLanguage: _options.sourceLanguage
+ }
+
+ const options = parse(defaults, defaults)
+ debugger
+
+ let eOptions = {
+ ...options,
+ root: [
+ ...options.profile.includes,
+ path.parse(file).dir
+ ],
+ toHTML: false,
+ cache: false,
+ keepOutputType: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: false
+ } as IOptions
+
+
+ const Engine = new engine(eOptions)
+ if (_options.onCompile) {
+ const newOpts = await _options.onCompile(options)
+ if (newOpts) {
+ eOptions = newOpts
+ }
+ }
+
+ options.source = path.resolve(options.source)
+ const osr_cache = OSR_CACHE()
+ let dst = path.resolve(resolve(output, false, options.variables))
+
+ const cache_key = {
+ file,
+ dst,
+ targetLanguage: eOptions.targetLanguage,
+ sourceLanguage: eOptions.sourceLanguage,
+ language: eOptions.language,
+ format: eOptions.format
+ }
+
+ const done = async (content) => {
+
+ const contentCompiled = await _options.onCompiled(options.source, output, content)
+ if(contentCompiled) {
+ content = contentCompiled
+ }else{
+ logger.warn(`onCompiled returned nothing : ${options.source}`)
+ }
+ if (_options.onCompileDone) {
+ await _options.onCompileDone(options.source, dst, options, content)
+ }
+ }
+
+ let cached = await get_cached(options.source, cache_key, _options.module || MODULE_NAME)
+ if (osr_cache && cached && _options.cache !== false) {
+ let md5Src = md5(Buffer.from(cached));
+ let md5Dst = md5(fileAsBuffer(options.output));
+ if (!exists(options.output) || md5Src !== md5Dst) {
+ write(options.output, cached);
+ }
+ logger.debug(`Compile file ${file} : serving from cache`)
+ lockMap[file] = false
+ cached = await done(cached)
+ return cached
+ }
+
+ let content = await Engine.render(options.source, options.variables)
+ if (!content) {
+ logger.error(`Error compiling ${options.source} to ${options.output}`)
+ lockMap[file] = false
+ return false
+ }
+ if (_options.onCompiled) {
+ const contentCompiled = await _options.onCompiled(options.source, output, content)
+ if(contentCompiled) {
+ content = contentCompiled
+ }else{
+ logger.warn(`onCompiled returned nothing : ${options.source}`)
+ }
+ }
+
+ if (osr_cache && _options.cache !== false) {
+ logger.debug('Write output to cache', output)
+ await set_cached(options.source, cache_key, _options.module || MODULE_NAME, content)
+ }
+
+ dst && content && write(dst, content)
+ if (_options.onCompileDone) {
+ await _options.onCompileDone(options.source, dst, options, content)
+ }
+ lockMap[file] = false
+ logger.info(`Compiled ${file} to: ${dst} `)
+ return content
+}
+
+const watch = async (src, options) => {
+ const dInfo = pathInfo(src, false, options.cwd)
+ src = path.resolve(src)
+ const dir = dInfo.IS_GLOB ? dInfo.DIR : src
+ const watcher = chokidar.watch(`${dir}`, {
+ ignored: /(^|[\/\\])\../,
+ persistent: true,
+ ignoreInitial: false,
+ followSymlinks: true,
+ disableGlobbing: false,
+ usePolling: false,
+ interval: 1000,
+ binaryInterval: 300,
+ alwaysStat: false,
+ depth: 99,
+ awaitWriteFinish: {
+ stabilityThreshold: 2500,
+ pollInterval: 2000
+ },
+ ignorePermissionErrors: false,
+ atomic: 2000
+ })
+ watcher.on('addDir', path => logger.debug(`Directory ${path} has been added`))
+ .on('unlinkDir', path => logger.debug(`Directory ${path} has been removed`))
+ .on('error', error => logger.debug(`Watcher error: ${error}`))
+ .on('raw', (event, _path, details) => {
+ if (!_path.endsWith(dInfo.FILE_EXT)) {
+ return
+ }
+ switch (event) {
+ case 'rename': {
+ const rel = path.relative(dir, path.parse(details.watchedPath).dir)
+ const dst = path.resolve(`${options.output}/${rel}/${_path}`)
+ if (exists(dst)) {
+ rm(dst)
+ }
+ const _src = path.resolve(`${details.watchedPath}`)
+ if (lockMap[_src]) {
+ return
+ }
+ if (exists(_src) && isFile(_src)) {
+ lockMap[_src] = true
+ createContent(_src, { ...options })
+ }
+ break
+ }
+ case 'change': {
+ let _src = ''
+ if (isFile(details.watchedPath)) {
+ _src = `${details.watchedPath}`
+ } else {
+ _src = path.resolve(`${details.watchedPath}/${_path}`)
+ }
+ if (!exists(details.watchedPath)) {
+ return
+ }
+ if (lockMap[_src]) {
+ return
+ }
+ if (exists(_src) && isFile(_src)) {
+ lockMap[_src] = true
+ createContent(_src, { ...options })
+ setTimeout(() => { lockMap[_src] = false }, 3000)
+ }
+ break;
+ }
+ }
+ })
+ return watcher
+}
+const compileAllEx = async (files, options) => await pMap(files, (f: string) => createContent(f, options), { concurrency: 1 })
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('compile', 'Compile ', async function () {
+ const done = this.async()
+ const task_options = this.data.options
+ const cwd = path.resolve(option('cwd', task_options, grunt, process.cwd()))
+
+ const options: ICompileTaskOptions2 = {
+ ...this.data.options,
+ cache: option('cache', task_options, grunt, true),
+ clear: option('clear', task_options, grunt, false),
+ debug: option('debug', task_options, grunt),
+ debugWatch: option('debugWatch', task_options, grunt),
+ env: option('env', task_options, grunt),
+ format: option('format', task_options, grunt, 'html'),
+ lang: option('lang', task_options, grunt, 'osr'),
+ language: option('language', task_options, grunt, 'en'),
+ sourceLanguage: option('sourceLanguage', task_options, grunt, 'en'),
+ targetLanguage: option('targetLanguage', task_options, grunt, 'en'),
+ logLevel: option('logLevel', task_options, grunt, 'warn'),
+ module: option('module', task_options, grunt),
+ onCompiled: option('onCompiled', task_options, grunt),
+ onCompileDone: option('onCompileDone', task_options, grunt),
+ onCompile: option('onCompile', task_options, grunt),
+ plugins: option('plugins', task_options, grunt, ['${root}/osr/plugins']),
+ profile: option('profile', task_options, grunt, '${OSR_ROOT}/.osrl.json'),
+ root: option('root', task_options, grunt, path.resolve('./')),
+ template: option('template', task_options, grunt),
+ variables: option('variables', task_options, grunt, {}),
+ watchContent: option('watchContent', task_options, grunt, false)
+ }
+
+ logger.setSettings({ minLevel: options.logLevel as TLogLevelName })
+ if (task_options.watchContent) {
+ this.data.src.map(f => watch(f, options))
+ }
+ let _files = []
+ this.data.src.map(f => {
+ const fInfo = pathInfoEx(f, false, { cwd: cwd, absolute: true })
+ _files = _files.concat(fInfo.FILES)
+ })
+ if (!_files.length) {
+ logger.error(`Have no files or glob in ${cwd}`, this.data.src)
+ done()
+ return
+ }
+ logger.debug(`Compile - task data`, _files, this.data.options)
+ if (options.clear !== false) {
+ if (exists(options.output)) {
+ rm(options.output)
+ }
+ }
+ const all = await compileAllEx(_files, options)
+ grunt.event.emit('compile.done', { all, options })
+ if (!task_options.watchContent) {
+ logger.info('Done compiling all!')
+ done()
+ }
+ return new Promise((resolve) => {
+ if (!task_options.watchContent) {
+ resolve(true)
+ done()
+ }
+ })
+ })
+}
+export const contentTasks = (
+ grunt: IGrunt,
+ taskOpts: ICompileTaskOptions,
+ compilerOpts: ICompileOptions) => {
+ taskOpts =
+ {
+ ...taskOptions().parse({
+ ...taskOpts,
+ ...gruntOptions(grunt)
+ })
+ }
+ compilerOpts = compilerOptions().parse(compilerOpts as any) as ICompileOptions
+ logger.setSettings({ minLevel: taskOpts.logLevel, prefix: [MODULE_NAME] })
+ // logger.warn(`Registering content tasks for ${taskOpts.taskPrefix}`,taskOpts)
+ const tasks = {}
+ const taskLanguages = taskOpts.languages as string[]
+ const taskLanguage = (lang) => {
+ const taskName = `${taskOpts.taskPrefix}-${lang}`
+ const config = {}
+ const taskVariables =
+ {
+ ...compilerOpts.variables,
+ ...gruntOptions(grunt),
+ targetLanguage: lang,
+ sourceLanguage: taskOpts.sourceLanguage,
+ i18n: I18N_STORE(OSR_ROOT(), lang)
+ }
+ config[taskName] = {
+ src: taskOpts.src,
+ options:
+ {
+ ...compilerOpts as any,
+ variables: { ...taskVariables },
+ output: path.resolve(resolve(compilerOpts.output, false, taskVariables)),
+ ...taskOpts,
+ ...gruntOptions(grunt)
+ }
+ };
+
+ (grunt as any).extendConfig({ compile: config })
+
+ const substituteTask = (task: string) => substitute(false, task, {
+ ...config[taskName].options.variables,
+ taskSuffix: taskOpts.taskSuffix,
+ taskPrefix: taskOpts.taskPrefix,
+ task
+ })
+ const tasksBefore = taskOpts.tasksBefore.map(substituteTask)
+ const tasksAfter = taskOpts.tasksAfter.map(substituteTask)
+ const languageTasks = [
+ ...tasksBefore,
+ `compile:${taskName}`,
+ ...tasksAfter,
+ ]
+ grunt.registerTask(taskName, languageTasks)
+ tasks[lang] = {
+ taskName,
+ tasks: languageTasks
+ }
+ }
+ taskLanguages.forEach(taskLanguage)
+ return tasks
+}
+
+export * from '../src/zod_types'
diff --git a/packages/tasks/src/config.ts b/packages/tasks/src/config.ts
index 9b8d79a7..17ac3e73 100644
--- a/packages/tasks/src/config.ts
+++ b/packages/tasks/src/config.ts
@@ -3,8 +3,9 @@ import { resolve } from '@plastichub/osr-commons'
export const OSR_ROOT = () => path.resolve(resolve("${OSR_ROOT}"))
+// Grunt Commons
+export const LOG_LEVEL_GRUNT = 'info'
// Supported languages
-export const TRANSLATE_CONTENT = true // translate regular pages
export const LANGUAGES = ['de']
// i18n constants
@@ -12,36 +13,119 @@ export const I18N_STORE = (root, lang) => `${root}/i18n-store/store-${lang}.json
export const I18N_SOURCE_LANGUAGE = 'en'
// Product compiler
+export const PRODUCT_BODY = `templates/shared/body.md`
export const PRODUCT_ROOT = () => path.resolve(resolve("${OSR_ROOT}/products"))
export const PRODUCT_CONFIG = (product) =>
- path.resolve(resolve("${OSR_ROOT}/products/${product}/config.json", false,
- {
- product
- }))
+ path.resolve(resolve("${OSR_ROOT}/products/${product}/config.json", false, { product }))
export const PRODUCT_DIR = (product) =>
- path.resolve(resolve("${OSR_ROOT}/products/${product}", false,
- {
- product
- }))
+ path.resolve(resolve("${OSR_ROOT}/products/${product}", false, { product }))
export const IS_DEV = true
export const OSRL_ENV = 'bazar-release'
export const OSRL_ENV_DEV = 'hugo-debug'
export const OSRL_ENVIRONMENT = IS_DEV ? OSRL_ENV_DEV : OSRL_ENV
+export const PRODUCT_HUGO_TEMPLATE = './osr/hugo/root.html'
+export const PRODUCTS_TARGET_SRC = './src/content/en/retail'
// OSRL - Language
export const OSRL_MODULE_NAME = 'osr-site'
-export const OSRL_PRODUCT_PROFILE = '${root}/.osrl.json'
-export const OSRL_LANG_FLAVOR = 'osr'
-export const OSRL_FORMAT = 'html'
-
-// Tasks
-export const TASK_CONFIG_LOG_DIRECTORY = './config/'
-
-// Task: compile:content
-export const TASK_COMPILE_CONTENT = true
-export const TASK_COMPILE_CONTENT_CACHE = true
-export const TASK_COMPILE_DEFAULT_PROFILE = '${OSR_ROOT}/osr-templates/osrl/.osrl.json'
-export const TASK_COMPILE_DEFAULT_PLUGINS = '${root}/osr/plugins'
// Task - Logging
-export const TASK_LOG_DIRECTORY = './logs/'
\ No newline at end of file
+export const TASK_LOG_DIRECTORY = './logs/'
+
+// Task - Retail Config
+
+export const RETAIL_DEFAULT_BRANCH = 'dev'
+export const RETAIL_MEDIA_CACHE = true
+export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = 'info'
+
+export const ConvertProductMedia = true
+export const TranslateProductAssets = true
+export const PopulateProductDefaults = true
+
+export const PRODUCT_TEMPLATE = './osr/bazar/root.html'
+export const HTML_DEFAULT_PATH = 'resources/edrawings.html'
+
+export const DEFAULT_CAD_CAM_EXPORT = '${SRC_DIR}/${SRC_NAME}.+(step)'
+export const DEFAULT_CAD_EXPORT = '${SRC_DIR}/${SRC_NAME}.+(json|html|step|x_t)'
+export const DEFAULT_CAD_EXPORT_CONFIGURATION = '${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(json|html|step|x_t)'
+export const DEFAULT_CAD_EXPORT_MIN = '${SRC_DIR}/${SRC_NAME}.+(json)'
+export const DEFAULT_CAD_EXPORT_MIN_CONFIGURATION = '${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(json)'
+
+export const SYNC_PROFILE = '${OSR_ROOT}/osr-commons/profiles/.osr-sync-public.json'
+export const PRODUCT_ROOT_REL = '${PRODUCT_ROOT}/products'
+export const SYNC_TARGET = '${OSR_ROOT}/osr-machines/'
+
+export const CAD_MAIN_MATCH = (product) => `${product}/cad*/**/*Global*.+(SLDASM)`
+export const CAD_CAM_MAIN_MATCH = (product) => `${product}/cad*/**/*-CNC*.+(SLDASM)`
+
+export const CAD_CACHE = false
+export const CAD_EXPORT_CONFIGURATIONS = false
+export const CAD_EXPORT_SUB_COMPONENTS = false
+export const CAD_MODEL_FILE_PATH = (SOURCE, CONFIGURATION = '') =>
+ SOURCE.replace('.json', `${CONFIGURATION ? '-' + CONFIGURATION : ''}.tree.json`)
+export const CAD_DEFAULT_CONFIGURATION = 'Default'
+export const CAD_RENDERER = 'solidworks'
+export const CAD_RENDERER_VIEW = 'Render'
+export const CAD_RENDERER_QUALITY = 1
+
+////////////////////////////////////////////////////////////
+//
+// Content Tasks
+
+export const ENABLE_NEWSLETTER = true
+export const ENABLE_MAIL = false
+
+// newsletter
+export const NEWSLETTER_ROOT = `company/new sletter/2024/08`
+export const NEWSLETTER_LOG_LEVEL = 'debug'
+export const NEWSLETTER_LANGUAGES = ['en']
+export const NEWSLETTER_TEMPLATE_FILE = 'root.osr'
+export const NEWSLETTER_SRC_FILE = 'mail.html'
+export const NEWSLETTER_DST_DIR = '${OSR_ROOT}/products/products/assets/newsletter/'
+export const NEWSLETTER_DST_FILE = '${prefix}_newsletter_${YYYY}-${MM}_${targetLanguage}.html'
+export const NEWSLETTER_DEFAULT_ENV = 'hugo-release'
+export const NEWSLETTER_DEBUG_PROFILE = 'hugo-debug'
+export const NEWSLETTER_RELEASE_PROFILE = 'hugo-release'
+export const NEWSLETTER_COMPILE_CACHE = false
+
+// mail
+export const MAIL_ROOT = `company/mail/2024/08`
+export const MAIL_LOG_LEVEL = 'debug'
+export const MAIL_CONTACTS_ROOT = () => `${PRODUCT_ROOT()}/company/campaign/contacts`
+export const MAIL_ASSETS_ROOT = () => `${PRODUCT_ROOT()}/company/campaign/data`
+export const MAIL_OUTPUT_DIR = '/products/assets/newsletter/mail/'
+export const MAIL_OUTPUT_FILE_NAME = 'mail_2024_09'
+export const MAIL_OUTPUT_FILE_NAME_PROD = `${MAIL_OUTPUT_FILE_NAME}_public`
+export const MAIL_OUTPUT_FILE_EXT = '.html'
+export const MAIL_PROFILE = "${OSR_ROOT}/osr-templates/osrl/.osrl.json"
+export const MAIL_SRC_LANGUAGE = 'en'
+export const MAIL_LANGUAGES = ['en', 'es']
+export const MAIL_LANGUAGES_RELEASE = ['en', 'es', 'de', 'fr']
+export const MAIL_ENV_DEV = 'hugo-debug'
+export const MAIL_ENV_PROD = 'hugo-release'
+export const MAIL_TEMPLATE = "./root.osr"
+export const MAIL_SOURCE_FILE = "mail.html"
+export const MAIL_COMPILE_CACHE = false
+export const MAIL_I18N_CACHE = true
+export const MAIL_SEND_INTERVAL = 1000
+export const MAIL_DEFAULT_OUTPUT_PATH = "${SRC_DIR}/${SRC_NAME-0}-${DST_LANG}${SRC_EXT}"
+//////////////////////////////////////////////////////
+//
+// Store query templates
+export const buildQuery = (typeFilter, emailRequired = true, geoFilter = {}, params = "", additionalFilter = "") => {
+ const types = typeFilter || [
+ "Carpenter",
+ "Woodworker",
+ "Furniture maker",
+ "Cabinet maker",
+ "Furniture manufacturer"
+ ]
+ const typeCondition = types.map(type => `@.type == "${type}"`).join(" || ")
+ const emailCondition = emailRequired ? "&& @.email != null" : ""
+ const geoConditions = Object.entries(geoFilter).map(([key, value]) => `&& @.geo.${key} == "${value}"`).join(" ")
+ return `$[?(((${typeCondition}) ${emailCondition} ${geoConditions} ${additionalFilter}) ${params})]`
+}
+
+export const QUERY_TEMPLATES = {
+
+}
\ No newline at end of file
diff --git a/packages/tasks/src/contacts.ts b/packages/tasks/src/contacts.ts
new file mode 100644
index 00000000..608321fc
--- /dev/null
+++ b/packages/tasks/src/contacts.ts
@@ -0,0 +1,51 @@
+import * as path from 'path'
+import { JSONPath } from 'jsonpath-plus'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { resolve } from '@plastichub/osr-commons'
+
+import {
+ MAIL_CONTACTS_ROOT,
+ QUERY_TEMPLATES
+} from './config'
+
+import { logger } from '../src'
+import { cleanArray } from './utils'
+
+export const resolveContactsPath = (mailerOptions) => {
+ if (!mailerOptions.contacts) {
+ return false
+ }
+ let contactFiles = path.resolve(resolve(mailerOptions.contacts))
+ if (!exists(contactFiles)) {
+ contactFiles = path.join(MAIL_CONTACTS_ROOT(), mailerOptions.contacts)
+ }
+ return contactFiles
+}
+
+export const getContacts = (mailerOptions) => {
+ let contactFiles = resolveContactsPath(mailerOptions)
+ if (!contactFiles) {
+ return []
+ }
+ logger.debug(`Reading Contact File : ${contactFiles}`)
+ let contacts = read(contactFiles, 'json') as any[]
+ if (!contacts) {
+ logger.error(`Cannot read contacts file ${contactFiles}`)
+ return []
+ }
+ return contacts
+}
+
+export const filterContacts = (grunt, contacts, mailerOptions) => {
+ if (!mailerOptions.query) {
+ return contacts
+ }
+ if (QUERY_TEMPLATES[mailerOptions.query]) {
+ mailerOptions.query = QUERY_TEMPLATES[mailerOptions.query](grunt.option('queryExtra'))
+ }
+ let queryResult = JSONPath({ path: mailerOptions.query, json: contacts })
+ logger.debug(`Query Result : ${queryResult.length} contacts : \n\t ${mailerOptions.query}`)
+ queryResult = cleanArray(queryResult)
+ return queryResult
+}
diff --git a/packages/tasks/src/cscart.ts b/packages/tasks/src/cscart.ts
new file mode 100644
index 00000000..7f31181e
--- /dev/null
+++ b/packages/tasks/src/cscart.ts
@@ -0,0 +1,30 @@
+import { logger } from '../src'
+import { option } from '../library'
+import { CONFIG_DEFAULT } from '@plastichub/osr-commons/config'
+import { resolve } from '@plastichub/osr-commons'
+import { IOSRConfig } from '@plastichub/osr-commons'
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('cscart', 'Deploy product to CSCart', async function () {
+
+ const done = this.async();
+ const task_options = this.data.options || {}
+
+ const config = CONFIG_DEFAULT() as IOSRConfig
+
+ const options = {
+ ...this.data.options,
+ debug: option('debug', task_options, grunt),
+ verbose: option('verbose', task_options, grunt),
+ vendor: option('vendor', task_options, grunt)
+ }
+
+ const src = this.data.src.map(f => (resolve(f)))
+
+ options.debug && logger.info('Compile - task data ', process.cwd(), this.data, src)
+
+ // let ret = await updateProducts(src, config.cscart, options.vendor)
+
+ debugger;
+ });
+};
diff --git a/packages/tasks/src/git.ts b/packages/tasks/src/git.ts
new file mode 100644
index 00000000..61cdfc1d
--- /dev/null
+++ b/packages/tasks/src/git.ts
@@ -0,0 +1,63 @@
+import { simpleGit } from 'simple-git'
+import { resolve } from '@plastichub/osr-commons'
+import { logger } from '../src/index'
+import { option } from '../library'
+
+const GIT_MESSAGE_PREFIX = (rel: string) => `Updating - ${rel}`
+
+export async function git_update(options) {
+
+ const { cwd, rel, message, debug } = options
+
+ const git = simpleGit(cwd)
+ let commit: any = null
+ let push: any = null
+
+ try {
+ debug && logger.debug("commit " + rel + " in " + cwd)
+ commit = await git.add(rel)
+ }
+ catch (e) {
+ logger.error('Error Git Commit', e)
+ }
+
+ try {
+ debug && logger.debug("commit " + rel + " in " + cwd)
+ commit = await git.commit(message || GIT_MESSAGE_PREFIX(rel), rel)
+ }
+ catch (e) {
+ logger.error('Error Git Commit', e)
+ }
+ try {
+ push = await git.push()
+ }
+ catch (e) {
+ logger.error('Error Git Push', e)
+ }
+ return { commit, push }
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('git', 'Adds, commits and pushes folders', async function () {
+ const done = this.async()
+ const task_options = this.data || {}
+ const logLevel = option('logLevel', task_options, grunt, 'warn')
+ logger.setSettings({ minLevel: logLevel })
+
+ let rel: string = this.data.rel
+ const variables = {
+ ...task_options.variables || {}
+ }
+ const options = {
+ rel: resolve(rel, false, variables),
+ cwd: resolve(option('cwd', task_options, grunt), false),
+ message: option('message', task_options, grunt),
+ debug: option('debug', task_options, grunt),
+ verbose: option('verbose', task_options, grunt),
+ logLevel
+ }
+ logger.info('Git - task data ', this.data)
+ await git_update(options)
+ done()
+ })
+}
\ No newline at end of file
diff --git a/packages/tasks/src/i18n.ts b/packages/tasks/src/i18n.ts
new file mode 100644
index 00000000..1619c700
--- /dev/null
+++ b/packages/tasks/src/i18n.ts
@@ -0,0 +1,55 @@
+import * as path from 'path'
+import { CONFIG_DEFAULT } from '@plastichub/osr-commons'
+import { resolve } from '@plastichub/osr-commons'
+import { IOptions } from '@plastichub/osr-i18n/types'
+import { translate } from '@plastichub/osr-i18n/lib/translate'
+import { sanitize } from '@plastichub/osr-i18n/_cli'
+import { isArray } from '@plastichub/core/primitives'
+import { logger } from '../src'
+import { option } from '../library'
+import * as pMap from 'p-map'
+
+const _translate = async (src, dst, options) => {
+ const i18nOptions = sanitize(
+ {
+ ...options,
+ src: src,
+ dst: dst,
+ debug: options.debug,
+ verbose: options.verbose,
+ dry: options.dry
+ }
+ ) as IOptions
+
+ if (!i18nOptions) {
+ logger.error('Invalid i18n options')
+ return
+ }
+ return await translate(i18nOptions)
+}
+
+const translateAll = async (files, options, dst: string) => {
+ return pMap(files, async (f) => _translate(f, dst, options), { concurrency: 1 })
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('i18n', 'translate files via osr-i18n', async function () {
+ const done = this.async();
+ const task_options = this.data.options || {}
+ const config: any = CONFIG_DEFAULT()
+ const options = {
+ ...this.data.options,
+ root: option('root', task_options, grunt, path.resolve('./')),
+ debug: option('debug', task_options, grunt , false),
+ logLevel: option('logLevel', task_options, grunt , 'warn'),
+ api_key: config.deepl.auth_key
+ }
+ logger.setSettings({ minLevel: options.logLevel })
+ let src: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+ src = src.map(f => (resolve(f)))
+ logger.debug('Translate - task data ', this.data)
+ await translateAll(src, options, this.data.options.dst)
+ logger.info(`Translate - task done : \n\t ${src.join('\n\t')}`)
+ done()
+ })
+}
diff --git a/packages/tasks/src/images.ts b/packages/tasks/src/images.ts
new file mode 100644
index 00000000..363effcf
--- /dev/null
+++ b/packages/tasks/src/images.ts
@@ -0,0 +1,55 @@
+import { Promise as BPromise } from 'bluebird'
+import { isArray } from '@plastichub/core/primitives'
+import { resolve } from '@plastichub/osr-commons'
+
+import { IOptions as IResizeOptions } from '@plastichub/osr-media/types'
+import { sanitize } from '@plastichub/osr-media/_cli'
+import { resize } from '@plastichub/osr-media/lib/media/images'
+
+import { logger } from '../src'
+import { option } from '../library'
+
+const convert = async (src, dst, options) => {
+ const resizeOptions = sanitize(
+ {
+ src: src,
+ dst: dst,
+ debug: options.debug,
+ verbose: options.verbose,
+ dry: options.dry
+ }
+ ) as IResizeOptions
+ return await resize(resizeOptions)
+}
+
+const resizeFiles = async (items, dst, options) => {
+ return BPromise.resolve(items).map((s) => {
+ return convert(s, options, dst)
+ }, {
+ concurrency: 1
+ })
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('images-resize', 'resizes images', function () {
+
+ const done = this.async()
+
+ const task_options = this.data.options || {}
+
+ const options = {
+ ...this.data.options,
+ debug: option('debug', task_options, grunt),
+ verbose: option('verbose', task_options, grunt),
+ dry: option('dry', task_options, grunt)
+ }
+
+ let src: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+
+ src = src.map(f => (resolve(f)))
+
+ options.debug && logger.info('Images-Resize : Task data ', process.cwd(), this.data, src)
+
+ resizeFiles(src, options, this.data.dst).then(done)
+ })
+}
diff --git a/packages/tasks/src/index.ts b/packages/tasks/src/index.ts
index 161309ae..5e16d23a 100644
--- a/packages/tasks/src/index.ts
+++ b/packages/tasks/src/index.ts
@@ -1,4 +1,17 @@
+/**
+ * Callback prototype signature when content has been compiled
+ * @param {string} src The path of the source file
+ * @param {string} dst The path of the destination file
+ * @param {string} content The content
+ * @returns {boolean}
+ */
+export type OnCompiled = (src: string, dst: string, content: string) => Promise
-import { MODULE_NAME } from './constants'
-import { logger as _logger } from '@plastichub/core/debug'
-export const logger = _logger(MODULE_NAME)
+/**
+ * Callback prototype signature when 'compile' task is finish
+ * @param {string} src The path of the source file
+ * @param {string} dst The path of the destination file
+ * @param {string} content The content
+ * @returns {boolean}
+ */
+export type OnCompileDone = (src: string, dst: string, options: any, content: string) => Promise
diff --git a/packages/tasks/src/laser.ts b/packages/tasks/src/laser.ts
new file mode 100644
index 00000000..4fdc8110
--- /dev/null
+++ b/packages/tasks/src/laser.ts
@@ -0,0 +1,213 @@
+import * as path from 'path'
+import * as pMap from 'p-map'
+import { resolve, isFolder } from '@plastichub/osr-commons'
+import { isArray } from '@plastichub/core/primitives'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync } from '@plastichub/osr-sync'
+import { IAssemblyData } from '@plastichub/osr-cad/cad/sw-types'
+import {
+ CAD_MAIN_PATTERN,
+ MainAssembly,
+ file_path_with_ext_ex,
+ forward_slash,
+ unique_by,
+ option
+} from '../library'
+import { logger } from '../src'
+export const regexLaserFile = /^(\d+)_([a-zA-Z0-9]+(?:[_-][a-zA-Z0-9]+)*)_x(\d+)_(\d+)mm_(\w+)$/;
+export const laserDetails = (input: string) => {
+ if(!input) {
+ return false
+ }
+ const match = (path.parse(input).name).match(regexLaserFile)
+ if (!match) {
+ const idMatch = input.match(/^(\d+)_/)
+ const nameMatch = input.match(/_(\w+)_/)
+ const quantityMatch = input.match(/_x\d+_/)
+ const thicknessMatch = input.match(/_\d+mm_/)
+ const materialMatch = input.match(/_\w+$/)
+ let errorMessage = 'Invalid input format:'
+ if (!idMatch) {
+ errorMessage += '\n- Leading ID (digits) is missing or invalid';
+ }
+ if (!nameMatch) {
+ errorMessage += '\n- Name (letters) is missing or invalid';
+ }
+ if (!quantityMatch) {
+ errorMessage += '\n- Quantity (x followed by digits) is missing or invalid';
+ }
+ if (!thicknessMatch) {
+ errorMessage += '\n- Thickness (digits followed by "mm") is missing or invalid';
+ }
+ if (!materialMatch) {
+ errorMessage += '\n- Material (alphanumeric characters) is missing or invalid';
+ }
+ logger.error(errorMessage)
+ return
+ }
+ const [_, id, name, quantity, thickness, material] = match
+ return {
+ id: parseInt(id),
+ name,
+ quantity: parseInt(quantity),
+ thickness: parseInt(thickness),
+ material
+ }
+}
+
+const parts_with_laser = (model) => {
+ let parts = [...model.filter((f) => f.IsLaser === "1"), ...model]
+ return parts.filter((f) => {
+ const _path = path.resolve(resolve(f['File Path']))
+ if (_path && exists(_path)) {
+ const dir = path.parse(_path).dir
+ const laser = path.resolve(path.join(dir, 'laser'))
+ if (exists(laser)) {
+ return f
+ }
+ }
+ })
+}
+
+const createLaserFiles = async (root, product, options, grunt) => {
+ if (!exists(root)) {
+ options.debug && logger.info("Create Laser Files : Root doesnt exists" + root)
+ }
+ const PRODUCT_ROOT = path.resolve(path.join(root, product))
+ if (!exists(PRODUCT_ROOT)) {
+ logger.warn(`Invalid product root : ${PRODUCT_ROOT}`)
+ return false
+ }
+ const main = MainAssembly(PRODUCT_ROOT, options.filePattern)
+ if (!main) {
+ logger.warn("Have no main assembly at " + PRODUCT_ROOT);
+ return false
+ }
+
+ const modelFilePath = file_path_with_ext_ex(main, 'json')
+ if (!modelFilePath || !exists(modelFilePath)) {
+ logger.warn("Have no model at " + modelFilePath)
+ return false
+ }
+ const model = read(modelFilePath, 'json')
+
+ let tree : IAssemblyData = null
+ const treeFilePath = file_path_with_ext_ex(main, 'tree.json')
+ if (!treeFilePath || !exists(treeFilePath)) {
+ logger.warn("Have no tree at " + treeFilePath)
+ }else{
+ tree = read(treeFilePath, 'json') as IAssemblyData
+ }
+
+ const laserParts = parts_with_laser(model)
+
+ let laserDirectories: any[] = [
+ ...new Set(laserParts.map((f) => {
+ const _path = path.resolve(resolve(f['File Path']))
+ const dir = path.parse(_path).dir
+ const ret = {
+ target: forward_slash(path.relative(PRODUCT_ROOT, dir)).
+ replace('../components/', '').
+ replace('components', '').
+ replace('cad', '').
+ replace('../', ''),
+ path: dir + '/laser'
+ }
+ return ret
+ }))
+ ]
+ const config: any = read(path.join(PRODUCT_ROOT, 'config.json'), 'json')
+ if (!config) {
+ return []
+ }
+ laserDirectories = unique_by(laserDirectories, 'path')
+ logger.debug('Create laser files for ', laserDirectories)
+ return (pMap as any)(laserDirectories, async (item) => {
+ return (pMap as any)(['en','es'], async (lCode) => {
+ const renamer = (from, to) => {
+ if (isFolder(from)) { return }
+ const lParts = laserDetails(from)
+ if(!lParts){
+ logger.warn(`Invalid laser file in ${PRODUCT_ROOT} : ${from}`)
+ }
+ const fromParts = path.parse('' + from)
+ const toParts = path.parse('' + to)
+ const pCode = config.code || ''
+ const toFileParts = ('' + toParts.name).split('_')
+ const fromFileParts = ('' + fromParts.name).split('_')
+ const thickness = fromFileParts[3]
+ let qty = fromFileParts[2]
+ let material = fromFileParts[4]
+ if (!material) {
+ logger.error('logger.error : invalid material ', from + ' : ' + ' to : ' + to, toFileParts)
+ return to
+ }
+ if (lCode === 'en') {
+ material = material.toLowerCase().replace("ferro", "Steel").replace("inox", "Stainless")
+ }
+ const newName = path.resolve(
+ toParts.dir + '/' +
+ material + '/' +
+ thickness + '/' +
+ pCode + '-' +
+ toFileParts[0] + '_' +
+ toFileParts[1] + '_' +
+ qty +
+ toParts.ext)
+
+ return newName
+ }
+ return sync({
+ renamer: renamer,
+ clear: options.clear,
+ source: path.resolve(item.path),
+ target: `${PRODUCT_ROOT}/laser/${lCode}/${item.target}`,
+ debug: options.debug,
+ verbose: options.verbose,
+ profile: options.profile
+ })
+ }, {concurrency: 1})
+ },{concurrency: 1})
+}
+
+const create = async (item, options, grunt) => {
+ try {
+ return createLaserFiles(options.cwd || '.', item, options, grunt);
+ } catch (e) {
+ logger.error(e)
+ return []
+ }
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('laser', 'Create laser files', function () {
+ const done = this.async()
+ const task_options = this.data.options || {};
+ let src: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+ logger.setSettings({ minLevel: option('logLevel', task_options, grunt, 'warn') })
+ let p
+ src.forEach((item) => {
+ try {
+ p = create(item, {
+ verbose: option('verbose', task_options, grunt, false),
+ clear: option('clear', task_options, grunt, true),
+ debug: option('debug', task_options, grunt, true),
+ filePattern: option('filePattern', task_options, grunt, CAD_MAIN_PATTERN),
+ profile: option('profile', task_options, grunt, {
+ "matching": ["*"]
+ }),
+ module: option('module', task_options, grunt, 'osr-tasks'),
+ cwd: option('cwd', task_options, grunt, process.cwd())
+ }, grunt)
+ } catch (e) {
+ logger.error(e)
+ }
+ })
+ if (p) {
+ p.then((result) => {
+ done(true)
+ })
+ }
+ })
+}
\ No newline at end of file
diff --git a/packages/tasks/src/laser2.ts b/packages/tasks/src/laser2.ts
new file mode 100644
index 00000000..07a45ee9
--- /dev/null
+++ b/packages/tasks/src/laser2.ts
@@ -0,0 +1,278 @@
+import * as path from 'path'
+import * as pMap from 'p-map'
+import { resolve, isFolder } from '@plastichub/osr-commons'
+import { isArray } from '@plastichub/core/primitives'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync } from '@plastichub/osr-sync'
+
+import {
+ CAD_MAIN_PATTERN,
+ MainAssembly,
+ file_path_with_ext_ex,
+ forward_slash,
+ unique_by,
+ option
+} from '../library'
+import { logger } from '../src'
+import { IAssemblyData, ITreeNode } from '@plastichub/osr-cad/cad/sw-types'
+export const regexLaserFile = /^(\d+)_([a-zA-Z0-9]+(?:[_-][a-zA-Z0-9]+)*)_x(\d+)_(\d+)mm_(\w+)$/;
+export const laserDetails = (input: string) => {
+ if (!input) {
+ return false
+ }
+ const fileName = (path.parse(input).name)
+ const match = fileName.match(regexLaserFile)
+ if (!match) {
+ const idMatch = input.match(/^(\d+)_/)
+ const nameMatch = input.match(/_(\w+)_/)
+ const quantityMatch = input.match(/_x\d+_/)
+ const thicknessMatch = input.match(/_\d+mm_/)
+ const materialMatch = input.match(/_\w+$/)
+ let errorMessage = 'Invalid input format:'
+ if (!idMatch) {
+ errorMessage += `\n- Leading ID (digits) is missing or invalid : ${fileName}`
+ }
+ if (!nameMatch) {
+ errorMessage += `\n- Name (letters) is missing or invalid ${fileName}`
+ }
+ if (!quantityMatch) {
+ errorMessage += `\n- Quantity (x followed by digits) is missing or invalid ${fileName}`
+ }
+ if (!thicknessMatch) {
+ errorMessage += `\n- Thickness (digits followed by "mm") is missing or invalid ${fileName}`
+ }
+ if (!materialMatch) {
+ errorMessage += `\n- Material (alphanumeric characters) is missing or invalid ${fileName}`
+ }
+ logger.error(errorMessage)
+ return
+ }
+ const [_, id, name, quantity, thickness, material] = match
+ return {
+ id: parseInt(id),
+ name,
+ quantity: parseInt(quantity),
+ thickness: parseInt(thickness),
+ material
+ }
+}
+
+const parts_with_laser = (model) => {
+ if(!model){
+ return []
+ }
+ let parts = [...model.filter((f) => f.IsLaser === "1"), ...model]
+ return parts.filter((f) => {
+ const _path = path.resolve(resolve(f['File Path']))
+ if (_path && exists(_path)) {
+ const dir = path.parse(_path).dir
+ const laser = path.resolve(path.join(dir, 'laser'))
+ if (exists(laser)) {
+ return f
+ }
+ }
+ })
+}
+
+export const createLaserFiles = async (root, product, options, grunt) => {
+ if (!exists(root)) {
+ options.debug && logger.info("Create Laser Files : Root doesnt exists" + root)
+ }
+ const PRODUCT_ROOT = path.resolve(path.join(root, product))
+ if (!exists(PRODUCT_ROOT)) {
+ logger.warn(`Invalid product root : ${PRODUCT_ROOT}`)
+ return false
+ }
+ const main = MainAssembly(PRODUCT_ROOT, options.filePattern)
+ if (!main) {
+ logger.warn("Have no main assembly at " + PRODUCT_ROOT);
+ return false
+ }
+
+ const modelFilePath = file_path_with_ext_ex(main, 'json')
+ if (!modelFilePath || !exists(modelFilePath)) {
+ logger.warn("Have no model at " + modelFilePath)
+ return false
+ }
+ const model = read(modelFilePath, 'json')
+
+ let tree: IAssemblyData = null
+ const treeFilePath = file_path_with_ext_ex(main, 'tree.json')
+ if (!treeFilePath || !exists(treeFilePath)) {
+ logger.warn("Have no tree at " + treeFilePath)
+ } else {
+ tree = read(treeFilePath, 'json') as IAssemblyData
+ }
+
+ const laserParts = parts_with_laser(model)
+
+ let laserDirectories: any[] = [
+ ...new Set(laserParts.map((f) => {
+ const _path = path.resolve(resolve(f['File Path']))
+ const dir = path.parse(_path).dir
+ const ret = {
+ target: forward_slash(path.relative(PRODUCT_ROOT, dir)).
+ replace('../components/', '').
+ replace('components', '').
+ replace('cad', '').
+ replace('../', ''),
+ path: path.resolve(dir + '/laser')
+ }
+ return ret
+ }))
+ ]
+ const config: any = read(path.join(PRODUCT_ROOT, 'config.json'), 'json')
+ if (!config) {
+ logger.warn("Have no config at " + PRODUCT_ROOT)
+ return []
+ }
+ laserDirectories = unique_by(laserDirectories, 'path')
+ logger.debug('Create laser files for ', laserDirectories)
+
+ const qtyTotal = (qty, filePath) => {
+ if (tree) {
+ const { Components } = tree.assembly
+ if (!Components) {
+ return qty
+ }
+ const c = Components.filter((c) => {
+
+ const partPath = path.parse(c.Path).name.toLowerCase()
+ const laserFilePath = path.parse(filePath).name.toLowerCase()
+
+ return partPath === laserFilePath && !c.IsSuppressed
+ }).length
+
+ if (c){
+ return c
+ }else{
+ debugger
+ logger.warn(`Cant find instances of file : ${path.parse(filePath).name} : \n\t${filePath} in tree : \n\t${treeFilePath}`)
+ }
+ }
+ return qty
+ }
+
+ const qtyTotal2 = (qty, filePath) => {
+ if (tree) {
+ const { Components } = tree.assembly
+ if (!Components) {
+ return qty
+ }
+ if(filePath.includes('7_Side_x2_6mm_FERRO')){
+ debugger
+ }
+ let count = 1;
+ const chlidren = tree.root.Children;
+ if(chlidren){
+ const items = chlidren.filter((c: ITreeNode) => {
+ const partPath = path.parse(c.Path).name.toLowerCase()
+ const laserFilePath = path.parse(filePath).name.toLowerCase()
+ return partPath === laserFilePath && !c.IsSuppressed
+ })
+ count = items.length;
+ }
+
+ if (count){
+ return count
+ }else{
+ logger.warn(`Cant find instances of file : ${path.parse(filePath).name} : \n\t${filePath} in tree : \n\t${treeFilePath}`)
+ }
+ }
+ return qty
+ }
+
+
+ return (pMap as any)(laserDirectories, async (item) => {
+ return (pMap as any)(['en', 'es'], async (lCode) => {
+ const renamer = (from, to) => {
+ if (isFolder(from)) {
+ return
+ }
+ const lParts: any = laserDetails(from) || {}
+ if (!lParts) {
+ logger.warn(`Invalid laser file in ${PRODUCT_ROOT} : ${from}`)
+ }
+ const fromParts = path.parse('' + from)
+ const toParts = path.parse('' + to)
+ const pCode = config.code || ''
+ const toFileParts = ('' + toParts.name).split('_')
+ const fromFileParts = ('' + fromParts.name).split('_')
+ let qty = qtyTotal2(lParts.quantity, from)
+ let material = fromFileParts[4]
+ if (!material) {
+ logger.error('logger.error : invalid material ', from + ' : ' + ' to : ' + to, toFileParts)
+ return to
+ }
+ if (lCode === 'en') {
+ material = material.toLowerCase().replace("ferro", "Steel").replace("inox", "Stainless")
+ }
+ const newName = path.resolve(
+ toParts.dir + '/' +
+ material + '/' +
+ `${lParts.thickness}mm` + '/' +
+ pCode + '-' +
+ toFileParts[0] + '_' +
+ toFileParts[1] + '_' +
+ `x${qty}` +
+ toParts.ext.toLowerCase())
+
+ return newName
+ }
+ const target = `${PRODUCT_ROOT}/laser/${lCode}/${item.target}`
+ logger.debug(`Create laser files for ${item.path} ${lCode} : to ${target}`)
+ return sync({
+ renamer: renamer,
+ clear: options.clear,
+ source: path.resolve(item.path),
+ target,
+ debug: options.debug,
+ verbose: options.verbose,
+ profile: options.profile,
+ logLevel: options.logLevel || 'warn'
+ })
+ }, { concurrency: 1 })
+ }, { concurrency: 1 })
+}
+
+const create = async (item, options, grunt) => {
+ try {
+ return createLaserFiles(options.cwd || '.', item, options, grunt);
+ } catch (e) {
+ logger.error(e)
+ return []
+ }
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('laser2', 'Create laser files', function () {
+ const done = this.async()
+ const task_options = this.data.options || {};
+ let src: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+ logger.setSettings({ minLevel: option('logLevel', task_options, grunt, 'warn') })
+ let p
+ src.forEach((item) => {
+ try {
+ p = create(item, {
+ verbose: option('verbose', task_options, grunt, false),
+ clear: option('clear', task_options, grunt, true),
+ debug: option('debug', task_options, grunt, true),
+ filePattern: option('filePattern', task_options, grunt, CAD_MAIN_PATTERN),
+ profile: option('profile', task_options, grunt, {
+ "matching": ["*"]
+ }),
+ module: option('module', task_options, grunt, 'osr-tasks'),
+ cwd: option('cwd', task_options, grunt, process.cwd())
+ }, grunt)
+ } catch (e) {
+ logger.error(e)
+ }
+ })
+ if (p) {
+ p.then((result) => {
+ done(true)
+ })
+ }
+ })
+}
\ No newline at end of file
diff --git a/packages/tasks/src/library-images.ts b/packages/tasks/src/library-images.ts
new file mode 100644
index 00000000..6f738e8d
--- /dev/null
+++ b/packages/tasks/src/library-images.ts
@@ -0,0 +1,221 @@
+import * as path from 'path'
+import * as sharp from 'sharp'
+import { sync as dir } from '@plastichub/fs/dir'
+import { sync as exists } from '@plastichub/fs/exists'
+
+import { files as _glob } from '@plastichub/osr-commons'
+
+import { logger } from '../src'
+
+const fg = require('fast-glob')
+
+export const getFormats = (product, folder) => {
+ return [{
+ src: `${product}/${folder}/*.jpg`,
+ dist: `${product}/${folder}/webp`,
+ format: 'webp',
+ }];
+}
+/*
+const updateImages = async (root, product_root, content) => {
+ // Feed the content into JSDOM
+ const dom = new JSDOM(content);
+ const document = dom.window.document;
+
+ // Find the image elements via `querySelectorAll`, replace this selector with your own custom one
+ const imageElems = document.querySelectorAll('img');
+
+ // If there are no matching elements, just return the original content :)
+
+ if (imageElems.length === 0) {
+ return content;
+ }
+
+ for (const imgElem of imageElems) {
+ // Get the `src` of the image element
+ const imgSrc = imgElem.getAttribute('src');
+
+ // Only add this transform for internal images
+ if (imgSrc.startsWith('https') || imgSrc.startsWith('http')) {
+ let srcSet = [];
+
+ // Replace all of the image sources with a new one that matches the results of the Sharp build
+
+
+ if (imgSrc.indexOf('.png') !== -1) {
+ continue;
+ }
+ if (imgSrc.indexOf('.png') !== -1) {
+ continue;
+ }
+
+ const parsed = URI.parse(decodeURIComponent(imgSrc));
+ const pParsed = path.parse(parsed.path);
+ const imageName = (url) => {
+ return decodeURIComponent(pParsed.base);
+ }
+ // const parts = url.parse(imgSrc);
+ // Get the metadata for the file and add it as the `${width}w` needed in defining a `srcset` in HTML for `
`
+ const name = imageName(imgSrc);
+ const _path = decodeURIComponent(parsed.path).replace('//', '');
+ const imageSrcPath = `${root}/${_path}`;
+ if (!exists(imageSrcPath)) {
+ console.log('image doesnt exists : ' + imageSrcPath + ' \n\t' + imgSrc);
+ return;
+ }
+ const imageSrcPathParts = path.parse(imageSrcPath);
+
+ const imgSrc80 = imgSrc.replace(name, '80/' + name);
+ const imgSrc60 = imgSrc.replace(name, '60/' + name);
+ const imgSrc40 = imgSrc.replace(name, '40/' + name);
+ const imgSrc20 = imgSrc.replace(name, '20/' + name);
+
+ const _set = (res) => {
+ return path.resolve(imageSrcPathParts.dir + '/' + res + '/' + name);
+ }
+
+ if (!exists(_set(80))) {
+ console.error('doesnt exists ', _set(80), imgSrc);
+ continue;
+ }
+
+ if (!exists(_set(60))) {
+ console.error('doesnt exists ', _set(60), imgSrc);
+ continue;
+ }
+ if (!exists(_set(40))) {
+ console.error('doesnt exists ', _set(40), imgSrc);
+ continue;
+ }
+ if (!exists(_set(20))) {
+ console.error('doesnt exists ', _set(20), imgSrc);
+ continue;
+ }
+
+ const img80 = await sharp(_set(80));
+ const md80 = await img80.metadata();
+ srcSet.push(`${imgSrc80.replace(/\s/g,'%20')} ${md80.width}w`);
+
+ // Repeat
+ const img60 = await sharp(_set(60));
+ const md60 = await img60.metadata();
+ srcSet.push(`${imgSrc60.replace(/\s/g,'%20')} ${md60.width}w`);
+
+ // Repeat
+ const img40 = await sharp(_set(40));
+ const md40 = await img40.metadata();
+ srcSet.push(`${imgSrc40.replace(/\s/g,'%20')} ${md40.width}w`);
+
+ // Repeat
+ const img20 = await sharp(_set(20));
+ const md20 = await img20.metadata();
+ srcSet.push(`${imgSrc20.replace(/\s/g,'%20')} ${md20.width}w`);
+
+ // Join the `srcset` into a string. that can be added to the `
` tag
+ srcSet = srcSet.join(', ');
+ // Set the `srcset` attribute
+ imgElem.setAttribute('srcset', srcSet);
+ // Find the new `src` for the WebP image
+
+ let webpSrc = imgSrc.replace(name, 'webp/' + encodeURIComponent(name)).replace('.png', '.webp').replace('.jpg', '.webp');
+
+ // const webpSrc = imgSrc
+ // .replace('/images/', '/images/webp/')
+ // .replace('.png', '.webp');
+ // Create a separate `source` element for the WebP with feature detection via `type`
+
+ const webpElement = document.createElement('source');
+ webpElement.setAttribute('srcset', webpSrc);
+ webpElement.setAttribute('type', 'image/webp');
+
+ // Wrap the `
` and the `` into one `` tag in order for it to work
+
+ const pictureElement = document.createElement('picture');
+ pictureElement.appendChild(webpElement);
+ pictureElement.appendChild(imgElem.cloneNode());
+
+ // Replace the `
` with the ``
+
+ imgElem.replaceWith(pictureElement);
+ }
+ }
+ return document.documentElement.outerHTML;
+}
+*/
+
+export const format = (formats) => {
+ return formats.forEach((format) => {
+ if (!exists(format.dist)) {
+ dir(format.dist)
+ }
+
+ // Find all files matching the glob patterns specified in `src`
+ let _files = fg.sync(format.src)
+
+ _files.forEach((file) => {
+ let filename = path.basename(file);
+ if (exists(path.resolve(`${format.dist}/${filename.replace('jpg', format.format)}`))) {
+ return;
+ }
+
+ const image = sharp(file);
+
+ // Convert to WebP via Sharp's inferencing automatically of extensions
+ image
+ .toFile(`${format.dist}/${filename.replace('jpg', format.format)}`)
+ .catch((err) => {
+ console.log(err);
+ });
+ });
+ });
+}
+
+export const getResizePatterns = (product, folder) => {
+ return [{
+ src: `${product}/${folder}/*.jpg`,
+ dist: `${product}/${folder}/80`,
+ percent: 80,
+ },
+ {
+ src: `${product}/${folder}/*.jpg`,
+ dist: `${product}/${folder}/60`,
+ percent: 60,
+ },
+ {
+ src: `${product}/${folder}/*.jpg`,
+ dist: `${product}/${folder}/40`,
+ percent: 40,
+ },
+ {
+ src: `${product}/${folder}/*.jpg`,
+ dist: `${product}/${folder}/20`,
+ percent: 20,
+ },
+ ];
+}
+
+const resize = (patterns) => {
+ return patterns.forEach((resize) => {
+ if (!exists(resize.dist)) {
+ dir(resize.dist)
+ }
+ let _files = fg.sync(resize.src)
+ _files.forEach((file) => {
+ let filename = path.basename(file)
+ const image = sharp(file)
+ if (exists(`${resize.dist}/${filename}`)) {
+ return
+ }
+ image
+ .metadata()
+ .then((metadata) => {
+ return image
+ .resize(Math.round(metadata.width * (resize.percent / 100)))
+ .png()
+ .toFile(`${resize.dist}/${filename}`)
+ .catch(logger.error);
+ })
+ .catch(logger.error)
+ })
+ })
+}
diff --git a/packages/tasks/src/mail.ts b/packages/tasks/src/mail.ts
new file mode 100644
index 00000000..b6c58901
--- /dev/null
+++ b/packages/tasks/src/mail.ts
@@ -0,0 +1,257 @@
+import * as path from 'path'
+import * as pMap from 'p-map'
+import { sync as write } from '@plastichub/fs/write'
+import { substitute } from '@plastichub/core'
+import { isArray, isObject } from '@plastichub/core/primitives'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { resolve, filesEx } from '@plastichub/osr-commons'
+import { test as send } from '@plastichub/osr-mail/lib/nodemailer'
+import {
+ MAIL_LOG_LEVEL,
+ MAIL_ENV_DEV,
+ MAIL_LANGUAGES,
+ MAIL_PROFILE,
+ MAIL_SOURCE_FILE,
+ MAIL_SRC_LANGUAGE,
+ MAIL_TEMPLATE,
+ MAIL_COMPILE_CACHE,
+ MAIL_ASSETS_ROOT,
+ MAIL_I18N_CACHE,
+ MAIL_DEFAULT_OUTPUT_PATH as SHEET_TRANSLATION_PATH
+} from './config'
+
+import { sheetTranslationTask } from './sheets'
+import { onCompiledMail } from './mail_utils'
+import { gruntOptions } from '../library'
+import { ICompileOptions } from './compile'
+import { I18N_STORE, OSR_ROOT } from './config'
+import { logger } from '../src'
+import { getOutputFileName, prepMailQueue } from './mail_utils'
+import { mailOptionSchema, enumerateHelpStrings, mailCompileSchema } from './utils'
+import { resolveContactsPath, getContacts, filterContacts } from './contacts'
+
+const getSubject = (language: string) => {
+ const subjectPath = path.resolve(resolve(`${OSR_ROOT()}/products/company/campaign/content/subject-${language}.md`))
+ if (!exists(subjectPath)) {
+ logger.error(`Cannot read subject file ${subjectPath}`)
+ return 'Default Subject'
+ }
+ return read(subjectPath) || 'Default Subject'
+}
+
+const sendOptions = (grunt, language: string = 'en') => {
+ const subject = getSubject(language)
+ return {
+ from: 'PlasticHub ',
+ transport: 'newsletter',
+ subject,
+ contacts: '',
+ filter: true,
+ query: null,
+ to: null,
+ source: `${OSR_ROOT()}/products/products/assets/newsletter/mail/mail_2024_09_public_${language}.html`,
+ ...gruntOptions(grunt)
+ }
+}
+
+const sendMailQueue = async (grunt) => {
+ const mailerOptions = sendOptions(grunt, grunt.option('lang') || 'en')
+ const source = read(path.resolve(resolve(mailerOptions.source)))
+ if (!source) {
+ logger.error(`Cannot read source file ${mailerOptions.source}`)
+ return
+ }
+ let contacts = getContacts(mailerOptions)
+ if (!contacts) {
+ logger.error(`Invalid contacts: ${resolveContactsPath(mailerOptions)}`)
+ return
+ }
+ if (!isArray(contacts) && isObject(contacts)) {
+ contacts = Object.keys(contacts).map((k) => contacts[k])
+ }
+ const total = contacts.length
+ contacts = filterContacts(grunt, contacts, mailerOptions)
+ if (mailerOptions.filter !== false) {
+ contacts = contacts.filter((contact) => contact.email && contact.email.length > 0)
+ contacts = contacts.filter((contact) => contact.status !== 'sent')
+ }
+ const sendMail = async (contact, options) => {
+ const subject = getSubject(grunt.option('lang'))
+ if (!contact.email) {
+ logger.error(`Invalid contact : ${contact}`)
+ return
+ }
+ logger.info(`Sending mail to ${contact.email}`)
+ const opts = {
+ ...options,
+ from: 'Lovebird ',
+ subject: subject,
+ transport: "newsletter",
+ to: contact.email,
+ html: substitute(source, {
+ unsubscribe_email: contact.email
+ })
+ }
+ const mail = await send(opts)
+ contact.mail = mail
+ contact.status = 'sent'
+ const contactsFile = resolveContactsPath(mailerOptions)
+ if (mailerOptions.contacts && contactsFile) {
+ const last = read(contactsFile, 'json')
+ last[contact.title] = contact
+ write(contactsFile, last)
+ }
+ logger.info(`Sent mail to ${contact.email}`)
+ return mail
+ }
+
+ if (contacts.length === 0 && mailerOptions.to) {
+ contacts = [{ email: mailerOptions.to }]
+ }
+ if (grunt.option('dry')) {
+ logger.info(`Dry : Sending ${contacts.length} mails in total, of ${total} contacts`)
+ return false
+ } else {
+ logger.debug(`Sending ${path.resolve(resolve(mailerOptions.source))} to ${contacts.length} mails`)
+ }
+
+ const mails = await pMap(contacts, async (contact) => {
+ return sendMail(contact, mailerOptions)
+ }, { concurrency: 1 })
+
+ logger.info(`Sent ${mails.length} mails`)
+ return mails
+}
+
+export const getOutputFile = (grunt, root, slug, options = {}, language: string = 'en') => {
+ const env = grunt.option('env') || MAIL_ENV_DEV
+ const isDebug = env === MAIL_ENV_DEV
+ const outFile = getOutputFileName(isDebug, slug, language)
+ const output = path.resolve(path.join(root, outFile))
+ return output
+}
+
+export const mailCompileOptions = (grunt: any, root, slug, options = {}, language: string = 'en') => {
+ const template = grunt.option('template') ?
+ path.resolve(resolve(grunt.option('template'))) : path.join(root, slug, MAIL_TEMPLATE)
+
+ const env = grunt.option('env') || MAIL_ENV_DEV
+ const isDebug = env === MAIL_ENV_DEV
+ const outFile = getOutputFileName(isDebug, slug, language)
+ const output = grunt.option('output') ?
+ path.resolve(resolve(grunt.option('output'))) : path.resolve(path.join(root, outFile))
+
+ root = path.join(root, slug)
+
+ const onCompiled = async (src, dst, content) => {
+ const ret = await onCompiledMail(src, dst, content)
+ if (grunt.option('send') && !grunt.option('contacts')) {
+ const opts = {
+ from: 'Lovebird ',
+ to: grunt.option('to') || 'cgoflyn@gmail.com',
+ html: substitute(ret, {
+ unsubscribe_email: 'cgoflyn@gmail.com'
+ }),
+ subject: `Test Mail : - ${language} : - ` + Math.random(),
+ transport: "newsletter",
+ ...gruntOptions(grunt)
+ }
+ await send(opts)
+ }
+ return ret
+ }
+
+ const ret: ICompileOptions = {
+ cache: MAIL_COMPILE_CACHE,
+ root,
+ cwd: root,
+ env,
+ format: 'html',
+ language: 'osr',
+ logLevel: grunt.option('logLevel') || MAIL_LOG_LEVEL,
+ module: 'plastichub-mail',
+ profile: MAIL_PROFILE as any,
+ template,
+ output,
+ // onCompiled: !isDebug || grunt.option('send') ? onCompiled : undefined,
+ variables: {
+ cwd: root,
+ root,
+ targetLanguage: language as any,
+ sourceLanguage: MAIL_SRC_LANGUAGE,
+ i18n: I18N_STORE(OSR_ROOT(), language),
+ ...gruntOptions(grunt)
+ },
+ ...options,
+ ...gruntOptions(grunt)
+ }
+ return ret
+}
+
+export const mailSendTask = (grunt, root, directory, options: any = {}, newsletter_tasks) => {
+ grunt.registerTask(`prepare-mail-contacts`, async () => {
+ prepMailQueue(grunt, root, directory, options)
+ })
+ grunt.registerTask(`send-mail-queue`, "help", async function () {
+ this.async()
+ try {
+ await sendMailQueue(grunt)
+ } catch (e) {
+ logger.error(`Error sending mail : ${e.message}`, e.stack)
+ }
+ })
+ if (grunt.option('describe')) {
+ grunt.registerTask(`send-mail`, () => {
+ logger.setSettings({
+ displayFunctionName: false,
+ displayInstanceName: false,
+ displayLogLevel: false,
+ displayLoggerName: false,
+ displayDateTime: false,
+ displayFilePath: "hidden"
+ })
+ logger.debug(`\nOptions : ${mailOptionSchema._def.description}`)
+ logger.info(`send mail options: Directory:${directory}`, enumerateHelpStrings(mailOptionSchema, [], logger))
+
+ logger.debug(`\nOptions : ${mailCompileSchema(grunt)._def.description}`)
+ logger.info(`send compile schema options:`, enumerateHelpStrings(mailCompileSchema(grunt), [], logger))
+ })
+ return
+ } else {
+ grunt.registerTask(`send-mail`, [`mail-tasks`, "send-mail-queue"])
+ }
+}
+
+export const mailTask = (grunt, root, directory, options: any = {}, newsletter_tasks) => {
+ const mailAssets = filesEx(MAIL_ASSETS_ROOT(), '*-en.xlsx')
+ const mailAssetTasks = []
+ const languages: string[] = grunt.option('languages') ? grunt.option('languages').split(',') : MAIL_LANGUAGES
+ sheetTranslationTask(grunt, 'mail-assets',
+ mailAssets, languages, mailAssetTasks,
+ {
+ dst: SHEET_TRANSLATION_PATH,
+ cache: MAIL_I18N_CACHE,
+ query: "$[*][0,1,2,3,4,5]"
+ })
+
+ ////////////////////////////////
+ // Content Compile Tasks
+ const config = {}
+ const slug = directory.replace(/\//g, '-')
+ const extraOptions = {}
+ const source = grunt.option('source') ?
+ path.resolve(resolve(grunt.option('source'))) : path.join(root, directory, MAIL_SOURCE_FILE)
+ languages.forEach((lang) => {
+ config[`${slug}-${lang}`] = {
+ src: [source],
+ options: mailCompileOptions(grunt, root, directory, extraOptions, lang)
+ }
+ grunt.extendConfig({ compile: config })
+ write('./tmp/compile-mail/options.json', config)
+ grunt.registerTask(`${slug}-${lang}`, [`mail-assets-${lang}`, `compile:${slug}-${lang}`])
+ newsletter_tasks.push(`compile:${slug}-${lang}`)
+ })
+ grunt.registerTask(`mail-tasks`, newsletter_tasks)
+}
+
diff --git a/packages/tasks/src/mail_utils.ts b/packages/tasks/src/mail_utils.ts
new file mode 100644
index 00000000..92060095
--- /dev/null
+++ b/packages/tasks/src/mail_utils.ts
@@ -0,0 +1,85 @@
+import * as path from 'path'
+import * as juice from 'juice'
+import { minify } from 'html-minifier-terser'
+
+import { filesEx } from '@plastichub/osr-commons/_glob'
+import { sync as write } from '@plastichub/fs/write'
+import * as XLSX from 'xlsx'
+import { logger } from '../src'
+import { gruntOptions } from '../library'
+
+import {
+ MAIL_OUTPUT_DIR,
+ MAIL_OUTPUT_FILE_EXT,
+ MAIL_OUTPUT_FILE_NAME,
+ MAIL_OUTPUT_FILE_NAME_PROD,
+ PRODUCT_ROOT
+} from './config'
+
+type TableData = (string | null)[][]
+
+export const prepMailQueue = async (grunt, root, directory, options: any = {},) => {
+
+ logger.info(`Sending mail queue from ${directory}`)
+
+ const mailRoot = path.join(root, directory)
+ const mailContentRoot = path.join(mailRoot, 'data')
+ const contactFiles = filesEx(mailContentRoot, '*.xlsx')
+ contactFiles.forEach((file) => {
+ const workbook = XLSX.readFile(file)
+ const worksheet = workbook.Sheets[workbook.SheetNames[0]]
+ const raw_data: any[] = XLSX.utils.sheet_to_json(worksheet, { header: 1, blankrows: false, raw: false, skipHidden: false })
+ const contacts = convertToJSON(raw_data)
+ const dst = path.join(mailContentRoot, path.parse(file).name + '.json')
+ logger.info(`Writing contacts from ${file} to ${dst}`)
+ write(dst, JSON.stringify(contacts, null, 2))
+ })
+}
+
+
+export const convertToJSON = (data: TableData): object[] => {
+ const [fields, ...rows] = data;
+ return rows.map(row => {
+ const jsonObject: any = {};
+ row.forEach((value, index) => {
+ let fieldName = fields[index];
+ if (fieldName?.toLowerCase().includes('mail')) {
+ fieldName = 'email';
+ } else if (fieldName?.toLowerCase().includes('name')) {
+ fieldName = 'name';
+ }
+ jsonObject[fieldName] = value;
+ });
+ return jsonObject;
+ });
+}
+
+export const sendOptions = (grunt, root, slug, options = {}, language: string = 'en', contacts) => {
+ return {
+ from: 'PlasticHub ',
+ transport: 'newsletter',
+ subject: 'New Sheetpresses, Extruders, Shredders and Injectors',
+ contacts,
+ source: `${PRODUCT_ROOT()}/${MAIL_OUTPUT_DIR}/${MAIL_OUTPUT_FILE_NAME}_public_${language}.html`,
+ ...gruntOptions(grunt)
+ }
+}
+export const getOutputFileName = (isDebug: boolean, slug: string, lang: string = 'en') => {
+ return isDebug ?
+ `${MAIL_OUTPUT_DIR}/${MAIL_OUTPUT_FILE_NAME}_${lang}${MAIL_OUTPUT_FILE_EXT}` :
+ `${MAIL_OUTPUT_DIR}/${MAIL_OUTPUT_FILE_NAME_PROD}_${lang}${MAIL_OUTPUT_FILE_EXT}`
+}
+
+export const mailDefault = async (content) => {
+ const options: juice.Options = {}
+ content = juice(content, options)
+ content = await minify(content, {
+ collapseWhitespace: true,
+ removeComments: true,
+ minifyCSS: true,
+ minifyJS: true
+ })
+ return content
+}
+export const onCompiledMail = async (src, dst, content) =>
+ mailDefault(content)
\ No newline at end of file
diff --git a/packages/tasks/src/newsletter.ts b/packages/tasks/src/newsletter.ts
new file mode 100644
index 00000000..f4638b73
--- /dev/null
+++ b/packages/tasks/src/newsletter.ts
@@ -0,0 +1,49 @@
+import * as path from 'path'
+import { contentTasks, ICompileOptions, ICompileTaskOptions } from './compile'
+import { option } from '../library'
+import { logger } from '../src/'
+import {
+ I18N_SOURCE_LANGUAGE,
+ NEWSLETTER_COMPILE_CACHE,
+ NEWSLETTER_DEFAULT_ENV,
+ NEWSLETTER_LOG_LEVEL} from './config'
+
+export const newsletterTasks = (
+ grunt,
+ taskPrefix = 'newsletter',
+ root,
+ template,
+ src,
+ dst,
+ taskOptions: ICompileTaskOptions = {},
+ compilerOptions: ICompileOptions = {}
+) => {
+
+ logger.info(`Registering newsletter tasks for ${taskPrefix}`)
+ const env = option('env', {}, grunt, NEWSLETTER_DEFAULT_ENV)
+ const newsletter_tasks = contentTasks(grunt,
+ {
+ sourceLanguage: I18N_SOURCE_LANGUAGE,
+ src: [path.join(root, src)],
+ taskPrefix,
+ ...taskOptions
+ },
+ {
+ cache: option('cache', {}, grunt, NEWSLETTER_COMPILE_CACHE),
+ root,
+ env,
+ logLevel: option('logLevel', {}, grunt, NEWSLETTER_LOG_LEVEL),
+ output: dst,
+ template:path.join(root, template),
+ variables: {
+ env,
+ prefix: env,
+ root,
+ targetLanguage: I18N_SOURCE_LANGUAGE,
+ sourceLanguage: I18N_SOURCE_LANGUAGE
+ },
+ ...compilerOptions
+ })
+ grunt.registerTask(taskPrefix, Object.keys(newsletter_tasks).map((lang: any) => newsletter_tasks[lang].taskName))
+ return newsletter_tasks
+}
\ No newline at end of file
diff --git a/packages/tasks/src/npm.ts b/packages/tasks/src/npm.ts
new file mode 100644
index 00000000..8090ab46
--- /dev/null
+++ b/packages/tasks/src/npm.ts
@@ -0,0 +1,290 @@
+import * as semver from 'semver'
+import * as child_process from 'child_process'
+let DESC = 'Increment the version, commit, tag and push.'
+export const register = (grunt) => {
+ grunt.registerTask('bump', DESC, function(versionType, incOrCommitOnly) {
+ const opts = this.options({
+ bumpVersion: true,
+ commit: true,
+ commitFiles: ['package.json'], // '-a' for all files
+ commitMessage: 'Release v%VERSION%',
+ createTag: true,
+ dryRun: false,
+ files: ['package.json'],
+ gitCommitOptions: '',
+ gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
+ globalReplace: false,
+ prereleaseName: false,
+ metadata: '',
+ push: true,
+ pushTo: 'upstream',
+ regExp: false,
+ setVersion: false,
+ tagMessage: 'Version %VERSION%',
+ tagName: 'v%VERSION%',
+ updateConfigs: [], // array of config properties to update (with files)
+ versionType: false
+ });
+
+ if (versionType === 'bump-only' || versionType === 'commit-only') {
+ incOrCommitOnly = versionType;
+ versionType = '';
+ }
+ versionType = versionType || opts.versionType;
+
+ const dryRun = grunt.option('dry-run') || opts.dryRun;
+
+ let setVersion = grunt.option('setversion') || opts.setVersion;
+ if (setVersion && !semver.valid(setVersion)) {
+ setVersion = false;
+ }
+
+ let globalVersion; // when bumping multiple files
+ let gitVersion; // when bumping using `git describe`
+
+ let VERSION_REGEXP = (typeof opts.regExp === 'function') ? opts.regExp(opts.prereleaseName) : opts.regExp || new RegExp(
+ '([\'|\"]?version[\'|\"]?[ ]*:[ ]*[\'|\"]?)(\\d+\\.\\d+\\.\\d+(-' +
+ opts.prereleaseName +
+ '\\.\\d+)?(-\\d+)?)[\\d||A-a|.|-]*([\'|\"]?)', 'i'
+ );
+ if (opts.globalReplace) {
+ VERSION_REGEXP = new RegExp(VERSION_REGEXP.source, 'gi');
+ }
+
+ const done = this.async();
+ const queue = [];
+ const next = function() {
+ if (!queue.length) {
+ grunt.config.set('bump.version', globalVersion);
+ return done();
+ }
+ queue.shift()();
+ };
+ const runIf = function(condition, behavior) {
+ if (condition) {
+ queue.push(behavior);
+ }
+ };
+
+ if (dryRun) {
+ grunt.log.writeln('Running grunt-bump in dry mode!');
+ }
+
+ if (incOrCommitOnly === 'bump-only') {
+ grunt.verbose.writeln('Only incrementing the version.');
+
+ opts.commit = false;
+ opts.createTag = false;
+ opts.push = false;
+ }
+
+ if (incOrCommitOnly === 'commit-only') {
+ grunt.verbose.writeln('Only committing/tagging/pushing.');
+
+ opts.bumpVersion = false;
+ }
+
+ // GET VERSION FROM GIT
+ runIf(opts.bumpVersion && versionType === 'git', function() {
+ child_process.execFile('git describe ' + opts.gitDescribeOptions, function(err, stdout) {
+ if (err) {
+ grunt.fatal('Can not get a version number using `git describe`');
+ }
+ gitVersion = stdout.trim();
+ next();
+ });
+ });
+
+ // BUMP ALL FILES
+ runIf(opts.bumpVersion, function() {
+ grunt.file.expand(opts.files).forEach(function(file, idx) {
+ let version = null;
+ const content = grunt.file.read(file).replace(
+ VERSION_REGEXP,
+ function(match, prefix, parsedVersion, namedPre, noNamePre, suffix) {
+ const type = versionType === 'git' ? 'prerelease' : versionType;
+ version = setVersion || semver.inc(
+ parsedVersion, type || 'patch', gitVersion || opts.prereleaseName
+ );
+ if (opts.metadata) {
+ if (!/^([0-9a-zA-Z-]+\.{0,1})*$/.test(opts.metadata)) {
+ grunt.fatal(
+ 'Metadata can only contain letters, numbers, dashes ' +
+ '(-) and dots (.)'
+ );
+ }
+ version += '+' + opts.metadata;
+ }
+ return prefix + version + (suffix || '');
+ }
+ );
+
+ if (!version) {
+ grunt.fatal('Can not find a version to bump in ' + file);
+ }
+
+ const logMsg = 'Version bumped to ' + version + ' (in ' + file + ')';
+ if (!dryRun) {
+ grunt.file.write(file, content);
+ grunt.log.ok(logMsg);
+ } else {
+ grunt.log.ok('bump-dry: ' + logMsg);
+ }
+
+ if (!globalVersion) {
+ globalVersion = version;
+ } else if (globalVersion !== version) {
+ grunt.warn('Bumping multiple files with different versions!');
+ }
+
+ const configProperty = opts.updateConfigs[idx];
+ if (!configProperty) {
+ return;
+ }
+
+ const cfg = grunt.config(configProperty);
+ if (!cfg) {
+ return grunt.warn(
+ 'Can not update "' + configProperty + '" config, it does not exist!'
+ );
+ }
+
+ cfg.version = version;
+ grunt.config(configProperty, cfg);
+ grunt.log.ok(configProperty + '\'s version updated');
+ });
+ next();
+ });
+
+
+ // when only committing, read the version from package.json / pkg config
+ runIf(!opts.bumpVersion, function() {
+ const configVersion = grunt.config.get('bump.version');
+
+ if (configVersion) {
+ globalVersion = configVersion;
+ }
+ else if (opts.updateConfigs.length) {
+ globalVersion = grunt.config(opts.updateConfigs[0]).version;
+ } else {
+ globalVersion = grunt.file.readJSON(opts.files[0]).version;
+ }
+
+ next();
+ });
+
+
+ // COMMIT
+ runIf(opts.commit, function() {
+ const commitMessage = opts.commitMessage.replace(
+ '%VERSION%', globalVersion
+ );
+ let cmd = 'git commit ' + opts.gitCommitOptions + ' ' + opts.commitFiles.join(' ');
+ cmd += ' -m "' + commitMessage + '"';
+
+ if (dryRun) {
+ grunt.log.ok('bump-dry: ' + cmd);
+ next();
+ } else {
+ child_process.execFile(cmd, function(err, stdout, stderr) {
+ if (err) {
+ grunt.fatal('Can not create the commit:\n ' + stderr);
+ }
+ grunt.log.ok('Committed as "' + commitMessage + '"');
+ next();
+ });
+ }
+ });
+
+
+ // CREATE TAG
+ runIf(opts.createTag, function() {
+ const tagName = opts.tagName.replace('%VERSION%', globalVersion);
+ const tagMessage = opts.tagMessage.replace('%VERSION%', globalVersion);
+
+ const cmd = 'git tag -a ' + tagName + ' -m "' + tagMessage + '"';
+ if (dryRun) {
+ grunt.log.ok('bump-dry: ' + cmd);
+ next();
+ } else {
+ child_process.execFile(cmd , function(err, stdout, stderr) {
+ if (err) {
+ grunt.fatal('Can not create the tag:\n ' + stderr);
+ }
+ grunt.log.ok('Tagged as "' + tagName + '"');
+ next();
+ });
+ }
+ });
+
+
+ // PUSH CHANGES
+ runIf(opts.push, function() {
+ let cmd;
+
+ if (opts.push === 'git' && !opts.pushTo) {
+ cmd = 'git push';
+ if (dryRun) {
+ grunt.log.ok('bump-dry: ' + cmd);
+ next();
+ } else {
+ child_process.execFile(cmd, function(err, stdout, stderr) {
+ if (err) {
+ grunt.fatal(
+ 'Can not push to the git default settings:\n ' + stderr
+ );
+ }
+ grunt.log.ok('Pushed to the git default settings');
+ next();
+ });
+ }
+
+ return;
+ }
+
+ child_process.execFile('git rev-parse --abbrev-ref HEAD', function(err, ref, stderr) {
+ if (err) {
+ grunt.fatal('Can not get ref for HEAD:\n' + stderr);
+ }
+
+ cmd = [];
+
+ if (opts.push === true || opts.push === 'branch') {
+ cmd.push('git push ' + opts.pushTo + ' ' + ref.trim());
+ }
+
+ if (opts.createTag && (opts.push === true || opts.push === 'tag')) {
+ const tagName = opts.tagName.replace('%VERSION%', globalVersion);
+ cmd.push('git push ' + opts.pushTo + ' ' + tagName);
+ }
+
+ cmd = cmd.join(' && ');
+
+ if (dryRun) {
+ grunt.log.ok('bump-dry: ' + cmd);
+ next();
+ } else {
+ child_process.execFile(cmd, function(err, stdout, stderr) {
+ if (err) {
+ grunt.fatal('Can not push to ' + opts.pushTo + ':\n ' + stderr);
+ }
+ grunt.log.ok('Pushed to ' + opts.pushTo);
+ next();
+ });
+ }
+ });
+ });
+
+ next();
+ });
+
+
+ // ALIASES
+ DESC = 'Increment the version only.';
+ grunt.registerTask('bump-only', DESC, function(versionType) {
+ grunt.task.run('bump:' + (versionType || '') + ':bump-only');
+ });
+
+ DESC = 'Commit, tag, push without incrementing the version.';
+ grunt.registerTask('bump-commit', DESC, 'bump::commit-only');
+}
diff --git a/packages/tasks/src/sheets.ts b/packages/tasks/src/sheets.ts
new file mode 100644
index 00000000..f0512231
--- /dev/null
+++ b/packages/tasks/src/sheets.ts
@@ -0,0 +1,93 @@
+import { sanitize } from '@plastichub/osr-i18n/_cli'
+
+import { CONFIG_DEFAULT } from '@plastichub/osr-commons'
+
+
+import { IOptions as IOptionsI18n } from '@plastichub/osr-i18n/types'
+import { translate } from '@plastichub/osr-i18n/lib/translate'
+import * as pMap from 'p-map'
+
+import {
+ I18N_SOURCE_LANGUAGE, I18N_STORE,
+ MAIL_DEFAULT_OUTPUT_PATH,
+ OSR_ROOT
+} from './config'
+
+import { logger } from '../src'
+
+export const defaultSheetOptions = (srcLang, dstLang, dst: string, logLevel: string, options: {} = {}) => {
+ const i18nOptions: IOptionsI18n = {
+ srcLang,
+ dstLang,
+ store: I18N_STORE(OSR_ROOT(), dstLang),
+ dst,
+ cache: true,
+ logLevel,
+ ...options
+ }
+ return i18nOptions
+}
+
+export const translateSheets = async (
+ languages: string[],
+ files: string[],
+ srcLang: string,
+ dstLanguage: string,
+ query: string = "$[*][0,1,2,3,4]",
+ dst: string = MAIL_DEFAULT_OUTPUT_PATH,
+ logLevel = 'info',
+ options: any = {}) => {
+
+ const config: any = CONFIG_DEFAULT()
+ if (dstLanguage === I18N_SOURCE_LANGUAGE) {
+ return
+ }
+ return await pMap(languages, async (dstLanguage) => {
+ return await pMap(files, async (src) => {
+ const i18nOptions: IOptionsI18n = {
+ srcLang: srcLang,
+ dstLang: dstLanguage,
+ src: src,
+ store: I18N_STORE(OSR_ROOT(), dstLanguage),
+ dst: dst,
+ query: query,
+ cache: true,
+ api_key: config.deepl.auth_key,
+ logLevel: logLevel,
+ ...options
+ }
+ logger.debug('Translate Sheet ' + src + ' ' + dstLanguage, i18nOptions)
+ const ret = await translate(sanitize(i18nOptions) as any)
+ return ret
+ })
+ })
+}
+export const sheetTranslationTask = (grunt, slug: string, files: string[], languages: string[], translationTasks: string[], options: {} = {}) => {
+ const config = {}
+ const key: any = (CONFIG_DEFAULT() as any).deepl.auth_key
+ languages.forEach((lang: string) => {
+ config[`${slug}-${lang}`] = {
+ src: files,
+ options: defaultSheetOptions(I18N_SOURCE_LANGUAGE, lang, `${OSR_ROOT()}/content/${lang}`, 'warn', { api_key: key, ...options })
+ }
+ grunt.extendConfig({ i18n: config })
+ grunt.registerTask(`${slug}-${lang}`, `i18n:${slug}-${lang}`)
+ translationTasks.push(`i18n:${slug}-${lang}`)
+ })
+ grunt.registerTask(`${slug}-tasks`, translationTasks)
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('sheets-i18n', 'Translate Sheets ', async function () {
+ const done = this.async()
+ const task_options = this.data.options
+ // const cwd = path.resolve(option('cwd', task_options, grunt, process.cwd()))
+
+ return new Promise((resolve) => {
+ if (!task_options.watchContent) {
+ resolve(true)
+ done()
+ }
+ })
+ })
+ }
\ No newline at end of file
diff --git a/packages/tasks/src/sshexec.ts b/packages/tasks/src/sshexec.ts
new file mode 100644
index 00000000..a430499a
--- /dev/null
+++ b/packages/tasks/src/sshexec.ts
@@ -0,0 +1,156 @@
+import { Client } from 'ssh2'
+import { isArray } from '@plastichub/core/primitives'
+import { CONFIG_DEFAULT } from '@plastichub/osr-commons/config'
+import { logger } from '../src'
+import { option } from '../library'
+
+const parseConnectionOptions = function (options: any) {
+ const connectionOptions: any = {
+ host: options.host,
+ port: options.port,
+ username: options.user,
+ readyTimeout: options.readyTimeout,
+ agentForward: options.agentForward
+ }
+
+ if (options.privateKey) {
+ connectionOptions.privateKey = options.privateKey.trim();
+
+ if (options.passphrase) {
+ connectionOptions.passphrase = options.passphrase.trim();
+ }
+ }
+ else if (options.password) {
+ connectionOptions.password = options.password;
+ if (options.agent) {
+ connectionOptions.agent = options.agent;
+ }
+ } else {
+ connectionOptions.agent = options.agent;
+ }
+
+ return connectionOptions
+}
+
+const exce = async (commands: string[], options: any) => {
+
+ return new Promise((resolve, reject) => {
+ const c = new Client()
+ const { debug, verbose } = options
+ c.on('keyboard-interactive', function () {
+ const prompts = arguments[3]
+ const reply = arguments[4]
+ prompts.forEach(function (question) {
+ const msg = question.prompt.toLowerCase()
+ if (msg.indexOf('password') !== -1) {
+ reply([options.password])
+ }
+ })
+ })
+
+ c.on('connect', () => logger.info('Connection :: connect'))
+ c.on('ready', () => {
+ logger.info('Connection :: ready')
+ execCommand()
+ })
+ c.on('error', (err) => logger.error('Connection :: error :: ' + err) && resolve(false))
+ c.on('end', () => logger.info('Connection :: end') && resolve(false))
+ const execCommand = () => {
+ if (commands.length === 0) {
+ c.end()
+ } else {
+ const command = commands.shift()
+ logger.info('Executing :: ' + command)
+ c.exec(command, options, function (err, stream) {
+ if (err) {
+ reject(err)
+ }
+ let out
+
+ stream.on('data', (data, extended) => {
+ out = String(data);
+ if (extended === 'stderr') {
+ if (!options.suppressRemoteErrors) {
+ logger.warn(out);
+ }
+ else {
+ logger.warn(out);
+ }
+ } else {
+ logger.info(out)
+ }
+ })
+
+ stream.on('end', () => {
+ resolve(out)
+ })
+
+ stream.on('close', (code, signal) => {
+ debug && logger.info('Stream :: close :: code: ' + code + ', signal: ' + signal)
+ if (!options.ignoreErrors && code !== 0) {
+ logger.error('Error executing task ' + command, code, signal)
+ c.end()
+ reject({ signal, code })
+ } else {
+ execCommand()
+ }
+ })
+ })
+ }
+ }
+
+ const connectionOptions = parseConnectionOptions(options)
+ connectionOptions.tryKeyboard = true;
+ const proxyHost = (options.proxy || {}).host
+ if (proxyHost) {
+
+ const proxyConnectionOptions = parseConnectionOptions(options.proxy)
+ const proxyConnection = new Client()
+ proxyConnection.on('connect', function () {
+ logger.info('Proxy connection :: connect')
+ })
+ proxyConnection.on('error', function (err) {
+ logger.error('Proxy connection :: error :: ' + err)
+ })
+ proxyConnection.on('ready', function () {
+ logger.info('Proxy connection :: ready')
+ proxyConnection.exec('nc ' + connectionOptions.host + ' ' + connectionOptions.port, function (err, stream) {
+ if (err) {
+ proxyConnection.end()
+ reject(err)
+ }
+ connectionOptions.sock = stream;
+ c.connect(connectionOptions)
+ })
+ })
+ proxyConnection.connect(proxyConnectionOptions)
+ }
+ else {
+ c.connect(connectionOptions)
+ }
+ })
+}
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('sshexec', 'Runs commands on SSH', async function () {
+ let done = this.async()
+ const task_options = this.data || {}
+ const sshConfig = (CONFIG_DEFAULT() as any || {}).ssh || {}
+ const opts = {
+ ...sshConfig,
+ debug: option('debug', task_options, grunt),
+ verbose: option('verbose', task_options, grunt),
+ port: option('port', task_options, grunt, sshConfig.port),
+ host: option('host', task_options, grunt, sshConfig.host),
+ user: option('user', task_options, grunt, sshConfig.user),
+ password: option('password', task_options, grunt, sshConfig.password),
+ logLevel: option('logLevel', task_options, grunt,'warn')
+ }
+ logger.setSettings({ minLevel: opts.logLevel })
+ logger.info('Git - task data ', this.data)
+ let commands: string[] = isArray(this.data.commands) ? this.data.commands : [this.data.commands]
+ const ret = await exce(commands, opts)
+ logger.info(`Exce : ${[this.data.command].join('\n')} : `, ret)
+ done()
+ })
+}
diff --git a/packages/tasks/src/sync.ts b/packages/tasks/src/sync.ts
new file mode 100644
index 00000000..1ddc168e
--- /dev/null
+++ b/packages/tasks/src/sync.ts
@@ -0,0 +1,37 @@
+
+import { isArray } from '@plastichub/core/primitives'
+import { sync } from '@plastichub/osr-sync/lib/sync'
+import { resolve } from '@plastichub/osr-commons'
+import { option } from '../library'
+import { logger } from '../src'
+
+export const register = (grunt) => {
+ grunt.registerMultiTask('sync', 'Synchronizes folders, using osr-sync', function () {
+ const done = this.async()
+ const task_options = this.data || {}
+ let source: string[] = isArray(this.data.src) ? this.data.src : [this.data.src]
+ const variables = { ...task_options.variables || {} }
+ logger.setSettings({ minLevel: option('logLevel', task_options, grunt, 'warn') })
+ source = source.map(f => resolve(f, false, variables))
+ const options = {
+ source,
+ target: resolve(option('target', task_options, grunt), variables),
+ root: option('root', task_options, grunt),
+ clear: option('clear', task_options, grunt),
+ debug: false,
+ verbose: false,
+ //debug: option('debug', task_options, grunt),
+ //verbose: option('verbose', task_options, grunt, false),
+ profile: option('profile', task_options, grunt),
+ logLevel: option('logLevel', task_options, grunt, 'warn'),
+ variables: variables
+ }
+ try {
+ sync(options)
+ } catch (e) {
+ logger.error(`Error while syncing : ${source.join('\n')} : ${e.messsage}`, e)
+ }
+ done()
+ return true
+ })
+}
diff --git a/packages/tasks/src/utils.ts b/packages/tasks/src/utils.ts
new file mode 100644
index 00000000..4aa8cb1b
--- /dev/null
+++ b/packages/tasks/src/utils.ts
@@ -0,0 +1,186 @@
+import { z, ZodObject, ZodTypeAny } from "zod"
+
+import { MAIL_SOURCE_FILE } from "./config"
+
+
+export const cleanArray = (arr: any[]): any[] => {
+ // Use a Set to eliminate duplicates
+ const uniqueItems = Array.from(new Set(arr.map(item => JSON.stringify(item))))
+ .map(item => JSON.parse(item))
+
+ return uniqueItems.filter(item => {
+ if (Array.isArray(item)) {
+ return item.length > 0; // Exclude empty arrays
+ } else if (typeof item === 'object' && item !== null) {
+ return Object.keys(item).length > 0; // Exclude empty objects
+ } else if (typeof item === 'string') {
+ // Remove URL parameters from strings
+ return item
+ }
+ return true; // Keep other types (e.g., numbers, etc.)
+ }).map(item => {
+ // Apply the URL cleanup on strings if they haven't been filtered out
+ if (typeof item === 'string') {
+ return item
+ }
+ return item
+ })
+}
+
+export const mailOptionSchema = z.object({
+ from: z
+ .string()
+ .default("'PlasticHub-Barcelona '")
+ .describe("The sender email address formatted as a string."),
+ transport: z
+ .string()
+ .default("newsletter")
+ .describe("The transport profile, e.g., 'newsletter'."),
+ subject: z
+ .string()
+ .default("Mejora tu CarpinterĂa: Prensas de Planchas, Extrusoras e Inyectores para Procesamiento de Plástico")
+ .describe("The subject of the email being sent."),
+ contacts: z
+ .string()
+ .default("${OSR_ROOT}/osr-directory/meta/index.json")
+ .describe("Path to the contacts directory or file."),
+ filter: z
+ .boolean()
+ .default(true)
+ .describe("Indicates whether a filter should be applied: true filters out already sent emails."),
+ query: z
+ .string()
+ .default("QT_CARPENTERS_SPAIN_ALL_EMAIL")
+ .describe("The query string used to select recipients. From profile or string"),
+ to: z
+ .string()
+ .nullable()
+ .default(null)
+ .describe("Optional recipient address; can be null if not specified."),
+ send: z
+ .boolean()
+ .default(true)
+ .describe("Indicates whether the email should be sent."),
+ dry: z
+ .boolean()
+ .default(false)
+ .describe("For testing purposes"),
+ logLevel: z
+ .string()
+ .default("debug")
+ .describe("The level of logging detail, e.g., 'debug', 'info', 'error'.")
+}, { description: "Options for sending an email." })
+
+export const compileVariablesSchema = (grunt) => z.object({
+ cwd: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\company\\mail\\2024\\08")
+ .describe("The current working directory for the process."),
+ root: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\company\\mail\\2024\\08")
+ .describe("The root directory for the project."),
+ targetLanguage: z
+ .string()
+ .default("es")
+ .describe("The target language code for the output."),
+ sourceLanguage: z
+ .string()
+ .default("en")
+ .describe("The source language code for the input."),
+ i18n: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr/i18n-store/store-es.json")
+ .describe("The path to the internationalization (i18n) store file.")
+});
+
+export const mailCompileSchema = (grunt) => z.object({
+ cache: z
+ .boolean()
+ .default(false)
+ .describe("Indicates whether caching is enabled."),
+ cwd: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\company\\mail\\2024\\08")
+ .describe("The current working directory for the process."),
+ env: z
+ .string()
+ .default("hugo-release")
+ .describe("The environment for the process, e.g., 'hugo-release'."),
+ format: z
+ .string()
+ .default("html")
+ .describe("The format of the output file."),
+ language: z
+ .string()
+ .default("osr")
+ .describe("The language code or identifier used for processing."),
+ logLevel: z
+ .string()
+ .default("debug")
+ .describe("The level of logging detail, e.g., 'debug', 'info', 'error'."),
+ module: z
+ .string()
+ .default("plastichub-mail")
+ .describe("The module being used for the process."),
+ profile: z
+ .string()
+ .default("${OSR_ROOT}/osr-templates/osrl/.osrl.json")
+ .describe("The path to the profile configuration file."),
+ root: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\company\\mail\\2024\\08")
+ .describe("The root directory for the project."),
+ sourceLanguage: z
+ .string()
+ .default("en")
+ .describe("The source language code for the input."),
+ targetLanguage: z
+ .string()
+ .default("en")
+ .describe("The target language code for the output."),
+ template: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\company\\mail\\2024\\08\\root.osr")
+ .describe("The path to the template file being used."),
+ output: z
+ .string()
+ .default("C:\\Users\\mc007\\Desktop\\osr\\products\\products\\assets\\newsletter\\mail\\mail_2024_09_public_es.html")
+ .describe("The path to the output file."),
+ source: z
+ .string()
+ .default(MAIL_SOURCE_FILE || grunt.option('source'))
+ .describe("The path to the source file."),
+ variables: compileVariablesSchema(grunt).describe("An object containing variable paths and language codes for processing.")
+})
+
+export const enumerateHelpStrings = (schema: ZodTypeAny, path: string[] = [], logger: any): void => {
+ if (schema instanceof ZodObject) {
+ for (const key in schema.shape) {
+ const nestedSchema = schema.shape[key];
+ enumerateHelpStrings(nestedSchema, [...path, key], logger)
+ }
+ } else {
+ const description = schema._def.description
+ const fieldDef = schema._def
+ const innerType = fieldDef.innerType
+
+ let type: 'string' | 'boolean' | 'number' | undefined
+ if (innerType._def.typeName === 'ZodString') {
+ type = 'string'
+ } else if (innerType._def.typeName === 'ZodBoolean') {
+ type = 'boolean'
+ } else if (innerType._def.typeName === 'ZodNumber') {
+ type = 'number'
+ }
+ let defaultValue = fieldDef.defaultValue
+ defaultValue = defaultValue !== undefined ? defaultValue() : undefined
+ if (type === 'boolean') {
+ defaultValue = defaultValue === 'true'
+ }
+
+ if (description) {
+ logger.debug(`\t ${path.join('.')}: ${description} \t Default: ${defaultValue}`)
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/ui/package-lock.json b/packages/ui/package-lock.json
index 38bd46b2..2d5b22f0 100644
--- a/packages/ui/package-lock.json
+++ b/packages/ui/package-lock.json
@@ -14259,7 +14259,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz",
"integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"orderedmap": "^2.0.0"
}
@@ -14293,7 +14292,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
"integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.0.0",
"prosemirror-transform": "^1.0.0",
@@ -14327,7 +14325,6 @@
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.5.tgz",
"integrity": "sha512-UDQbIPnDrjE8tqUBbPmCOZgtd75htE6W3r0JCmY9bL6W1iemDM37MZEKC49d+tdQ0v/CKx4gjxLoLsfkD2NiZA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"prosemirror-model": "^1.20.0",
"prosemirror-state": "^1.0.0",