Filesystem Sync (#142)

This commit is contained in:
Gregory Schier
2025-01-03 20:41:00 -08:00
committed by GitHub
parent 6ad27c4458
commit 31440eea76
159 changed files with 4296 additions and 1016 deletions

333
src-tauri/Cargo.lock generated
View File

@@ -17,6 +17,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
version = "0.7.8"
@@ -504,7 +510,7 @@ dependencies = [
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"miniz_oxide 0.7.4",
"object",
"rustc-demangle",
]
@@ -620,7 +626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0"
dependencies = [
"once_cell",
"proc-macro-crate 2.0.2",
"proc-macro-crate 2.0.0",
"proc-macro2",
"quote",
"syn 2.0.87",
@@ -795,7 +801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719"
dependencies = [
"serde",
"toml 0.8.2",
"toml 0.8.19",
]
[[package]]
@@ -1216,37 +1222,14 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "darling"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
dependencies = [
"darling_core 0.14.4",
"darling_macro 0.14.4",
]
[[package]]
name = "darling"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core 0.20.10",
"darling_macro 0.20.10",
]
[[package]]
name = "darling_core"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"syn 1.0.109",
"darling_core",
"darling_macro",
]
[[package]]
@@ -1263,24 +1246,13 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "darling_macro"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
dependencies = [
"darling_core 0.14.4",
"quote",
"syn 1.0.109",
]
[[package]]
name = "darling_macro"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core 0.20.10",
"darling_core",
"quote",
"syn 2.0.87",
]
@@ -1503,7 +1475,7 @@ dependencies = [
"cc",
"memchr",
"rustc_version",
"toml 0.8.2",
"toml 0.8.19",
"vswhom",
"winreg",
]
@@ -1649,7 +1621,7 @@ dependencies = [
"flume",
"half",
"lebe",
"miniz_oxide",
"miniz_oxide 0.7.4",
"rayon-core",
"smallvec",
"zune-inflate",
@@ -1722,12 +1694,12 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.0.31"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide",
"miniz_oxide 0.8.0",
]
[[package]]
@@ -2165,7 +2137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
dependencies = [
"heck 0.4.1",
"proc-macro-crate 2.0.2",
"proc-macro-crate 2.0.0",
"proc-macro-error",
"proc-macro2",
"quote",
@@ -2557,7 +2529,7 @@ dependencies = [
"tokio",
"tokio-rustls 0.26.0",
"tower-service",
"webpki-roots 0.26.3",
"webpki-roots",
]
[[package]]
@@ -3065,9 +3037,9 @@ dependencies = [
[[package]]
name = "libsqlite3-sys"
version = "0.28.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
dependencies = [
"cc",
"pkg-config",
@@ -3236,6 +3208,15 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "miniz_oxide"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
]
[[package]]
name = "mio"
version = "1.0.1"
@@ -3274,6 +3255,15 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
[[package]]
name = "nanoid"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
dependencies = [
"rand 0.8.5",
]
[[package]]
name = "native-tls"
version = "0.2.12"
@@ -3471,7 +3461,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate 2.0.2",
"proc-macro-crate 2.0.0",
"proc-macro2",
"quote",
"syn 2.0.87",
@@ -4173,7 +4163,7 @@ dependencies = [
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
"miniz_oxide 0.7.4",
]
[[package]]
@@ -4234,11 +4224,10 @@ dependencies = [
[[package]]
name = "proc-macro-crate"
version = "2.0.2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [
"toml_datetime",
"toml_edit 0.20.2",
]
@@ -4550,9 +4539,9 @@ dependencies = [
[[package]]
name = "r2d2_sqlite"
version = "0.24.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a982edf65c129796dba72f8775b292ef482b40d035e827a9825b3bc07ccc5f2"
checksum = "eb14dba8247a6a15b7fdbc7d389e2e6f03ee9f184f87117706d509c092dfe846"
dependencies = [
"r2d2",
"rusqlite",
@@ -4844,7 +4833,7 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots 0.26.3",
"webpki-roots",
"winreg",
]
@@ -4958,9 +4947,9 @@ dependencies = [
[[package]]
name = "rusqlite"
version = "0.31.0"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
dependencies = [
"bitflags 2.6.0",
"chrono",
@@ -5195,34 +5184,22 @@ dependencies = [
[[package]]
name = "sea-query"
version = "0.31.0"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e5073b2cfed767511a57d18115f3b3d8bcb5690bf8c89518caec6cb22c0cd74"
checksum = "085e94f7d7271c0393ac2d164a39994b1dff1b06bc40cd9a0da04f3d672b0fee"
dependencies = [
"chrono",
"inherent",
"sea-query-attr",
"sea-query-derive",
]
[[package]]
name = "sea-query-attr"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168a31e0ef5a791ad26aa97c502eaed8d2a1ffdc22b3249f9947c1e12be6b477"
dependencies = [
"darling 0.14.4",
"heck 0.4.1",
"quote",
"syn 1.0.109",
]
[[package]]
name = "sea-query-derive"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc"
checksum = "9834af2c4bd8c5162f00c89f1701fb6886119a88062cf76fe842ea9e232b9839"
dependencies = [
"darling",
"heck 0.4.1",
"proc-macro2",
"quote",
@@ -5232,9 +5209,9 @@ dependencies = [
[[package]]
name = "sea-query-rusqlite"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd26649cda07604727e01106ca109e4d0796a6d09c627eaa7831fbe46daf78b"
checksum = "3743bbdfb24b1a84cc1a6fbf4b1188e6851f6e00ea20944b44c56bf03a585bb4"
dependencies = [
"rusqlite",
"sea-query",
@@ -5418,12 +5395,25 @@ version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
dependencies = [
"darling 0.20.10",
"darling",
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.3.0",
"itoa 1.0.11",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "serialize-to-javascript"
version = "0.1.1"
@@ -5642,9 +5632,9 @@ dependencies = [
[[package]]
name = "sqlx"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27144619c6e5802f1380337a209d2ac1c431002dd74c6e60aebff3c506dc4f0c"
checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e"
dependencies = [
"sqlx-core",
"sqlx-macros",
@@ -5655,9 +5645,9 @@ dependencies = [
[[package]]
name = "sqlx-core"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a999083c1af5b5d6c071d34a708a19ba3e02106ad82ef7bbd69f5e48266b613b"
checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e"
dependencies = [
"atoi",
"byteorder",
@@ -5680,8 +5670,8 @@ dependencies = [
"once_cell",
"paste",
"percent-encoding",
"rustls 0.21.12",
"rustls-pemfile 1.0.4",
"rustls 0.23.12",
"rustls-pemfile 2.1.3",
"serde",
"serde_json",
"sha2",
@@ -5692,14 +5682,14 @@ dependencies = [
"tokio-stream",
"tracing",
"url",
"webpki-roots 0.25.4",
"webpki-roots",
]
[[package]]
name = "sqlx-macros"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23217eb7d86c584b8cbe0337b9eacf12ab76fe7673c513141ec42565698bb88"
checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657"
dependencies = [
"proc-macro2",
"quote",
@@ -5710,9 +5700,9 @@ dependencies = [
[[package]]
name = "sqlx-macros-core"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776"
checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
dependencies = [
"dotenvy",
"either",
@@ -5736,9 +5726,9 @@ dependencies = [
[[package]]
name = "sqlx-mysql"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5afe4c38a9b417b6a9a5eeffe7235d0a106716495536e7727d1c7f4b1ff3eba6"
checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a"
dependencies = [
"atoi",
"base64 0.22.1",
@@ -5778,9 +5768,9 @@ dependencies = [
[[package]]
name = "sqlx-postgres"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1dbb157e65f10dbe01f729339c06d239120221c9ad9fa0ba8408c4cc18ecf21"
checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8"
dependencies = [
"atoi",
"base64 0.22.1",
@@ -5816,9 +5806,9 @@ dependencies = [
[[package]]
name = "sqlx-sqlite"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2cdd83c008a622d94499c0006d8ee5f821f36c89b7d625c900e5dc30b5c5ee"
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
dependencies = [
"atoi",
"flume",
@@ -5994,7 +5984,7 @@ dependencies = [
"cfg-expr",
"heck 0.5.0",
"pkg-config",
"toml 0.8.2",
"toml 0.8.19",
"version-compare",
]
@@ -6111,7 +6101,7 @@ dependencies = [
"tauri-runtime",
"tauri-runtime-wry",
"tauri-utils",
"thiserror 2.0.3",
"thiserror 2.0.7",
"tokio",
"tray-icon",
"url",
@@ -6140,7 +6130,7 @@ dependencies = [
"serde_json",
"tauri-utils",
"tauri-winres",
"toml 0.8.2",
"toml 0.8.19",
"walkdir",
]
@@ -6164,7 +6154,7 @@ dependencies = [
"sha2",
"syn 2.0.87",
"tauri-utils",
"thiserror 2.0.3",
"thiserror 2.0.7",
"time",
"url",
"uuid",
@@ -6198,7 +6188,7 @@ dependencies = [
"serde",
"serde_json",
"tauri-utils",
"toml 0.8.2",
"toml 0.8.19",
"walkdir",
]
@@ -6363,22 +6353,6 @@ dependencies = [
"thiserror 1.0.63",
]
[[package]]
name = "tauri-plugin-yaak-license"
version = "0.1.0"
dependencies = [
"chrono",
"log",
"reqwest",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"thiserror 2.0.3",
"ts-rs",
"yaak_models",
]
[[package]]
name = "tauri-runtime"
version = "2.2.0"
@@ -6393,7 +6367,7 @@ dependencies = [
"serde",
"serde_json",
"tauri-utils",
"thiserror 2.0.3",
"thiserror 2.0.7",
"url",
"windows",
]
@@ -6453,8 +6427,8 @@ dependencies = [
"serde_json",
"serde_with",
"swift-rs",
"thiserror 2.0.3",
"toml 0.8.2",
"thiserror 2.0.7",
"toml 0.8.19",
"url",
"urlpattern",
"uuid",
@@ -6521,11 +6495,11 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.3"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767"
dependencies = [
"thiserror-impl 2.0.3",
"thiserror-impl 2.0.7",
]
[[package]]
@@ -6541,9 +6515,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
version = "2.0.3"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36"
dependencies = [
"proc-macro2",
"quote",
@@ -6717,21 +6691,21 @@ dependencies = [
[[package]]
name = "toml"
version = "0.8.2"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.20.2",
"toml_edit 0.22.22",
]
[[package]]
name = "toml_datetime"
version = "0.6.3"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
@@ -6746,7 +6720,7 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
"winnow 0.5.40",
]
[[package]]
@@ -6754,12 +6728,23 @@ name = "toml_edit"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
dependencies = [
"indexmap 2.3.0",
"toml_datetime",
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap 2.3.0",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
"winnow 0.6.20",
]
[[package]]
@@ -7079,6 +7064,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"
@@ -7429,12 +7420,6 @@ dependencies = [
"system-deps",
]
[[package]]
name = "webpki-roots"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webpki-roots"
version = "0.26.3"
@@ -7845,6 +7830,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.52.0"
@@ -7997,21 +7991,22 @@ dependencies = [
"tauri-plugin-shell",
"tauri-plugin-updater",
"tauri-plugin-window-state",
"tauri-plugin-yaak-license",
"tokio",
"tokio-stream",
"ts-rs",
"urlencoding",
"uuid",
"yaak_grpc",
"yaak_models",
"yaak_plugin_runtime",
"yaak_sse",
"yaak_templates",
"yaak-grpc",
"yaak-license",
"yaak-models",
"yaak-plugins",
"yaak-sse",
"yaak-sync",
"yaak-templates",
]
[[package]]
name = "yaak_grpc"
name = "yaak-grpc"
version = "0.1.0"
dependencies = [
"anyhow",
@@ -8036,14 +8031,30 @@ dependencies = [
]
[[package]]
name = "yaak_models"
name = "yaak-license"
version = "0.1.0"
dependencies = [
"chrono",
"log",
"reqwest",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"thiserror 2.0.7",
"ts-rs",
"yaak-models",
]
[[package]]
name = "yaak-models"
version = "0.1.0"
dependencies = [
"chrono",
"log",
"nanoid",
"r2d2",
"r2d2_sqlite",
"rand 0.8.5",
"rusqlite",
"sea-query",
"sea-query-rusqlite",
@@ -8056,7 +8067,7 @@ dependencies = [
]
[[package]]
name = "yaak_plugin_runtime"
name = "yaak-plugins"
version = "0.1.0"
dependencies = [
"dunce",
@@ -8069,16 +8080,16 @@ dependencies = [
"serde_json",
"tauri",
"tauri-plugin-shell",
"thiserror 1.0.63",
"thiserror 2.0.7",
"tokio",
"tonic 0.12.1",
"tonic-build",
"ts-rs",
"yaak_models",
"yaak-models",
]
[[package]]
name = "yaak_sse"
name = "yaak-sse"
version = "0.1.0"
dependencies = [
"serde",
@@ -8086,7 +8097,25 @@ dependencies = [
]
[[package]]
name = "yaak_templates"
name = "yaak-sync"
version = "0.1.0"
dependencies = [
"chrono",
"hex",
"log",
"serde",
"serde_json",
"serde_yaml",
"sha1",
"tauri",
"tauri-plugin",
"thiserror 2.0.7",
"ts-rs",
"yaak-models",
]
[[package]]
name = "yaak-templates"
version = "0.1.0"
dependencies = [
"log",

View File

@@ -1,11 +1,12 @@
[workspace]
members = [
"yaak_grpc",
"yaak_license",
"yaak_models",
"yaak_plugin_runtime",
"yaak_sse",
"yaak_templates",
"yaak-grpc",
"yaak-license",
"yaak-models",
"yaak-plugins",
"yaak-sse",
"yaak-sync",
"yaak-templates",
]
[package]
@@ -34,15 +35,10 @@ cocoa = "0.26.0"
openssl-sys = { version = "0.9", features = ["vendored"] } # For Ubuntu installation to work
[dependencies]
yaak_grpc = { path = "yaak_grpc" }
tauri-plugin-yaak-license = { path = "yaak_license" }
yaak_models = { workspace = true }
yaak_plugin_runtime = { workspace = true }
yaak_sse = { workspace = true }
yaak_templates = { path = "yaak_templates" }
base64 = "0.22.0"
chrono = { version = "0.4.31", features = ["serde"] }
datetime = "0.5.2"
eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.13.0" }
hex_color = "3.0.0"
http = "1"
log = "0.4.21"
@@ -53,26 +49,32 @@ reqwest_cookie_store = "0.8.0"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["raw_value"] }
tauri = { workspace = true, features = ["devtools", "protocol-asset"] }
tauri-plugin-shell = { workspace = true }
tauri-plugin-clipboard-manager = "2.0.1"
tauri-plugin-dialog = "2.0.3"
tauri-plugin-fs = "2.0.3"
tauri-plugin-log = { version = "2.0.1", features = ["colored"] }
tauri-plugin-os = "2.0.1"
tauri-plugin-shell = { workspace = true }
tauri-plugin-updater = "2.0.2"
tauri-plugin-window-state = "2.0.1"
tokio = { version = "1.36.0", features = ["sync"] }
tokio-stream = "0.1.15"
ts-rs = { workspace = true }
uuid = "1.7.0"
mime_guess = "2.0.5"
urlencoding = "2.1.3"
eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.13.0" }
uuid = "1.7.0"
yaak-grpc = { path = "yaak-grpc" }
yaak-license = { path = "yaak-license" }
yaak-models = { workspace = true }
yaak-plugins = { workspace = true }
yaak-sse = { workspace = true }
yaak-sync = { path = "yaak-sync" }
yaak-templates = { path = "yaak-templates" }
[workspace.dependencies]
yaak_models = { path = "yaak_models" }
yaak_sse = { path = "yaak_sse" }
yaak_plugin_runtime = { path = "yaak_plugin_runtime" }
yaak-models = { path = "yaak-models" }
yaak-sse = { path = "yaak-sse" }
yaak-plugins = { path = "yaak-plugins" }
serde = "1.0.215"
serde_json = "1.0.132"
tauri-plugin-shell = "2.0.2"

View File

@@ -7,7 +7,6 @@
"*"
],
"permissions": [
"yaak-license:default",
"core:event:allow-emit",
"core:event:allow-listen",
"core:event:allow-unlisten",
@@ -45,6 +44,8 @@
"core:window:allow-toggle-maximize",
"core:window:allow-unmaximize",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text"
"clipboard-manager:allow-write-text",
"yaak-license:default",
"yaak-sync:default"
]
}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["yaak-license:default","core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","yaak-license:default","yaak-sync:default"]}}

View File

@@ -5166,6 +5166,221 @@
"description": "Denies the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-license:deny-check"
},
{
"description": "Default permissions for the plugin",
"type": "string",
"const": "yaak-sync:default"
},
{
"description": "Enables the activate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-activate"
},
{
"description": "Enables the add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-add"
},
{
"description": "Enables the apply command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-apply"
},
{
"description": "Enables the calculate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-calculate"
},
{
"description": "Enables the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-check"
},
{
"description": "Enables the checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-checkout"
},
{
"description": "Enables the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-add"
},
{
"description": "Enables the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-checkout"
},
{
"description": "Enables the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-commit"
},
{
"description": "Enables the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-init"
},
{
"description": "Enables the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-log"
},
{
"description": "Enables the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-status"
},
{
"description": "Enables the commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-commit"
},
{
"description": "Enables the init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-init"
},
{
"description": "Enables the init_repo command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-init-repo"
},
{
"description": "Enables the initialize command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-initialize"
},
{
"description": "Enables the log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-log"
},
{
"description": "Enables the status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-status"
},
{
"description": "Enables the sync command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-sync"
},
{
"description": "Enables the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-sync-fs"
},
{
"description": "Enables the unstage command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-unstage"
},
{
"description": "Denies the activate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-activate"
},
{
"description": "Denies the add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-add"
},
{
"description": "Denies the apply command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-apply"
},
{
"description": "Denies the calculate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-calculate"
},
{
"description": "Denies the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-check"
},
{
"description": "Denies the checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-checkout"
},
{
"description": "Denies the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-add"
},
{
"description": "Denies the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-checkout"
},
{
"description": "Denies the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-commit"
},
{
"description": "Denies the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-init"
},
{
"description": "Denies the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-log"
},
{
"description": "Denies the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-status"
},
{
"description": "Denies the commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-commit"
},
{
"description": "Denies the init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-init"
},
{
"description": "Denies the init_repo command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-init-repo"
},
{
"description": "Denies the initialize command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-initialize"
},
{
"description": "Denies the log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-log"
},
{
"description": "Denies the status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-status"
},
{
"description": "Denies the sync command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-sync"
},
{
"description": "Denies the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-sync-fs"
},
{
"description": "Denies the unstage command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-unstage"
}
]
},

View File

@@ -5166,6 +5166,221 @@
"description": "Denies the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-license:deny-check"
},
{
"description": "Default permissions for the plugin",
"type": "string",
"const": "yaak-sync:default"
},
{
"description": "Enables the activate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-activate"
},
{
"description": "Enables the add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-add"
},
{
"description": "Enables the apply command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-apply"
},
{
"description": "Enables the calculate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-calculate"
},
{
"description": "Enables the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-check"
},
{
"description": "Enables the checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-checkout"
},
{
"description": "Enables the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-add"
},
{
"description": "Enables the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-checkout"
},
{
"description": "Enables the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-commit"
},
{
"description": "Enables the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-init"
},
{
"description": "Enables the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-log"
},
{
"description": "Enables the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-cmd-status"
},
{
"description": "Enables the commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-commit"
},
{
"description": "Enables the init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-init"
},
{
"description": "Enables the init_repo command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-init-repo"
},
{
"description": "Enables the initialize command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-initialize"
},
{
"description": "Enables the log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-log"
},
{
"description": "Enables the status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-status"
},
{
"description": "Enables the sync command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-sync"
},
{
"description": "Enables the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-sync-fs"
},
{
"description": "Enables the unstage command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:allow-unstage"
},
{
"description": "Denies the activate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-activate"
},
{
"description": "Denies the add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-add"
},
{
"description": "Denies the apply command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-apply"
},
{
"description": "Denies the calculate command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-calculate"
},
{
"description": "Denies the check command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-check"
},
{
"description": "Denies the checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-checkout"
},
{
"description": "Denies the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-add"
},
{
"description": "Denies the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-checkout"
},
{
"description": "Denies the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-commit"
},
{
"description": "Denies the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-init"
},
{
"description": "Denies the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-log"
},
{
"description": "Denies the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-cmd-status"
},
{
"description": "Denies the commit command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-commit"
},
{
"description": "Denies the init command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-init"
},
{
"description": "Denies the init_repo command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-init-repo"
},
{
"description": "Denies the initialize command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-initialize"
},
{
"description": "Denies the log command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-log"
},
{
"description": "Denies the status command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-status"
},
{
"description": "Denies the sync command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-sync"
},
{
"description": "Denies the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-sync-fs"
},
{
"description": "Denies the unstage command without any pre-configured scope.",
"type": "string",
"const": "yaak-sync:deny-unstage"
}
]
},

View File

@@ -0,0 +1,21 @@
ALTER TABLE workspaces
ADD COLUMN setting_sync_dir TEXT;
CREATE TABLE sync_states
(
id TEXT NOT NULL
PRIMARY KEY,
model TEXT DEFAULT 'sync_state' NOT NULL,
workspace_id TEXT NOT NULL
REFERENCES workspaces
ON DELETE CASCADE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
flushed_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
checksum TEXT NOT NULL,
model_id TEXT NOT NULL,
sync_dir TEXT NOT NULL,
rel_path TEXT NOT NULL,
UNIQUE (workspace_id, model_id)
);

View File

@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tauri::{Manager, Runtime, WebviewWindow};
use ts_rs::TS;
use yaak_models::queries::{generate_id, get_key_value_int, get_key_value_string, get_or_create_settings, set_key_value_int, set_key_value_string};
use yaak_models::queries::{generate_id, get_key_value_int, get_key_value_string, get_or_create_settings, set_key_value_int, set_key_value_string, UpdateSource};
use crate::is_dev;
@@ -49,11 +49,7 @@ impl AnalyticsResource {
impl Display for AnalyticsResource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
serde_json::to_string(self).unwrap().replace("\"", "")
)
write!(f, "{}", serde_json::to_string(self).unwrap().replace("\"", ""))
}
}
@@ -89,11 +85,7 @@ impl AnalyticsAction {
impl Display for AnalyticsAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
serde_json::to_string(self).unwrap().replace("\"", "")
)
write!(f, "{}", serde_json::to_string(self).unwrap().replace("\"", ""))
}
}
@@ -115,13 +107,7 @@ pub async fn track_launch_event<R: Runtime>(w: &WebviewWindow<R>) -> LaunchEvent
info.current_version = w.package_info().version.to_string();
if info.previous_version.is_empty() {
track_event(
w,
AnalyticsResource::App,
AnalyticsAction::LaunchFirst,
None,
)
.await;
track_event(w, AnalyticsResource::App, AnalyticsAction::LaunchFirst, None).await;
} else {
info.launched_after_update = info.current_version != info.previous_version;
if info.launched_after_update {
@@ -151,9 +137,11 @@ pub async fn track_launch_event<R: Runtime>(w: &WebviewWindow<R>) -> LaunchEvent
NAMESPACE,
last_tracked_version_key,
info.current_version.as_str(),
&UpdateSource::Background,
)
.await;
set_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches).await;
set_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches, &UpdateSource::Background)
.await;
info
}
@@ -164,7 +152,6 @@ pub async fn track_event<R: Runtime>(
action: AnalyticsAction,
attributes: Option<Value>,
) {
let id = get_id(w).await;
let event = format!("{}.{}", resource, action);
let attributes_json = attributes.unwrap_or("{}".to_string().into()).to_string();
@@ -188,16 +175,13 @@ pub async fn track_event<R: Runtime>(
("tz", tz),
("xy", get_window_size(w)),
];
let req = reqwest::Client::builder()
.build()
.unwrap()
.get(format!("{base_url}/t/e"))
.query(&params);
let req =
reqwest::Client::builder().build().unwrap().get(format!("{base_url}/t/e")).query(&params);
let settings = get_or_create_settings(w).await;
if !settings.telemetry {
info!("Track event (disabled): {}", event);
return
return;
}
// Disable analytics actual sending in dev
@@ -234,18 +218,15 @@ fn get_window_size<R: Runtime>(w: &WebviewWindow<R>) -> String {
let width: f64 = size.width as f64 / scale_factor;
let height: f64 = size.height as f64 / scale_factor;
format!(
"{}x{}",
(width / 100.0).round() * 100.0,
(height / 100.0).round() * 100.0
)
format!("{}x{}", (width / 100.0).round() * 100.0, (height / 100.0).round() * 100.0)
}
async fn get_id<R: Runtime>(w: &WebviewWindow<R>) -> String {
let id = get_key_value_string(w, "analytics", "id", "").await;
if id.is_empty() {
let new_id = generate_id();
set_key_value_string(w, "analytics", "id", new_id.as_str()).await;
set_key_value_string(w, "analytics", "id", new_id.as_str(), &UpdateSource::Background)
.await;
new_id
} else {
id

View File

@@ -1,77 +0,0 @@
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use tauri::{Manager, WebviewWindow};
use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, Workspace};
#[derive(Default, Debug, Deserialize, Serialize)]
#[serde(default, rename_all = "camelCase")]
pub struct WorkspaceExport {
pub yaak_version: String,
pub yaak_schema: i64,
pub timestamp: NaiveDateTime,
pub resources: WorkspaceExportResources,
}
#[derive(Default, Debug, Deserialize, Serialize)]
#[serde(default, rename_all = "camelCase")]
pub struct WorkspaceExportResources {
pub workspaces: Vec<Workspace>,
pub environments: Vec<Environment>,
pub folders: Vec<Folder>,
pub http_requests: Vec<HttpRequest>,
pub grpc_requests: Vec<GrpcRequest>,
}
#[derive(Default, Debug, Deserialize, Serialize)]
pub struct ImportResult {
pub resources: WorkspaceExportResources,
}
pub async fn get_workspace_export_resources(
window: &WebviewWindow,
workspace_ids: Vec<&str>,
) -> WorkspaceExport {
let app_handle = window.app_handle();
let mut data = WorkspaceExport {
yaak_version: app_handle.package_info().version.clone().to_string(),
yaak_schema: 3,
timestamp: chrono::Utc::now().naive_utc(),
resources: WorkspaceExportResources {
workspaces: Vec::new(),
environments: Vec::new(),
folders: Vec::new(),
http_requests: Vec::new(),
grpc_requests: Vec::new(),
},
};
for workspace_id in workspace_ids {
data.resources.workspaces.push(
yaak_models::queries::get_workspace(window, workspace_id)
.await
.expect("Failed to get workspace"),
);
data.resources.environments.append(
&mut yaak_models::queries::list_environments(window, workspace_id)
.await
.expect("Failed to get environments"),
);
data.resources.folders.append(
&mut yaak_models::queries::list_folders(window, workspace_id)
.await
.expect("Failed to get folders"),
);
data.resources.http_requests.append(
&mut yaak_models::queries::list_http_requests(window, workspace_id)
.await
.expect("Failed to get http requests"),
);
data.resources.grpc_requests.append(
&mut yaak_models::queries::list_grpc_requests(window, workspace_id)
.await
.expect("Failed to get grpc requests"),
);
}
return data;
}

View File

@@ -27,11 +27,8 @@ use yaak_models::models::{
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader,
HttpResponseState, ProxySetting, ProxySettingAuth,
};
use yaak_models::queries::{
get_base_environment, get_http_response, get_or_create_settings, get_workspace,
update_response_if_id, upsert_cookie_jar,
};
use yaak_plugin_runtime::events::{RenderPurpose, WindowContext};
use yaak_models::queries::{get_base_environment, get_http_response, get_or_create_settings, get_workspace, update_response_if_id, upsert_cookie_jar, UpdateSource};
use yaak_plugins::events::{RenderPurpose, WindowContext};
pub async fn send_http_request<R: Runtime>(
window: &WebviewWindow<R>,
@@ -439,7 +436,7 @@ pub async fn send_http_request<R: Runtime>(
};
r.state = HttpResponseState::Connected;
update_response_if_id(&window, &r)
update_response_if_id(&window, &r, &UpdateSource::Window)
.await
.expect("Failed to update response after connected");
}
@@ -468,7 +465,7 @@ pub async fn send_http_request<R: Runtime>(
f.flush().await.expect("Failed to flush file");
written_bytes += bytes.len();
r.content_length = Some(written_bytes as i32);
update_response_if_id(&window, &r)
update_response_if_id(&window, &r, &UpdateSource::Window)
.await
.expect("Failed to update response");
}
@@ -490,7 +487,7 @@ pub async fn send_http_request<R: Runtime>(
None => Some(written_bytes as i32),
};
r.state = HttpResponseState::Closed;
update_response_if_id(&window, &r)
update_response_if_id(&window, &r, &UpdateSource::Window)
.await
.expect("Failed to update response");
};
@@ -516,7 +513,9 @@ pub async fn send_http_request<R: Runtime>(
})
.collect::<Vec<_>>();
cookie_jar.cookies = json_cookies;
if let Err(e) = upsert_cookie_jar(&window, &cookie_jar).await {
if let Err(e) =
upsert_cookie_jar(&window, &cookie_jar, &UpdateSource::Window).await
{
error!("Failed to update cookie jar: {}", e);
};
}
@@ -538,7 +537,7 @@ pub async fn send_http_request<R: Runtime>(
match get_http_response(window, response_id.as_str()).await {
Ok(mut r) => {
r.state = HttpResponseState::Closed;
update_response_if_id(&window, &r).await.expect("Failed to update response")
update_response_if_id(&window, &r, &UpdateSource::Window).await.expect("Failed to update response")
},
_ => {
response_err(&*response.lock().await, "Ephemeral request was cancelled".to_string(), &window).await

View File

@@ -33,10 +33,8 @@ use tokio::sync::Mutex;
use tokio::task::block_in_place;
use yaak_grpc::manager::{DynamicMessage, GrpcHandle};
use yaak_grpc::{deserialize_message, serialize_message, Code, ServiceDefinition};
use yaak_plugin_runtime::manager::PluginManager;
use crate::analytics::{AnalyticsAction, AnalyticsResource};
use crate::export_resources::{get_workspace_export_resources, WorkspaceExportResources};
use crate::grpc::metadata_to_map;
use crate::http_request::send_http_request;
use crate::notifications::YaakNotifier;
@@ -50,36 +48,38 @@ use yaak_models::models::{
ModelType, Plugin, Settings, Workspace,
};
use yaak_models::queries::{
cancel_pending_grpc_connections, cancel_pending_responses, create_default_http_response,
delete_all_grpc_connections, delete_all_grpc_connections_for_workspace,
delete_all_http_responses_for_request, delete_all_http_responses_for_workspace,
delete_cookie_jar, delete_environment, delete_folder, delete_grpc_connection,
delete_grpc_request, delete_http_request, delete_http_response, delete_plugin,
delete_workspace, duplicate_folder, duplicate_grpc_request, duplicate_http_request,
generate_id, generate_model_id, get_base_environment, get_cookie_jar, get_environment,
get_folder, get_grpc_connection, get_grpc_request, get_http_request, get_http_response,
get_key_value_raw, get_or_create_settings, get_plugin, get_workspace, list_cookie_jars,
list_environments, list_folders, list_grpc_connections_for_workspace, list_grpc_events,
list_grpc_requests, list_http_requests, list_http_responses_for_request,
batch_upsert, cancel_pending_grpc_connections, cancel_pending_responses,
create_default_http_response, delete_all_grpc_connections,
delete_all_grpc_connections_for_workspace, delete_all_http_responses_for_request,
delete_all_http_responses_for_workspace, delete_cookie_jar, delete_environment, delete_folder,
delete_grpc_connection, delete_grpc_request, delete_http_request, delete_http_response,
delete_plugin, delete_workspace, duplicate_folder, duplicate_grpc_request,
duplicate_http_request, ensure_base_environment, generate_id, generate_model_id,
get_base_environment, get_cookie_jar, get_environment, get_folder, get_grpc_connection,
get_grpc_request, get_http_request, get_http_response, get_key_value_raw,
get_or_create_settings, get_plugin, get_workspace, get_workspace_export_resources,
list_cookie_jars, list_environments, list_folders, list_grpc_connections_for_workspace,
list_grpc_events, list_grpc_requests, list_http_requests, list_http_responses_for_request,
list_http_responses_for_workspace, list_key_values_raw, list_plugins, list_workspaces,
set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar,
upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event,
upsert_grpc_request, upsert_http_request, upsert_plugin, upsert_workspace,
upsert_grpc_request, upsert_http_request, upsert_plugin, upsert_workspace, BatchUpsertResult,
UpdateSource,
};
use yaak_plugin_runtime::events::{
use yaak_plugins::events::{
BootResponse, CallHttpRequestActionRequest, FilterResponse, FindHttpResponsesResponse,
GetHttpRequestActionsResponse, GetHttpRequestByIdResponse, GetTemplateFunctionsResponse, Icon,
InternalEvent, InternalEventPayload, PromptTextResponse, RenderHttpRequestResponse,
RenderPurpose, SendHttpRequestResponse, ShowToastRequest, TemplateRenderResponse,
WindowContext,
};
use yaak_plugin_runtime::plugin_handle::PluginHandle;
use yaak_plugins::manager::PluginManager;
use yaak_plugins::plugin_handle::PluginHandle;
use yaak_sse::sse::ServerSentEvent;
use yaak_templates::format::format_json;
use yaak_templates::{Parser, Tokens};
mod analytics;
mod export_resources;
mod grpc;
mod http_request;
mod notifications;
@@ -269,6 +269,7 @@ async fn cmd_grpc_go<R: Runtime>(
url: req.url.clone(),
..Default::default()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())?
@@ -321,6 +322,7 @@ async fn cmd_grpc_go<R: Runtime>(
state: GrpcConnectionState::Closed,
..conn.clone()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())?;
@@ -394,6 +396,7 @@ async fn cmd_grpc_go<R: Runtime>(
content: e.to_string(),
..base_msg.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -410,6 +413,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::ClientMessage,
..base_msg.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -454,6 +458,7 @@ async fn cmd_grpc_go<R: Runtime>(
metadata: metadata.clone(),
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -492,6 +497,7 @@ async fn cmd_grpc_go<R: Runtime>(
content: msg,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -512,6 +518,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::Info,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -522,6 +529,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::ServerMessage,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -533,6 +541,7 @@ async fn cmd_grpc_go<R: Runtime>(
status: Some(Code::Ok as i32),
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -557,12 +566,13 @@ async fn cmd_grpc_go<R: Runtime>(
..base_event.clone()
},
}),
&UpdateSource::Window,
)
.await
.unwrap();
}
None => {
// Server streaming doesn't return initial message
// Server streaming doesn't return the initial message
}
}
@@ -581,6 +591,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::Info,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -607,6 +618,7 @@ async fn cmd_grpc_go<R: Runtime>(
..base_event.clone()
},
}),
&UpdateSource::Window,
)
.await
.unwrap();
@@ -626,6 +638,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::ServerMessage,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -642,6 +655,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::ConnectionEnd,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -657,6 +671,7 @@ async fn cmd_grpc_go<R: Runtime>(
event_type: GrpcEventType::ConnectionEnd,
..base_event.clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -687,6 +702,7 @@ async fn cmd_grpc_go<R: Runtime>(
state: GrpcConnectionState::Closed,
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
},
&UpdateSource::Window,
).await.unwrap();
},
_ = cancelled_rx.changed() => {
@@ -698,6 +714,7 @@ async fn cmd_grpc_go<R: Runtime>(
status: Some(Code::Cancelled as i32),
..base_msg.clone()
},
&UpdateSource::Window,
).await.unwrap();
upsert_grpc_connection(
&w,
@@ -707,6 +724,7 @@ async fn cmd_grpc_go<R: Runtime>(
state: GrpcConnectionState::Closed,
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
},
&UpdateSource::Window,
)
.await
.unwrap();
@@ -809,7 +827,7 @@ async fn cmd_import_data<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
file_path: &str,
) -> Result<WorkspaceExportResources, String> {
) -> Result<BatchUpsertResult, String> {
let file = read_to_string(file_path)
.await
.unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
@@ -817,7 +835,6 @@ async fn cmd_import_data<R: Runtime>(
let (import_result, plugin_name) =
plugin_manager.import_data(&window, file_contents).await.map_err(|e| e.to_string())?;
let mut imported_resources = WorkspaceExportResources::default();
let mut id_map: BTreeMap<String, String> = BTreeMap::new();
fn maybe_gen_id(id: &str, model: ModelType, ids: &mut BTreeMap<String, String>) -> String {
@@ -848,87 +865,68 @@ async fn cmd_import_data<R: Runtime>(
let resources = import_result.resources;
for mut v in resources.workspaces {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
let x = upsert_workspace(&window, v).await.map_err(|e| e.to_string())?;
imported_resources.workspaces.push(x.clone());
}
info!("Imported {} workspaces", imported_resources.workspaces.len());
let workspaces: Vec<Workspace> = resources
.workspaces
.into_iter()
.map(|mut v| {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v
})
.collect();
// Environments can foreign-key to themselves, so we need to import from
// the top of the tree to the bottom to avoid foreign key conflicts.
// We do this by looping until we've imported them all, only importing if:
// - The parent has been imported
// - The environment hasn't already been imported
// The loop exits when imported.len == to_import.len
while imported_resources.environments.len() < resources.environments.len() {
for mut v in resources.environments.clone() {
let environments: Vec<Environment> = resources
.environments
.into_iter()
.map(|mut v| {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeEnvironment, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.environment_id =
maybe_gen_id_opt(v.environment_id, ModelType::TypeEnvironment, &mut id_map);
if let Some(fid) = v.environment_id.clone() {
let imported_parent = imported_resources.environments.iter().find(|f| f.id == fid);
if imported_parent.is_none() {
continue;
}
}
if let Some(_) = imported_resources.environments.iter().find(|f| f.id == v.id) {
continue;
}
let x = upsert_environment(&window, v).await.map_err(|e| e.to_string())?;
imported_resources.environments.push(x.clone());
}
}
info!("Imported {} environments", imported_resources.environments.len());
v
})
.collect();
// Folders can foreign-key to themselves, so we need to import from
// the top of the tree to the bottom to avoid foreign key conflicts.
// We do this by looping until we've imported them all, only importing if:
// - The parent folder has been imported
// - The folder hasn't already been imported
// The loop exits when imported.len == to_import.len
while imported_resources.folders.len() < resources.folders.len() {
for mut v in resources.folders.clone() {
let folders: Vec<Folder> = resources
.folders
.into_iter()
.map(|mut v| {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeFolder, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
if let Some(fid) = v.folder_id.clone() {
let imported_parent = imported_resources.folders.iter().find(|f| f.id == fid);
if imported_parent.is_none() {
continue;
}
}
if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) {
continue;
}
let x = upsert_folder(&window, v).await.map_err(|e| e.to_string())?;
imported_resources.folders.push(x.clone());
}
}
info!("Imported {} folders", imported_resources.folders.len());
v
})
.collect();
for mut v in resources.http_requests {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeHttpRequest, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
let x = upsert_http_request(&window, v).await.map_err(|e| e.to_string())?;
imported_resources.http_requests.push(x.clone());
}
info!("Imported {} http_requests", imported_resources.http_requests.len());
let http_requests: Vec<HttpRequest> = resources
.http_requests
.into_iter()
.map(|mut v| {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeHttpRequest, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
v
})
.collect();
for mut v in resources.grpc_requests {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeGrpcRequest, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
let x = upsert_grpc_request(&window, v).await.map_err(|e| e.to_string())?;
imported_resources.grpc_requests.push(x.clone());
}
info!("Imported {} grpc_requests", imported_resources.grpc_requests.len());
let grpc_requests: Vec<GrpcRequest> = resources
.grpc_requests
.into_iter()
.map(|mut v| {
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeGrpcRequest, &mut id_map);
v.workspace_id =
maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map);
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
v
})
.collect();
let upserted =
batch_upsert(&window, workspaces, environments, folders, http_requests, grpc_requests)
.await
.map_err(|e| e.to_string())?;
analytics::track_event(
&window,
@@ -938,7 +936,7 @@ async fn cmd_import_data<R: Runtime>(
)
.await;
Ok(imported_resources)
Ok(upserted)
}
#[tauri::command]
@@ -1000,7 +998,7 @@ async fn cmd_export_data(
export_path: &str,
workspace_ids: Vec<&str>,
) -> Result<(), String> {
let export_data = get_workspace_export_resources(&window, workspace_ids).await;
let export_data = get_workspace_export_resources(window.app_handle(), workspace_ids).await;
let f = File::options()
.create(true)
.truncate(true)
@@ -1049,8 +1047,9 @@ async fn cmd_send_http_request(
// that has not yet been saved in the DB.
request: HttpRequest,
) -> Result<HttpResponse, String> {
let response =
create_default_http_response(&window, &request.id).await.map_err(|e| e.to_string())?;
let response = create_default_http_response(&window, &request.id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())?;
let (cancel_tx, mut cancel_rx) = tokio::sync::watch::channel(false);
window.listen_any(format!("cancel_http_response_{}", response.id), move |_event| {
@@ -1087,7 +1086,9 @@ async fn response_err<R: Runtime>(
let mut response = response.clone();
response.state = HttpResponseState::Closed;
response.error = Some(error.clone());
response = update_response_if_id(w, &response).await.expect("Failed to update response");
response = update_response_if_id(w, &response, &UpdateSource::Window)
.await
.expect("Failed to update response");
response
}
@@ -1135,15 +1136,11 @@ async fn cmd_set_key_value(
value: &str,
w: WebviewWindow,
) -> Result<KeyValue, String> {
let (key_value, _created) = set_key_value_raw(&w, namespace, key, value).await;
let (key_value, _created) =
set_key_value_raw(&w, namespace, key, value, &UpdateSource::Window).await;
Ok(key_value)
}
#[tauri::command]
async fn cmd_create_workspace(name: &str, w: WebviewWindow) -> Result<Workspace, String> {
upsert_workspace(&w, Workspace::new(name.to_string())).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_install_plugin<R: Runtime>(
directory: &str,
@@ -1163,6 +1160,7 @@ async fn cmd_install_plugin<R: Runtime>(
url,
..Default::default()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())?;
@@ -1176,7 +1174,9 @@ async fn cmd_uninstall_plugin<R: Runtime>(
plugin_manager: State<'_, PluginManager>,
window: WebviewWindow<R>,
) -> Result<Plugin, String> {
let plugin = delete_plugin(&window, plugin_id).await.map_err(|e| e.to_string())?;
let plugin = delete_plugin(&window, plugin_id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())?;
plugin_manager
.uninstall(WindowContext::from_window(&window), plugin.directory.as_str())
@@ -1191,12 +1191,12 @@ async fn cmd_update_cookie_jar(
cookie_jar: CookieJar,
w: WebviewWindow,
) -> Result<CookieJar, String> {
upsert_cookie_jar(&w, &cookie_jar).await.map_err(|e| e.to_string())
upsert_cookie_jar(&w, &cookie_jar, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_delete_cookie_jar(w: WebviewWindow, cookie_jar_id: &str) -> Result<CookieJar, String> {
delete_cookie_jar(&w, cookie_jar_id).await.map_err(|e| e.to_string())
delete_cookie_jar(&w, cookie_jar_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1212,6 +1212,7 @@ async fn cmd_create_cookie_jar(
workspace_id: workspace_id.to_string(),
..Default::default()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())
@@ -1234,6 +1235,7 @@ async fn cmd_create_environment(
variables,
..Default::default()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())
@@ -1256,6 +1258,7 @@ async fn cmd_create_grpc_request(
sort_priority,
..Default::default()
},
&UpdateSource::Window,
)
.await
.map_err(|e| e.to_string())
@@ -1263,7 +1266,7 @@ async fn cmd_create_grpc_request(
#[tauri::command]
async fn cmd_duplicate_grpc_request(id: &str, w: WebviewWindow) -> Result<GrpcRequest, String> {
duplicate_grpc_request(&w, id).await.map_err(|e| e.to_string())
duplicate_grpc_request(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1280,17 +1283,17 @@ async fn cmd_create_http_request(
request: HttpRequest,
w: WebviewWindow,
) -> Result<HttpRequest, String> {
upsert_http_request(&w, request).await.map_err(|e| e.to_string())
upsert_http_request(&w, request, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_duplicate_http_request(id: &str, w: WebviewWindow) -> Result<HttpRequest, String> {
duplicate_http_request(&w, id).await.map_err(|e| e.to_string())
duplicate_http_request(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_update_workspace(workspace: Workspace, w: WebviewWindow) -> Result<Workspace, String> {
upsert_workspace(&w, workspace).await.map_err(|e| e.to_string())
upsert_workspace(&w, workspace, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1298,7 +1301,7 @@ async fn cmd_update_environment(
environment: Environment,
w: WebviewWindow,
) -> Result<Environment, String> {
upsert_environment(&w, environment).await.map_err(|e| e.to_string())
upsert_environment(&w, environment, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1306,7 +1309,7 @@ async fn cmd_update_grpc_request(
request: GrpcRequest,
w: WebviewWindow,
) -> Result<GrpcRequest, String> {
upsert_grpc_request(&w, request).await.map_err(|e| e.to_string())
upsert_grpc_request(&w, request, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1314,7 +1317,7 @@ async fn cmd_update_http_request(
request: HttpRequest,
window: WebviewWindow,
) -> Result<HttpRequest, String> {
upsert_http_request(&window, request).await.map_err(|e| e.to_string())
upsert_http_request(&window, request, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1322,7 +1325,7 @@ async fn cmd_delete_grpc_request(
w: WebviewWindow,
request_id: &str,
) -> Result<GrpcRequest, String> {
delete_grpc_request(&w, request_id).await.map_err(|e| e.to_string())
delete_grpc_request(&w, request_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1330,7 +1333,7 @@ async fn cmd_delete_http_request(
w: WebviewWindow,
request_id: &str,
) -> Result<HttpRequest, String> {
delete_http_request(&w, request_id).await.map_err(|e| e.to_string())
delete_http_request(&w, request_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1338,31 +1341,9 @@ async fn cmd_list_folders(workspace_id: &str, w: WebviewWindow) -> Result<Vec<Fo
list_folders(&w, workspace_id).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_create_folder(
workspace_id: &str,
name: &str,
sort_priority: f32,
folder_id: Option<&str>,
w: WebviewWindow,
) -> Result<Folder, String> {
upsert_folder(
&w,
Folder {
workspace_id: workspace_id.to_string(),
name: name.to_string(),
folder_id: folder_id.map(|s| s.to_string()),
sort_priority,
..Default::default()
},
)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_update_folder(folder: Folder, w: WebviewWindow) -> Result<Folder, String> {
upsert_folder(&w, folder).await.map_err(|e| e.to_string())
upsert_folder(&w, folder, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1376,7 +1357,7 @@ async fn cmd_write_file_dev(pathname: &str, contents: &str) -> Result<(), String
#[tauri::command]
async fn cmd_delete_folder(w: WebviewWindow, folder_id: &str) -> Result<Folder, String> {
delete_folder(&w, folder_id).await.map_err(|e| e.to_string())
delete_folder(&w, folder_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1384,7 +1365,7 @@ async fn cmd_delete_environment(
w: WebviewWindow,
environment_id: &str,
) -> Result<Environment, String> {
delete_environment(&w, environment_id).await.map_err(|e| e.to_string())
delete_environment(&w, environment_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1424,6 +1405,9 @@ async fn cmd_list_environments(
workspace_id: &str,
w: WebviewWindow,
) -> Result<Vec<Environment>, String> {
// Not sure of a better place to put this...
ensure_base_environment(&w, workspace_id).await.map_err(|e| e.to_string())?;
list_environments(&w, workspace_id).await.map_err(|e| e.to_string())
}
@@ -1466,7 +1450,7 @@ async fn cmd_get_settings(w: WebviewWindow) -> Result<Settings, ()> {
#[tauri::command]
async fn cmd_update_settings(settings: Settings, w: WebviewWindow) -> Result<Settings, String> {
update_settings(&w, settings).await.map_err(|e| e.to_string())
update_settings(&w, settings, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1504,6 +1488,7 @@ async fn cmd_list_cookie_jars(
workspace_id: workspace_id.to_string(),
..Default::default()
},
&UpdateSource::Window,
)
.await
.expect("Failed to create CookieJar");
@@ -1539,29 +1524,37 @@ async fn cmd_list_http_responses(
#[tauri::command]
async fn cmd_delete_http_response(id: &str, w: WebviewWindow) -> Result<HttpResponse, String> {
delete_http_response(&w, id).await.map_err(|e| e.to_string())
delete_http_response(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_delete_grpc_connection(id: &str, w: WebviewWindow) -> Result<GrpcConnection, String> {
delete_grpc_connection(&w, id).await.map_err(|e| e.to_string())
delete_grpc_connection(&w, id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_delete_all_grpc_connections(request_id: &str, w: WebviewWindow) -> Result<(), String> {
delete_all_grpc_connections(&w, request_id).await.map_err(|e| e.to_string())
delete_all_grpc_connections(&w, request_id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_delete_send_history(workspace_id: &str, w: WebviewWindow) -> Result<(), String> {
delete_all_http_responses_for_workspace(&w, workspace_id).await.map_err(|e| e.to_string())?;
delete_all_grpc_connections_for_workspace(&w, workspace_id).await.map_err(|e| e.to_string())?;
delete_all_http_responses_for_workspace(&w, workspace_id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())?;
delete_all_grpc_connections_for_workspace(&w, workspace_id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())?;
Ok(())
}
#[tauri::command]
async fn cmd_delete_all_http_responses(request_id: &str, w: WebviewWindow) -> Result<(), String> {
delete_all_http_responses_for_request(&w, request_id).await.map_err(|e| e.to_string())
delete_all_http_responses_for_request(&w, request_id, &UpdateSource::Window)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1576,6 +1569,7 @@ async fn cmd_list_workspaces(w: WebviewWindow) -> Result<Vec<Workspace>, String>
setting_validate_certificates: true,
..Default::default()
},
&UpdateSource::Window,
)
.await
.expect("Failed to create Workspace");
@@ -1662,7 +1656,7 @@ async fn cmd_new_main_window(app_handle: AppHandle, url: &str) -> Result<(), Str
#[tauri::command]
async fn cmd_delete_workspace(w: WebviewWindow, workspace_id: &str) -> Result<Workspace, String> {
delete_workspace(&w, workspace_id).await.map_err(|e| e.to_string())
delete_workspace(&w, workspace_id, &UpdateSource::Window).await.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1724,9 +1718,10 @@ pub fn run() {
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_fs::init())
.plugin(yaak_license::init())
.plugin(yaak_models::plugin::Builder::default().build())
.plugin(tauri_plugin_yaak_license::init())
.plugin(yaak_plugin_runtime::plugin::init());
.plugin(yaak_plugins::init())
.plugin(yaak_sync::init());
#[cfg(target_os = "macos")]
{
@@ -1759,10 +1754,8 @@ pub fn run() {
cmd_check_for_updates,
cmd_create_cookie_jar,
cmd_create_environment,
cmd_create_folder,
cmd_create_grpc_request,
cmd_create_http_request,
cmd_create_workspace,
cmd_curl_to_request,
cmd_delete_all_grpc_connections,
cmd_delete_all_http_responses,
@@ -1897,7 +1890,16 @@ fn is_dev() -> bool {
}
fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow {
let label = format!("{MAIN_WINDOW_PREFIX}{}", handle.webview_windows().len());
let mut counter = 0;
let label = loop {
let label = format!("{MAIN_WINDOW_PREFIX}{counter}");
match handle.webview_windows().get(label.as_str()) {
None => break Some(label),
Some(_) => counter += 1,
}
}
.expect("Failed to generate label for new window");
let config = CreateWindowConfig {
url,
label: label.as_str(),
@@ -2183,7 +2185,7 @@ async fn handle_plugin_event<R: Runtime>(
updated_at: Utc::now().naive_utc(), // TODO: Add reloaded_at field to use instead
..plugin
};
upsert_plugin(&window, new_plugin).await.unwrap();
upsert_plugin(&window, new_plugin, &UpdateSource::Plugin).await.unwrap();
}
let toast_event = plugin_handle.build_event_to_send(
WindowContext::from_window(&window),
@@ -2203,8 +2205,13 @@ async fn handle_plugin_event<R: Runtime>(
let cookie_jar = cookie_jar_from_window(&window).await;
let environment = environment_from_window(&window).await;
let resp =
create_default_http_response(&window, req.http_request.id.as_str()).await.unwrap();
let resp = create_default_http_response(
&window,
req.http_request.id.as_str(),
&UpdateSource::Plugin,
)
.await
.unwrap();
let result = send_http_request(
&window,

View File

@@ -6,7 +6,7 @@ use log::debug;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use tauri::{Emitter, Manager, Runtime, WebviewWindow};
use yaak_models::queries::{get_key_value_raw, set_key_value_raw};
use yaak_models::queries::{get_key_value_raw, set_key_value_raw, UpdateSource};
// Check for updates every hour
const MAX_UPDATE_CHECK_SECONDS: u64 = 60 * 60;
@@ -47,7 +47,7 @@ impl YaakNotifier {
seen.push(id.to_string());
debug!("Marked notification as seen {}", id);
let seen_json = serde_json::to_string(&seen).map_err(|e| e.to_string())?;
set_key_value_raw(w, KV_NAMESPACE, KV_KEY, seen_json.as_str()).await;
set_key_value_raw(w, KV_NAMESPACE, KV_KEY, seen_json.as_str(), &UpdateSource::Window).await;
Ok(())
}

View File

@@ -1,7 +1,7 @@
use std::collections::HashMap;
use tauri::{AppHandle, Manager, Runtime};
use yaak_plugin_runtime::events::{RenderPurpose, TemplateFunctionArg, WindowContext};
use yaak_plugin_runtime::manager::PluginManager;
use yaak_plugins::events::{RenderPurpose, TemplateFunctionArg, WindowContext};
use yaak_plugins::manager::PluginManager;
use yaak_templates::TemplateCallback;
#[derive(Clone)]

View File

@@ -6,7 +6,7 @@ use tauri::{AppHandle, Manager};
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
use tauri_plugin_updater::UpdaterExt;
use tokio::task::block_in_place;
use yaak_plugin_runtime::manager::PluginManager;
use yaak_plugins::manager::PluginManager;
use crate::is_dev;

View File

@@ -1,5 +1,5 @@
[package]
name = "yaak_grpc"
name = "yaak-grpc"
version = "0.1.0"
edition = "2021"
publish = false

View File

@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-yaak-license"
links = "tauri-plugin-yaak-license"
name = "yaak-license"
links = "yaak-license"
version = "0.1.0"
edition = "2021"
publish = false
@@ -11,7 +11,7 @@ serde = { version = "1.0.208", features = ["derive"] }
ts-rs = { workspace = true }
thiserror = { workspace = true }
tauri = { workspace = true }
yaak_models = { workspace = true }
yaak-models = { workspace = true }
chrono = "0.4.38"
log = "0.4.22"
serde_json = "1.0.132"

View File

@@ -1,6 +1,7 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api/core';
import { useListenToTauriEvent } from '@yaakapp/app/hooks/useListenToTauriEvent';
import { listen } from '@tauri-apps/api/event';
import { useEffect } from 'react';
import { LicenseCheckStatus } from './bindings/license';
export * from './bindings/license';
@@ -10,15 +11,15 @@ export function useLicense() {
const activate = useMutation<void, string, { licenseKey: string }>({
mutationKey: ['license.activate'],
mutationFn: (payload) => invoke('plugin:yaak-license|activate', payload),
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY });
},
onSuccess: () => queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY }),
});
// Check the license again after a license is activated
useListenToTauriEvent('license-activated', async () => {
await queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY });
});
useEffect(() => {
listen('license-activated', () => {
queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY }).catch(console.error);
}).then(console.error);
}, []);
const CHECK_QUERY_KEY = ['license.check'];
const check = useQuery<void, string, LicenseCheckStatus>({

View File

@@ -7,6 +7,7 @@ use std::ops::Add;
use std::time::Duration;
use tauri::{is_dev, AppHandle, Emitter, Runtime, WebviewWindow};
use ts_rs::TS;
use yaak_models::queries::UpdateSource;
const KV_NAMESPACE: &str = "license";
const KV_ACTIVATION_ID_KEY: &str = "activation_id";
@@ -75,6 +76,7 @@ pub async fn activate_license<R: Runtime>(
KV_ACTIVATION_ID_KEY,
KV_NAMESPACE,
body.activation_id.as_str(),
&UpdateSource::Window,
)
.await;

View File

@@ -1,21 +1,21 @@
[package]
name = "yaak_models"
name = "yaak-models"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
chrono = { version = "0.4.38", features = ["serde"] }
rusqlite = { version = "0.31.0", features = ["bundled", "chrono"] }
sea-query = { version = "0.31.0", features = ["with-chrono", "attr"] }
sea-query-rusqlite = { version = "0.6.0", features = ["with-chrono"] }
log = "0.4.22"
nanoid = "0.4.0"
r2d2 = "0.8.10"
r2d2_sqlite = { version = "0.25.0" }
rusqlite = { version = "0.32.1", features = ["bundled", "chrono"] }
sea-query = { version = "0.32.1", features = ["with-chrono", "attr"] }
sea-query-rusqlite = { version = "0.7.0", features = ["with-chrono"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.122"
sqlx = { version = "0.8.0", features = ["sqlite", "runtime-tokio-rustls"] }
tauri = { workspace = true }
thiserror = "1.0.63"
ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] }
tauri = { workspace = true }
sqlx = { version = "0.8.0", features = ["sqlite", "runtime-tokio-rustls"] }
log = "0.4.22"
rand = "0.8.5"
r2d2 = "0.8.10"
r2d2_sqlite = { version = "0.24.0" }

View File

@@ -42,6 +42,8 @@ export type HttpUrlParameter = { enabled?: boolean, name: string, value: string,
export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, key: string, namespace: string, value: string, };
export type ModelPayload = { model: AnyModel, windowLabel: string, updateSource: UpdateSource, };
export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, };
export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" };
@@ -50,4 +52,8 @@ export type ProxySettingAuth = { user: string, password: string, };
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, proxy: ProxySetting | null, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, };
export type UpdateSource = "sync" | "window" | "plugin" | "background";
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, settingSyncDir: string | null, };

View File

@@ -1,5 +1,5 @@
pub mod models;
pub mod queries;
mod error;
pub mod error;
pub mod plugin;

View File

@@ -1,7 +1,7 @@
use chrono::NaiveDateTime;
use rusqlite::Row;
use sea_query::Iden;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
use ts_rs::TS;
@@ -117,6 +117,7 @@ pub struct Workspace {
#[serde(default = "default_true")]
pub setting_follow_redirects: bool,
pub setting_request_timeout: i32,
pub setting_sync_dir: Option<String>,
}
#[derive(Iden)]
@@ -132,6 +133,7 @@ pub enum WorkspaceIden {
Name,
SettingFollowRedirects,
SettingRequestTimeout,
SettingSyncDir,
SettingValidateCertificates,
}
@@ -146,9 +148,10 @@ impl<'s> TryFrom<&Row<'s>> for Workspace {
updated_at: r.get("updated_at")?,
name: r.get("name")?,
description: r.get("description")?,
setting_validate_certificates: r.get("setting_validate_certificates")?,
setting_follow_redirects: r.get("setting_follow_redirects")?,
setting_request_timeout: r.get("setting_request_timeout")?,
setting_sync_dir: r.get("setting_sync_dir")?,
setting_validate_certificates: r.get("setting_validate_certificates")?,
})
}
}
@@ -864,6 +867,60 @@ impl<'s> TryFrom<&Row<'s>> for Plugin {
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[serde(default, rename_all = "camelCase")]
#[ts(export, export_to = "models.ts")]
pub struct SyncState {
#[ts(type = "\"sync_state\"")]
pub model: String,
pub id: String,
pub workspace_id: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub flushed_at: NaiveDateTime,
pub model_id: String,
pub checksum: String,
pub rel_path: String,
pub sync_dir: String,
}
#[derive(Iden)]
pub enum SyncStateIden {
#[iden = "sync_states"]
Table,
Model,
Id,
WorkspaceId,
CreatedAt,
UpdatedAt,
Checksum,
FlushedAt,
ModelId,
RelPath,
SyncDir,
}
impl<'s> TryFrom<&Row<'s>> for SyncState {
type Error = rusqlite::Error;
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
Ok(SyncState {
id: r.get("id")?,
workspace_id: r.get("workspace_id")?,
model: r.get("model")?,
created_at: r.get("created_at")?,
updated_at: r.get("updated_at")?,
flushed_at: r.get("flushed_at")?,
checksum: r.get("checksum")?,
model_id: r.get("model_id")?,
sync_dir: r.get("sync_dir")?,
rel_path: r.get("rel_path")?,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[serde(default, rename_all = "camelCase")]
#[ts(export, export_to = "models.ts")]
@@ -925,6 +982,7 @@ pub enum ModelType {
TypeHttpResponse,
TypePlugin,
TypeWorkspace,
TypeSyncState,
}
impl ModelType {
@@ -940,12 +998,13 @@ impl ModelType {
ModelType::TypeHttpResponse => "rs",
ModelType::TypePlugin => "pg",
ModelType::TypeWorkspace => "wk",
ModelType::TypeSyncState => "ss",
}
.to_string()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[derive(Debug, Clone, Serialize, TS)]
#[serde(rename_all = "camelCase", untagged)]
#[ts(export, export_to = "models.ts")]
pub enum AnyModel {
@@ -962,3 +1021,54 @@ pub enum AnyModel {
KeyValue(KeyValue),
Workspace(Workspace),
}
impl<'de> Deserialize<'de> for AnyModel {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = Value::deserialize(deserializer)?;
let model = value.as_object().unwrap();
let model = match model.get("model") {
Some(m) if m == "http_request" => {
AnyModel::HttpRequest(serde_json::from_value(value).unwrap())
}
Some(m) if m == "grpc_request" => {
AnyModel::GrpcRequest(serde_json::from_value(value).unwrap())
}
Some(m) if m == "workspace" => {
AnyModel::Workspace(serde_json::from_value(value).unwrap())
}
Some(m) if m == "environment" => {
AnyModel::Environment(serde_json::from_value(value).unwrap())
}
Some(m) if m == "folder" => {
AnyModel::Folder(serde_json::from_value(value).unwrap())
}
Some(m) if m == "key_value" => {
AnyModel::KeyValue(serde_json::from_value(value).unwrap())
}
Some(m) if m == "grpc_connection" => {
AnyModel::GrpcConnection(serde_json::from_value(value).unwrap())
}
Some(m) if m == "grpc_event" => {
AnyModel::GrpcEvent(serde_json::from_value(value).unwrap())
}
Some(m) if m == "cookie_jar" => {
AnyModel::CookieJar(serde_json::from_value(value).unwrap())
}
Some(m) if m == "plugin" => {
AnyModel::Plugin(serde_json::from_value(value).unwrap())
}
Some(m) => {
return Err(serde::de::Error::custom(format!("Unknown model {}", m)));
}
None => {
return Err(serde::de::Error::custom("Missing or invalid model"));
}
};
Ok(model)
}
}

View File

@@ -4,15 +4,14 @@ use r2d2_sqlite::SqliteConnectionManager;
use serde::Deserialize;
use sqlx::migrate::Migrator;
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::SqlitePool;
use std::fs::{create_dir_all, File};
use sqlx::{ConnectOptions, SqlitePool};
use std::fs::create_dir_all;
use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use tauri::async_runtime::Mutex;
use tauri::path::BaseDirectory;
use tauri::plugin::TauriPlugin;
use tauri::{plugin, AppHandle, Manager, Runtime};
use tauri::{plugin, AppHandle, Manager, Runtime, Url};
pub struct SqliteConnection(pub Mutex<Pool<SqliteConnectionManager>>);
@@ -62,25 +61,17 @@ impl Builder {
}
}
async fn must_migrate_db<R: Runtime>(app_handle: &AppHandle<R>, path: &PathBuf) {
let app_data_dir = app_handle.path().app_data_dir().unwrap();
let sqlite_file_path = app_data_dir.join("db.sqlite");
info!("Creating database file at {:?}", sqlite_file_path);
File::options()
.write(true)
.create(true)
.open(&sqlite_file_path)
.expect("Problem creating database file!");
fn db_connection_url(sqlite_file_path: &PathBuf) -> Url {
let p_string = sqlite_file_path.to_string_lossy().replace(' ', "%20");
let url = format!("sqlite://{}?mode=rwc", p_string);
Url::parse(&url).unwrap()
}
async fn must_migrate_db<R: Runtime>(app_handle: &AppHandle<R>, sqlite_file_path: &PathBuf) {
let url = db_connection_url(sqlite_file_path);
info!("Connecting to database at {}", url);
let opts = SqliteConnectOptions::from_str(path.to_string_lossy().to_string().as_str()).unwrap();
let pool = SqlitePool::connect_with(opts)
.await
.expect("Failed to connect to database");
let opts = SqliteConnectOptions::from_url(&url).unwrap();
let pool = SqlitePool::connect_with(opts).await.expect("Failed to connect to database");
let p = app_handle
.path()
.resolve("migrations", BaseDirectory::Resource)

View File

@@ -1,5 +1,5 @@
[package]
name = "yaak_plugin_runtime"
name = "yaak-plugins"
version = "0.1.0"
edition = "2021"
publish = false
@@ -16,8 +16,8 @@ tauri-plugin-shell = { workspace = true }
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "process"] }
tonic = "0.12.1"
ts-rs = "10.0.0"
thiserror = "1.0.63"
yaak_models = { workspace = true }
thiserror = "2.0.7"
yaak-models = { workspace = true }
regex = "1.10.6"
path-slash = "0.2.1"

View File

@@ -114,7 +114,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**
@@ -132,7 +132,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**
@@ -158,7 +158,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**
@@ -176,7 +176,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**
@@ -198,7 +198,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**
@@ -222,7 +222,7 @@ name: string,
*/
optional?: boolean,
/**
* The label of the input
* The label of the input
*/
label?: string,
/**

View File

@@ -22,4 +22,4 @@ export type HttpResponseState = "initialized" | "connected" | "closed";
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id: string, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, settingSyncDir: string | null, };

View File

@@ -0,0 +1,6 @@
{
"name": "@yaakapp-internal/plugins",
"private": true,
"version": "1.0.0",
"main": "index.ts"
}

View File

@@ -296,7 +296,7 @@ pub struct TemplateFunction {
pub name: String,
#[ts(optional)]
pub description: Option<String>,
/// Also support alternative names. This is useful for not breaking existing
/// tags when changing the `name` property
#[ts(optional)]
@@ -321,15 +321,15 @@ pub enum TemplateFunctionArg {
pub struct TemplateFunctionBaseArg {
/// The name of the argument. Should be `camelCase` format
pub name: String,
/// Whether the user must fill in the argument
#[ts(optional)]
pub optional: Option<bool>,
/// The label of the input
/// The label of the input
#[ts(optional)]
pub label: Option<String>,
/// The default value
#[ts(optional)]
pub default_value: Option<String>,
@@ -341,7 +341,7 @@ pub struct TemplateFunctionBaseArg {
pub struct TemplateFunctionTextArg {
#[serde(flatten)]
pub base: TemplateFunctionBaseArg,
/// Placeholder for the text input
#[ts(optional)]
pub placeholder: Option<String>,
@@ -361,22 +361,22 @@ pub struct TemplateFunctionHttpRequestArg {
pub struct TemplateFunctionFileArg {
#[serde(flatten)]
pub base: TemplateFunctionBaseArg,
/// The title of the file selection window
pub title: String,
/// Allow selecting multiple files
#[ts(optional)]
pub multiple: Option<bool>,
// Select a directory, not a file
#[ts(optional)]
pub directory: Option<bool>,
// Default file path for selection dialog
#[ts(optional)]
pub default_path: Option<String>,
// Specify to only allow selection of certain file extensions
#[ts(optional)]
pub filters: Option<Vec<OpenFileFilter>>,
@@ -397,7 +397,7 @@ pub struct OpenFileFilter {
pub struct TemplateFunctionSelectArg {
#[serde(flatten)]
pub base: TemplateFunctionBaseArg,
/// The options that will be available in the select input
pub options: Vec<TemplateFunctionSelectOption>,
}

View File

@@ -1,11 +1,19 @@
use crate::manager::PluginManager;
use log::info;
use std::process::exit;
use log::info;
use tauri::plugin::{Builder, TauriPlugin};
use tauri::{Manager, RunEvent, Runtime, State};
use crate::manager::PluginManager;
pub mod error;
pub mod events;
pub mod manager;
mod nodejs;
mod server;
pub mod plugin_handle;
mod util;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("yaak_plugin_runtime")
Builder::new("yaak-plugins")
.setup(|app_handle, _| {
let manager = PluginManager::new(app_handle.clone());
app_handle.manage(manager.clone());

View File

@@ -1,5 +1,5 @@
[package]
name = "yaak_sse"
name = "yaak-sse"
version = "0.1.0"
edition = "2021"
publish = false

View File

@@ -0,0 +1,22 @@
[package]
name = "yaak-sync"
links = "yaak-sync"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
yaak-models = { workspace = true }
chrono = { version = "0.4.38", features = ["serde"] }
serde = { version = "1.0.215", features = ["derive"] }
tauri = { workspace = true }
thiserror = { workspace = true }
ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] }
serde_yaml = "0.9.34"
log = "0.4.22"
serde_json = "1.0.132"
hex = "0.4.3"
sha1 = "0.10.6"
[build-dependencies]
tauri-plugin = { version = "2.0.3", features = ["build"] }

View File

@@ -0,0 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GitCommit = { author: string, when: string, message: string | null, };
export type GitStatus = "added" | "conflict" | "current" | "modified" | "removed" | "renamed" | "type_change";
export type GitStatusEntry = { relaPath: string, status: GitStatus, staged: boolean, prev: string | null, next: string | null, };

View File

@@ -0,0 +1,23 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id: string, };
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, };
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id: string, };
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, description: string, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, description: string, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, id: string, };
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id: string, };
export type SyncModel = { "type": "workspace" } & Workspace | { "type": "environment" } & Environment | { "type": "folder" } & Folder | { "type": "http_request" } & HttpRequest | { "type": "grpc_request" } & GrpcRequest;
export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, settingSyncDir: string | null, };

View File

@@ -0,0 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { SyncModel } from "./models";
import type { SyncState } from "./models";
export type FsCandidate = { "type": "FsCandidate", model: SyncModel, relPath: string, checksum: string, };
export type SyncOp = { "type": "fsCreate", model: SyncModel, } | { "type": "fsUpdate", model: SyncModel, state: SyncState, } | { "type": "fsDelete", state: SyncState, fs: FsCandidate | null, } | { "type": "dbCreate", fs: FsCandidate, } | { "type": "dbUpdate", state: SyncState, fs: FsCandidate, } | { "type": "dbDelete", model: SyncModel, state: SyncState, };

View File

@@ -0,0 +1,5 @@
const COMMANDS: &[&str] = &["calculate", "apply"];
fn main() {
tauri_plugin::Builder::new(COMMANDS).build();
}

View File

@@ -0,0 +1,20 @@
import { invoke } from '@tauri-apps/api/core';
import { Workspace } from '@yaakapp-internal/models';
import { SyncOp } from './bindings/sync';
export const calculateSync = async (workspace: Workspace) => {
if (!workspace.settingSyncDir) throw new Error("Workspace sync dir not configured");
return invoke<SyncOp[]>('plugin:yaak-sync|calculate', {
workspaceId: workspace.id,
dir: workspace.settingSyncDir,
});
};
export const applySync = async (workspace: Workspace, ops: SyncOp[]) => {
console.log('Applying sync', ops);
return invoke<void>('plugin:yaak-sync|apply', {
workspaceId: workspace.id,
dir: workspace.settingSyncDir,
});
};

View File

@@ -1,5 +1,5 @@
{
"name": "@yaakapp-internal/plugin",
"name": "@yaakapp-internal/sync",
"private": true,
"version": "1.0.0",
"main": "index.ts"

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-activate"
description = "Enables the activate command without any pre-configured scope."
commands.allow = ["activate"]
[[permission]]
identifier = "deny-activate"
description = "Denies the activate command without any pre-configured scope."
commands.deny = ["activate"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-add"
description = "Enables the add command without any pre-configured scope."
commands.allow = ["add"]
[[permission]]
identifier = "deny-add"
description = "Denies the add command without any pre-configured scope."
commands.deny = ["add"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-apply"
description = "Enables the apply command without any pre-configured scope."
commands.allow = ["apply"]
[[permission]]
identifier = "deny-apply"
description = "Denies the apply command without any pre-configured scope."
commands.deny = ["apply"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-calculate"
description = "Enables the calculate command without any pre-configured scope."
commands.allow = ["calculate"]
[[permission]]
identifier = "deny-calculate"
description = "Denies the calculate command without any pre-configured scope."
commands.deny = ["calculate"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-check"
description = "Enables the check command without any pre-configured scope."
commands.allow = ["check"]
[[permission]]
identifier = "deny-check"
description = "Denies the check command without any pre-configured scope."
commands.deny = ["check"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-checkout"
description = "Enables the checkout command without any pre-configured scope."
commands.allow = ["checkout"]
[[permission]]
identifier = "deny-checkout"
description = "Denies the checkout command without any pre-configured scope."
commands.deny = ["checkout"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-add"
description = "Enables the cmd_add command without any pre-configured scope."
commands.allow = ["cmd_add"]
[[permission]]
identifier = "deny-cmd-add"
description = "Denies the cmd_add command without any pre-configured scope."
commands.deny = ["cmd_add"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-checkout"
description = "Enables the cmd_checkout command without any pre-configured scope."
commands.allow = ["cmd_checkout"]
[[permission]]
identifier = "deny-cmd-checkout"
description = "Denies the cmd_checkout command without any pre-configured scope."
commands.deny = ["cmd_checkout"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-commit"
description = "Enables the cmd_commit command without any pre-configured scope."
commands.allow = ["cmd_commit"]
[[permission]]
identifier = "deny-cmd-commit"
description = "Denies the cmd_commit command without any pre-configured scope."
commands.deny = ["cmd_commit"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-init"
description = "Enables the cmd_init command without any pre-configured scope."
commands.allow = ["cmd_init"]
[[permission]]
identifier = "deny-cmd-init"
description = "Denies the cmd_init command without any pre-configured scope."
commands.deny = ["cmd_init"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-log"
description = "Enables the cmd_log command without any pre-configured scope."
commands.allow = ["cmd_log"]
[[permission]]
identifier = "deny-cmd-log"
description = "Denies the cmd_log command without any pre-configured scope."
commands.deny = ["cmd_log"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-cmd-status"
description = "Enables the cmd_status command without any pre-configured scope."
commands.allow = ["cmd_status"]
[[permission]]
identifier = "deny-cmd-status"
description = "Denies the cmd_status command without any pre-configured scope."
commands.deny = ["cmd_status"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-commit"
description = "Enables the commit command without any pre-configured scope."
commands.allow = ["commit"]
[[permission]]
identifier = "deny-commit"
description = "Denies the commit command without any pre-configured scope."
commands.deny = ["commit"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-init"
description = "Enables the init command without any pre-configured scope."
commands.allow = ["init"]
[[permission]]
identifier = "deny-init"
description = "Denies the init command without any pre-configured scope."
commands.deny = ["init"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-init-repo"
description = "Enables the init_repo command without any pre-configured scope."
commands.allow = ["init_repo"]
[[permission]]
identifier = "deny-init-repo"
description = "Denies the init_repo command without any pre-configured scope."
commands.deny = ["init_repo"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-initialize"
description = "Enables the initialize command without any pre-configured scope."
commands.allow = ["initialize"]
[[permission]]
identifier = "deny-initialize"
description = "Denies the initialize command without any pre-configured scope."
commands.deny = ["initialize"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-log"
description = "Enables the log command without any pre-configured scope."
commands.allow = ["log"]
[[permission]]
identifier = "deny-log"
description = "Denies the log command without any pre-configured scope."
commands.deny = ["log"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-status"
description = "Enables the status command without any pre-configured scope."
commands.allow = ["status"]
[[permission]]
identifier = "deny-status"
description = "Denies the status command without any pre-configured scope."
commands.deny = ["status"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-sync"
description = "Enables the sync command without any pre-configured scope."
commands.allow = ["sync"]
[[permission]]
identifier = "deny-sync"
description = "Denies the sync command without any pre-configured scope."
commands.deny = ["sync"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-sync-fs"
description = "Enables the sync_fs command without any pre-configured scope."
commands.allow = ["sync_fs"]
[[permission]]
identifier = "deny-sync-fs"
description = "Denies the sync_fs command without any pre-configured scope."
commands.deny = ["sync_fs"]

View File

@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-unstage"
description = "Enables the unstage command without any pre-configured scope."
commands.allow = ["unstage"]
[[permission]]
identifier = "deny-unstage"
description = "Denies the unstage command without any pre-configured scope."
commands.deny = ["unstage"]

View File

@@ -0,0 +1,562 @@
## Default Permission
Default permissions for the plugin
- `allow-calculate`
- `allow-apply`
## Permission Table
<table>
<tr>
<th>Identifier</th>
<th>Description</th>
</tr>
<tr>
<td>
`yaak-sync:allow-activate`
</td>
<td>
Enables the activate command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-activate`
</td>
<td>
Denies the activate command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-add`
</td>
<td>
Enables the add command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-add`
</td>
<td>
Denies the add command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-apply`
</td>
<td>
Enables the apply command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-apply`
</td>
<td>
Denies the apply command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-calculate`
</td>
<td>
Enables the calculate command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-calculate`
</td>
<td>
Denies the calculate command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-check`
</td>
<td>
Enables the check command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-check`
</td>
<td>
Denies the check command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-checkout`
</td>
<td>
Enables the checkout command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-checkout`
</td>
<td>
Denies the checkout command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-add`
</td>
<td>
Enables the cmd_add command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-add`
</td>
<td>
Denies the cmd_add command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-checkout`
</td>
<td>
Enables the cmd_checkout command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-checkout`
</td>
<td>
Denies the cmd_checkout command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-commit`
</td>
<td>
Enables the cmd_commit command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-commit`
</td>
<td>
Denies the cmd_commit command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-init`
</td>
<td>
Enables the cmd_init command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-init`
</td>
<td>
Denies the cmd_init command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-log`
</td>
<td>
Enables the cmd_log command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-log`
</td>
<td>
Denies the cmd_log command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-cmd-status`
</td>
<td>
Enables the cmd_status command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-cmd-status`
</td>
<td>
Denies the cmd_status command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-commit`
</td>
<td>
Enables the commit command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-commit`
</td>
<td>
Denies the commit command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-init`
</td>
<td>
Enables the init command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-init`
</td>
<td>
Denies the init command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-init-repo`
</td>
<td>
Enables the init_repo command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-init-repo`
</td>
<td>
Denies the init_repo command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-initialize`
</td>
<td>
Enables the initialize command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-initialize`
</td>
<td>
Denies the initialize command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-log`
</td>
<td>
Enables the log command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-log`
</td>
<td>
Denies the log command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-status`
</td>
<td>
Enables the status command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-status`
</td>
<td>
Denies the status command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-sync`
</td>
<td>
Enables the sync command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-sync`
</td>
<td>
Denies the sync command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-sync-fs`
</td>
<td>
Enables the sync_fs command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-sync-fs`
</td>
<td>
Denies the sync_fs command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:allow-unstage`
</td>
<td>
Enables the unstage command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`yaak-sync:deny-unstage`
</td>
<td>
Denies the unstage command without any pre-configured scope.
</td>
</tr>
</table>

View File

@@ -0,0 +1,6 @@
[default]
description = "Default permissions for the plugin"
permissions = [
"allow-calculate",
"allow-apply",
]

View File

@@ -0,0 +1,515 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PermissionFile",
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
"type": "object",
"properties": {
"default": {
"description": "The default permission set for the plugin",
"anyOf": [
{
"$ref": "#/definitions/DefaultPermission"
},
{
"type": "null"
}
]
},
"set": {
"description": "A list of permissions sets defined",
"type": "array",
"items": {
"$ref": "#/definitions/PermissionSet"
}
},
"permission": {
"description": "A list of inlined permissions",
"default": [],
"type": "array",
"items": {
"$ref": "#/definitions/Permission"
}
}
},
"definitions": {
"DefaultPermission": {
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
"type": "object",
"required": [
"permissions"
],
"properties": {
"version": {
"description": "The version of the permission.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
]
},
"permissions": {
"description": "All permissions this set contains.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"PermissionSet": {
"description": "A set of direct permissions grouped together under a new name.",
"type": "object",
"required": [
"description",
"identifier",
"permissions"
],
"properties": {
"identifier": {
"description": "A unique identifier for the permission.",
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does.",
"type": "string"
},
"permissions": {
"description": "All permissions this set contains.",
"type": "array",
"items": {
"$ref": "#/definitions/PermissionKind"
}
}
}
},
"Permission": {
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
"type": "object",
"required": [
"identifier"
],
"properties": {
"version": {
"description": "The version of the permission.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 1.0
},
"identifier": {
"description": "A unique identifier for the permission.",
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
]
},
"commands": {
"description": "Allowed or denied commands when using this permission.",
"default": {
"allow": [],
"deny": []
},
"allOf": [
{
"$ref": "#/definitions/Commands"
}
]
},
"scope": {
"description": "Allowed or denied scoped when using this permission.",
"allOf": [
{
"$ref": "#/definitions/Scopes"
}
]
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Target"
}
}
}
},
"Commands": {
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
"type": "object",
"properties": {
"allow": {
"description": "Allowed command.",
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Denied command, which takes priority.",
"default": [],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"Scopes": {
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
"type": "object",
"properties": {
"allow": {
"description": "Data that defines what is allowed by the scope.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Value"
}
},
"deny": {
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Value"
}
}
}
},
"Value": {
"description": "All supported ACL values.",
"anyOf": [
{
"description": "Represents a null JSON value.",
"type": "null"
},
{
"description": "Represents a [`bool`].",
"type": "boolean"
},
{
"description": "Represents a valid ACL [`Number`].",
"allOf": [
{
"$ref": "#/definitions/Number"
}
]
},
{
"description": "Represents a [`String`].",
"type": "string"
},
{
"description": "Represents a list of other [`Value`]s.",
"type": "array",
"items": {
"$ref": "#/definitions/Value"
}
},
{
"description": "Represents a map of [`String`] keys to [`Value`]s.",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/Value"
}
}
]
},
"Number": {
"description": "A valid ACL number.",
"anyOf": [
{
"description": "Represents an [`i64`].",
"type": "integer",
"format": "int64"
},
{
"description": "Represents a [`f64`].",
"type": "number",
"format": "double"
}
]
},
"Target": {
"description": "Platform target.",
"oneOf": [
{
"description": "MacOS.",
"type": "string",
"enum": [
"macOS"
]
},
{
"description": "Windows.",
"type": "string",
"enum": [
"windows"
]
},
{
"description": "Linux.",
"type": "string",
"enum": [
"linux"
]
},
{
"description": "Android.",
"type": "string",
"enum": [
"android"
]
},
{
"description": "iOS.",
"type": "string",
"enum": [
"iOS"
]
}
]
},
"PermissionKind": {
"type": "string",
"oneOf": [
{
"description": "Enables the activate command without any pre-configured scope.",
"type": "string",
"const": "allow-activate"
},
{
"description": "Denies the activate command without any pre-configured scope.",
"type": "string",
"const": "deny-activate"
},
{
"description": "Enables the add command without any pre-configured scope.",
"type": "string",
"const": "allow-add"
},
{
"description": "Denies the add command without any pre-configured scope.",
"type": "string",
"const": "deny-add"
},
{
"description": "Enables the apply command without any pre-configured scope.",
"type": "string",
"const": "allow-apply"
},
{
"description": "Denies the apply command without any pre-configured scope.",
"type": "string",
"const": "deny-apply"
},
{
"description": "Enables the calculate command without any pre-configured scope.",
"type": "string",
"const": "allow-calculate"
},
{
"description": "Denies the calculate command without any pre-configured scope.",
"type": "string",
"const": "deny-calculate"
},
{
"description": "Enables the check command without any pre-configured scope.",
"type": "string",
"const": "allow-check"
},
{
"description": "Denies the check command without any pre-configured scope.",
"type": "string",
"const": "deny-check"
},
{
"description": "Enables the checkout command without any pre-configured scope.",
"type": "string",
"const": "allow-checkout"
},
{
"description": "Denies the checkout command without any pre-configured scope.",
"type": "string",
"const": "deny-checkout"
},
{
"description": "Enables the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-add"
},
{
"description": "Denies the cmd_add command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-add"
},
{
"description": "Enables the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-checkout"
},
{
"description": "Denies the cmd_checkout command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-checkout"
},
{
"description": "Enables the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-commit"
},
{
"description": "Denies the cmd_commit command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-commit"
},
{
"description": "Enables the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-init"
},
{
"description": "Denies the cmd_init command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-init"
},
{
"description": "Enables the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-log"
},
{
"description": "Denies the cmd_log command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-log"
},
{
"description": "Enables the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "allow-cmd-status"
},
{
"description": "Denies the cmd_status command without any pre-configured scope.",
"type": "string",
"const": "deny-cmd-status"
},
{
"description": "Enables the commit command without any pre-configured scope.",
"type": "string",
"const": "allow-commit"
},
{
"description": "Denies the commit command without any pre-configured scope.",
"type": "string",
"const": "deny-commit"
},
{
"description": "Enables the init command without any pre-configured scope.",
"type": "string",
"const": "allow-init"
},
{
"description": "Denies the init command without any pre-configured scope.",
"type": "string",
"const": "deny-init"
},
{
"description": "Enables the init_repo command without any pre-configured scope.",
"type": "string",
"const": "allow-init-repo"
},
{
"description": "Denies the init_repo command without any pre-configured scope.",
"type": "string",
"const": "deny-init-repo"
},
{
"description": "Enables the initialize command without any pre-configured scope.",
"type": "string",
"const": "allow-initialize"
},
{
"description": "Denies the initialize command without any pre-configured scope.",
"type": "string",
"const": "deny-initialize"
},
{
"description": "Enables the log command without any pre-configured scope.",
"type": "string",
"const": "allow-log"
},
{
"description": "Denies the log command without any pre-configured scope.",
"type": "string",
"const": "deny-log"
},
{
"description": "Enables the status command without any pre-configured scope.",
"type": "string",
"const": "allow-status"
},
{
"description": "Denies the status command without any pre-configured scope.",
"type": "string",
"const": "deny-status"
},
{
"description": "Enables the sync command without any pre-configured scope.",
"type": "string",
"const": "allow-sync"
},
{
"description": "Denies the sync command without any pre-configured scope.",
"type": "string",
"const": "deny-sync"
},
{
"description": "Enables the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "allow-sync-fs"
},
{
"description": "Denies the sync_fs command without any pre-configured scope.",
"type": "string",
"const": "deny-sync-fs"
},
{
"description": "Enables the unstage command without any pre-configured scope.",
"type": "string",
"const": "allow-unstage"
},
{
"description": "Denies the unstage command without any pre-configured scope.",
"type": "string",
"const": "deny-unstage"
},
{
"description": "Default permissions for the plugin",
"type": "string",
"const": "default"
}
]
}
}
}

View File

@@ -0,0 +1,13 @@
use crate::error::Result;
use crate::sync::{apply_sync, calculate_sync, SyncOp};
use tauri::{command, Runtime, WebviewWindow};
#[command]
pub async fn apply<R: Runtime>(window: WebviewWindow<R>, workspace_id: &str) -> Result<()> {
apply_sync(&window, workspace_id).await
}
#[command]
pub async fn calculate<R: Runtime>(window: WebviewWindow<R>, workspace_id: &str) -> Result<Vec<SyncOp>> {
calculate_sync(&window, workspace_id).await
}

View File

@@ -0,0 +1,38 @@
use serde::{Serialize, Serializer};
use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Yaml error: {0}")]
YamlParseError(#[from] serde_yaml::Error),
#[error("Yaml error: {0}")]
ModelError(#[from] yaak_models::error::Error),
#[error("Unknown model: {0}")]
UnknownModel(String),
#[error("Workspace not configured for sync: {0}")]
WorkspaceSyncNotConfigured(String),
#[error("I/o error: {0}")]
IoError(#[from] io::Error),
#[error("Yaml error: {0}")]
JsonParseError(#[from] serde_json::Error),
#[error("Invalid sync file: {0}")]
InvalidSyncFile(String),
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
pub type Result<T> = std::result::Result<T, Error>;

View File

@@ -0,0 +1,15 @@
use crate::commands::{apply, calculate};
use tauri::{
generate_handler,
plugin::{Builder, TauriPlugin},
Runtime,
};
mod commands;
mod error;
mod models;
mod sync;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("yaak-sync").invoke_handler(generate_handler![calculate, apply]).build()
}

Some files were not shown because too many files have changed in this diff Show More