From c4604a7f9505c62fc7a29fa375a3af7a8d721a7c Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Tue, 21 May 2024 17:32:36 +0200 Subject: [PATCH 1/2] Upgrade wasmtime (#539) * Upgrade wasmtime * restructure kv storage structure * use eyre * rebuild mrf --- Cargo.lock | 274 +++++++++--------- crates/kitsune-wasm-mrf/Cargo.toml | 6 +- .../kitsune-wasm-mrf/example-mrf/src/lib.rs | 13 +- crates/kitsune-wasm-mrf/src/kv_storage/fs.rs | 12 +- crates/kitsune-wasm-mrf/src/kv_storage/mod.rs | 99 ++++--- .../kitsune-wasm-mrf/src/kv_storage/redis.rs | 12 +- crates/kitsune-wasm-mrf/src/logging.rs | 9 +- .../tests/example_mrf.component.wasm | Bin 77285 -> 80867 bytes crates/kitsune-wasm-mrf/wit/mrf.wit | 24 +- lib/mrf-manifest/Cargo.toml | 6 +- lib/mrf-tool/Cargo.toml | 4 +- 11 files changed, 229 insertions(+), 230 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84e97fbae..785336274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,15 +700,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -1094,6 +1085,12 @@ dependencies = [ "serde", ] +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "codemap" version = "0.1.3" @@ -1267,18 +1264,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf72ceaf38f7d41194d0cf6748214d8ef7389167fe09aad80f87646dbfa325b" +checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee7fde5cd9173f00ce02c491ee9e306d64740f4b1a697946e0474f389999e13" +checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" dependencies = [ "bumpalo", "cranelift-bforest", @@ -1291,39 +1288,40 @@ dependencies = [ "hashbrown 0.14.5", "log", "regalloc2", + "rustc-hash", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49bec6a517e78d4067500dc16acb558e772491a2bcb37301127448adfb8413c" +checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead4ea497b2dc2ac31fcabd6d5d0d5dc25b3964814122e343724bdf65a53c843" +checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" [[package]] name = "cranelift-control" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81e8028c8d711ea7592648e70221f2e54acb8665f7ecd49545f021ec14c3341" +checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32acd0632ba65c2566e75f64af9ef094bb8d90e58a9fbd33d920977a9d85c054" +checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" dependencies = [ "serde", "serde_derive", @@ -1331,9 +1329,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a395a704934aa944ba8939cac9001174b9ae5236f48bc091f89e33bb968336f6" +checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" dependencies = [ "cranelift-codegen", "log", @@ -1343,15 +1341,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b325ce81c4ee7082dc894537eb342c37898e14230fe7c02ea945691db3e2dd01" +checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" [[package]] name = "cranelift-native" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea11f5ac85996fa093075d66397922d4f56085d5d84ec13043d0cd4f159c6818" +checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" dependencies = [ "cranelift-codegen", "libc", @@ -1360,9 +1358,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.107.2" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f175d4e299a8edabfbd64fa93c7650836cc8ad7f4879f9bd2632575a1f12d0" +checksum = "318b671ce0a174347dcbc4a5e8b8fe292864fd63fdb0c91324239245c3d4caa2" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1370,7 +1368,7 @@ dependencies = [ "itertools 0.12.1", "log", "smallvec", - "wasmparser 0.202.0", + "wasmparser 0.207.0", "wasmtime-types", ] @@ -1921,6 +1919,12 @@ dependencies = [ "smol_str", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -2505,6 +2509,7 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", + "serde", ] [[package]] @@ -4415,8 +4420,8 @@ dependencies = [ "serde", "serde_json", "thiserror", - "wasm-encoder 0.208.0", - "wasmparser 0.208.0", + "wasm-encoder 0.208.1", + "wasmparser 0.208.1", "wat", ] @@ -4428,7 +4433,7 @@ dependencies = [ "color-eyre", "mrf-manifest", "serde_json", - "wasmparser 0.208.0", + "wasmparser 0.208.1", "wat", ] @@ -5207,6 +5212,17 @@ dependencies = [ "pretty_assertions", ] +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "embedded-io", + "serde", +] + [[package]] name = "postgres-protocol" version = "0.6.6" @@ -7800,27 +7816,27 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" -version = "0.202.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd106365a7f5f7aa3c1916a98cbb3ad477f5ff96ddb130285a91c6e7429e67a" +checksum = "d996306fb3aeaee0d9157adbe2f670df0236caf19f6728b221e92d0f27b3fe17" dependencies = [ "leb128", ] [[package]] name = "wasm-encoder" -version = "0.208.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc0fb39838056aeb096b2e7dd94bb2f0c2df3c9fb4d1055f2cb3c35c286ee71" +checksum = "6425e84e42f7f558478e40ecc2287912cb319f2ca68e5c0bb93c61d4fc63fa17" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.208.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0477c12795d0de6243d03e0101e6a21b24a5f2f350f2e2bf9c80da274e68d243" +checksum = "42a2c4280ad374a6db3d76d4bb61e2ec4b3b9ce5469cc4f2bbc5708047a2bbff" dependencies = [ "anyhow", "indexmap 2.2.6", @@ -7828,98 +7844,110 @@ dependencies = [ "serde_derive", "serde_json", "spdx", - "wasm-encoder 0.208.0", - "wasmparser 0.208.0", + "wasm-encoder 0.208.1", + "wasmparser 0.208.1", ] [[package]] name = "wasmparser" -version = "0.202.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6998515d3cf3f8b980ef7c11b29a9b1017d4cf86b99ae93b546992df9931413" +checksum = "e19bb9f8ab07616da582ef8adb24c54f1424c7ec876720b7da9db8ec0626c92c" dependencies = [ + "ahash 0.8.11", "bitflags 2.5.0", + "hashbrown 0.14.5", "indexmap 2.2.6", "semver", ] [[package]] name = "wasmparser" -version = "0.208.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20bf2b2d07ec86bab7a05ae4e3a290e5b333319cd73253bc79bfedb6c59c83" +checksum = "dd921789c9dcc495f589cb37d200155dee65b4a4beeb853323b5e24e0a5f9c58" dependencies = [ "ahash 0.8.11", "bitflags 2.5.0", "hashbrown 0.14.5", "indexmap 2.2.6", "semver", + "serde", ] [[package]] name = "wasmprinter" -version = "0.202.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab1cc9508685eef9502e787f4d4123745f5651a1e29aec047645d3cac1e2da7a" +checksum = "9c2d8a7b4dabb460208e6b4334d9db5766e84505038b2529e69c3d07ac619115" dependencies = [ "anyhow", - "wasmparser 0.202.0", + "wasmparser 0.207.0", ] [[package]] name = "wasmtime" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af5cb32045daee8476711eb12b8b71275c2dd1fc7a58cc2a11b33ce9205f6a2" +checksum = "6fe2db63de4669214120414ae6d86afb6bb011748bf942836aba2d45f011972b" dependencies = [ "addr2line", "anyhow", "async-trait", - "bincode", "bumpalo", + "cc", "cfg-if", "encoding_rs", "gimli", + "hashbrown 0.14.5", "indexmap 2.2.6", "libc", + "libm", "log", + "mach2", + "memfd", + "memoffset", "object 0.33.0", "once_cell", "paste", + "postcard", + "psm", "rayon", "rustix", "semver", "serde", "serde_derive", - "serde_json", + "smallvec", + "sptr", "target-lexicon", - "wasmparser 0.202.0", + "wasmparser 0.207.0", + "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-component-util", "wasmtime-cranelift", "wasmtime-environ", "wasmtime-fiber", "wasmtime-jit-icache-coherence", - "wasmtime-runtime", "wasmtime-slab", + "wasmtime-versioned-export-macros", "wasmtime-winch", "windows-sys 0.52.0", ] [[package]] name = "wasmtime-asm-macros" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515c4d24c8b55c0feab67e3d52a42f999fda8b9cfafbd69a82ed6bcf299d26e" +checksum = "821f87828a6508995bf1243fda9dafd1b671a49b3bf998394c7b73f0f5d9eb5f" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-component-macro" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794839a710a39a12677c67ff43fec54ef00d0ca6c6f631209a7c5524522221d3" +checksum = "aab7a588beec0116e99488768395eee70a1dc53869aae111d006f8928a16ed46" dependencies = [ "anyhow", "proc-macro2", @@ -7927,20 +7955,20 @@ dependencies = [ "syn 2.0.65", "wasmtime-component-util", "wasmtime-wit-bindgen", - "wit-parser 0.202.0", + "wit-parser 0.207.0", ] [[package]] name = "wasmtime-component-util" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7839a1b9e15d17be1cb2a105f18be8e0bbf52bdec7a7cd6eb5d80d4c2cdf74f0" +checksum = "52cc81977f24da3071f3f4b32f40ef6d8fb4f14e12f0bc4c68163935d6694ded" [[package]] name = "wasmtime-cranelift" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ec2d9a4b9990bea53a5dfd689d48663dbd19a46903eaf73e2022b3d1ef20d3" +checksum = "e45cc4915c2b37b4d8b49aaab29d6e2612b393eabb01ae3a410d95e372c22d13" dependencies = [ "anyhow", "cfg-if", @@ -7955,30 +7983,29 @@ dependencies = [ "object 0.33.0", "target-lexicon", "thiserror", - "wasmparser 0.202.0", + "wasmparser 0.207.0", "wasmtime-environ", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-environ" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad72e2e3f7ea5b50fedf66dd36ba24634e4f445c370644683b433d45d88f6126" +checksum = "bba5317f774e37197d588deadb794289438866b72bc1531c593506a004d6cfe0" dependencies = [ "anyhow", - "bincode", "cranelift-entity", "gimli", "indexmap 2.2.6", "log", "object 0.33.0", + "postcard", "serde", "serde_derive", "target-lexicon", - "thiserror", - "wasm-encoder 0.202.0", - "wasmparser 0.202.0", + "wasm-encoder 0.207.0", + "wasmparser 0.207.0", "wasmprinter", "wasmtime-component-util", "wasmtime-types", @@ -7986,9 +8013,9 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbdf3053e7e7ced0cd4ed76579995b62169a1a43696890584eae2de2e33bf54" +checksum = "89ecb5dd1253786c4809588b722a5990367ad0b730f53e676ea8edd2962a6834" dependencies = [ "anyhow", "cc", @@ -8001,67 +8028,40 @@ dependencies = [ [[package]] name = "wasmtime-jit-icache-coherence" -version = "20.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede45379f3b4d395d8947006de8043801806099a240a26db553919b68e96ab15" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "wasmtime-runtime" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65019d29d175c567b84173f2adf3b7a3af6d5592f8fe510dccae55d2569ec0d2" +checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" dependencies = [ "anyhow", - "cc", "cfg-if", - "encoding_rs", - "indexmap 2.2.6", "libc", - "log", - "mach2", - "memfd", - "memoffset", - "paste", - "psm", - "rustix", - "sptr", - "wasmtime-asm-macros", - "wasmtime-environ", - "wasmtime-fiber", - "wasmtime-slab", - "wasmtime-versioned-export-macros", "windows-sys 0.52.0", ] [[package]] name = "wasmtime-slab" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6585868f5c427c3e9d2a8c0c3354e6d7d4518a0d17723ab25a0c1eebf5d5b4" +checksum = "90814f57c64afa02324829c3a8f88616ce3a75f1b2ce9728d34827d21329a836" [[package]] name = "wasmtime-types" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d5381ff174faded38c7b2085fbe430dff59489c87a91403354d710075750fb" +checksum = "629bdcf8b1f7590834c1ad6cd043e93e1d57e80b776adb84109eed203fb74d38" dependencies = [ "cranelift-entity", "serde", "serde_derive", - "thiserror", - "wasmparser 0.202.0", + "smallvec", + "wasmparser 0.207.0", ] [[package]] name = "wasmtime-versioned-export-macros" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3b70422fdfa915c903f003b8b42554a8ae1aa0c6208429d8314ebf5721f3ac" +checksum = "89b3438cb56868e235825c7026e85fe8a6c4b5437b5786ad010948e5c6eff0d4" dependencies = [ "proc-macro2", "quote", @@ -8070,9 +8070,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08dd00241969c3be8c5dfdedbb8d9c5af6783e514ffbf8f7522036561bd1337a" +checksum = "82e7931e19286a853fb5cae7790f9be473f7ab763043c659f1fa0a2a8eada10b" dependencies = [ "anyhow", "async-trait", @@ -8100,16 +8100,16 @@ dependencies = [ [[package]] name = "wasmtime-winch" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996360967b5196dec20ddcfce499ce4dc80cc925c088b0f2b376d29b96833a6a" +checksum = "dd04ad4f7bbcf7925455cec6420481b972071284e611e105cc16b847fc6415e8" dependencies = [ "anyhow", "cranelift-codegen", "gimli", "object 0.33.0", "target-lexicon", - "wasmparser 0.202.0", + "wasmparser 0.207.0", "wasmtime-cranelift", "wasmtime-environ", "winch-codegen", @@ -8117,34 +8117,34 @@ dependencies = [ [[package]] name = "wasmtime-wit-bindgen" -version = "20.0.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01840c0cfbbb01664c796e3f4edbd656e58f9d76db083c7e7c6bba59ea657a96" +checksum = "50c5e4fc265a4d78c334b9fcd846ffd94859bf821ee34a77bc68035526d455ee" dependencies = [ "anyhow", "heck 0.4.1", "indexmap 2.2.6", - "wit-parser 0.202.0", + "wit-parser 0.207.0", ] [[package]] name = "wast" -version = "208.0.0" +version = "208.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0450a853119b35441264ca99bd90be37d6f85f99decc4d993795ad396ed56b97" +checksum = "bc00b3f023b4e2ccd2e054e240294263db52ae962892e6523e550783c83a67f1" dependencies = [ "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder 0.208.0", + "wasm-encoder 0.208.1", ] [[package]] name = "wat" -version = "1.208.0" +version = "1.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72fd5b4d1e1fb745f2eb6e8004563ffbf0858681c11a79f4ec663ee31907080d" +checksum = "58ed38e59176550214c025ea2bd0eeefd8e86b92d0af6698d5ba95020ec2e07b" dependencies = [ "wast", ] @@ -8244,9 +8244,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefeb84a0f39227cf2eb665cf348e6150ebf3372d08adff03264064ab590fdf4" +checksum = "48691637c874363258ea7295497afdcfd426e5608fa36f62ab6bd0b9cac2bcb8" dependencies = [ "anyhow", "cranelift-codegen", @@ -8254,7 +8254,7 @@ dependencies = [ "regalloc2", "smallvec", "target-lexicon", - "wasmparser 0.202.0", + "wasmparser 0.207.0", "wasmtime-cranelift", "wasmtime-environ", ] @@ -8473,7 +8473,7 @@ checksum = "7076a12e69af6e1f6093bd16657d7ae61c30cfd3c5f62321046eb863b17ab1e2" dependencies = [ "anyhow", "heck 0.5.0", - "wit-parser 0.208.0", + "wit-parser 0.208.1", ] [[package]] @@ -8515,9 +8515,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.208.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0397074e61e235635133f1301d1808545e4cb2701d117dc2aca128e65168ae" +checksum = "fef7dd0e47f5135dd8739ccc5b188ab8b7e27e1d64df668aa36680f0b8646db8" dependencies = [ "anyhow", "bitflags 2.5.0", @@ -8526,17 +8526,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.208.0", + "wasm-encoder 0.208.1", "wasm-metadata", - "wasmparser 0.208.0", - "wit-parser 0.208.0", + "wasmparser 0.208.1", + "wit-parser 0.208.1", ] [[package]] name = "wit-parser" -version = "0.202.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744237b488352f4f27bca05a10acb79474415951c450e52ebd0da784c1df2bcc" +checksum = "78c83dab33a9618d86cfe3563cc864deffd08c17efc5db31a3b7cd1edeffe6e1" dependencies = [ "anyhow", "id-arena", @@ -8547,14 +8547,14 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.202.0", + "wasmparser 0.207.0", ] [[package]] name = "wit-parser" -version = "0.208.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27e6bf94e83a0633ae1790912fbe3a97c2fd1ea7956fc58be18aa03517b1b887" +checksum = "516417a730725fe3e6c9e2efc8d86697480f80496d32b24e62736950704c047c" dependencies = [ "anyhow", "id-arena", @@ -8565,7 +8565,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.208.0", + "wasmparser 0.208.1", ] [[package]] diff --git a/crates/kitsune-wasm-mrf/Cargo.toml b/crates/kitsune-wasm-mrf/Cargo.toml index 364a027c2..f2c3b983b 100644 --- a/crates/kitsune-wasm-mrf/Cargo.toml +++ b/crates/kitsune-wasm-mrf/Cargo.toml @@ -29,7 +29,7 @@ tokio = { version = "1.37.0", features = ["fs"] } tracing = "0.1.40" triomphe = "0.1.11" walkdir = "2.5.0" -wasmtime = { version = "20.0.2", default-features = false, features = [ +wasmtime = { version = "21.0.0", default-features = false, features = [ "addr2line", "async", "component-model", @@ -38,13 +38,13 @@ wasmtime = { version = "20.0.2", default-features = false, features = [ "pooling-allocator", "runtime", ] } -wasmtime-wasi = { version = "20.0.2", default-features = false } +wasmtime-wasi = { version = "21.0.0", default-features = false } [dev-dependencies] tempfile = "3.10.1" tokio = { version = "1.37.0", features = ["macros", "rt"] } tracing-subscriber = "0.3.18" -wat = "1.208.0" +wat = "1.208.1" [lints] workspace = true diff --git a/crates/kitsune-wasm-mrf/example-mrf/src/lib.rs b/crates/kitsune-wasm-mrf/example-mrf/src/lib.rs index cd166d156..5d463b9ba 100644 --- a/crates/kitsune-wasm-mrf/example-mrf/src/lib.rs +++ b/crates/kitsune-wasm-mrf/example-mrf/src/lib.rs @@ -1,7 +1,7 @@ #![allow(clippy::missing_safety_doc, clippy::transmute_int_to_bool, unsafe_code)] use self::{ - fep::mrf::keyvalue::{self, Bucket}, + fep::mrf::keyvalue::Bucket, wasi::logging::logging::{self, Level}, }; use rand::{distributions::Alphanumeric, Rng}; @@ -32,11 +32,14 @@ impl Guest for Mrf { // We even have a key-value store! Check this out: let key = generate_random_key(); - let bucket = Bucket::open_bucket("example-bucket").unwrap(); + let bucket = Bucket::open("example-bucket").unwrap(); - keyvalue::set(&bucket, &key, b"world").unwrap(); - assert!(keyvalue::exists(&bucket, &key).unwrap()); - keyvalue::delete(&bucket, &key).unwrap(); + bucket.set(&key, b"world").unwrap(); + + assert!(bucket.exists(&key).unwrap()); + assert_eq!(bucket.get(&key).unwrap(), Some(b"world".to_vec())); + + bucket.delete(&key).unwrap(); Ok(activity) } diff --git a/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs b/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs index 9ee6befc9..09242f8b1 100644 --- a/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs +++ b/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs @@ -1,4 +1,4 @@ -use super::{Backend, BoxError, BucketBackend}; +use super::{Backend, BucketBackend}; use color_eyre::eyre; use std::path::Path; @@ -20,7 +20,7 @@ impl FsBackend { impl Backend for FsBackend { type Bucket = FsBucketBackend; - async fn open(&self, module_name: &str, name: &str) -> Result { + async fn open(&self, module_name: &str, name: &str) -> eyre::Result { self.inner .open_tree(format!("{module_name}:{name}")) .map(|tree| FsBucketBackend { inner: tree }) @@ -33,23 +33,23 @@ pub struct FsBucketBackend { } impl BucketBackend for FsBucketBackend { - async fn exists(&self, key: &str) -> Result { + async fn exists(&self, key: &str) -> eyre::Result { self.inner.contains_key(key).map_err(Into::into) } - async fn delete(&self, key: &str) -> Result<(), BoxError> { + async fn delete(&self, key: &str) -> eyre::Result<()> { self.inner.remove(key)?; Ok(()) } - async fn get(&self, key: &str) -> Result>, BoxError> { + async fn get(&self, key: &str) -> eyre::Result>> { self.inner .get(key) .map(|maybe_val| maybe_val.map(|val| val.to_vec())) .map_err(Into::into) } - async fn set(&self, key: &str, value: &[u8]) -> Result<(), BoxError> { + async fn set(&self, key: &str, value: &[u8]) -> eyre::Result<()> { self.inner.insert(key, value)?; Ok(()) } diff --git a/crates/kitsune-wasm-mrf/src/kv_storage/mod.rs b/crates/kitsune-wasm-mrf/src/kv_storage/mod.rs index 75e7847a7..0834ecc4f 100644 --- a/crates/kitsune-wasm-mrf/src/kv_storage/mod.rs +++ b/crates/kitsune-wasm-mrf/src/kv_storage/mod.rs @@ -1,8 +1,9 @@ use crate::mrf_wit::v1::fep::mrf::keyvalue; use async_trait::async_trait; +use color_eyre::eyre; use derive_more::From; use enum_dispatch::enum_dispatch; -use std::{error::Error, future::Future}; +use std::future::Future; use wasmtime::component::Resource; pub use self::{ @@ -13,7 +14,13 @@ pub use self::{ mod fs; mod redis; -type BoxError = Box; +#[inline] +fn get_bucket<'a>( + ctx: &'a crate::ctx::Context, + rep: &Resource, +) -> &'a BucketBackendDispatch { + &ctx.kv_ctx.buckets[rep.rep() as usize] +} pub trait Backend { type Bucket: BucketBackend; @@ -22,16 +29,16 @@ pub trait Backend { &self, module_name: &str, name: &str, - ) -> impl Future> + Send; + ) -> impl Future> + Send; } #[enum_dispatch] #[allow(async_fn_in_trait)] pub trait BucketBackend { - async fn exists(&self, key: &str) -> Result; - async fn delete(&self, key: &str) -> Result<(), BoxError>; - async fn get(&self, key: &str) -> Result>, BoxError>; - async fn set(&self, key: &str, value: &[u8]) -> Result<(), BoxError>; + async fn exists(&self, key: &str) -> eyre::Result; + async fn delete(&self, key: &str) -> eyre::Result<()>; + async fn get(&self, key: &str) -> eyre::Result>>; + async fn set(&self, key: &str, value: &[u8]) -> eyre::Result<()>; } #[derive(From)] @@ -43,7 +50,7 @@ pub enum BackendDispatch { impl Backend for BackendDispatch { type Bucket = BucketBackendDispatch; - async fn open(&self, module_name: &str, name: &str) -> Result { + async fn open(&self, module_name: &str, name: &str) -> eyre::Result { match self { Self::Fs(fs) => fs.open(module_name, name).await.map(Into::into), Self::Redis(redis) => redis.open(module_name, name).await.map(Into::into), @@ -59,10 +66,10 @@ pub enum BucketBackendDispatch { #[async_trait] impl keyvalue::HostBucket for crate::ctx::Context { - async fn open_bucket( + async fn open( &mut self, name: String, - ) -> wasmtime::Result, Resource>> { + ) -> Result, Resource> { let module_name = self .kv_ctx .module_name @@ -72,41 +79,25 @@ impl keyvalue::HostBucket for crate::ctx::Context { let bucket = match self.kv_ctx.storage.open(&name, module_name).await { Ok(bucket) => bucket, Err(error) => { - error!(?error, "failed to open bucket"); - return Ok(Err(Resource::new_own(0))); + error!(?error, %module_name, %name, "failed to open bucket"); + return Err(Resource::new_own(0)); } }; let idx = self.kv_ctx.buckets.insert(bucket); - Ok(Ok(Resource::new_own(idx as u32))) - } - - fn drop(&mut self, rep: Resource) -> wasmtime::Result<()> { - self.kv_ctx.buckets.remove(rep.rep() as usize); - Ok(()) + Ok(Resource::new_own(idx as u32)) } -} -#[async_trait] -impl keyvalue::HostError for crate::ctx::Context { - fn drop(&mut self, _rep: Resource) -> wasmtime::Result<()> { - Ok(()) - } -} - -#[async_trait] -impl keyvalue::Host for crate::ctx::Context { async fn get( &mut self, bucket: Resource, key: String, - ) -> wasmtime::Result>, Resource>> { - let bucket = &self.kv_ctx.buckets[bucket.rep() as usize]; - match bucket.get(&key).await { - Ok(val) => Ok(Ok(val)), + ) -> Result>, Resource> { + match get_bucket(self, &bucket).get(&key).await { + Ok(value) => Ok(value), Err(error) => { error!(?error, %key, "failed to get key from storage"); - Ok(Err(Resource::new_own(0))) + Err(Resource::new_own(0)) } } } @@ -116,13 +107,12 @@ impl keyvalue::Host for crate::ctx::Context { bucket: Resource, key: String, value: Vec, - ) -> wasmtime::Result>> { - let bucket = &self.kv_ctx.buckets[bucket.rep() as usize]; - match bucket.set(&key, &value).await { - Ok(()) => Ok(Ok(())), + ) -> Result<(), Resource> { + match get_bucket(self, &bucket).set(&key, &value).await { + Ok(value) => Ok(value), Err(error) => { error!(?error, %key, "failed to set key in storage"); - Ok(Err(Resource::new_own(0))) + Err(Resource::new_own(0)) } } } @@ -131,13 +121,12 @@ impl keyvalue::Host for crate::ctx::Context { &mut self, bucket: Resource, key: String, - ) -> wasmtime::Result>> { - let bucket = &self.kv_ctx.buckets[bucket.rep() as usize]; - match bucket.delete(&key).await { - Ok(()) => Ok(Ok(())), + ) -> Result<(), Resource> { + match get_bucket(self, &bucket).delete(&key).await { + Ok(value) => Ok(value), Err(error) => { error!(?error, %key, "failed to delete key from storage"); - Ok(Err(Resource::new_own(0))) + Err(Resource::new_own(0)) } } } @@ -146,14 +135,28 @@ impl keyvalue::Host for crate::ctx::Context { &mut self, bucket: Resource, key: String, - ) -> wasmtime::Result>> { - let bucket = &self.kv_ctx.buckets[bucket.rep() as usize]; - match bucket.exists(&key).await { - Ok(exists) => Ok(Ok(exists)), + ) -> Result> { + match get_bucket(self, &bucket).exists(&key).await { + Ok(value) => Ok(value), Err(error) => { error!(?error, %key, "failed to check existence of key in storage"); - Ok(Err(Resource::new_own(0))) + Err(Resource::new_own(0)) } } } + + fn drop(&mut self, rep: Resource) -> wasmtime::Result<()> { + self.kv_ctx.buckets.remove(rep.rep() as usize); + Ok(()) + } +} + +#[async_trait] +impl keyvalue::HostError for crate::ctx::Context { + fn drop(&mut self, _rep: Resource) -> wasmtime::Result<()> { + Ok(()) + } } + +#[async_trait] +impl keyvalue::Host for crate::ctx::Context {} diff --git a/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs b/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs index 09937c08f..66bd353fe 100644 --- a/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs +++ b/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs @@ -1,4 +1,4 @@ -use super::BoxError; +use color_eyre::eyre; use fred::{clients::RedisPool, interfaces::HashesInterface}; use kitsune_derive::typed_builder::TypedBuilder; @@ -12,7 +12,7 @@ pub struct RedisBackend { impl super::Backend for RedisBackend { type Bucket = RedisBucketBackend; - async fn open(&self, module_name: &str, name: &str) -> Result { + async fn open(&self, module_name: &str, name: &str) -> eyre::Result { Ok(RedisBucketBackend { name: format!("{REDIS_NAMESPACE}:{module_name}:{name}"), pool: self.pool.clone(), @@ -26,19 +26,19 @@ pub struct RedisBucketBackend { } impl super::BucketBackend for RedisBucketBackend { - async fn exists(&self, key: &str) -> Result { + async fn exists(&self, key: &str) -> eyre::Result { self.pool.hexists(&self.name, key).await.map_err(Into::into) } - async fn delete(&self, key: &str) -> Result<(), BoxError> { + async fn delete(&self, key: &str) -> eyre::Result<()> { self.pool.hdel(&self.name, key).await.map_err(Into::into) } - async fn get(&self, key: &str) -> Result>, BoxError> { + async fn get(&self, key: &str) -> eyre::Result>> { self.pool.hget(&self.name, key).await.map_err(Into::into) } - async fn set(&self, key: &str, value: &[u8]) -> Result<(), BoxError> { + async fn set(&self, key: &str, value: &[u8]) -> eyre::Result<()> { self.pool .hset(&self.name, (key, value)) .await diff --git a/crates/kitsune-wasm-mrf/src/logging.rs b/crates/kitsune-wasm-mrf/src/logging.rs index 82ca56eea..152f4e49d 100644 --- a/crates/kitsune-wasm-mrf/src/logging.rs +++ b/crates/kitsune-wasm-mrf/src/logging.rs @@ -15,12 +15,7 @@ macro_rules! event_dispatch { #[async_trait] impl logging::Host for crate::ctx::Context { - async fn log( - &mut self, - level: Level, - context: String, - message: String, - ) -> wasmtime::Result<()> { + async fn log(&mut self, level: Level, context: String, message: String) { event_dispatch!(level, context, message, { Level::Trace => tracing::Level::TRACE, Level::Debug => tracing::Level::DEBUG, @@ -29,7 +24,5 @@ impl logging::Host for crate::ctx::Context { Level::Error => tracing::Level::ERROR, Level::Critical => tracing::Level::ERROR, }); - - Ok(()) } } diff --git a/crates/kitsune-wasm-mrf/tests/example_mrf.component.wasm b/crates/kitsune-wasm-mrf/tests/example_mrf.component.wasm index f976d17d4cbfae9b5c0d12ff297ee4b9590e6a38..2c3c3106b7812dc5b93b017dcac1963d9d18d44b 100755 GIT binary patch literal 80867 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 QMS9G8IN1r4&iDuaKdT^KF8}}l delta 32495 zcmdUY33Ob=mG-OmdS9fceY33UwropY8NBxFt&2AqKql92fSZq<9;ZL>_yoSE~V z-_Uxs+`4t^*1flG-Ky99%Rf4P^|GT(=^I%eRG8xa7GpgXpD*jkHC{9_+Bdpp;8XpV z53J3Mc5K{~*)UV4nUh_nuuY#~S%qn=TXV@`m$o)@)rfOT-@3~)ZpGtJw2{mx^RjOB z1OTdW4QAG5Ml;OEvMfh9P6F{e$`x1U$~7aSBP`%+VyrgbH;vWqkFei*)$e@XoZw%o zI&=Dw`N|cAFqWTLu6TSt zujcVMoNN<|#he;bDqLRhz!)1lsQBG|PS^U(`i;X^sfu@WxNpPA(8l5Q$}OyFps#<; zs!bb5MpqS!KgZ0SWz8!it0Ky+EFd6;GkxpUZ5&W;W8O4V4Capp1NGh0riW*=q`T(M zn?L*f_yy&)=MF86L}Lr)oMQAWJbT&lQ%_qlFqr9IbLnNPR`=b+eEWW)ZexF9=9j8N z<;Si&IHnjL&W!qOo2r;UsGeH!z9@5X#n?JFHm2yenlnO6-A`^ONY&iBzQ)bk)N12f z+s(T}lg;KDpZgmG=YQ4gs9EaSFW~lVH*+;LE(>eECc(zc=W6Dae^b2%9ERq5f|!%nVrs(f46 z)uUY#c0U;Ma959dP1yTj$cGfWChU4JL*zB%~pMGq6N@m0T3_SNWj9OP#EbMB0VY8%0r>ad{Sr%o>TE`BbxPaduSSfss+&W z&p#{7v)Xisy3_ds1!{>)iL4G0fy~r;@elhY(kY9@YGUS(|pHtD# zY3TQKbaRH*&6n|(Y`A5dFXucP=DBgq-ZmZ@=aWS0227NpUl9)Rj%;|+IA#bFLah{d(c41NyuAlaM8J&@GsAXfqw~a z&W4-E`BFYH8=ff9d&YUdf_Do_J$za=92l3vMx?j!8QJhO3B3f3i_n29a$$jUsSOU= zn@>b;69eR+)WZWM$WhQjy%mu+7mTtZ|1Y$gCX$O_0YThJ&7@iVjG83HGD zfT#%NL=rtM&4$4dNP^&fk=GsL++z_X#l%BXiPD0YOeztRLMK9~#1McO(6jHy4H)X>pU(6?D!*YN;JkDD!nx%X+@pv{o z!J61|SLf#-~@8ylzaDza~ed9c6pb=CaB!Tju+_4W$7nD@i5HIZ z-Xb(eUr40)+R$PG&_@w><2dXu(GKJw)yIP+$WhQpgDE1nX$LgqVj;0X7V*Y$-emQB zj-YcHp+f07Hl0C26_a#=#S3j{=)WKoJOD2xxXpB{XJ~@W1Rw`lLE=!`jd z&joHwqMQ@JL$nuL>=H!x3XWj1kXytXa)mJ@#=-8wR6;72k(^)#3o-svY;ZA(MFr&0qq-tE zNVEjsLXLtdL`tfF+@4e^oZxQ{KSiML<~4$JgV$!mH4@%G&dZR>k@%f2WX8`sv*EIF ze!eX;wLF;(OA>hZI5#X}01ZmJ`NC}2u%QL%=%k3ewg?SM{k*IMHwtQro4`%-PsnZB zfgFT)bFe`c@!FyxUMc8YM7Y45l{TGagiH3v!Q*bLXFv-&!Gk&*8U=L8ps z2>=IOWh6D7HaH3<6VH+YW%vT3w5Nz3vVDrhErRFR-D- zAbJY8p+=T5%aQPb#)UNF1>`6wwemo2PpTA7aC;tKAnS7yVyWMKI?cUZ(+ zB)IF~r)I+_y~q}s3VvEPTnQM+Ki9_joFX_#)rj^vHn^Z2e5sPi9pk*B2n|ZxczHIA zQi&V|wFv19Mf0oXjES)6`&QFa~=mkz&$DV>sQ07QBYA zpCN~EQRz$yO5w#zUk9UEX8B@BE-Cn0q1+;C(L?dV!a4=#URoEFb{8}pTLH;wlxn=% zfbFghip^acTszv2(Ov|;ZU?2SX|KmaUa>Kwt)nqF%Q{KQe1hWBNV~%BZ7C96=o7*UE9R@aZ7`rEhl3XZDB3Vz-Dv}0$fSe? z01$Tz>WHix)f^IDOo(c9hcxVt8A+v>8?M3P7|$uR^_CP-$vmqhn^X`!A&Hn{9F{Qi ztb|ns^5+?)a%RVat}6WV!3PNq;10Xi^J$kqvc&$19=$_stXw8}8}LMPKt#@>zs z4y>3Ej7Z6zfOWov&Qai~fOf8h7Az~EoqaOeE)?iM8vxo;lrn%)fR~ayY)?fY#x(=0k482Q15mRv{^b7!VwyQCF2&b|HCe27Lr)=}*|5sl zQbgiJM1>h_6e|y;n5)a1!YTrY_=r?)#Aw-)3pr#%G|(tWRxe_2oF&x>D8Qqh%a}}3 ztwvDJ@MH-U64hDV6tOcz!U7?N&XMp?zg!gpPdFR_)elxtgzw5lLB<)vd?1p>h56U- z7|S8#rug+c2@{5?8HG69zcWQrMom;BcWMxQh!XVUKq2)Aa)75abja19YA{35|3D~1 zET93a5Mlj4trFE=j5I?2(Yh2Kp+{B!4+-igmQw#9n#?!iub6bH&ft|&PLahA)u2Gu z0OZ6rC)coKpQ`u;OBDS}k_V?VRx-JYoLqEMokge*nEGJ{bhC|Ly*d1hs1GzioK#OyVjzrWFL0C6t9`Rx)j4!3U+)05}A3Y`@ z9*ajk!m)T%hl2FbLuJN`*7SpBW_Tzod&nVvi)i@q0vZoPLhvmJl?n;d?3fbX}D974K^UmF* zJ#H}%fU)n3WUD^|y&Re(vHfs$-BCU?;gSXNEoIoUlJf!U7=hMAeNL zO(ThmV#M^@sV#`wsb)hyJU!Wv7mFG&-Kd5rhRb`{3Qz^W zBdVb+p(HPt=LBGak9&1-PC&NN*NogwL8JlMB1+vvCWZ#yc+Jbak00hXx1cx$qNou6st8tR^1zf)(PVwu>mXxG~0`CP8x)fTSPOWf0oLLX)cn?fJHy@(#~6Xh%nr~ zgCxR8!UcXxCJkk_azF^S(}-B>u^|e|{j`4JObjZX6QmkPuS0YFUg}U((NszU0C7F? zNtFjnD~%5XduAJNY$bfVJ{sS?k|vt}a%S>1)%_}*6lsRACW`%sapWN&A=On4!D(9O zRgRK+dvOS%4z=~LOK@61Ge?0wPThtWD(n@SGykcg8}r+}b?N)J3B1_%*sBrtKImTG zE$Kaq1K5&vO>IT-7*x>w?UuP%gbS{R*l>U(>3V=NEcU|nfZIZ@2T@RPJydc%G)x{6 z()FMf7W87qgzKRdT@Q`sTSIHx^+5NQ=aHlNDGtnkA1kiG2bJQ%pK44OTRP)inhCM3 zGj?AmlGT!lH2nH3aa|SeI)nrnLkO*8I=lxO-L~zbSv`{5$1VXWNi`wZ9s%3ANa;wW zMT(Y)h`@{!OKV*}r$}Pa2jm)cE!+f6PPm5IFxB2kIjh+PXhwDqJj0Soo|6NU3MONf zWpLK)8b_ImgLJ>)k+p%K3R6?eF+aIJoCz;ZT5NC^1^Vx3T7^#oq)MZf3n+g7h0Js= zYAJv2K@8fMZoK#nJoR1X^hK@ymnHmX!E$ro>D8P>k>*K=EBSW?W@?Z;BVg`cRPEV$ z6A*y^CSTFfY>lh}{o^p!U?AdtLh841nmZSjS9}zr8n+Z$!qZ@0w7AA8aG6)?S@pNu z%{TNAJ=_(m=y6#^d-rc?*0Qq{WsafI zSgU{4{82?Ud&qpR;t+el{A*>i`C?_ONL_%x=U08TT)Jlzv=H{x^igx|^QOhi z&$+ooF5!MzI)wfN&(N(@@sgpcf@fJnSiOP(l4kC+SvYgajPe7w(1ciw+!Zu0ThgB6 z*0C$rwh;URcu_2bl}m#y#kseO1`QL+ppwo-K~>0&V}_!Hz2vIHd{R3P_Zr99=8%_| z<(R23EQnZ`y++Gs!iB^tTKYVOYn1zjF>D8|Y94}K;-f;eQPE~N>$FMeI+(!43AjoDR2f2yZZ#9Kz(*^!Cg~TF_Z5+*N zHHt7{a-w0rDj=$3ir6o}(uL3`CPznCr;!{%lC-RG&E~LoZP28;yc`A&^^3#6E*oZ6l9 z(H2uB@*&b<`Wz5bjDRM}L9)y&zEMIli&Bz9l+q-xe87UK#-4__=%X5ksG*dzka87L zZc42n`oM@n8&9F$TS)l|DZfaCe0~m#PZEYnAvOa?K@@yu<7qASji9-wwdIHhQXAm^ zo(AIZ0GnuhG-M1KiwQ4tV98Li;dh4|s3PYSv&*)S%0Q+l1&31@28XQym}V#ixsIe8 z!dsX2l!)`fx5f@ZH;9}nnDg%CpLl#+CnLcm_$NP zN(!Quil_hUT5&BshUMN0s6cR^q6LeVe1t$~xi6Gd%N0r|;TDmSobkR~OX^7iAYPzF zqgYvS?bi@3JHZ*yj2BUl1zRIu0lJ-3FUDi<4WiSPND3!5sm?`j)H+WIzeN$nGN3?q5iVCzCAV;ZE{CM+g%d~d zk%P+JNE{YRw*h~R#&PuT8poN1amW#Idqf{Upn73Q;cSr1ILL->9Wy_3dUbdY(crH` zjj*#)Vz?rGSO4oy=7)<><3i97E2a6})0@p-oj$eRvM-PhSZ2C&1iXeenl*7<2Y;*%o*0+Fv8W?r5QhkxESSR zSA9#HVD4!5tO+AvzJ6BK`LsZdVFylL8#8`Q9-e`Xr?Hj7lq?Icjo1d{@P9vyJoQPq zaqRwI;Wqc3T{8o|G{G4!Qs?@8)E})jA1bmPTFBnt;UvFddw6h?ZTJ6Y4(5kvhl#@) zET#*Vm_&^n3X&<3GY>vq;pqwQO~zfZxmMw;fwhcdYT%FA|AE(@wOE2Za68}vXu@AX zisHR^tPT5ngSb`;7NW6_E7_TfVxZQERYU=Y!{nFwk?|T=;%?dUpoV!=X$n1L(Gj=_ zKu|x_+=1nxq&a~(B@Uq&e!u9=5A=}dMhILuXzaLS&k<$BIR4kaT!F|J9E#0cF{{rB zAqtPp4FVuMfYnVnK0synj^*9Q{j|(NJlA5dLbDXXp_1`HuTCZiEwNU@24JQVk|5@3~;A`qbU#_b%wM z_Vl8TLrnpqj>7sqbvGu176zk++%VPPu>VF&NHu=ygo6f8Ni{;on|VO#|6ti2r*W{f z6$MOHA)Ts(hx;VjsiQ^oX70jJDnl*mmmzgi`LFUW#GV|&$kSUYtYd0HTIwp(> zGgfaljy`Xtb5DQ%@~q*KKs!HJoHcfSK)A$lkm1T=pGmPiS_v=(E-X`6LAPL;Fy6eL zSO&$It&rb`bH0;{VVY5_pIi)$L2qgYC$>-74~!|(W-D@X=kpK7}H;K056BYQOs->6Meww&W1!o zHfAe6vX#s@O#6OghOzr|^gP6jH*TfG_cZ;RLLbHH88aTZol4t`_r&wds&VI?RPeAW z!QiSBS`mGKh%*ox$f3vyAu~QWLAHn!|J$q=oX?2~{C~oF!TGk2XFaX#dbSk|hO_#X zIsKA@91*g*N;bMX~r6R{dH=J+<-o43;u5PLmaV)u& z!wln)<*(Q=>W}a5U%ik5i5yN6nHxMPBtrHPN8)lLd1??g5fy6@|Dfo)W?L`;6ULra z3FBOs4oa968X~)e(2xrc1cu-;Qw&HM#wo6#QKeu~Qf)O@h-?vss8El_GDf6;9@P*r zB09047!jjAs0}59L#~qG5Lu){u5iF*Jizj_eoWIs}c) z+L|^z=?XwnodIDNq23-R?U|g$o7gj1yEn?daborrWOvX!k{jowdlOh6jhl-lI1Egn z;)5N~GsJ$)mcbUYX&}173em}axeKR{puy@{>>{05uTJRM!d*fOC@0)c-CTnEn*+_~ z6>xtPwI%H>jD?V*-M`o^I%)Su=yw%KUu1iqFmo>B81<`LvTj%*VaSwyt|5d8asw%o zl77pH*B#VW6vO&35%?z`77mDbtw}6<)-gF%Ll`ip@S9FE-XNnO1NK6qX}fd6CQ*f@ zlx_^L04Zi$A`OYfxp3y8`QI>qHP~hcNAyesd(51c`BFfgsrYdQhjD7at&ygMy1D! z1$3GL*3m%)ECIn`hyLN6;m2<~F&up< z*=WPDC8U^dpXIzn?)Lt!P3Xt>_&>21ZU1}sqCY3zeTqcxBY1bhIm~~XPqaP%|By4U znT=~^Qdo{eG3+wJ&_MZ89B!lNVUHc_fH(t4gO(~G+8%3AVROTpMLE0(f{yVHNGO4hNYV?CdcL>=xPIl--ECD^TvHGq4*VQ^OF1X~ffaMi83@icJcSTPnPQ_aV#aJQ!`jL8!lqy_Tla z)da?E_MvB}pD-VdVP;T#$+x@-J7nqycO~ee1VcfE*3B#UWSmyeokuv~xJV&7=P05b z5jw}FyquSXn0aJvW6n(*U4~JCGnN~`C|z&^h-2gikXJ*SdpyCkwRoc?MB8SB4ajXK zx5H47pTzEXJk@kF^+;1~y0$DNKTJ-DEx1 zD3>Vbn)%qe=?zd~*%t!VrG5R_e0|-lj{4F&0d!*h0$FEyvV9v_ck(JMnT36du5YC2 zgBiCk0SH1dK5MPfifauFVaZxU3IKa5mYZKciauz$LA$+$wAD+gjV5uWL-dk+3;I-) zyjdjDay{BemdN)yf!3-MX(eP4bLqxOIdDXl?z!RFo8SLpPP`u6^VZLQ_~d6F zdGI<9y(U~u#I?ywd#`*|@I>)@sgR`6kN^Mf%Xxbq63t64=apHv^Y&4VevkR=#tvw| zv3n1)_WcT}P8#W{IL%Our@kieAWCOo+a^~W@oF^OOoT(GZ<=I2xoKMPZJIX7qqx3e z-o9x?%?Tw4X?Yd>y)pC8n^yQsYRr|Jmp9%>ZNpBX$rM1MB>BF^PV=8O-)e(9fZ9B7 zczXFRqR0+XZpT~Zyv}@Z_-B)TKxjfx*23ln7ep$Fd2)z|5}EgpL{*^q>By8tk_!Kw zOk?70>*Do2GK)sNb;(ZwOE7I)fgD%h2peKaG#dtP_aEJFc8@kx9ic5cGQ~feNL_WnKGG4gLynX<2BA>2{*VL=0C}7GYr@*=k0?-3TI4Y) zAcYx^l0q3yeGdUc(U|dsC~=4q^N}spIcsbV1-(LO!1}`y^H!(kzzxdM3!bXw&H}%@ z-ze^7gb@67gwVD9AF>ul=;|v3A8vL4#E;?WL7V{9f22MrSSx}-VhB%wRJeNL14o&U|%i<&KyL3vCdnbd2#oL-H=1@&)7*|v>IYBIa`^9hlZQP z6e*z;UQAG1@uc2RfaYl-%^GdUB~No&VcA5tBo{N4$bV(qBf_?mcmp$*{x&rcvfCnV z=pgUFVQ3J0z>t)KxAM$R2z|x%L^U;VwB^K2c`Ps1#3@z+l}-@!v8EZ;(Zb zm0HX#PCacE;F-}OpMB?#mV1khcaZLcNoR>4_yhmph@i~xSGc0TBGW%MkAHf?1*pV8 zXh$#qBhL?4&=dyE*MbnY2Y?JqlH~$vP;)?F*t~?bJaDq>Ml`|lO_H~YKyXUOv4o$Teb>}3DZ$-Qp!((I2@AUiZHEMZxVkHQ5Vb- z8RC_-c!-u_8KI&V2o&fL@X~O6YP_ptiFp*M0>{?jv4=L`N%b=LaxUXd3M*|w0-7eX z`1@-mt3OSH;jWoVH(gg=s6Rt_dx1ey=WOLHJRmw};sJh~iU;_y1nu`dEP7Z-{abMm zU=gH<%jzz=%|N8QD*-`@@p-~ecMymwx`P0skOEnB-vAebXDcg3iJ*8jO6XRD6n{za zIAI7O#5hw~Dehl8>mhqM*~L8<+$L{RFAg~&kW_81yf)Qj$*NPzYH?@)G{1K39BX;y z*4^V`{YS9$z&$C2DENiI;#%+)!EZ=p?cx49wrNhB{c z59a2Cts&XhrEQuG;sVLn3;WIHu>|f7lUUL2qeO_XNW#KVB-0i^s(g;bsm!4{7(5K) zkL1-LLVr{^XI3apw8D|NYVWJu7%3Ea3q9JEr^yjbu?;eJ5V;(-S(h3A_O<7~;-ul( z{~3%Z5R^ILK!{1@&MX`vx}<{_9B|G~z5!5&ac$1=hBt(&3$o5=1Sw_d`1lQ7K2MpRwJQ8;R#J&nIVE_uQh*5@9Q`u5K zK4xCLbz;tPFle&S6(Z2Y&7x~b#Okk-IMO{1ynaCUz4Wc*mB?Afktl94X_^AN<2H^F zH}Qta7yHVYE+!O3pCo znAIgVzF6(>Jt(*vu2ft{lwm~plB1rILr#K&cY!ZLI^mp?Tpf;a7F!y*edFkaRE>al z{L2knZ~D>aj^CBL0ewjX@BHE?M|a%z-cMJHgHi_<_blk93ikeV5LtK=OO((RE{wS7 zCn16XPKi}V%rp%w0W#pyVZl{%LS{%jk4bBXrS^wH`(ZMzLb8_BOhABH;@uD&RgxN5 zvj+KxJ#b^#=#FH|@P@Dzl4GO&p&MQms^}7jV5w!FoOqj-OcH6ceXYu6d{7z?7jlM5 zL%b?NJ;EH&i>@x?DB-8LjmwVQ!xAC`!4%dLNxGbUr6`<%lr)5763M=h9qbo%A880d zleK+Dmt+Wqf^n!24H}jZvq_dvAp%ejj);XG_aYaI^EF}x?re}d+gxzOto59DQfO`d z`}N6F-X^ZYJt(aAQkil3?NFGCy{;S>{(@S(E%!5m7n)1fhbXwr{Nc7#+`=O_mSX!U z)nB$_AKC7q8&bB7w%d_Ei(^a@3gN543W<#HLO{fa7sDgp5VP^$wA`)WCRRvcq{TI> zB8wN=1MD_IsJ++}2_+^-81ww?N!t~sdh_n>ExCUcjFqdrSkfVcWWPZz70#9}0mm*) z)n6c3!Rn6~A9*xVat_KQtxS+LV-MMK`|{q&&6nEF!m*EB*&tC+Mj>@#&f&}L|j6{rrmSXnjULw3TuzBiP~)htj#E`3b>$K*hew! z%`^{rHFP13Tvv=yfqD70x&Nj$l?9~KZ6hq7$E>)i+U(iU#C~mFvZJM;V4h@jrf9*; zyLL=!5;{x9$3v$wcp}J!eLLLSt>z0m-e6xa|MBL2cDp&@mI-XD*>%gLRkB0-f(i#E zJ-hz6i1tQLr0Ip_=!qafGR@SHGe zkA8`0-7gIYL>Ey5}`;;1H~u-ie*w~3a{*))^39imGvT(jP^rB_Cf`41vrTp7WJh2&ZF z`!HDjtugb5wDpg9PK`2|@b1kBj9 z*?945|L1GYkuX+O(Ug=hslFkBDESyA{n$Jo0-|G-!Oat_+=!h}QBIbvHC{qF+S1i! zS(H={SXe|WyxvEYf+y%|mrNR1aPGE}B^|8A`(o5o!xqeVjOytvkv$?ogaQTfyG1@n z;Sk!-?Uis=?kT&~KG{kXi&JNUJ!ID&khK<0tL;HqD+(P3u1_L7q%MYsCdXx5X%88< zU6hGdAzm6O-`s@vSi<6cV0$#??pqtD9;Lw~)jJ3;$wX4!W+ky*5c9`1pfO*+wMBh@ zzp36fHz)@ehJs?;=JMN`sUmyZB6aLB^U>Q5lzqHLUqC_$ zXa0X)qs^{+mbQGn9zp_lK4#u`&mt1U-`q3lqLV;Dk*%^Ailwsnt_UMdFG`B51K=`V zlcoWLz2g0q0^c|;rjlKEVcSKFzVr)SFpcI{zHn!Qr2*7b;K%i9nne(C=Dqb(g}TD< zfYEUHE#)Oxp-~nrRPeTY&s29mX1;#!g!1==BXuqJUV)1~Fd2be-y&T-ysNofXt{AM zcTyF!`Q2Uj&Dt#(F5^aoSTv{21g1&bf^WV+3>Lk^%s?1{?$8&9^*xW%B#~=KEr4jz zms;p?>6hNgoy4|}vUFZ?0@1D>BzYiD$BWIhTq;s3u1+IQZ)J#TmmOW(9SU&gAhsSc@p#?PPKRq-?T>YpaJ@~b&bc-U|YlCQDjC?&|OO|?~ zWFdZz(UeFQJXtAO=GQk@T9Q?mWlUl1UZF3ky-!w2=LfHXBFqEtlDr|)Ile@NZ+FIc zGrP`QKVDb=7EPOA0yDbB(rQGKBvZS_&!z?B*!U$a?}(|DP-5*D>=%AQ3j3#4a{_8hx3R>JI#-n8L;l;$@@rR2H_FE?B#fJrh8}pLChRu5(72P-OFLrN>?Be}GWWT@vlv0tk?YhJ&tuex87_Ll12@Jwc+mf9wgBk$`PG5GGOFbKr>j&X{@iKYl7F zrcIg^e~SXW#DOyHmuL!wlyXYHOKHDD!ER*$n=V4WSHv!a>frDb8!UZ0MFqn$`Y+`9 z;25|hjNCF_5aaMSU7nWFC?1oE%NL$NJ(=ym$dOx*C$n<-T; zI8Jr?I?C(C{7sAs{D;;fmqDO>OPw@G~9yr;)V4Kx+$_L4j`ik9RjBONKpPeOVwK4)h}HeNnFkh!dH!{EA%x%u#f z)`7lFeFJMoui_iGWQK><*&tHI%7%;ztYOiOysy z-PPBRUo05HIi=EFrQ@%nd;l0$^4!$7VGVuf6}My(nD753wRQb?z5h=d9imzlN3_x06xUNdVCu2X~c)q zzfbcS_~V=5`wah#Is4frHqSio*&3uweub3**}=mez8MWDp9%t&oG|& zQHV=3JhNetuh}q|xsvZjInlnseEbK~eFu@NMeZjK^LIb!X!sMdWyrdnx**AqCjmE^ zvF8?t<|5}uZZV!Tm+SHL;CVToE&=t0=UOUksQXb$sGH1ZpPQt=fE*F+1`y+w-&uJGQr(8!nfTE2kl*~vzjd&{{%JqHLR+?G!)RuB zL*Kep0~-f3gPDCIdssF8HP|_z5&1VF>qO5 z|GEq(o(a*g1&{Qu6(5=gnpeA=^p|+wZoc=ki`q9->q-i_v+$%r-VM$K@jUz773Zw# zF-}>2&e_H(y%?x@^~(!teh(;O5mEUf(j?fQGynDFy6B7=T`5P7Ft1zFKioHb)vS@x z!C5221G9t@b_|a!0Su|bAMmL(-+Fm!?KA6 z9?cBS!jGD)9htTM^3lwdz^5p?&^~FN{>lUr;5U#V+hJy3S?N(~b!8=GzW2%`pRyV` zQvb`%w_aJ%@Gr=Dkb53an!K0sB*Sv1dEw8`&nb1fayoK%pp?eC4OJutr97O5Jn?|A zkSI+*DNnjE6Q2%zNYe-g-`t`^@HxQ@A@3{Ns3Ave%EYF55Bbp_2PeaHe+kJLj3pLd}fO}dU%Pgl;x=d<`chR-kYaa2Gj z@F5uboQ`x3pS}3JQlXpGuT38OU%*RL8#sAU`~e0E?{6@__*!COv?HQlv1W8;KMdKW z_^l#RBv+&(7U_tvcRy#o{n`Yx>S&AGDSj?U*&jXn6vI#Xy!HA-yo`R9+O)sz7bwuo zsH4{W%P%8Vs^^Wi_UY5SZlBZbXMW~zdvFsDV3-Lf3LJ2+aQ6>C@#BRpH}8DoX8y0| zO{)Xwnxfz6 zdy{b*NavILFL+PWq7P~Gb)7gMrY}rXXzx}0Pk!r|BgC|BO44b%Cu?r~Q}t;aCs=rM zisO};YzSXGLhr=ldWN`!=famWX$bB+5!{6v79)HF!Qr{#(Pp3bb07kV6xvpsJO0eQ z_!a??n?Si$IGry5BZlG#UaqZ5FS##*c<64#~ zXu^+{q<R_FC?!ieLUw#V`M;Ip?*QGWs?U6_ZQSKqo6%J%EQ!HxuX-QT|6a z&gsj?RJ!nZ$R4X-g!*njyye# zZZ@iz*$}-3Tu-l^CqhD|9~~a@hAhecwip8@$k!EPQp201Uba4 z+VH^bX^sbea;YAVfcycbAWpdm8?KQNbB^K0pyFR3bwQVWRrMg9hk&U7n1VaFfYzs| z-Qsc=u@nbzI$Z(NiI1db{%rnMmGK3V88a0JwlAs(vV%1qVl?(6244Pxfy1p-Xf%xy z!XQozX)EGDC)yMLM`dL!KkQ)l=6|WN+iLKV8E)kYCB=k;0y>yCZ+-j1{B|d+19^G3 zliij7wu^lsA9S*vPpova*-X2VY56-nEPO8d2D33@^h8&6K!PBH#vky1p|jpm;p<&9a+7)&<*6dgsoi`{iS@R zD=Qz#*AnViDEYg+Y-0X9URIw!ia#FR<@bL@WsZE%$6E8Vd@Q*TFT_A4>xp-QPddJ1 zfwYO_!Qz#8Q<>m|{z2?fPY03IAV3qI|Avp%_QHNMh^qKk+R>of8Vem0H$TYjOR#j419(3h70)V|Z0|FoYq^cedhS-qoC*P(W} zD~j`aA>ZP=e#9)I6v{}*Y2AS-AXJom38#RXaUhcak)PGNob*;U%OCf%xqUzv4B=uB zUO2(q(WEXK-CCj8F(uzGqJt9I=x)NwSYhjMgD~#=55{+$Ac`x@=ZGP=4a`w zUA=!s{z9E~I`>aspsdgTzJWF6AJ$nGTN){V5=@XJsOGSk5#Z` zzBQw(EcYqDxtg^!_6?*mLqna({^U?J)0s^6I&K&6(Fnmu^M@;0=%hxxVJOuVi+3fW zslI6cKrGVh#9QF#BN~-$uBc++liIX2#^e2|WGs`)#AE$kotbp6D=!;$Qlpu9eG;q6 zC#zZA$u0FvGM?%h7>H)#>BvyuKs>*@nq5>i)SryTBLmS?XR0sJ7t8c|7E9)hH8OWT zQp2jN`qSw?z!MvzvD9Fu*Lz6;#Ff9YhRv+(?2AWI(Sb-`bg*kMmFe|eMG)=8&;@!t zmFi5y6Y)Om$c7ThbbeMXTUXVe>W>X2`!lh4f3!1}=sYvIAQS0}B)Vclon6UfG!yGBJHH6=^*Yv2H5f@HyAtt% z$Y5k}s4F$tTmC51*Um}xE_v$4b4Ai58R5TGyMx(LxU@VEiM^|sf zMrwXa{^fesRF#f*#*;&tu2>9H(V2?$R$fN6J^AGgtVV}mVPgBil>T@;Iuy%qYG51m zSSr>ZAL>k{`(lHAgF~78TMcZmD$*HEr{l4%bb1i;KRDQ1(?yt?@|cFQiq2GjC!mwD z!9=t_)74v>e?7^n^ZOfFv@$i+8IMI0vE)#^FOtdh)-RC_E1KAZ%JdNSztMOS!rnEI zi1qh2n8)6z&aY@<3-xp&5sPF}eSL{8kdun$A8cZaD~ICgSac}am5j#vJNt(^dne}m zfGIy=0&CR!y3+k!XcHYA=p0I8M2jY1eh2!&hM~b^W(dq47|7)BoWOdjlF=djgW$vx z(ZRlSyth^ImSkdLQ-XdoHJZ9?Fx@%W*&pldOLs-O`jSJvljlnEFKuReRjfZbFqldW zCXz#g1L8E(YU$>4DTh@6;aI_M(Zbx+Zm5XS#o&6Y`bm zkM(B;2Ksv2goHKaQ9pHBJRTcL0d2BB74Pherg}Tpt=qD`BNaE0Q6Jd43cMV43kytF_>P-w0#0oHaFxu7G)fG+j4MLHV=}2$qwfVPN*}2mbi9VQ=zSO`_ z8uAhww0N9`I;UfuoroxQ#Zsw6GL}3~&KxXuFrS}{$xSEvhLX_Rf%IViU^3p-n>wuk z(pVSYkhuahB_IINNV*ej9LPk|1No{cY;$8I)tOE}>Y=h3u%f?r9{slKz^1F_=YKwh zUE7uHi14;T+=#~_vBbZLVZHv<8g{_SYM1=kTxGQ*UonftCuw!H z3d4@f;dIeIRdu-?9VHkk9Yu31k}lo6)*9#U)Ji;y>>8Wb|I zE`Z6nG!{ix!IYACw4qkOK`h3n4UO{hgg~}292K}m<^@i}S>cf1z$>u3Dx7%#59N4$ z)^Jz2@;`5b7f^yKa1!bu<*5PS%PL%jba@575lM8QQwJ7AMFlqYCDWC`e_vU}t&YGNiy|v2h{M+p;?zMk3c@ky06Td91 zP7z6u{1IeL=G-#8?#TaX8Vjq=RDSn#)?nV`E6XpO&UDqagbLF6Tam#E_T}kpnd<45 zWgF7Wqk89xjEgLgZ#JbT=XcIvHLAZm|C<@C)4WFWvq1jWGuRw8c$zGFO{-VSPO;P8 z{J{isvhw_anJmuq{F^gbf>q>09dJ4;C+Bx{ux9Vj;3}axRr$>wtR2Ss-VQd4)#QHw zpoxc7`Wb2V31XI*zJt{%jABbHsxXDc6jfny`jb#Jg>@pp#gd9sVJXFx-!zLgovtcs zlmOId0#Rf&+Nrql7r#1!zbVAc)My%^7d6^N=~zVkjUt*`6w^(tw$?j=DTd;&&A&E_ z)vDI4xvg2tPmQo8YJ(%cIl}6l>ZKGH+6UOLM_9v(Px`rNRs2r0X8oGA;;?@y+UatG z3m9HPMX-oz>o#7hxLmDHDg)K|GaI(7 z8Q!=-RCp`w+{l`%Gb5tR=iM~CabOjsW|X4tn*4F<{0mWbc})-_uz&a2CZ#ifNsQI< zGFLgGSAL%z72i1Q!K-N#aQR&joXp=EV-5Ll#8`-xn;~zjrs%EtAH`Uex%U^9YDJSs z=Sku;rLs=ey!{KOT2&*ZO{vbWk2AKUbe$o%2dl1r7@TP^LfF4jt;vmYLqRdZamT-t-S4pu{cTwyvU=X4r z$~>a1nz8&3Q>@PA#oHW?N%=QZEW&*G<}?)4pFb-NvIF^R(qK^#v+8O@hkiK`E{_|T zvi#vRT9oJi1W>Bt!{-Mz=ws+o8|Xpw2K}$_&<}%v7Thr9+KIm02Vg z5z_7`DR+!?J5H*dAkFS1#ZHo5r%0{SYAmXBDH>BME8QJxmW|}UIh(C)p6vi}0mV5d XKXT3x9hbJbpye0LVLSdW^x1i= diff --git a/crates/kitsune-wasm-mrf/wit/mrf.wit b/crates/kitsune-wasm-mrf/wit/mrf.wit index f365f1922..6a9d19909 100644 --- a/crates/kitsune-wasm-mrf/wit/mrf.wit +++ b/crates/kitsune-wasm-mrf/wit/mrf.wit @@ -10,22 +10,22 @@ interface keyvalue { /// Logical collection of Key-Value pairs resource bucket { /// Open or create a new bucket - open-bucket: static func(name: string) -> result; - } + open: static func(name: string) -> result; - /// Get a value from a bucket - get: func(bucket: borrow, key: string) -> result>, error>; + /// Get a value from a bucket + get: func(key: string) -> result>, error>; - /// Set the value inside a bucket - /// - /// Overwrites existing values - set: func(bucket: borrow, key: string, value: list) -> result<_, error>; + /// Set the value inside a bucket + /// + /// Overwrites existing values silently + set: func(key: string, value: list) -> result<_, error>; - /// Delete the value from a bucket - delete: func(bucket: borrow, key: string) -> result<_, error>; + /// Delete the value from a bucket + delete: func(key: string) -> result<_, error>; - /// Check if a key exists in the bucket - exists: func(bucket: borrow, key: string) -> result; + /// Check if a key exists in the bucket + exists: func(key: string) -> result; + } } interface types { diff --git a/lib/mrf-manifest/Cargo.toml b/lib/mrf-manifest/Cargo.toml index c38e9f937..6830c6c17 100644 --- a/lib/mrf-manifest/Cargo.toml +++ b/lib/mrf-manifest/Cargo.toml @@ -13,13 +13,13 @@ semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0.202", features = ["derive"] } serde_json = { version = "1.0.117", optional = true } thiserror = { version = "1.0.61", optional = true } -wasm-encoder = { version = "0.208.0", optional = true } -wasmparser = { version = "0.208.0", optional = true } +wasm-encoder = { version = "0.208.1", optional = true } +wasmparser = { version = "0.208.1", optional = true } [dev-dependencies] serde_json = "1.0.117" insta = { version = "1.39.0", default-features = false, features = ["json"] } -wat = "1.208.0" +wat = "1.208.1" [features] decode = ["dep:leb128", "dep:serde_json", "dep:thiserror", "dep:wasmparser"] diff --git a/lib/mrf-tool/Cargo.toml b/lib/mrf-tool/Cargo.toml index b49cbb7fe..3d29787a6 100644 --- a/lib/mrf-tool/Cargo.toml +++ b/lib/mrf-tool/Cargo.toml @@ -15,11 +15,11 @@ mrf-manifest = { path = "../mrf-manifest", features = [ "serialise", ] } serde_json = "1.0.117" -wasmparser = "0.208.0" +wasmparser = "0.208.1" [lints] workspace = true [dev-dependencies] serde_json = "1.0.117" -wat = "1.208.0" +wat = "1.208.1" From ef0ed293f8f3f1919c9235adfd4e6b9160440b7c Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Wed, 22 May 2024 22:32:58 +0200 Subject: [PATCH 2/2] Miscellaneous changes (#541) * fix some things * remove utoipa * move some dependencies into workspace toml, use graphiql instead * fix deprecated * allow deprecated diesel stuff * use diesel * use workspace for member deps * automatically enable some features --- Cargo.lock | 253 ++++++++---------- Cargo.toml | 85 +++++- crates/kitsune-activitypub/Cargo.toml | 46 ++-- crates/kitsune-cache/Cargo.toml | 8 +- crates/kitsune-captcha/Cargo.toml | 6 +- crates/kitsune-core/Cargo.toml | 6 +- crates/kitsune-db/Cargo.toml | 29 +- crates/kitsune-derive/Cargo.toml | 2 +- crates/kitsune-email/Cargo.toml | 18 +- crates/kitsune-embed/Cargo.toml | 12 +- crates/kitsune-error/Cargo.toml | 4 +- crates/kitsune-federation-filter/Cargo.toml | 8 +- crates/kitsune-federation/Cargo.toml | 26 +- crates/kitsune-http-client/Cargo.toml | 8 +- crates/kitsune-jobs/Cargo.toml | 16 +- crates/kitsune-language/Cargo.toml | 6 +- crates/kitsune-mastodon/Cargo.toml | 24 +- crates/kitsune-observability/Cargo.toml | 4 +- crates/kitsune-oidc/Cargo.toml | 14 +- crates/kitsune-s3/Cargo.toml | 6 +- crates/kitsune-search/Cargo.toml | 20 +- crates/kitsune-service/Cargo.toml | 66 +++-- crates/kitsune-service/src/post/mod.rs | 22 +- crates/kitsune-storage/Cargo.toml | 6 +- crates/kitsune-test/Cargo.toml | 10 +- crates/kitsune-type/Cargo.toml | 5 +- crates/kitsune-type/src/mastodon/account.rs | 7 +- .../kitsune-type/src/mastodon/custom_emoji.rs | 3 +- crates/kitsune-type/src/mastodon/instance.rs | 7 +- .../src/mastodon/media_attachment.rs | 5 +- crates/kitsune-type/src/mastodon/mod.rs | 3 +- .../kitsune-type/src/mastodon/notification.rs | 6 +- .../kitsune-type/src/mastodon/preview_card.rs | 5 +- .../kitsune-type/src/mastodon/relationship.rs | 3 +- crates/kitsune-type/src/mastodon/search.rs | 4 +- crates/kitsune-type/src/mastodon/status.rs | 12 +- crates/kitsune-type/src/nodeinfo/two_one.rs | 20 +- .../kitsune-type/src/nodeinfo/well_known.rs | 7 +- crates/kitsune-type/src/webfinger.rs | 5 +- crates/kitsune-url/Cargo.toml | 4 +- crates/kitsune-util/Cargo.toml | 4 +- crates/kitsune-wasm-mrf/Cargo.toml | 18 +- crates/kitsune-webfinger/Cargo.toml | 16 +- kitsune-cli/Cargo.toml | 16 +- kitsune-job-runner/Cargo.toml | 32 +-- kitsune/Cargo.toml | 98 ++++--- kitsune/src/http/graphql/mod.rs | 12 +- .../mastodon/api/v1/accounts/follow.rs | 14 +- .../mastodon/api/v1/accounts/lookup.rs | 15 +- .../handler/mastodon/api/v1/accounts/mod.rs | 8 - .../mastodon/api/v1/accounts/relationships.rs | 15 +- .../mastodon/api/v1/accounts/statuses.rs | 15 +- .../api/v1/accounts/update_credentials.rs | 10 - .../api/v1/accounts/verify_credentials.rs | 11 - .../src/http/handler/mastodon/api/v1/apps.rs | 11 +- .../handler/mastodon/api/v1/custom_emojis.rs | 10 - .../mastodon/api/v1/follow_requests/accept.rs | 11 - .../mastodon/api/v1/follow_requests/mod.rs | 14 +- .../mastodon/api/v1/follow_requests/reject.rs | 11 - .../http/handler/mastodon/api/v1/instance.rs | 7 - .../src/http/handler/mastodon/api/v1/media.rs | 41 +-- .../mastodon/api/v1/notifications/clear.rs | 10 - .../mastodon/api/v1/notifications/dismiss.rs | 10 - .../mastodon/api/v1/notifications/mod.rs | 24 +- .../mastodon/api/v1/statuses/context.rs | 12 - .../mastodon/api/v1/statuses/favourite.rs | 10 - .../mastodon/api/v1/statuses/favourited_by.rs | 14 +- .../handler/mastodon/api/v1/statuses/mod.rs | 50 +--- .../mastodon/api/v1/statuses/reblog.rs | 14 +- .../mastodon/api/v1/statuses/reblogged_by.rs | 14 +- .../mastodon/api/v1/statuses/source.rs | 10 - .../mastodon/api/v1/statuses/unfavourite.rs | 10 - .../mastodon/api/v1/statuses/unreblog.rs | 11 - .../handler/mastodon/api/v1/timelines/home.rs | 14 +- .../mastodon/api/v1/timelines/public.rs | 11 +- .../http/handler/mastodon/api/v2/search.rs | 16 +- kitsune/src/http/handler/nodeinfo/two_one.rs | 7 - kitsune/src/http/handler/oauth/token.rs | 1 - .../src/http/handler/well_known/nodeinfo.rs | 7 - .../src/http/handler/well_known/webfinger.rs | 12 +- kitsune/src/http/mod.rs | 14 +- kitsune/src/http/openapi.rs | 138 ---------- lib/athena/Cargo.toml | 10 +- lib/athena/src/redis/mod.rs | 30 ++- lib/cursiv/Cargo.toml | 2 +- lib/geomjeungja/Cargo.toml | 4 +- lib/http-signatures/Cargo.toml | 6 +- lib/mrf-tool/Cargo.toml | 4 +- lib/speedy-uuid/Cargo.toml | 2 +- lib/speedy-uuid/src/lib.rs | 5 +- lib/tower-x-clacks-overhead/Cargo.toml | 4 +- 91 files changed, 570 insertions(+), 1096 deletions(-) delete mode 100644 kitsune/src/http/openapi.rs diff --git a/Cargo.lock b/Cargo.lock index 785336274..db8edc755 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -328,6 +328,7 @@ dependencies = [ "bytes", "fnv", "futures-util", + "handlebars", "http", "indexmap 2.2.6", "mime", @@ -496,8 +497,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +source = "git+https://github.com/tokio-rs/axum.git?rev=8d0c5c05eb75eb779591c8000705e785123868a0#8d0c5c05eb75eb779591c8000705e785123868a0" dependencies = [ "async-trait", "axum-core", @@ -523,7 +523,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.1", + "sync_wrapper", "tokio", "tokio-tungstenite", "tower", @@ -535,8 +535,7 @@ dependencies = [ [[package]] name = "axum-core" version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +source = "git+https://github.com/tokio-rs/axum.git?rev=8d0c5c05eb75eb779591c8000705e785123868a0#8d0c5c05eb75eb779591c8000705e785123868a0" dependencies = [ "async-trait", "bytes", @@ -547,7 +546,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper", "tower-layer", "tower-service", "tracing", @@ -599,8 +598,7 @@ dependencies = [ [[package]] name = "axum-macros" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" +source = "git+https://github.com/tokio-rs/axum.git?rev=8d0c5c05eb75eb779591c8000705e785123868a0#8d0c5c05eb75eb779591c8000705e785123868a0" dependencies = [ "heck 0.4.1", "proc-macro2", @@ -1264,18 +1262,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" +checksum = "29daf137addc15da6bab6eae2c4a11e274b1d270bf2759508e62f6145e863ef6" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" +checksum = "de619867d5de4c644b7fd9904d6e3295269c93d8a71013df796ab338681222d4" dependencies = [ "bumpalo", "cranelift-bforest", @@ -1295,33 +1293,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" +checksum = "29f5cf277490037d8dae9513d35e0ee8134670ae4a964a5ed5b198d4249d7c10" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" +checksum = "8c3e22ecad1123343a3c09ac6ecc532bb5c184b6fcb7888df0ea953727f79924" [[package]] name = "cranelift-control" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" +checksum = "53ca3ec6d30bce84ccf59c81fead4d16381a3ef0ef75e8403bc1e7385980da09" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" +checksum = "7eabb8d36b0ca8906bec93c78ea516741cac2d7e6b266fa7b0ffddcc09004990" dependencies = [ "serde", "serde_derive", @@ -1329,9 +1327,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" +checksum = "44b42630229e49a8cfcae90bdc43c8c4c08f7a7aa4618b67f79265cd2f996dd2" dependencies = [ "cranelift-codegen", "log", @@ -1341,15 +1339,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" +checksum = "918d1e36361805dfe0b6cdfd5a5ffdb5d03fa796170c5717d2727cbe623b93a0" [[package]] name = "cranelift-native" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" +checksum = "75aea85a0d7e1800b14ce9d3f53adf8ad4d1ee8a9e23b0269bdc50285e93b9b3" dependencies = [ "cranelift-codegen", "libc", @@ -1358,9 +1356,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.108.0" +version = "0.108.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318b671ce0a174347dcbc4a5e8b8fe292864fd63fdb0c91324239245c3d4caa2" +checksum = "dac491fd3473944781f0cf9528c90cc899d18ad438da21961a839a3a44d57dfb" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -2483,6 +2481,20 @@ dependencies = [ "serde", ] +[[package]] +name = "handlebars" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3217,8 +3229,6 @@ dependencies = [ "triomphe", "typed-builder", "url", - "utoipa", - "utoipa-swagger-ui", ] [[package]] @@ -3444,7 +3454,7 @@ dependencies = [ "garde", "http", "simd-json", - "sync_wrapper 1.0.1", + "sync_wrapper", "tracing", ] @@ -3800,7 +3810,6 @@ dependencies = [ "smol_str", "speedy-uuid", "strum", - "utoipa", ] [[package]] @@ -4982,6 +4991,40 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "pest_meta" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "phf" version = "0.8.0" @@ -5298,30 +5341,6 @@ dependencies = [ "toml_edit 0.21.1", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -6732,12 +6751,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.1" @@ -7412,8 +7425,6 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" dependencies = [ - "serde", - "stable_deref_trait", "unsize", ] @@ -7603,48 +7614,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "utoipa" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_json", - "utoipa-gen", -] - -[[package]] -name = "utoipa-gen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "regex", - "syn 2.0.65", - "uuid", -] - -[[package]] -name = "utoipa-swagger-ui" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b39868d43c011961e04b41623e050aedf2cc93652562ff7935ce0f819aaf2da" -dependencies = [ - "axum", - "mime_guess", - "regex", - "rust-embed", - "serde", - "serde_json", - "utoipa", - "zip", -] - [[package]] name = "uuid" version = "1.8.0" @@ -7887,9 +7856,9 @@ dependencies = [ [[package]] name = "wasmtime" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2db63de4669214120414ae6d86afb6bb011748bf942836aba2d45f011972b" +checksum = "f92a1370c66a0022e6d92dcc277e2c84f5dece19569670b8ce7db8162560d8b6" dependencies = [ "addr2line", "anyhow", @@ -7936,18 +7905,18 @@ dependencies = [ [[package]] name = "wasmtime-asm-macros" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "821f87828a6508995bf1243fda9dafd1b671a49b3bf998394c7b73f0f5d9eb5f" +checksum = "6dee8679c974a7f258c03d60d3c747c426ed219945b6d08cbc77fd2eab15b2d1" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-component-macro" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aab7a588beec0116e99488768395eee70a1dc53869aae111d006f8928a16ed46" +checksum = "32cae30035f1cf97dcc6657c979cf39f99ce6be93583675eddf4aeaa5548509c" dependencies = [ "anyhow", "proc-macro2", @@ -7960,15 +7929,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cc81977f24da3071f3f4b32f40ef6d8fb4f14e12f0bc4c68163935d6694ded" +checksum = "f7ae611f08cea620c67330925be28a96115bf01f8f393a6cbdf4856a86087134" [[package]] name = "wasmtime-cranelift" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45cc4915c2b37b4d8b49aaab29d6e2612b393eabb01ae3a410d95e372c22d13" +checksum = "b2909406a6007e28be964067167890bca4574bd48a9ff18f1fa9f4856d89ea40" dependencies = [ "anyhow", "cfg-if", @@ -7990,9 +7959,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba5317f774e37197d588deadb794289438866b72bc1531c593506a004d6cfe0" +checksum = "40e227f9ed2f5421473723d6c0352b5986e6e6044fde5410a274a394d726108f" dependencies = [ "anyhow", "cranelift-entity", @@ -8013,9 +7982,9 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ecb5dd1253786c4809588b722a5990367ad0b730f53e676ea8edd2962a6834" +checksum = "42edb392586d07038c1638e854382db916b6ca7845a2e6a7f8dc49e08907acdd" dependencies = [ "anyhow", "cc", @@ -8028,9 +7997,9 @@ dependencies = [ [[package]] name = "wasmtime-jit-icache-coherence" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" +checksum = "afe088f9b56bb353adaf837bf7e10f1c2e1676719dd5be4cac8e37f2ba1ee5bc" dependencies = [ "anyhow", "cfg-if", @@ -8040,15 +8009,15 @@ dependencies = [ [[package]] name = "wasmtime-slab" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90814f57c64afa02324829c3a8f88616ce3a75f1b2ce9728d34827d21329a836" +checksum = "4ff75cafffe47b04b036385ce3710f209153525b0ed19d57b0cf44a22d446460" [[package]] name = "wasmtime-types" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629bdcf8b1f7590834c1ad6cd043e93e1d57e80b776adb84109eed203fb74d38" +checksum = "2f2fa462bfea3220711c84e2b549f147e4df89eeb49b8a2a3d89148f6cc4a8b1" dependencies = [ "cranelift-entity", "serde", @@ -8059,9 +8028,9 @@ dependencies = [ [[package]] name = "wasmtime-versioned-export-macros" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b3438cb56868e235825c7026e85fe8a6c4b5437b5786ad010948e5c6eff0d4" +checksum = "d4cedc5bfef3db2a85522ee38564b47ef3b7fc7c92e94cacbce99808e63cdd47" dependencies = [ "proc-macro2", "quote", @@ -8070,9 +8039,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e7931e19286a853fb5cae7790f9be473f7ab763043c659f1fa0a2a8eada10b" +checksum = "bdbbe94245904d4c96c7c5f7b55bad896cc27908644efd9442063c0748b631fc" dependencies = [ "anyhow", "async-trait", @@ -8100,9 +8069,9 @@ dependencies = [ [[package]] name = "wasmtime-winch" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04ad4f7bbcf7925455cec6420481b972071284e611e105cc16b847fc6415e8" +checksum = "97b27054fed6be4f3800aba5766f7ef435d4220ce290788f021a08d4fa573108" dependencies = [ "anyhow", "cranelift-codegen", @@ -8117,9 +8086,9 @@ dependencies = [ [[package]] name = "wasmtime-wit-bindgen" -version = "21.0.0" +version = "21.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c5e4fc265a4d78c334b9fcd846ffd94859bf821ee34a77bc68035526d455ee" +checksum = "c936a52ce69c28de2aa3b5fb4f2dbbb2966df304f04cccb7aca4ba56d915fda0" dependencies = [ "anyhow", "heck 0.4.1", @@ -8244,9 +8213,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48691637c874363258ea7295497afdcfd426e5608fa36f62ab6bd0b9cac2bcb8" +checksum = "1dc69899ccb2da7daa4df31426dcfd284b104d1a85e1dae35806df0c46187f87" dependencies = [ "anyhow", "cranelift-codegen", @@ -8663,18 +8632,6 @@ dependencies = [ "syn 2.0.65", ] -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "byteorder", - "crc32fast", - "crossbeam-utils", - "flate2", -] - [[package]] name = "zxcvbn" version = "2.2.2" diff --git a/Cargo.toml b/Cargo.toml index 8aa28c606..418492ccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,12 +75,91 @@ members = [ resolver = "2" [workspace.dependencies] +askama = { version = "0.12.1", default-features = false, features = [ + "with-axum", +] } +clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +diesel = { version = "2.1.6", default-features = false, features = [ + "32-column-tables", + "with-deprecated", +] } +diesel-async = { version = "0.4.1", features = [ + "async-connection-wrapper", + "bb8", + "postgres", + "tokio", +] } +diesel_full_text_search = { version = "2.1.1", default-features = false } fred = { version = "9.0.3", features = [ "enable-rustls-ring", + "full-tracing", "i-scripts", - "partial-tracing", "sha-1", ] } +garde = { version = "0.18.0", default-features = false, features = [ + "derive", + "email", + "email-idna", + "regex", + "serde", +] } +itertools = { version = "0.13.0", default-features = false } +moka = { version = "0.12.7", features = ["sync"] } +simd-json = "0.13.10" +simdutf8 = { version = "0.1.4", features = ["aarch64_neon"] } +triomphe = { version = "0.1.11", default-features = false, features = [ + "unsize", +] } + +# Local workspace dependencies (crate directory) +kitsune-activitypub = { path = "crates/kitsune-activitypub" } +kitsune-cache = { path = "crates/kitsune-cache" } +kitsune-captcha = { path = "crates/kitsune-captcha" } +kitsune-config = { path = "crates/kitsune-config" } +kitsune-core = { path = "crates/kitsune-core" } +kitsune-db = { path = "crates/kitsune-db" } +kitsune-derive = { path = "crates/kitsune-derive" } +kitsune-email = { path = "crates/kitsune-email" } +kitsune-embed = { path = "crates/kitsune-embed" } +kitsune-error = { path = "crates/kitsune-error" } +kitsune-federation = { path = "crates/kitsune-federation" } +kitsune-federation-filter = { path = "crates/kitsune-federation-filter" } +kitsune-http-client = { path = "crates/kitsune-http-client" } +kitsune-jobs = { path = "crates/kitsune-jobs" } +kitsune-language = { path = "crates/kitsune-language" } +kitsune-mastodon = { path = "crates/kitsune-mastodon" } +kitsune-observability = { path = "crates/kitsune-observability" } +kitsune-oidc = { path = "crates/kitsune-oidc" } +kitsune-s3 = { path = "crates/kitsune-s3" } +kitsune-scss-compiler = { path = "crates/kitsune-scss-compiler" } +kitsune-search = { path = "crates/kitsune-search" } +kitsune-service = { path = "crates/kitsune-service" } +kitsune-storage = { path = "crates/kitsune-storage" } +kitsune-test = { path = "crates/kitsune-test" } +kitsune-type = { path = "crates/kitsune-type" } +kitsune-url = { path = "crates/kitsune-url" } +kitsune-util = { path = "crates/kitsune-util" } +kitsune-wasm-mrf = { path = "crates/kitsune-wasm-mrf" } +kitsune-webfinger = { path = "crates/kitsune-webfinger" } +kitsune = { path = "kitsune" } +kitsune-job-runner = { path = "kitsune-job-runner" } + +# Local workspace dependences (lib directory) +athena = { path = "lib/athena", features = ["redis"] } +blowocking = { path = "lib/blowocking" } +cursiv = { path = "lib/cursiv" } +geomjeungja = { path = "lib/geomjeungja" } +http-signatures = { path = "lib/http-signatures" } +just-retry = { path = "lib/just-retry" } +masto-id-convert = { path = "lib/masto-id-convert" } +mrf-manifest = { path = "lib/mrf-manifest" } +post-process = { path = "lib/post-process" } +speedy-uuid = { path = "lib/speedy-uuid", features = ["serde"] } +tick-tock-mock = { path = "lib/tick-tock-mock" } +tower-http-digest = { path = "lib/tower-http-digest" } +tower-stop-using-brave = { path = "lib/tower-stop-using-brave" } +tower-x-clacks-overhead = { path = "lib/tower-x-clacks-overhead" } +trials = { path = "lib/trials" } [workspace.lints.clippy] all = "warn" @@ -133,6 +212,10 @@ diesel-async = { git = "https://github.com/weiznich/diesel_async.git", rev = "d0 scraper = { git = "https://github.com/causal-agent/scraper.git", rev = "d67111f5cc0b7da6e6ff10e4549d87cf09ba3e5b" } tokio-postgres-rustls = { git = "https://github.com/jbg/tokio-postgres-rustls.git", rev = "b16c1bc0f5d4f91324174fd1bd839d743a70f86a" } +# TCP nodelay for `axum::serve` +axum = { git = "https://github.com/tokio-rs/axum.git", rev = "8d0c5c05eb75eb779591c8000705e785123868a0" } +axum-core = { git = "https://github.com/tokio-rs/axum.git", rev = "8d0c5c05eb75eb779591c8000705e785123868a0" } + # Patch to make OpenTelemetry with with hyper 1 opentelemetry = { git = "https://github.com/open-telemetry/opentelemetry-rust.git", rev = "40fb924215c84d6e3818351b2c0e3d2ba01a7db9" } opentelemetry-http = { git = "https://github.com/open-telemetry/opentelemetry-rust.git", rev = "40fb924215c84d6e3818351b2c0e3d2ba01a7db9" } diff --git a/crates/kitsune-activitypub/Cargo.toml b/crates/kitsune-activitypub/Cargo.toml index 823ef6dde..57de79250 100644 --- a/crates/kitsune-activitypub/Cargo.toml +++ b/crates/kitsune-activitypub/Cargo.toml @@ -8,35 +8,35 @@ license.workspace = true [dependencies] async-trait = "0.1.80" base64-simd = "0.8.0" -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } futures-util = "0.3.30" headers = "0.4.0" http = "1.1.0" iso8601-timestamp = "0.2.17" -kitsune-cache = { path = "../kitsune-cache" } -kitsune-config = { path = "../kitsune-config" } -kitsune-core = { path = "../kitsune-core" } -kitsune-db = { path = "../kitsune-db" } -kitsune-embed = { path = "../kitsune-embed" } -kitsune-error = { path = "../kitsune-error" } -kitsune-federation-filter = { path = "../kitsune-federation-filter" } -kitsune-http-client = { path = "../kitsune-http-client" } -kitsune-language = { path = "../kitsune-language" } -kitsune-search = { path = "../kitsune-search" } -kitsune-service = { path = "../kitsune-service" } -kitsune-type = { path = "../kitsune-type" } -kitsune-url = { path = "../kitsune-url" } -kitsune-util = { path = "../kitsune-util" } -kitsune-wasm-mrf = { path = "../kitsune-wasm-mrf" } +kitsune-cache = { workspace = true } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-embed = { workspace = true } +kitsune-error = { workspace = true } +kitsune-federation-filter = { workspace = true } +kitsune-http-client = { workspace = true } +kitsune-language = { workspace = true } +kitsune-search = { workspace = true } +kitsune-service = { workspace = true } +kitsune-type = { workspace = true } +kitsune-url = { workspace = true } +kitsune-util = { workspace = true } +kitsune-wasm-mrf = { workspace = true } mime = "0.3.17" mime_guess = { version = "2.0.4", default-features = false } serde = "1.0.202" sha2 = "0.10.8" -simd-json = "0.13.10" -speedy-uuid = { path = "../../lib/speedy-uuid" } +simd-json = { workspace = true } +speedy-uuid = { workspace = true } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } typed-builder = "0.18.2" url = "2.5.0" @@ -46,9 +46,9 @@ sha2 = { version = "0.10.8", features = ["asm"] } [dev-dependencies] http-body-util = "0.1.1" hyper = "1.3.1" -kitsune-config = { path = "../kitsune-config" } -kitsune-test = { path = "../kitsune-test" } -kitsune-webfinger = { path = "../kitsune-webfinger" } +kitsune-config = { workspace = true } +kitsune-test = { workspace = true } +kitsune-webfinger = { workspace = true } pretty_assertions = "1.4.0" tokio = { version = "1.37.0", features = ["macros"] } tower = { version = "0.4.13", default-features = false, features = ["util"] } diff --git a/crates/kitsune-cache/Cargo.toml b/crates/kitsune-cache/Cargo.toml index c48a4ee76..4a2236167 100644 --- a/crates/kitsune-cache/Cargo.toml +++ b/crates/kitsune-cache/Cargo.toml @@ -8,12 +8,12 @@ license.workspace = true [dependencies] enum_dispatch = "0.3.13" fred = { workspace = true } -kitsune-error = { path = "../kitsune-error" } -moka = { version = "0.12.7", features = ["sync"] } +kitsune-error = { workspace = true } +moka = { workspace = true } serde = "1.0.202" -simd-json = "0.13.10" +simd-json = { workspace = true } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } typed-builder = "0.18.2" [dev-dependencies] diff --git a/crates/kitsune-captcha/Cargo.toml b/crates/kitsune-captcha/Cargo.toml index b941c004e..ca05c8da8 100644 --- a/crates/kitsune-captcha/Cargo.toml +++ b/crates/kitsune-captcha/Cargo.toml @@ -8,11 +8,11 @@ license.workspace = true [dependencies] enum_dispatch = "0.3.13" http = "1.1.0" -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } serde = { version = "1.0.202", features = ["derive"] } serde_urlencoded = "0.7.1" -simd-json = "0.13.10" +simd-json = { workspace = true } strum = { version = "0.26.2", features = ["derive"] } typed-builder = "0.18.2" diff --git a/crates/kitsune-core/Cargo.toml b/crates/kitsune-core/Cargo.toml index 0ab3259d5..01d881b05 100644 --- a/crates/kitsune-core/Cargo.toml +++ b/crates/kitsune-core/Cargo.toml @@ -9,11 +9,11 @@ build = "build.rs" [dependencies] async-trait = "0.1.80" const_format = "0.2.32" -kitsune-db = { path = "../kitsune-db" } -kitsune-error = { path = "../kitsune-error" } +kitsune-db = { workspace = true } +kitsune-error = { workspace = true } paste = "1.0.15" serde = { version = "1.0.202", features = ["derive"] } -triomphe = { version = "0.1.11", features = ["unsize"] } +triomphe = { workspace = true } typed-builder = "0.18.2" unsize = "1.1.0" diff --git a/crates/kitsune-db/Cargo.toml b/crates/kitsune-db/Cargo.toml index d73c95ca1..84149be9c 100644 --- a/crates/kitsune-db/Cargo.toml +++ b/crates/kitsune-db/Cargo.toml @@ -7,24 +7,19 @@ license.workspace = true build = "build.rs" [dependencies] -blowocking = { path = "../../lib/blowocking" } -diesel = { version = "2.1.6", features = ["uuid"] } -diesel-async = { version = "0.4.1", features = [ - "async-connection-wrapper", - "bb8", - "postgres", - "tokio", -] } -diesel_full_text_search = { version = "2.1.1", default-features = false } +blowocking = { workspace = true } +diesel = { workspace = true } +diesel-async = { workspace = true } +diesel_full_text_search = { workspace = true } diesel_migrations = "2.1.0" futures-util = { version = "0.3.30", default-features = false, features = [ "alloc", ] } iso8601-timestamp = { version = "0.2.17", features = ["diesel-pg"] } -kitsune-config = { path = "../kitsune-config" } -kitsune-error = { path = "../kitsune-error" } -kitsune-language = { path = "../kitsune-language" } -kitsune-type = { path = "../kitsune-type" } +kitsune-config = { workspace = true } +kitsune-error = { workspace = true } +kitsune-language = { workspace = true } +kitsune-type = { workspace = true } num-derive = "0.4.2" num-traits = "0.2.19" rustls = { version = "0.23.7", default-features = false, features = [ @@ -35,18 +30,18 @@ rustls = { version = "0.23.7", default-features = false, features = [ ] } rustls-native-certs = "0.7.0" serde = { version = "1.0.202", features = ["derive"] } -simd-json = "0.13.10" -speedy-uuid = { path = "../../lib/speedy-uuid", features = ["diesel"] } +simd-json = { workspace = true } +speedy-uuid = { workspace = true, features = ["diesel"] } tokio = { version = "1.37.0", features = ["rt"] } tokio-postgres = "0.7.10" tokio-postgres-rustls = "0.12.0" tracing = "0.1.40" tracing-log = "0.2.0" -trials = { path = "../../lib/trials" } +trials = { workspace = true } typed-builder = "0.18.2" [dev-dependencies] -kitsune-test = { path = "../kitsune-test" } +kitsune-test = { workspace = true } tokio = { version = "1.37.0", features = ["macros"] } [lints] diff --git a/crates/kitsune-derive/Cargo.toml b/crates/kitsune-derive/Cargo.toml index 742d07bc4..97e09937b 100644 --- a/crates/kitsune-derive/Cargo.toml +++ b/crates/kitsune-derive/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true [dependencies] kitsune-derive-impl = { path = "impl" } -triomphe = "0.1.11" +triomphe = { workspace = true } typed-builder = "0.18.2" [lints] diff --git a/crates/kitsune-email/Cargo.toml b/crates/kitsune-email/Cargo.toml index 1abecc912..ce6fdd090 100644 --- a/crates/kitsune-email/Cargo.toml +++ b/crates/kitsune-email/Cargo.toml @@ -9,14 +9,14 @@ license.workspace = true ignored = ["askama_axum"] # See reason below. [dependencies] -askama = "0.12.1" +askama = { workspace = true } askama_axum = "0.4.0" # Damn it, cargo. Because "kitsune" uses "askama" with the axum feature, we have to have the crate available here as well.. -diesel = "2.1.6" -diesel-async = "0.4.1" -kitsune-db = { path = "../kitsune-db" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-url = { path = "../kitsune-url" } +diesel = { workspace = true } +diesel-async = { workspace = true } +kitsune-db = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-url = { workspace = true } lettre = { version = "0.11.7", default-features = false, features = [ "builder", "hostname", @@ -31,8 +31,8 @@ mrml = { version = "3.1.5", default-features = false, features = [ "parse", "render", ] } -speedy-uuid = { path = "../../lib/speedy-uuid" } -triomphe = "0.1.11" +speedy-uuid = { workspace = true } +triomphe = { workspace = true } typed-builder = "0.18.2" [lints] diff --git a/crates/kitsune-embed/Cargo.toml b/crates/kitsune-embed/Cargo.toml index 861d57624..7c146d9be 100644 --- a/crates/kitsune-embed/Cargo.toml +++ b/crates/kitsune-embed/Cargo.toml @@ -6,15 +6,15 @@ version.workspace = true license.workspace = true [dependencies] -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } embed-sdk = { git = "https://github.com/Lantern-chat/embed-service.git", rev = "f46ea95ca89775a6c35d0d5cef9172cbc931258a" } http = "1.1.0" iso8601-timestamp = "0.2.17" -kitsune-db = { path = "../kitsune-db" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } +kitsune-db = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } once_cell = "1.19.0" scraper = { version = "0.19.0", default-features = false } smol_str = "0.2.2" diff --git a/crates/kitsune-error/Cargo.toml b/crates/kitsune-error/Cargo.toml index f15a53b84..574b32ec8 100644 --- a/crates/kitsune-error/Cargo.toml +++ b/crates/kitsune-error/Cargo.toml @@ -8,9 +8,9 @@ license.workspace = true [dependencies] axum-core = "0.4.3" eyre = "0.6.12" -garde = { version = "0.18.0", default-features = false, features = ["serde"] } +garde = { workspace = true } http = "1.1.0" -simd-json = "0.13.10" +simd-json = { workspace = true } sync_wrapper = "1.0.1" tracing = "0.1.40" diff --git a/crates/kitsune-federation-filter/Cargo.toml b/crates/kitsune-federation-filter/Cargo.toml index 06d8d4cd7..778604a7d 100644 --- a/crates/kitsune-federation-filter/Cargo.toml +++ b/crates/kitsune-federation-filter/Cargo.toml @@ -7,10 +7,10 @@ license.workspace = true [dependencies] globset = "0.4.14" -kitsune-config = { path = "../kitsune-config" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-type = { path = "../kitsune-type" } +kitsune-config = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-type = { workspace = true } url = "2.5.0" [lints] diff --git a/crates/kitsune-federation/Cargo.toml b/crates/kitsune-federation/Cargo.toml index b8ae36e89..e8f049a59 100644 --- a/crates/kitsune-federation/Cargo.toml +++ b/crates/kitsune-federation/Cargo.toml @@ -6,19 +6,19 @@ version.workspace = true license.workspace = true [dependencies] -kitsune-activitypub = { path = "../kitsune-activitypub" } -kitsune-cache = { path = "../kitsune-cache" } -kitsune-config = { path = "../kitsune-config" } -kitsune-core = { path = "../kitsune-core" } -kitsune-db = { path = "../kitsune-db" } -kitsune-embed = { path = "../kitsune-embed" } -kitsune-federation-filter = { path = "../kitsune-federation-filter" } -kitsune-search = { path = "../kitsune-search" } -kitsune-service = { path = "../kitsune-service" } -kitsune-url = { path = "../kitsune-url" } -kitsune-wasm-mrf = { path = "../kitsune-wasm-mrf" } -kitsune-webfinger = { path = "../kitsune-webfinger" } -triomphe = "0.1.11" +kitsune-activitypub = { workspace = true } +kitsune-cache = { workspace = true } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-embed = { workspace = true } +kitsune-federation-filter = { workspace = true } +kitsune-search = { workspace = true } +kitsune-service = { workspace = true } +kitsune-url = { workspace = true } +kitsune-wasm-mrf = { workspace = true } +kitsune-webfinger = { workspace = true } +triomphe = { workspace = true } typed-builder = "0.18.2" [lints] diff --git a/crates/kitsune-http-client/Cargo.toml b/crates/kitsune-http-client/Cargo.toml index a55d44632..8b9c34a0f 100644 --- a/crates/kitsune-http-client/Cargo.toml +++ b/crates/kitsune-http-client/Cargo.toml @@ -13,7 +13,7 @@ futures-util = { version = "0.3.30", default-features = false, features = [ ] } http-body = "1.0.0" http-body-util = "0.1.1" -http-signatures = { path = "../../lib/http-signatures" } +http-signatures = { workspace = true } hyper = "1.3.1" hyper-util = { version = "0.1.3", features = [ "client-legacy", @@ -29,11 +29,11 @@ hyper-rustls = { version = "0.27.1", default-features = false, features = [ "ring", "tls12", ] } -kitsune-type = { path = "../kitsune-type" } +kitsune-type = { workspace = true } pin-project = "1.1.5" serde = "1.0.202" -simdutf8 = { version = "0.1.4", features = ["aarch64_neon"] } -simd-json = "0.13.10" +simdutf8 = { workspace = true } +simd-json = { workspace = true } tower = { version = "0.4.13", features = ["util"] } tower-http = { version = "0.5.2", features = [ # Explicitly exclude `zstd` diff --git a/crates/kitsune-jobs/Cargo.toml b/crates/kitsune-jobs/Cargo.toml index e28f645a0..0832537ea 100644 --- a/crates/kitsune-jobs/Cargo.toml +++ b/crates/kitsune-jobs/Cargo.toml @@ -6,17 +6,17 @@ version.workspace = true license.workspace = true [dependencies] -athena = { path = "../../lib/athena" } +athena = { workspace = true } derive_more = { version = "1.0.0-beta.6", features = ["from"] } -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } futures-util = "0.3.30" -kitsune-core = { path = "../kitsune-core" } -kitsune-db = { path = "../kitsune-db" } -kitsune-email = { path = "../kitsune-email" } -kitsune-error = { path = "../kitsune-error" } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-email = { workspace = true } +kitsune-error = { workspace = true } serde = { version = "1.0.202", features = ["derive"] } -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } tracing = "0.1.40" typed-builder = "0.18.2" diff --git a/crates/kitsune-language/Cargo.toml b/crates/kitsune-language/Cargo.toml index ea1df141a..8b9a821f6 100644 --- a/crates/kitsune-language/Cargo.toml +++ b/crates/kitsune-language/Cargo.toml @@ -6,9 +6,9 @@ version.workspace = true license.workspace = true [dependencies] -diesel = "2.1.6" -diesel-async = { version = "0.4.1", features = ["postgres"] } -kitsune-config = { path = "../kitsune-config" } +diesel = { workspace = true } +diesel-async = { workspace = true } +kitsune-config = { workspace = true } isolang = { version = "2.4.0", features = [ "english_names", "list_languages", diff --git a/crates/kitsune-mastodon/Cargo.toml b/crates/kitsune-mastodon/Cargo.toml index b734c4373..205570880 100644 --- a/crates/kitsune-mastodon/Cargo.toml +++ b/crates/kitsune-mastodon/Cargo.toml @@ -6,23 +6,23 @@ version.workspace = true license.workspace = true [dependencies] -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } futures-util = "0.3.30" iso8601-timestamp = "0.2.17" -kitsune-cache = { path = "../kitsune-cache" } -kitsune-db = { path = "../kitsune-db" } -kitsune-embed = { path = "../kitsune-embed" } -kitsune-error = { path = "../kitsune-error" } -kitsune-service = { path = "../kitsune-service" } -kitsune-type = { path = "../kitsune-type" } -kitsune-url = { path = "../kitsune-url" } -kitsune-util = { path = "../kitsune-util" } +kitsune-cache = { workspace = true } +kitsune-db = { workspace = true } +kitsune-embed = { workspace = true } +kitsune-error = { workspace = true } +kitsune-service = { workspace = true } +kitsune-type = { workspace = true } +kitsune-url = { workspace = true } +kitsune-util = { workspace = true } mime = "0.3.17" serde = "1.0.202" -simd-json = "0.13.10" +simd-json = { workspace = true } smol_str = "0.2.2" -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } tracing = "0.1.40" typed-builder = "0.18.2" diff --git a/crates/kitsune-observability/Cargo.toml b/crates/kitsune-observability/Cargo.toml index f6cb87b69..88c843c10 100644 --- a/crates/kitsune-observability/Cargo.toml +++ b/crates/kitsune-observability/Cargo.toml @@ -10,8 +10,8 @@ async-trait = "0.1.80" eyre = "0.6.12" http-body-util = "0.1.1" hyper = { version = "1.3.1", default-features = false } -kitsune-config = { path = "../kitsune-config" } -kitsune-http-client = { path = "../kitsune-http-client" } +kitsune-config = { workspace = true } +kitsune-http-client = { workspace = true } opentelemetry = { version = "0.23.0", default-features = false, features = [ "trace", ] } diff --git a/crates/kitsune-oidc/Cargo.toml b/crates/kitsune-oidc/Cargo.toml index b32bf6c8b..0f42dc7fa 100644 --- a/crates/kitsune-oidc/Cargo.toml +++ b/crates/kitsune-oidc/Cargo.toml @@ -10,11 +10,11 @@ enum_dispatch = "0.3.13" fred = { workspace = true } http = "1.1.0" http-body-util = "0.1.1" -kitsune-config = { path = "../kitsune-config" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } -moka = { version = "0.12.7", features = ["sync"] } +kitsune-config = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } +moka = { workspace = true } oauth2 = { version = "5.0.0-alpha.4", default-features = false } once_cell = "1.19.0" openidconnect = { version = "4.0.0-alpha.1", default-features = false, features = [ @@ -23,8 +23,8 @@ openidconnect = { version = "4.0.0-alpha.1", default-features = false, features "accept-string-booleans", ] } serde = { version = "1.0.202", features = ["derive"] } -simd-json = "0.13.10" -speedy-uuid = { path = "../../lib/speedy-uuid", features = ["serde"] } +simd-json = { workspace = true } +speedy-uuid = { workspace = true } url = "2.5.0" [lints] diff --git a/crates/kitsune-s3/Cargo.toml b/crates/kitsune-s3/Cargo.toml index 5461d9f4d..d40a34a3e 100644 --- a/crates/kitsune-s3/Cargo.toml +++ b/crates/kitsune-s3/Cargo.toml @@ -9,15 +9,15 @@ license.workspace = true bytes = "1.6.0" futures-util = { version = "0.3.30", default-features = false } http = "1.1.0" -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } quick-xml = { version = "0.31.0", features = ["serialize"] } rusty-s3 = "0.5.0" serde = { version = "1.0.202", features = ["derive"] } typed-builder = "0.18.2" [dev-dependencies] -kitsune-test = { path = "../kitsune-test" } +kitsune-test = { workspace = true } tokio = { version = "1.37.0", features = ["macros", "rt"] } [lints] diff --git a/crates/kitsune-search/Cargo.toml b/crates/kitsune-search/Cargo.toml index 9e247865f..4b003bc88 100644 --- a/crates/kitsune-search/Cargo.toml +++ b/crates/kitsune-search/Cargo.toml @@ -8,24 +8,24 @@ license.workspace = true [dependencies] async-trait = "0.1.80" bytes = "1.6.0" -diesel = "2.1.6" -diesel-async = "0.4.1" -diesel_full_text_search = { version = "2.1.1", default-features = false } +diesel = { workspace = true } +diesel-async = { workspace = true } +diesel_full_text_search = { workspace = true } enum_dispatch = "0.3.13" futures-io = "0.3.30" futures-util = "0.3.30" http = "1.1.0" -kitsune-config = { path = "../kitsune-config" } -kitsune-db = { path = "../kitsune-db" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } -kitsune-language = { path = "../kitsune-language" } +kitsune-config = { workspace = true } +kitsune-db = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } +kitsune-language = { workspace = true } meilisearch-sdk = { version = "0.26.1", default-features = false } pin-project-lite = "0.2.14" serde = { version = "1.0.202", features = ["derive"] } serde_urlencoded = "0.7.1" -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } strum = { version = "0.26.2", features = ["derive"] } tracing = "0.1.40" diff --git a/crates/kitsune-service/Cargo.toml b/crates/kitsune-service/Cargo.toml index d647af811..5fa9a1d84 100644 --- a/crates/kitsune-service/Cargo.toml +++ b/crates/kitsune-service/Cargo.toml @@ -9,54 +9,48 @@ license.workspace = true ahash = "0.8.11" argon2 = "0.5.3" async-stream = "0.3.5" -athena = { path = "../../lib/athena" } -blowocking = { path = "../../lib/blowocking" } +athena = { workspace = true } +blowocking = { workspace = true } bytes = "1.6.0" derive_builder = "0.20.0" -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } eyre = "0.6.12" fred = { workspace = true } futures-util = "0.3.30" -garde = { version = "0.18.0", default-features = false, features = [ - "derive", - "email", - "email-idna", - "regex", - "serde", -] } +garde = { workspace = true } http = "1.1.0" img-parts = "0.3.0" iso8601-timestamp = "0.2.17" -kitsune-cache = { path = "../kitsune-cache" } -kitsune-captcha = { path = "../kitsune-captcha" } -kitsune-config = { path = "../kitsune-config" } -kitsune-core = { path = "../kitsune-core" } -kitsune-db = { path = "../kitsune-db" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-email = { path = "../kitsune-email" } -kitsune-embed = { path = "../kitsune-embed" } -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } -kitsune-jobs = { path = "../kitsune-jobs" } -kitsune-language = { path = "../kitsune-language" } -kitsune-search = { path = "../kitsune-search" } -kitsune-storage = { path = "../kitsune-storage" } -kitsune-url = { path = "../kitsune-url" } -kitsune-util = { path = "../kitsune-util" } +kitsune-cache = { workspace = true } +kitsune-captcha = { workspace = true } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-email = { workspace = true } +kitsune-embed = { workspace = true } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } +kitsune-jobs = { workspace = true } +kitsune-language = { workspace = true } +kitsune-search = { workspace = true } +kitsune-storage = { workspace = true } +kitsune-url = { workspace = true } +kitsune-util = { workspace = true } mime = "0.3.17" password-hash = { version = "0.5.0", features = ["std"] } pkcs8 = "0.10.2" -post-process = { path = "../../lib/post-process" } +post-process = { workspace = true } rand = "0.8.5" rsa = "0.9.6" rusty-s3 = { version = "0.5.0", default-features = false } serde = "1.0.202" smol_str = "0.2.2" -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } tokio = { version = "1.37.0", features = ["macros", "sync"] } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } typed-builder = "0.18.2" url = "2.5.0" zxcvbn = { version = "2.2.2", default-features = false } @@ -65,12 +59,12 @@ zxcvbn = { version = "2.2.2", default-features = false } hex-simd = "0.8.0" http-body-util = "0.1.1" hyper = "1.3.1" -kitsune-activitypub = { path = "../kitsune-activitypub" } -kitsune-config = { path = "../kitsune-config" } -kitsune-federation-filter = { path = "../kitsune-federation-filter" } -kitsune-jobs = { path = "../kitsune-jobs" } -kitsune-test = { path = "../kitsune-test" } -kitsune-webfinger = { path = "../kitsune-webfinger" } +kitsune-activitypub = { workspace = true } +kitsune-config = { workspace = true } +kitsune-federation-filter = { workspace = true } +kitsune-jobs = { workspace = true } +kitsune-test = { workspace = true } +kitsune-webfinger = { workspace = true } pretty_assertions = "1.4.0" tempfile = "3.10.1" tower = { version = "0.4.13", default-features = false, features = ["util"] } diff --git a/crates/kitsune-service/src/post/mod.rs b/crates/kitsune-service/src/post/mod.rs index daff6bd92..4258e8b21 100644 --- a/crates/kitsune-service/src/post/mod.rs +++ b/crates/kitsune-service/src/post/mod.rs @@ -53,6 +53,7 @@ use typed_builder::TypedBuilder; mod resolver; pub use self::resolver::PostResolver; +use self::resolver::ResolvedPost; macro_rules! min_character_limit { ($self:ident) => {{ @@ -442,16 +443,22 @@ impl PostService { character_limit: self.instance_service.character_limit(), })?; + let content_source = create_post.content.clone(); let subject = create_post.subject.map(|mut subject| { subject.clean_html(); subject }); - let content_source = create_post.content.clone(); + let ResolvedPost { + mentioned_accounts, + custom_emojis, + content, + } = self.post_resolver.resolve(&create_post.content).await?; + let mut content = if create_post.process_markdown { - process::markdown(&create_post.content) + process::markdown(&content) } else { - create_post.content + content }; content.clean_html(); @@ -463,7 +470,6 @@ impl PostService { |lang| Language::from_639_1(&lang).unwrap_or_else(|| detect_language(&content)), ); - let resolved = self.post_resolver.resolve(&content).await?; let link_preview_url = if let Some(ref embed_client) = self.embed_client { embed_client .fetch_embed_for_fragment(&content) @@ -496,7 +502,7 @@ impl PostService { in_reply_to_id, reposted_post_id: None, subject: subject.as_deref(), - content: resolved.content.as_str(), + content: content.as_str(), content_source: content_source.as_str(), content_lang: content_lang.into(), link_preview_url: link_preview_url.as_deref(), @@ -510,10 +516,10 @@ impl PostService { .get_result(tx) .await?; - Self::process_mentions(tx, post.account_id, post.id, resolved.mentioned_accounts) - .await?; - Self::process_custom_emojis(tx, post.id, resolved.custom_emojis).await?; + Self::process_mentions(tx, post.account_id, post.id, mentioned_accounts).await?; + Self::process_custom_emojis(tx, post.id, custom_emojis).await?; Self::process_media_attachments(tx, post.id, &create_post.media_ids).await?; + NotificationService::notify_on_new_post(tx, post.account_id, post.id).await?; Ok::<_, Error>(post) diff --git a/crates/kitsune-storage/Cargo.toml b/crates/kitsune-storage/Cargo.toml index 7bd7a35a9..4089346f4 100644 --- a/crates/kitsune-storage/Cargo.toml +++ b/crates/kitsune-storage/Cargo.toml @@ -9,12 +9,12 @@ license.workspace = true bytes = "1.6.0" derive_more = { version = "1.0.0-beta.6", features = ["from"] } futures-util = "0.3.30" -kitsune-error = { path = "../kitsune-error" } -kitsune-s3 = { path = "../kitsune-s3" } +kitsune-error = { workspace = true } +kitsune-s3 = { workspace = true } rusty-s3 = { version = "0.5.0", default-features = false } tokio = { version = "1.37.0", features = ["fs", "io-util"] } tokio-util = { version = "0.7.11", features = ["io"] } -triomphe = "0.1.11" +triomphe = { workspace = true } [dev-dependencies] tempfile = "3.10.1" diff --git a/crates/kitsune-test/Cargo.toml b/crates/kitsune-test/Cargo.toml index 3d7eec741..bd7e4a5b0 100644 --- a/crates/kitsune-test/Cargo.toml +++ b/crates/kitsune-test/Cargo.toml @@ -7,20 +7,20 @@ license.workspace = true [dependencies] bytes = "1.6.0" -diesel-async = "0.4.1" +diesel-async = { workspace = true } fred = { workspace = true } futures-util = "0.3.30" http = "1.1.0" http-body-util = "0.1.1" isolang = "2.4.0" -kitsune-config = { path = "../kitsune-config" } -kitsune-db = { path = "../kitsune-db" } -kitsune-s3 = { path = "../kitsune-s3" } +kitsune-config = { workspace = true } +kitsune-db = { workspace = true } +kitsune-s3 = { workspace = true } pin-project-lite = "0.2.14" rand = "0.8.5" rusty-s3 = { version = "0.5.0", default-features = false } tokio = { version = "1.37.0", features = ["time"] } -triomphe = "0.1.11" +triomphe = { workspace = true } url = "2.5.0" uuid = { version = "1.8.0", features = ["fast-rng", "v4"] } diff --git a/crates/kitsune-type/Cargo.toml b/crates/kitsune-type/Cargo.toml index 8ca25e0dd..0e76447a6 100644 --- a/crates/kitsune-type/Cargo.toml +++ b/crates/kitsune-type/Cargo.toml @@ -8,11 +8,10 @@ license.workspace = true [dependencies] iso8601-timestamp = "0.2.17" serde = { version = "1.0.202", features = ["derive"] } -simd-json = "0.13.10" +simd-json = { workspace = true } smol_str = { version = "0.2.2", features = ["serde"] } -speedy-uuid = { path = "../../lib/speedy-uuid", features = ["serde"] } +speedy-uuid = { workspace = true, features = ["diesel"] } strum = { version = "0.26.2", features = ["derive"] } -utoipa = { version = "4.2.3", features = ["chrono", "uuid"] } [dev-dependencies] pretty_assertions = "1.4.0" diff --git a/crates/kitsune-type/src/mastodon/account.rs b/crates/kitsune-type/src/mastodon/account.rs index 4be6a0105..a7e91c347 100644 --- a/crates/kitsune-type/src/mastodon/account.rs +++ b/crates/kitsune-type/src/mastodon/account.rs @@ -1,16 +1,15 @@ use iso8601_timestamp::Timestamp; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Field { pub name: String, pub value: String, pub verified_at: Option, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Source { pub privacy: String, pub sensitive: bool, @@ -19,7 +18,7 @@ pub struct Source { pub fields: Vec, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Account { pub id: Uuid, pub acct: String, diff --git a/crates/kitsune-type/src/mastodon/custom_emoji.rs b/crates/kitsune-type/src/mastodon/custom_emoji.rs index 654e602df..21038b8b9 100644 --- a/crates/kitsune-type/src/mastodon/custom_emoji.rs +++ b/crates/kitsune-type/src/mastodon/custom_emoji.rs @@ -1,7 +1,6 @@ use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct CustomEmoji { pub shortcode: String, pub url: String, diff --git a/crates/kitsune-type/src/mastodon/instance.rs b/crates/kitsune-type/src/mastodon/instance.rs index bb43c9140..0ad7d8a4e 100644 --- a/crates/kitsune-type/src/mastodon/instance.rs +++ b/crates/kitsune-type/src/mastodon/instance.rs @@ -1,19 +1,18 @@ use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; -#[derive(Deserialize, Serialize, ToSchema)] +#[derive(Deserialize, Serialize)] pub struct Stats { pub user_count: u64, pub status_count: u64, pub domain_count: u64, } -#[derive(Deserialize, Serialize, ToSchema)] +#[derive(Deserialize, Serialize)] pub struct Urls { pub streaming_api: String, } -#[derive(Deserialize, Serialize, ToSchema)] +#[derive(Deserialize, Serialize)] pub struct Instance { pub uri: String, pub title: String, diff --git a/crates/kitsune-type/src/mastodon/media_attachment.rs b/crates/kitsune-type/src/mastodon/media_attachment.rs index 5e3e2cd70..7c442332f 100644 --- a/crates/kitsune-type/src/mastodon/media_attachment.rs +++ b/crates/kitsune-type/src/mastodon/media_attachment.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[derive(Clone, Copy, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Copy, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub enum MediaType { Unknown, @@ -12,7 +11,7 @@ pub enum MediaType { Audio, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct MediaAttachment { pub id: Uuid, pub r#type: MediaType, diff --git a/crates/kitsune-type/src/mastodon/mod.rs b/crates/kitsune-type/src/mastodon/mod.rs index 1bc7e4425..84e4086b2 100644 --- a/crates/kitsune-type/src/mastodon/mod.rs +++ b/crates/kitsune-type/src/mastodon/mod.rs @@ -1,6 +1,5 @@ use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; -use utoipa::ToSchema; pub mod account; pub mod custom_emoji; @@ -21,7 +20,7 @@ pub use self::preview_card::PreviewCard; pub use self::search::SearchResult; pub use self::status::Status; -#[derive(Deserialize, Serialize, ToSchema)] +#[derive(Deserialize, Serialize)] pub struct App { pub id: Uuid, pub name: String, diff --git a/crates/kitsune-type/src/mastodon/notification.rs b/crates/kitsune-type/src/mastodon/notification.rs index e2f0db93d..e7c764ea4 100644 --- a/crates/kitsune-type/src/mastodon/notification.rs +++ b/crates/kitsune-type/src/mastodon/notification.rs @@ -1,9 +1,7 @@ +use super::{Account, Status}; use iso8601_timestamp::Timestamp; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; -use utoipa::ToSchema; - -use super::{Account, Status}; #[derive(Copy, Clone, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] @@ -17,7 +15,7 @@ pub enum NotificationType { Update, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Notification { pub id: Uuid, pub r#type: NotificationType, diff --git a/crates/kitsune-type/src/mastodon/preview_card.rs b/crates/kitsune-type/src/mastodon/preview_card.rs index 3f6d0822f..7f48600e2 100644 --- a/crates/kitsune-type/src/mastodon/preview_card.rs +++ b/crates/kitsune-type/src/mastodon/preview_card.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; use smol_str::SmolStr; -use utoipa::ToSchema; -#[derive(Clone, Copy, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Copy, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum PreviewType { Link, @@ -10,7 +9,7 @@ pub enum PreviewType { Video, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct PreviewCard { pub url: String, pub title: SmolStr, diff --git a/crates/kitsune-type/src/mastodon/relationship.rs b/crates/kitsune-type/src/mastodon/relationship.rs index 26ac5ff0f..d087b52bf 100644 --- a/crates/kitsune-type/src/mastodon/relationship.rs +++ b/crates/kitsune-type/src/mastodon/relationship.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[allow(clippy::struct_excessive_bools)] pub struct Relationship { pub id: Uuid, diff --git a/crates/kitsune-type/src/mastodon/search.rs b/crates/kitsune-type/src/mastodon/search.rs index e9768268c..22a7a0dcf 100644 --- a/crates/kitsune-type/src/mastodon/search.rs +++ b/crates/kitsune-type/src/mastodon/search.rs @@ -1,12 +1,10 @@ use super::{Account, Status}; use serde::{Deserialize, Serialize}; use simd_json::OwnedValue; -use utoipa::ToSchema; -#[derive(Default, Deserialize, Serialize, ToSchema)] +#[derive(Default, Deserialize, Serialize)] pub struct SearchResult { pub accounts: Vec, - #[schema(value_type = Object)] pub hashtags: Vec, // Placeholder pub statuses: Vec, } diff --git a/crates/kitsune-type/src/mastodon/status.rs b/crates/kitsune-type/src/mastodon/status.rs index ea2406a3b..6b94b5bfd 100644 --- a/crates/kitsune-type/src/mastodon/status.rs +++ b/crates/kitsune-type/src/mastodon/status.rs @@ -3,16 +3,14 @@ use iso8601_timestamp::Timestamp; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; use std::collections::VecDeque; -use utoipa::ToSchema; -#[derive(Deserialize, Serialize, ToSchema)] +#[derive(Deserialize, Serialize)] pub struct Context { - #[schema(value_type = Vec)] pub ancestors: VecDeque, pub descendants: Vec, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Mention { pub id: Uuid, pub username: String, @@ -20,7 +18,7 @@ pub struct Mention { pub acct: String, } -#[derive(Clone, Copy, Default, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Copy, Default, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum Visibility { #[default] @@ -30,7 +28,7 @@ pub enum Visibility { Direct, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Status { pub id: Uuid, pub created_at: Timestamp, @@ -56,7 +54,7 @@ pub struct Status { pub card: Option, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct StatusSource { pub id: Uuid, pub text: String, diff --git a/crates/kitsune-type/src/nodeinfo/two_one.rs b/crates/kitsune-type/src/nodeinfo/two_one.rs index d9ae13e3b..82d8029e3 100644 --- a/crates/kitsune-type/src/nodeinfo/two_one.rs +++ b/crates/kitsune-type/src/nodeinfo/two_one.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; use simd_json::OwnedValue; -use utoipa::ToSchema; -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "lowercase")] pub enum Protocol { ActivityPub, @@ -17,7 +16,7 @@ pub enum Protocol { Zot, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "lowercase")] pub enum InboundService { #[serde(rename = "atom1.0")] @@ -32,7 +31,7 @@ pub enum InboundService { Twitter, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "lowercase")] pub enum OutboundService { #[serde(rename = "atom1.0")] @@ -67,13 +66,13 @@ pub enum OutboundService { Xmpp, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub enum Version { #[serde(rename = "2.1")] TwoOne, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "camelCase")] pub struct Software { pub name: String, @@ -82,14 +81,14 @@ pub struct Software { pub homepage: Option, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "camelCase")] pub struct Services { pub inbound: Vec, pub outbound: Vec, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "camelCase")] pub struct UsageUsers { pub total: u64, @@ -97,7 +96,7 @@ pub struct UsageUsers { pub active_month: Option, } -#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, ToSchema)] +#[derive(Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "camelCase")] pub struct Usage { pub users: UsageUsers, @@ -105,7 +104,7 @@ pub struct Usage { pub local_comments: Option, } -#[derive(Debug, Deserialize, PartialEq, Serialize, ToSchema)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] /// Definitions of Nodeinfo 2.1 pub struct TwoOne { @@ -115,7 +114,6 @@ pub struct TwoOne { pub services: Services, pub open_registrations: bool, pub usage: Usage, - #[schema(value_type = Object)] pub metadata: OwnedValue, } diff --git a/crates/kitsune-type/src/nodeinfo/well_known.rs b/crates/kitsune-type/src/nodeinfo/well_known.rs index a82554b18..48002cdba 100644 --- a/crates/kitsune-type/src/nodeinfo/well_known.rs +++ b/crates/kitsune-type/src/nodeinfo/well_known.rs @@ -1,19 +1,18 @@ use serde::Serialize; -use utoipa::ToSchema; -#[derive(Debug, Serialize, ToSchema)] +#[derive(Debug, Serialize)] pub enum Rel { #[serde(rename = "http://nodeinfo.diaspora.software/ns/schema/2.1")] TwoOne, } -#[derive(Debug, Serialize, ToSchema)] +#[derive(Debug, Serialize)] pub struct Link { pub rel: Rel, pub href: String, } -#[derive(Debug, Serialize, ToSchema)] +#[derive(Debug, Serialize)] pub struct WellKnown { pub links: Vec, } diff --git a/crates/kitsune-type/src/webfinger.rs b/crates/kitsune-type/src/webfinger.rs index a6b678ca0..5d25406d8 100644 --- a/crates/kitsune-type/src/webfinger.rs +++ b/crates/kitsune-type/src/webfinger.rs @@ -1,14 +1,13 @@ use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; -#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Link { pub rel: String, pub r#type: Option, pub href: Option, } -#[derive(Clone, Deserialize, Serialize, ToSchema)] +#[derive(Clone, Deserialize, Serialize)] pub struct Resource { pub subject: String, #[serde(default)] diff --git a/crates/kitsune-url/Cargo.toml b/crates/kitsune-url/Cargo.toml index fa2ea7493..34d95c964 100644 --- a/crates/kitsune-url/Cargo.toml +++ b/crates/kitsune-url/Cargo.toml @@ -6,9 +6,9 @@ version.workspace = true license.workspace = true [dependencies] -kitsune-derive = { path = "../kitsune-derive" } +kitsune-derive = { workspace = true } smol_str = "0.2.2" -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } [lints] workspace = true diff --git a/crates/kitsune-util/Cargo.toml b/crates/kitsune-util/Cargo.toml index 7a7e8ff58..1160c9b87 100644 --- a/crates/kitsune-util/Cargo.toml +++ b/crates/kitsune-util/Cargo.toml @@ -8,14 +8,14 @@ license.workspace = true [dependencies] bubble-bath = "0.1.3" iso8601-timestamp = "0.2.17" -kitsune-type = { path = "../kitsune-type" } +kitsune-type = { workspace = true } once_cell = "1.19.0" pulldown-cmark = { version = "0.11.0", default-features = false, features = [ "html", "simd", ] } rand = "0.8.5" -speedy-uuid = { path = "../../lib/speedy-uuid" } +speedy-uuid = { workspace = true } tokio = { version = "1.37.0", features = ["macros"] } [lints] diff --git a/crates/kitsune-wasm-mrf/Cargo.toml b/crates/kitsune-wasm-mrf/Cargo.toml index f2c3b983b..6f1d0a2da 100644 --- a/crates/kitsune-wasm-mrf/Cargo.toml +++ b/crates/kitsune-wasm-mrf/Cargo.toml @@ -16,20 +16,20 @@ fred = { workspace = true } futures-util = { version = "0.3.30", default-features = false, features = [ "alloc", ] } -kitsune-config = { path = "../kitsune-config" } -kitsune-derive = { path = "../kitsune-derive" } -kitsune-error = { path = "../kitsune-error" } -kitsune-type = { path = "../kitsune-type" } -mrf-manifest = { path = "../../lib/mrf-manifest", features = ["decode"] } -simd-json = "0.13.10" +kitsune-config = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-error = { workspace = true } +kitsune-type = { workspace = true } +mrf-manifest = { workspace = true, features = ["decode"] } +simd-json = { workspace = true } slab = "0.4.9" sled = "0.34.7" smol_str = "0.2.2" tokio = { version = "1.37.0", features = ["fs"] } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } walkdir = "2.5.0" -wasmtime = { version = "21.0.0", default-features = false, features = [ +wasmtime = { version = "21.0.1", default-features = false, features = [ "addr2line", "async", "component-model", @@ -38,7 +38,7 @@ wasmtime = { version = "21.0.0", default-features = false, features = [ "pooling-allocator", "runtime", ] } -wasmtime-wasi = { version = "21.0.0", default-features = false } +wasmtime-wasi = { version = "21.0.1", default-features = false } [dev-dependencies] tempfile = "3.10.1" diff --git a/crates/kitsune-webfinger/Cargo.toml b/crates/kitsune-webfinger/Cargo.toml index 44333a57b..1bcb4d2c0 100644 --- a/crates/kitsune-webfinger/Cargo.toml +++ b/crates/kitsune-webfinger/Cargo.toml @@ -10,21 +10,21 @@ async-trait = "0.1.80" fred = { workspace = true } futures-util = "0.3.30" http = "1.1.0" -kitsune-cache = { path = "../kitsune-cache" } -kitsune-core = { path = "../kitsune-core" } -kitsune-error = { path = "../kitsune-error" } -kitsune-http-client = { path = "../kitsune-http-client" } -kitsune-type = { path = "../kitsune-type" } -kitsune-util = { path = "../kitsune-util" } +kitsune-cache = { workspace = true } +kitsune-core = { workspace = true } +kitsune-error = { workspace = true } +kitsune-http-client = { workspace = true } +kitsune-type = { workspace = true } +kitsune-util = { workspace = true } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } urlencoding = "2.1.3" [dev-dependencies] http-body-util = "0.1.1" hyper = "1.3.1" pretty_assertions = "1.4.0" -simd-json = "0.13.10" +simd-json = { workspace = true } tokio = { version = "1.37.0", features = ["macros"] } tower = { version = "0.4.13", default-features = false, features = ["util"] } diff --git a/kitsune-cli/Cargo.toml b/kitsune-cli/Cargo.toml index 3edade15c..418857fe1 100644 --- a/kitsune-cli/Cargo.toml +++ b/kitsune-cli/Cargo.toml @@ -12,18 +12,18 @@ license = false eula = false [dependencies] -clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +clap = { workspace = true } color-eyre = "0.6.3" -diesel = "2.1.6" -diesel-async = "0.4.1" +diesel = { workspace = true } +diesel-async = { workspace = true } dotenvy = "0.15.7" envy = "0.4.2" -kitsune-config = { path = "../crates/kitsune-config" } -kitsune-core = { version = "0.0.1-pre.6", path = "../crates/kitsune-core" } -kitsune-db = { path = "../crates/kitsune-db" } -kitsune-error = { path = "../crates/kitsune-error" } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-error = { workspace = true } serde = { version = "1.0.202", features = ["derive"] } -speedy-uuid = { path = "../lib/speedy-uuid" } +speedy-uuid = { workspace = true } tokio = { version = "1.37.0", features = ["full"] } tracing-subscriber = "0.3.18" diff --git a/kitsune-job-runner/Cargo.toml b/kitsune-job-runner/Cargo.toml index 0c070e55d..9a17502bc 100644 --- a/kitsune-job-runner/Cargo.toml +++ b/kitsune-job-runner/Cargo.toml @@ -12,27 +12,27 @@ license = false eula = false [dependencies] -athena = { path = "../lib/athena", features = ["redis"] } -clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +athena = { workspace = true } +clap = { workspace = true } color-eyre = "0.6.3" fred = { workspace = true } -just-retry = { path = "../lib/just-retry" } -kitsune-config = { path = "../crates/kitsune-config" } -kitsune-core = { path = "../crates/kitsune-core" } -kitsune-db = { path = "../crates/kitsune-db" } -kitsune-email = { path = "../crates/kitsune-email" } -kitsune-error = { path = "../crates/kitsune-error" } -kitsune-federation = { path = "../crates/kitsune-federation" } -kitsune-federation-filter = { path = "../crates/kitsune-federation-filter" } -kitsune-jobs = { path = "../crates/kitsune-jobs" } -kitsune-observability = { path = "../crates/kitsune-observability" } -kitsune-service = { path = "../crates/kitsune-service" } -kitsune-url = { path = "../crates/kitsune-url" } -kitsune-wasm-mrf = { path = "../crates/kitsune-wasm-mrf" } +just-retry = { workspace = true } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-email = { workspace = true } +kitsune-error = { workspace = true } +kitsune-federation = { workspace = true } +kitsune-federation-filter = { workspace = true } +kitsune-jobs = { workspace = true } +kitsune-observability = { workspace = true } +kitsune-service = { workspace = true } +kitsune-url = { workspace = true } +kitsune-wasm-mrf = { workspace = true } mimalloc = "0.1.42" tokio = { version = "1.37.0", features = ["full"] } tracing = "0.1.40" -triomphe = "0.1.11" +triomphe = { workspace = true } typed-builder = "0.18.2" [features] diff --git a/kitsune/Cargo.toml b/kitsune/Cargo.toml index 777ad9fb5..03bc9b74e 100644 --- a/kitsune/Cargo.toml +++ b/kitsune/Cargo.toml @@ -15,11 +15,9 @@ license = false eula = false [dependencies] -athena = { path = "../lib/athena", features = ["redis"] } +athena = { workspace = true } argon2 = { version = "0.5.3", features = ["std"] } -askama = { version = "0.12.1", features = [ - "with-axum", -], default-features = false } +askama = { workspace = true } askama_axum = "0.4.0" async-trait = "0.1.80" axum = { version = "0.7.5", features = ["macros", "multipart"] } @@ -30,45 +28,45 @@ axum-extra = { version = "0.9.3", features = [ "typed-header", ] } axum-flash = "0.8.0" -blowocking = { path = "../lib/blowocking" } +blowocking = { workspace = true } bytes = "1.6.0" chrono = { version = "0.4.38", default-features = false } -clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +clap = { workspace = true } color-eyre = "0.6.3" -cursiv = { path = "../lib/cursiv", features = ["axum"] } -diesel = "2.1.6" -diesel-async = "0.4.1" +cursiv = { workspace = true, features = ["axum"] } +diesel = { workspace = true } +diesel-async = { workspace = true } futures-util = "0.3.30" headers = "0.4.0" http = "1.1.0" http-body-util = "0.1.1" -http-signatures = { path = "../lib/http-signatures" } +http-signatures = { workspace = true } iso8601-timestamp = "0.2.17" -itertools = { version = "0.13.0", default-features = false } -kitsune-activitypub = { path = "../crates/kitsune-activitypub" } -kitsune-cache = { path = "../crates/kitsune-cache" } -kitsune-captcha = { path = "../crates/kitsune-captcha" } -kitsune-config = { path = "../crates/kitsune-config" } -kitsune-core = { path = "../crates/kitsune-core" } -kitsune-db = { path = "../crates/kitsune-db" } -kitsune-derive = { path = "../crates/kitsune-derive" } -kitsune-email = { path = "../crates/kitsune-email" } -kitsune-embed = { path = "../crates/kitsune-embed" } -kitsune-error = { path = "../crates/kitsune-error" } -kitsune-federation = { path = "../crates/kitsune-federation" } -kitsune-federation-filter = { path = "../crates/kitsune-federation-filter" } -kitsune-job-runner = { path = "../kitsune-job-runner" } -kitsune-jobs = { path = "../crates/kitsune-jobs" } -kitsune-language = { path = "../crates/kitsune-language" } -kitsune-observability = { path = "../crates/kitsune-observability" } -kitsune-search = { path = "../crates/kitsune-search" } -kitsune-service = { path = "../crates/kitsune-service" } -kitsune-storage = { path = "../crates/kitsune-storage" } -kitsune-type = { path = "../crates/kitsune-type" } -kitsune-url = { path = "../crates/kitsune-url" } -kitsune-util = { path = "../crates/kitsune-util" } -kitsune-wasm-mrf = { path = "../crates/kitsune-wasm-mrf" } -kitsune-webfinger = { path = "../crates/kitsune-webfinger" } +itertools = { workspace = true } +kitsune-activitypub = { workspace = true } +kitsune-cache = { workspace = true } +kitsune-captcha = { workspace = true } +kitsune-config = { workspace = true } +kitsune-core = { workspace = true } +kitsune-db = { workspace = true } +kitsune-derive = { workspace = true } +kitsune-email = { workspace = true } +kitsune-embed = { workspace = true } +kitsune-error = { workspace = true } +kitsune-federation = { workspace = true } +kitsune-federation-filter = { workspace = true } +kitsune-job-runner = { workspace = true } +kitsune-jobs = { workspace = true } +kitsune-language = { workspace = true } +kitsune-observability = { workspace = true } +kitsune-search = { workspace = true } +kitsune-service = { workspace = true } +kitsune-storage = { workspace = true } +kitsune-type = { workspace = true } +kitsune-url = { workspace = true } +kitsune-util = { workspace = true } +kitsune-wasm-mrf = { workspace = true } +kitsune-webfinger = { workspace = true } mimalloc = "0.1.42" mime = "0.3.17" mime_guess = { version = "2.0.4", default-features = false } @@ -79,17 +77,17 @@ rust-embed = { version = "8.4.0", features = ["include-exclude"] } scoped-futures = "0.1.3" serde = { version = "1.0.202", features = ["derive"] } serde_urlencoded = "0.7.1" -simd-json = "0.13.10" -simdutf8 = { version = "0.1.4", features = ["aarch64_neon"] } -speedy-uuid = { path = "../lib/speedy-uuid" } +simd-json = { workspace = true } +simdutf8 = { workspace = true } +speedy-uuid = { workspace = true } strum = { version = "0.26.2", features = ["derive", "phf"] } tempfile = "3.10.1" time = "0.3.36" tokio = { version = "1.37.0", features = ["full"] } tokio-util = { version = "0.7.11", features = ["io"] } tower = { version = "0.4.13", features = ["util"] } -tower-stop-using-brave = { path = "../lib/tower-stop-using-brave" } -tower-x-clacks-overhead = { path = "../lib/tower-x-clacks-overhead" } +tower-stop-using-brave = { workspace = true } +tower-x-clacks-overhead = { workspace = true } tower-http = { version = "0.5.2", features = [ "catch-panic", "cors", @@ -98,20 +96,18 @@ tower-http = { version = "0.5.2", features = [ "timeout", "trace", ] } -tower-http-digest = { path = "../lib/tower-http-digest" } +tower-http-digest = { workspace = true } tracing = "0.1.40" -trials = { path = "../lib/trials" } -triomphe = "0.1.11" +trials = { workspace = true } +triomphe = { workspace = true } typed-builder = "0.18.2" url = "2.5.0" -utoipa = { version = "4.2.3", features = ["axum_extras", "uuid"] } -utoipa-swagger-ui = { version = "=6.0.0", features = ["axum"] } # --- Optional dependencies --- # "graphql" feature async-graphql = { version = "7.0.5", default-features = false, features = [ - "playground", + "graphiql", "tempfile", "time", "tracing", @@ -120,19 +116,19 @@ async-graphql = { version = "7.0.5", default-features = false, features = [ async-graphql-axum = { version = "7.0.5", optional = true } # "mastodon-api" feature -kitsune-mastodon = { path = "../crates/kitsune-mastodon", optional = true } +kitsune-mastodon = { workspace = true, optional = true } # "oidc" feature -kitsune-oidc = { path = "../crates/kitsune-oidc", optional = true } +kitsune-oidc = { workspace = true, optional = true } [build-dependencies] camino = "1.1.7" fs_extra = "1.3.0" -kitsune-scss-compiler = { path = "../crates/kitsune-scss-compiler" } +kitsune-scss-compiler = { workspace = true } [dev-dependencies] -kitsune-http-client = { path = "../crates/kitsune-http-client" } -kitsune-test = { path = "../crates/kitsune-test" } +kitsune-http-client = { workspace = true } +kitsune-test = { workspace = true } pretty_assertions = "1.4.0" fred = { workspace = true } diff --git a/kitsune/src/http/graphql/mod.rs b/kitsune/src/http/graphql/mod.rs index d1b1ff0b1..aae5f7c26 100644 --- a/kitsune/src/http/graphql/mod.rs +++ b/kitsune/src/http/graphql/mod.rs @@ -2,9 +2,7 @@ use self::{mutation::RootMutation, query::RootQuery}; use super::extractor::{AuthExtractor, UserData}; use crate::state::Zustand; use async_graphql::{ - extensions::Tracing, - http::{playground_source, GraphQLPlaygroundConfig}, - Context, EmptySubscription, Error, Result, Schema, + extensions::Tracing, http::GraphiQLSource, Context, EmptySubscription, Error, Result, Schema, }; use async_graphql_axum::{GraphQLBatchRequest, GraphQLResponse}; use axum::{ @@ -52,10 +50,12 @@ async fn graphql_route( #[allow(clippy::unused_async)] async fn graphiql_route() -> Html { - let config = GraphQLPlaygroundConfig::new("/graphql") - .title(concat!(env!("CARGO_PKG_NAME"), " - GraphiQL")); + let source = GraphiQLSource::build() + .endpoint("/graphql") + .title(concat!(env!("CARGO_PKG_NAME"), " - GraphiQL")) + .finish(); - Html(playground_source(config)) + Html(source) } pub fn routes(state: Zustand) -> Router { diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/follow.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/follow.rs index 36cb59b3f..0a9ccdc26 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/follow.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/follow.rs @@ -10,26 +10,14 @@ use kitsune_service::account::{AccountService, Follow}; use kitsune_type::mastodon::relationship::Relationship; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct FollowBody { #[serde(default)] notify: bool, } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/accounts/{id}/follow", - security( - ("oauth_token" = []) - ), - request_body = FollowBody, - responses( - (status = 200, description = "Followed user successfully", body = Relationship) - ), -)] pub async fn post( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/lookup.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/lookup.rs index 43d3936b1..c20cf7671 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/lookup.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/lookup.rs @@ -9,26 +9,13 @@ use kitsune_mastodon::MastodonMapper; use kitsune_service::account::{AccountService, GetUser}; use kitsune_type::mastodon::Account; use serde::Deserialize; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct LookupQuery { acct: String, } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/accounts/lookup", - security( - ("oauth_token" = []) - ), - params(LookupQuery), - responses( - (status = 200, description = "Return the account that goes by the acct structure", body = Account), - (status = 404, description = "The account isn't known and has to be looked up via Webfinger"), - ), -)] pub async fn get( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/mod.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/mod.rs index 39299fe7f..3decad346 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/mod.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/mod.rs @@ -17,14 +17,6 @@ pub mod unfollow; pub mod update_credentials; pub mod verify_credentials; -#[utoipa::path( - get, - path = "/api/v1/accounts/{id}", - responses( - (status = 200, description = "Account information", body = Account), - (status = StatusCode::NOT_FOUND, description = "No account with that ID exists"), - ) -)] async fn get( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/relationships.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/relationships.rs index 30fa92cf5..2655a2d0c 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/relationships.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/relationships.rs @@ -10,26 +10,13 @@ use kitsune_mastodon::MastodonMapper; use kitsune_type::mastodon::relationship::Relationship; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct RelationshipQuery { id: Vec, } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/accounts/relationships", - security( - ("oauth_token" = []) - ), - params(RelationshipQuery), - responses( - (status = 200, description = "Relationship between you and the other accounts", body = Vec), - (status = 400, description = "One of the account IDs you input isn't known"), - ), -)] pub async fn get( AuthExtractor(user_data): MastodonAuthExtractor, State(db_pool): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/statuses.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/statuses.rs index a9802bb8f..d26d9fd0d 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/statuses.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/statuses.rs @@ -17,9 +17,8 @@ use kitsune_type::mastodon::Status; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { max_id: Option, since_id: Option, @@ -28,18 +27,6 @@ pub struct GetQuery { limit: usize, } -#[utoipa::path( - get, - path = "/api/v1/accounts/{id}/statuses", - security( - (), - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = 200, description = "Statuses by the user", body = Vec), - ) -)] pub async fn get( State(account): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/update_credentials.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/update_credentials.rs index 687caf532..a60779430 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/update_credentials.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/update_credentials.rs @@ -14,16 +14,6 @@ use kitsune_service::{ }; use kitsune_type::mastodon::Account; -#[utoipa::path( - patch, - path = "/api/v1/accounts/update_credentials", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "Updated account of the user", body = Account), - ) -)] pub async fn patch( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/accounts/verify_credentials.rs b/kitsune/src/http/handler/mastodon/api/v1/accounts/verify_credentials.rs index 1e967beaa..df9dd2601 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/accounts/verify_credentials.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/accounts/verify_credentials.rs @@ -4,17 +4,6 @@ use kitsune_error::Result; use kitsune_mastodon::MastodonMapper; use kitsune_type::mastodon::Account; -#[utoipa::path( - get, - path = "/api/v1/accounts/verify_credentials", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "Account of the logged in user", body = Account), - (status = StatusCode::BAD_REQUEST, description = "The request was invalid"), - ) -)] pub async fn get( State(mastodon_mapper): State, AuthExtractor(user): MastodonAuthExtractor, diff --git a/kitsune/src/http/handler/mastodon/api/v1/apps.rs b/kitsune/src/http/handler/mastodon/api/v1/apps.rs index 15e9f4541..60013f712 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/apps.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/apps.rs @@ -7,22 +7,13 @@ use axum::{extract::State, routing, Json, Router}; use kitsune_error::Result; use kitsune_type::mastodon::App; use serde::Deserialize; -use utoipa::ToSchema; -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct AppForm { client_name: String, redirect_uris: String, } -#[utoipa::path( - post, - path = "/api/v1/apps", - request_body = AppForm, - responses( - (status = 200, description = "Newly created application", body = App), - ), -)] async fn post( State(oauth2): State, AgnosticForm(form): AgnosticForm, diff --git a/kitsune/src/http/handler/mastodon/api/v1/custom_emojis.rs b/kitsune/src/http/handler/mastodon/api/v1/custom_emojis.rs index d9ef601d4..994803cc7 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/custom_emojis.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/custom_emojis.rs @@ -7,16 +7,6 @@ use kitsune_service::custom_emoji::{CustomEmojiService, GetEmojiList}; use kitsune_type::mastodon::CustomEmoji; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/custom_emojis", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "List of custom emojis available on the server", body = Vec) - ), -)] pub async fn get( State(custom_emoji_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/accept.rs b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/accept.rs index d37760662..05429c199 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/accept.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/accept.rs @@ -11,17 +11,6 @@ use kitsune_type::mastodon::relationship::Relationship; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/follow_requests/{id}/authorize", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "Follow request accepted", body = Relationship), - (status = 404, description = "No pending follow request from that account ID") - ), -)] pub async fn post( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/mod.rs b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/mod.rs index 91519fce5..7c17228ea 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/mod.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/mod.rs @@ -20,12 +20,11 @@ use kitsune_type::mastodon::Account; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; pub mod accept; pub mod reject; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { max_id: Option, since_id: Option, @@ -34,17 +33,6 @@ pub struct GetQuery { } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/follow_requests", - security( - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = 200, description = "List of accounts requesting a follow", body = Vec) - ), -)] pub async fn get( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/reject.rs b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/reject.rs index b387f09ba..3e82b8b70 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/follow_requests/reject.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/follow_requests/reject.rs @@ -11,17 +11,6 @@ use kitsune_type::mastodon::relationship::Relationship; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/follow_requests/{id}/reject", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "Follow request rejected", body = Relationship), - (status = 404, description = "No pending follow request from that account ID") - ), -)] pub async fn post( State(account_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/instance.rs b/kitsune/src/http/handler/mastodon/api/v1/instance.rs index b7d15fdd0..af690a464 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/instance.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/instance.rs @@ -9,13 +9,6 @@ use kitsune_type::mastodon::{ }; use kitsune_url::UrlService; -#[utoipa::path( - get, - path = "/api/v1/instance", - responses( - (status = 200, description = "Instance metadata", body = Instance), - ), -)] async fn get( State(instance_service): State, State(url_service): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/media.rs b/kitsune/src/http/handler/mastodon/api/v1/media.rs index b7dd8b267..a9fdde9de 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/media.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/media.rs @@ -17,29 +17,12 @@ use kitsune_service::attachment::{AttachmentService, Update, Upload}; use kitsune_type::mastodon::MediaAttachment; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[allow(dead_code)] -#[derive(ToSchema)] -pub struct CreateAttachment { - pub description: Option, - #[schema(value_type = String, format = Binary)] - pub file: (), -} - -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct UpdateAttachment { description: String, } -#[utoipa::path( - get, - path = "/api/v1/media/{id}", - responses( - (status = 200, description = "Media attachment", body = MediaAttachment), - (status = 404, description = "Media attachment doesn't exist"), - ), -)] pub async fn get( State(attachment_service): State, State(mapper): State, @@ -50,17 +33,6 @@ pub async fn get( )) } -#[utoipa::path( - post, - path = "/api/v1/media", - security( - ("oauth_token" = []) - ), - request_body(content = MediaAttachmentBody, content_type = "multipart/form-data"), - responses( - (status = 200, description = "New media attachment", body = MediaAttachment), - ), -)] pub async fn post( State(attachment_service): State, State(mastodon_mapper): State, @@ -99,17 +71,6 @@ pub async fn post( } #[debug_handler(state = Zustand)] -#[utoipa::path( - put, - path = "/api/v1/media/{id}", - security( - ("oauth_token" = []) - ), - request_body = UpdateAttachment, - responses( - (status = 200, description = "Updated media attachment", body = MediaAttachment), - ), -)] pub async fn put( State(attachment_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/notifications/clear.rs b/kitsune/src/http/handler/mastodon/api/v1/notifications/clear.rs index 6d94a1d95..6efeb03ee 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/notifications/clear.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/notifications/clear.rs @@ -5,16 +5,6 @@ use kitsune_error::Result; use kitsune_service::notification::NotificationService; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/notifications/clear", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "All notifications have been dismissed"), - ) -)] pub async fn post( State(notification_service): State, AuthExtractor(user_data): MastodonAuthExtractor, diff --git a/kitsune/src/http/handler/mastodon/api/v1/notifications/dismiss.rs b/kitsune/src/http/handler/mastodon/api/v1/notifications/dismiss.rs index 6bb537041..78f1f62a5 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/notifications/dismiss.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/notifications/dismiss.rs @@ -9,16 +9,6 @@ use kitsune_service::notification::NotificationService; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/notifications/{id}/dismiss", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "Notification has been dismissed"), - ) -)] pub async fn post( State(notification_service): State, AuthExtractor(user_data): MastodonAuthExtractor, diff --git a/kitsune/src/http/handler/mastodon/api/v1/notifications/mod.rs b/kitsune/src/http/handler/mastodon/api/v1/notifications/mod.rs index e059c5df7..cdcf8658c 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/notifications/mod.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/notifications/mod.rs @@ -20,12 +20,11 @@ use kitsune_type::mastodon::{notification::NotificationType, Notification}; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; pub mod clear; pub mod dismiss; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { #[serde(default)] max_id: Option, @@ -44,17 +43,6 @@ pub struct GetQuery { } #[debug_handler(state = Zustand)] -#[utoipa::path( - get, - path = "/api/v1/notifications", - security( - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = StatusCode::OK, description = "List of notifications concerning the user", body = Vec) - ), -)] pub async fn get( State(notification_service): State, State(mastodon_mapper): State, @@ -101,16 +89,6 @@ pub async fn get( } #[debug_handler(state = Zustand)] -#[utoipa::path( - get, - path = "/api/v1/notifications/{id}", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "A single notification", body = Notification) - ), -)] pub async fn get_by_id( State(notification_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/context.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/context.rs index 9df69d470..c00ce5bd0 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/context.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/context.rs @@ -13,18 +13,6 @@ use speedy_uuid::Uuid; use std::collections::VecDeque; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/statuses/{id}/context", - security( - (), - ("oauth_token" = []) - ), - responses( - (status = 200, description = "Ancestor and descendant statuses in the thread", body = Context), - (status = 404, description = "Status doesn't exist"), - ) -)] pub async fn get( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/favourite.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/favourite.rs index ab3b9c848..8993e171b 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/favourite.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/favourite.rs @@ -11,16 +11,6 @@ use kitsune_type::mastodon::Status; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/statuses/{id}/favourite", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "The status with updated information regarding like status"), - ) -)] pub async fn post( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/favourited_by.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/favourited_by.rs index e0f43048b..282d04a1a 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/favourited_by.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/favourited_by.rs @@ -19,9 +19,8 @@ use kitsune_type::mastodon::Account; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { min_id: Option, max_id: Option, @@ -31,17 +30,6 @@ pub struct GetQuery { } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/statuses/{id}/favourited_by", - security( - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = 200, description = "List of accounts that favourited the status", body = Vec) - ), -)] pub async fn get( State(post_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/mod.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/mod.rs index af5f28e25..8275a9074 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/mod.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/mod.rs @@ -14,7 +14,6 @@ use kitsune_service::post::{CreatePost, DeletePost, PostService, UpdatePost}; use kitsune_type::mastodon::{status::Visibility, Status}; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::ToSchema; pub mod context; pub mod favourite; @@ -25,7 +24,7 @@ pub mod source; pub mod unfavourite; pub mod unreblog; -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct CreateForm { #[serde(default)] media_ids: Vec, @@ -38,7 +37,7 @@ pub struct CreateForm { visibility: Visibility, } -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct UpdateForm { #[serde(default)] media_ids: Vec, @@ -51,16 +50,6 @@ pub struct UpdateForm { } #[debug_handler(state = Zustand)] -#[utoipa::path( - delete, - path = "/api/v1/statuses/{id}", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "Status was deleted"), - ) -)] async fn delete( State(post): State, AuthExtractor(user_data): MastodonAuthExtractor, @@ -78,18 +67,6 @@ async fn delete( } #[debug_handler(state = Zustand)] -#[utoipa::path( - get, - path = "/api/v1/statuses/{id}", - security( - (), - ("oauth_token" = []) - ), - responses( - (status = 200, description = "The requested status", body = Status), - (status = 404, description = "Requested status doesn't exist"), - ) -)] async fn get( State(mastodon_mapper): State, State(post): State, @@ -109,17 +86,6 @@ async fn get( } #[debug_handler(state = Zustand)] -#[utoipa::path( - post, - path = "/api/v1/statuses", - security( - ("oauth_token" = []) - ), - request_body = CreateForm, - responses( - (status = 200, description = "Newly created post", body = Status), - ) -)] async fn post( State(mastodon_mapper): State, State(post_service): State, @@ -142,18 +108,6 @@ async fn post( } #[debug_handler(state = Zustand)] -#[utoipa::path( - put, - path = "/api/v1/statuses/{id}", - security( - ("oauth_token" = []) - ), - request_body = UpdateForm, - responses( - (status = StatusCode::OK, description = "Status has been successfully edited", body = Status), - (status = StatusCode::NOT_FOUND, description = "Requested status doesn't exist"), - ) -)] async fn put( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/reblog.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/reblog.rs index fc3d49253..97355aa19 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/reblog.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/reblog.rs @@ -10,26 +10,14 @@ use kitsune_service::post::{PostService, RepostPost}; use kitsune_type::mastodon::{status::Visibility, Status}; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::ToSchema; -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] pub struct RepostBody { #[serde(default)] visibility: Visibility, } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/statuses/{id}/reblog", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "The new status referencing the reblog", body = Status), - (status = StatusCode::NOT_FOUND, description = "Requested status doesn't exist"), - ) -)] pub async fn post( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/reblogged_by.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/reblogged_by.rs index da0682df2..b3b37a04d 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/reblogged_by.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/reblogged_by.rs @@ -19,9 +19,8 @@ use kitsune_type::mastodon::Account; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { min_id: Option, max_id: Option, @@ -31,17 +30,6 @@ pub struct GetQuery { } #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/statuses/{id}/reblogged_by", - security( - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = 200, description = "List of accounts that reblogged the status", body = Vec) - ), -)] pub async fn get( State(post_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/source.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/source.rs index b56e05bed..e91654c8b 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/source.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/source.rs @@ -10,16 +10,6 @@ use kitsune_type::mastodon::status::StatusSource; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/api/v1/statuses/{id}/source", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "Source of the status", body = StatusSource), - ) -)] pub async fn get( State(mastodon_mapper): State, State(post_service): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/unfavourite.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/unfavourite.rs index a7f0ba012..47aba8adf 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/unfavourite.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/unfavourite.rs @@ -11,16 +11,6 @@ use kitsune_type::mastodon::Status; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - post, - path = "/api/v1/statuses/{id}/unfavourite", - security( - ("oauth_token" = []) - ), - responses( - (status = 200, description = "The status with updated information regarding like status"), - ) -)] pub async fn post( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/statuses/unreblog.rs b/kitsune/src/http/handler/mastodon/api/v1/statuses/unreblog.rs index 6bab52630..68eccf99e 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/statuses/unreblog.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/statuses/unreblog.rs @@ -11,17 +11,6 @@ use kitsune_type::mastodon::Status; use speedy_uuid::Uuid; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - delete, - path = "/api/v1/statuses/{id}/unreblog", - security( - ("oauth_token" = []) - ), - responses( - (status = StatusCode::OK, description = "Status was unboosted or was already not boosted", body = Status), - (status = StatusCode::NOT_FOUND, description = "Status does not exist or is private") - ) -)] pub async fn post( State(mastodon_mapper): State, State(post): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/timelines/home.rs b/kitsune/src/http/handler/mastodon/api/v1/timelines/home.rs index 8f5545364..ae9469f1f 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/timelines/home.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/timelines/home.rs @@ -17,9 +17,8 @@ use kitsune_type::mastodon::Status; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { max_id: Option, since_id: Option, @@ -28,17 +27,6 @@ pub struct GetQuery { limit: usize, } -#[utoipa::path( - get, - path = "/api/v1/timelines/home", - security( - ("oauth_token" = []) - ), - params(GetQuery), - responses( - (status = 200, description = "Current home timeline", body = Vec), - ), -)] pub async fn get( State(mastodon_mapper): State, State(timeline): State, diff --git a/kitsune/src/http/handler/mastodon/api/v1/timelines/public.rs b/kitsune/src/http/handler/mastodon/api/v1/timelines/public.rs index f203a2ef2..f43783039 100644 --- a/kitsune/src/http/handler/mastodon/api/v1/timelines/public.rs +++ b/kitsune/src/http/handler/mastodon/api/v1/timelines/public.rs @@ -17,9 +17,8 @@ use kitsune_type::mastodon::Status; use kitsune_url::UrlService; use serde::Deserialize; use speedy_uuid::Uuid; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] pub struct GetQuery { #[serde(default)] local: bool, @@ -32,14 +31,6 @@ pub struct GetQuery { limit: usize, } -#[utoipa::path( - get, - path = "/api/v1/timelines/public", - params(GetQuery), - responses( - (status = 200, description = "Current public timeline", body = Vec), - ), -)] pub async fn get( State(mastodon_mapper): State, State(timeline): State, diff --git a/kitsune/src/http/handler/mastodon/api/v2/search.rs b/kitsune/src/http/handler/mastodon/api/v2/search.rs index 681595e68..94be57ef2 100644 --- a/kitsune/src/http/handler/mastodon/api/v2/search.rs +++ b/kitsune/src/http/handler/mastodon/api/v2/search.rs @@ -15,9 +15,8 @@ use kitsune_type::mastodon::SearchResult as MastodonSearchResult; use serde::Deserialize; use speedy_uuid::Uuid; use std::cmp::min; -use utoipa::{IntoParams, ToSchema}; -#[derive(Deserialize, ToSchema)] +#[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub enum SearchType { Accounts, @@ -25,7 +24,7 @@ pub enum SearchType { Statuses, } -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] struct SearchQuery { #[serde(rename = "q")] query: String, @@ -41,17 +40,6 @@ struct SearchQuery { } #[debug_handler(state = Zustand)] -#[utoipa::path( - get, - path = "/api/v2/search", - security( - ("oauth_token" = []) - ), - params(SearchQuery), - responses( - (status = 200, description = "Search results", body = SearchResult), - ), -)] async fn get( State(search_service): State, State(mastodon_mapper): State, diff --git a/kitsune/src/http/handler/nodeinfo/two_one.rs b/kitsune/src/http/handler/nodeinfo/two_one.rs index b9b6b647a..b484bf720 100644 --- a/kitsune/src/http/handler/nodeinfo/two_one.rs +++ b/kitsune/src/http/handler/nodeinfo/two_one.rs @@ -16,13 +16,6 @@ use kitsune_util::try_join; use simd_json::{OwnedValue, ValueBuilder}; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path( - get, - path = "/nodeinfo/2.1", - responses( - (status = 200, description = "Get response following the Nodeinfo 2.1 schema", body = TwoOne) - ), -)] async fn get( State(db_pool): State, State(user_service): State, diff --git a/kitsune/src/http/handler/oauth/token.rs b/kitsune/src/http/handler/oauth/token.rs index 7c8392676..c338ba215 100644 --- a/kitsune/src/http/handler/oauth/token.rs +++ b/kitsune/src/http/handler/oauth/token.rs @@ -8,7 +8,6 @@ use oxide_auth_async::endpoint::{ use oxide_auth_axum::{OAuthRequest, OAuthResponse}; #[debug_handler(state = crate::state::Zustand)] -#[utoipa::path(post, path = "/oauth/token")] pub async fn post( State(oauth_endpoint): State, oauth_req: OAuthRequest, diff --git a/kitsune/src/http/handler/well_known/nodeinfo.rs b/kitsune/src/http/handler/well_known/nodeinfo.rs index 99d568136..1653f169b 100644 --- a/kitsune/src/http/handler/well_known/nodeinfo.rs +++ b/kitsune/src/http/handler/well_known/nodeinfo.rs @@ -4,13 +4,6 @@ use kitsune_type::nodeinfo::well_known::{Link, WellKnown}; use kitsune_url::UrlService; #[allow(clippy::unused_async)] -#[utoipa::path( - get, - path = "/.well-known/nodeinfo", - responses( - (status = 200, description = "Response with the location of the nodeinfo endpoints", body = WellKnown) - ) -)] async fn get(State(url_service): State) -> Json { let href = format!("{}/nodeinfo/2.1", url_service.base_url()); diff --git a/kitsune/src/http/handler/well_known/webfinger.rs b/kitsune/src/http/handler/well_known/webfinger.rs index cc4a1c3c5..fb7b4c556 100644 --- a/kitsune/src/http/handler/well_known/webfinger.rs +++ b/kitsune/src/http/handler/well_known/webfinger.rs @@ -10,22 +10,12 @@ use kitsune_service::account::{AccountService, GetUser}; use kitsune_type::webfinger::{Link, Resource}; use kitsune_url::UrlService; use serde::Deserialize; -use utoipa::IntoParams; -#[derive(Deserialize, IntoParams)] +#[derive(Deserialize)] struct WebfingerQuery { resource: String, } -#[utoipa::path( - get, - path = "/.well-known/webfinger", - params(WebfingerQuery), - responses( - (status = 200, description = "Response with the location of the user's profile", body = Resource), - (status = StatusCode::NOT_FOUND, description = "The service doesn't know this user"), - ) -)] async fn get( State(account_service): State, State(url_service): State, diff --git a/kitsune/src/http/mod.rs b/kitsune/src/http/mod.rs index 8a113524c..08ab0c108 100644 --- a/kitsune/src/http/mod.rs +++ b/kitsune/src/http/mod.rs @@ -1,8 +1,5 @@ -use self::{ - handler::{ - confirm_account, custom_emojis, media, nodeinfo, oauth, posts, public, users, well_known, - }, - openapi::api_docs, +use self::handler::{ + confirm_account, custom_emojis, media, nodeinfo, oauth, posts, public, users, well_known, }; use crate::state::Zustand; use axum::{ @@ -30,7 +27,6 @@ use tower_http::{ }; use tower_stop_using_brave::StopUsingBraveLayer; use tower_x_clacks_overhead::XClacksOverheadLayer; -use utoipa_swagger_ui::SwaggerUi; const FALLBACK_FALLBACK_INDEX: &str = include_str!("../../templates/fallback-fallback.html"); @@ -40,7 +36,6 @@ static X_REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id"); mod graphql; mod handler; mod middleware; -mod openapi; #[cfg(feature = "mastodon-api")] mod pagination; mod responder; @@ -133,9 +128,7 @@ pub fn create_router( router = router.merge(handler::mastodon::routes()); } - router = router - .merge(SwaggerUi::new("/swagger-ui").url("/api-doc/openapi.json", api_docs())) - .fallback_service(serve_frontend(server_config)); + router = router.fallback_service(serve_frontend(server_config)); if !server_config.clacks_overhead.is_empty() { let clacks_overhead_layer = @@ -178,6 +171,7 @@ pub async fn run( let listener = TcpListener::bind(("0.0.0.0", server_config.port)).await?; axum::serve(listener, router) + .tcp_nodelay(true) .with_graceful_shutdown(shutdown_signal.wait()) .await?; diff --git a/kitsune/src/http/openapi.rs b/kitsune/src/http/openapi.rs deleted file mode 100644 index fb4ff14ce..000000000 --- a/kitsune/src/http/openapi.rs +++ /dev/null @@ -1,138 +0,0 @@ -use crate::http::handler::{nodeinfo, well_known}; -use kitsune_type::{ - mastodon as mastodon_type, nodeinfo as nodeinfo_type, webfinger as webfinger_type, -}; -use utoipa::{ - openapi::{ - security::{AuthorizationCode, Flow, OAuth2, Scopes, SecurityScheme}, - OpenApi as OpenApiStruct, - }, - Modify, OpenApi, ToSchema, -}; - -#[cfg(feature = "mastodon-api")] -use crate::http::handler::mastodon; - -struct SecurityAddon; - -impl Modify for SecurityAddon { - fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { - if let Some(components) = openapi.components.as_mut() { - components.add_security_scheme( - "oauth_token", - SecurityScheme::OAuth2(OAuth2::new([Flow::AuthorizationCode( - AuthorizationCode::new("/oauth/authorize", "/oauth/token", Scopes::new()), - )])), - ); - } - } -} - -#[derive(ToSchema)] -#[schema(as = SmolStr)] -#[allow(dead_code)] // Otherwise `utoipa::ToSchema` can't correctly infer the type -struct SmolStrPolyfill(String); - -#[derive(ToSchema)] -#[schema(as = Timestamp)] -#[allow(dead_code)] // Otherwise `utoipa::ToSchema` can't correctly infer the type -struct TimestampPolyfill(String); - -#[derive(OpenApi)] -#[openapi( - components(schemas( - SmolStrPolyfill, - TimestampPolyfill, - mastodon_type::App, - mastodon_type::account::Account, - mastodon_type::account::Field, - mastodon_type::account::Source, - mastodon_type::instance::Stats, - mastodon_type::instance::Urls, - mastodon_type::instance::Instance, - mastodon_type::media_attachment::MediaType, - mastodon_type::media_attachment::MediaAttachment, - mastodon_type::preview_card::PreviewCard, - mastodon_type::preview_card::PreviewType, - mastodon_type::relationship::Relationship, - mastodon_type::search::SearchResult, - mastodon_type::status::Context, - mastodon_type::status::Mention, - mastodon_type::status::Visibility, - mastodon_type::status::Status, - mastodon_type::status::StatusSource, - nodeinfo_type::two_one::TwoOne, - nodeinfo_type::two_one::Protocol, - nodeinfo_type::two_one::InboundService, - nodeinfo_type::two_one::OutboundService, - nodeinfo_type::two_one::Version, - nodeinfo_type::two_one::Software, - nodeinfo_type::two_one::Services, - nodeinfo_type::two_one::UsageUsers, - nodeinfo_type::two_one::Usage, - nodeinfo_type::well_known::Rel, - nodeinfo_type::well_known::Link, - nodeinfo_type::well_known::WellKnown, - webfinger_type::Link, - webfinger_type::Resource, - )), - modifiers(&SecurityAddon), - paths( - nodeinfo::two_one::get, - well_known::nodeinfo::get, - well_known::webfinger::get, - ), -)] -struct CommonApiDocs; - -#[cfg(feature = "mastodon-api")] -#[derive(OpenApi)] -#[openapi( - components(schemas( - mastodon::api::v1::apps::AppForm, - mastodon::api::v1::media::CreateAttachment, - mastodon::api::v1::media::UpdateAttachment, - mastodon::api::v1::statuses::CreateForm, - mastodon::api::v2::search::SearchType, - )), - modifiers(&SecurityAddon), - paths( - mastodon::api::v1::accounts::get, - mastodon::api::v1::accounts::lookup::get, - mastodon::api::v1::accounts::relationships::get, - mastodon::api::v1::accounts::statuses::get, - mastodon::api::v1::accounts::update_credentials::patch, - mastodon::api::v1::accounts::verify_credentials::get, - mastodon::api::v1::apps::post, - mastodon::api::v1::follow_requests::get, - mastodon::api::v1::follow_requests::accept::post, - mastodon::api::v1::follow_requests::reject::post, - mastodon::api::v1::instance::get, - mastodon::api::v1::media::post, - mastodon::api::v1::media::put, - mastodon::api::v1::statuses::delete, - mastodon::api::v1::statuses::get, - mastodon::api::v1::statuses::post, - mastodon::api::v1::statuses::put, - mastodon::api::v1::statuses::context::get, - mastodon::api::v1::statuses::favourite::post, - mastodon::api::v1::statuses::favourited_by::get, - mastodon::api::v1::statuses::reblog::post, - mastodon::api::v1::statuses::reblogged_by::get, - mastodon::api::v1::statuses::source::get, - mastodon::api::v1::statuses::unfavourite::post, - mastodon::api::v1::statuses::unreblog::post, - mastodon::api::v1::timelines::home::get, - mastodon::api::v1::timelines::public::get, - mastodon::api::v2::search::get, - ) -)] -struct MastodonApiDocs; - -pub fn api_docs() -> OpenApiStruct { - #[allow(unused_mut)] - let mut api_docs = CommonApiDocs::openapi(); - #[cfg(feature = "mastodon-api")] - api_docs.merge(MastodonApiDocs::openapi()); - api_docs -} diff --git a/lib/athena/Cargo.toml b/lib/athena/Cargo.toml index 6072d046d..ae558353b 100644 --- a/lib/athena/Cargo.toml +++ b/lib/athena/Cargo.toml @@ -16,18 +16,18 @@ either = { version = "1.12.0", default-features = false, optional = true } futures-util = { version = "0.3.30", default-features = false } iso8601-timestamp = "0.2.17" fred = { workspace = true, optional = true } -just-retry = { path = "../just-retry" } +just-retry = { workspace = true } once_cell = { version = "1.19.0", optional = true } rand = { version = "0.8.5", optional = true } serde = { version = "1.0.202", features = ["derive"] } -simd-json = { version = "0.13.10", optional = true } +simd-json = { workspace = true, optional = true } smol_str = "0.2.2" -speedy-uuid = { path = "../speedy-uuid", features = ["redis", "serde"] } +speedy-uuid = { workspace = true, features = ["redis"] } thiserror = "1.0.61" tokio = { version = "1.37.0", features = ["macros", "rt", "sync"] } tokio-util = { version = "0.7.11", features = ["rt"] } tracing = "0.1.40" -triomphe = { version = "0.1.11", features = ["unsize"] } +triomphe = { workspace = true } typed-builder = "0.18.2" typetag = "0.2.16" unsize = "1.1.0" @@ -36,7 +36,7 @@ unsize = "1.1.0" redis = ["dep:either", "dep:fred", "dep:once_cell", "dep:rand", "dep:simd-json"] [dev-dependencies] -kitsune-test = { path = "../../crates/kitsune-test" } +kitsune-test = { workspace = true } tracing-subscriber = "0.3.18" [lints] diff --git a/lib/athena/src/redis/mod.rs b/lib/athena/src/redis/mod.rs index 2422d1cc5..43f758579 100644 --- a/lib/athena/src/redis/mod.rs +++ b/lib/athena/src/redis/mod.rs @@ -62,13 +62,29 @@ where { async fn initialise_group(&self) -> Result<()> { self.group_initialised - .get_or_try_init(|| { - self.redis_pool.xgroup_create( - self.queue_name.as_str(), - self.consumer_group.as_str(), - "0", - true, - ) + .get_or_try_init(|| async move { + let result = self + .redis_pool + .xgroup_create( + self.queue_name.as_str(), + self.consumer_group.as_str(), + "0", + true, + ) + .await; + + result.or_else(|err| { + if err.details().starts_with("BUSYGROUP") { + debug!( + recv_error = err.details(), + "Consumer group already exists, skipping creation", + ); + + Ok(()) + } else { + Err(err) + } + }) }) .await?; diff --git a/lib/cursiv/Cargo.toml b/lib/cursiv/Cargo.toml index efa3d3c28..2905310c2 100644 --- a/lib/cursiv/Cargo.toml +++ b/lib/cursiv/Cargo.toml @@ -14,7 +14,7 @@ http = "1.1.0" pin-project-lite = "0.2.14" rand = "0.8.5" tower = { version = "0.4.13", default-features = false } -triomphe = "0.1.11" +triomphe = { workspace = true } zeroize = { version = "1.7.0", features = ["derive"] } # `axum` feature diff --git a/lib/geomjeungja/Cargo.toml b/lib/geomjeungja/Cargo.toml index f9c299897..a4be16983 100644 --- a/lib/geomjeungja/Cargo.toml +++ b/lib/geomjeungja/Cargo.toml @@ -10,10 +10,10 @@ async-trait = "0.1.80" hickory-resolver = "0.24.1" rand = "0.8.5" serde = { version = "1.0.202", features = ["derive"] } -simdutf8 = { version = "0.1.4", features = ["aarch64_neon"] } +simdutf8 = { workspace = true } thiserror = "1.0.61" tracing = "0.1.40" -triomphe = { version = "0.1.11", features = ["unsize"] } +triomphe = { workspace = true } typed-builder = "0.18.2" unsize = "1.1.0" diff --git a/lib/http-signatures/Cargo.toml b/lib/http-signatures/Cargo.toml index 12bf1062c..464332521 100644 --- a/lib/http-signatures/Cargo.toml +++ b/lib/http-signatures/Cargo.toml @@ -20,19 +20,19 @@ path = "bin/parse_header.rs" [dependencies] atoi_radix10 = "0.0.1" base64-simd = "0.8.0" -blowocking = { path = "../blowocking", default-features = false, optional = true } +blowocking = { workspace = true, default-features = false, optional = true } const-oid = { version = "0.9.6", features = ["db"] } derive_builder = "0.20.0" http = "1.1.0" httpdate = "1.0.3" -itertools = { version = "0.13.0", default-features = false } +itertools = { workspace = true } logos = "0.14.0" miette = "7.2.0" pkcs8 = { version = "0.10.2", features = ["pem", "std"] } ring = { version = "0.17.8", features = ["std"] } scoped-futures = { version = "0.1.3", default-features = false } thiserror = "1.0.61" -tick-tock-mock = { path = "../tick-tock-mock" } +tick-tock-mock = { workspace = true } tracing = { version = "0.1.40", default-features = false, optional = true } [dev-dependencies] diff --git a/lib/mrf-tool/Cargo.toml b/lib/mrf-tool/Cargo.toml index 3d29787a6..947e84adb 100644 --- a/lib/mrf-tool/Cargo.toml +++ b/lib/mrf-tool/Cargo.toml @@ -7,9 +7,9 @@ version.workspace = true license = "MIT OR Apache-2.0" [dependencies] -clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +clap = { workspace = true } color-eyre = "0.6.3" -mrf-manifest = { path = "../mrf-manifest", features = [ +mrf-manifest = { workspace = true, features = [ "decode", "encode", "serialise", diff --git a/lib/speedy-uuid/Cargo.toml b/lib/speedy-uuid/Cargo.toml index 2eaed9914..65a5c2f31 100644 --- a/lib/speedy-uuid/Cargo.toml +++ b/lib/speedy-uuid/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] async-graphql = { version = "7.0.5", default-features = false, optional = true } -diesel = { version = "2.1.6", features = [ +diesel = { version = "2.1.6", default-features = false, features = [ "postgres_backend", "uuid", ], optional = true } diff --git a/lib/speedy-uuid/src/lib.rs b/lib/speedy-uuid/src/lib.rs index 58d0938e6..5351014c9 100644 --- a/lib/speedy-uuid/src/lib.rs +++ b/lib/speedy-uuid/src/lib.rs @@ -6,6 +6,9 @@ use std::{ use thiserror::Error; use uuid_simd::{format_hyphenated, AsciiCase, Out, UuidExt}; +#[cfg(feature = "diesel")] +use diesel::{deserialize::FromSqlRow, expression::AsExpression}; + pub use uuid; #[derive(Debug, Error)] @@ -17,7 +20,7 @@ pub enum Error { Uuid(#[from] uuid::Error), } -#[cfg_attr(feature = "diesel", derive(diesel::AsExpression, diesel::FromSqlRow))] +#[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))] #[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Uuid))] #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] #[repr(transparent)] diff --git a/lib/tower-x-clacks-overhead/Cargo.toml b/lib/tower-x-clacks-overhead/Cargo.toml index 9b0da103c..b5d12c447 100644 --- a/lib/tower-x-clacks-overhead/Cargo.toml +++ b/lib/tower-x-clacks-overhead/Cargo.toml @@ -7,11 +7,11 @@ license = "MIT OR Apache-2.0" [dependencies] http = "1.1.0" -itertools = { version = "0.13.0", default-features = false } +itertools = { workspace = true } pin-project-lite = "0.2.14" tower-layer = "0.3.2" tower-service = "0.3.2" -triomphe = "0.1.11" +triomphe = { workspace = true } [dev-dependencies] futures-test = "0.3.30"