From d63c3db64b824891fb4174be1b083d759d05fec4 Mon Sep 17 00:00:00 2001 From: Christian van der Loo Date: Fri, 3 Jul 2026 20:34:19 -0400 Subject: [PATCH] add lexicons package --- Cargo.lock | 559 ++++++++++++++++++++++- Justfile | 8 + README.md | 10 + crates/lexicons/.gitignore | 2 + crates/lexicons/Cargo.toml | 11 + crates/lexicons/README.md | 3 + crates/lexicons/src/.gitkeep | 0 crates/server/Cargo.toml | 1 + lexicons/com/schedj/actor/profile.json | 72 ++- lexicons/com/schedj/book.json | 124 ++++- lexicons/com/schedj/getAvailability.json | 103 ++++- lexicons/com/schedj/meetingType.json | 38 -- 12 files changed, 826 insertions(+), 105 deletions(-) create mode 100644 crates/lexicons/.gitignore create mode 100644 crates/lexicons/Cargo.toml create mode 100644 crates/lexicons/README.md create mode 100644 crates/lexicons/src/.gitkeep delete mode 100644 lexicons/com/schedj/meetingType.json diff --git a/Cargo.lock b/Cargo.lock index b63988a..f2e0218 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -11,12 +26,73 @@ dependencies = [ "libc", ] +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atrium-api" +version = "0.25.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04c38c6bfc922a7950a13ad52f8d21bee77020b90e822364c7ec8625c4cd403" +dependencies = [ + "atrium-common", + "atrium-xrpc", + "chrono", + "http", + "ipld-core", + "langtag", + "regex", + "serde", + "serde_bytes", + "serde_json", + "thiserror 1.0.69", + "tokio", + "trait-variant", +] + +[[package]] +name = "atrium-common" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98466259d2e6189ddf3439b96432d5303668b4d51c2a78996934d981065550f3" +dependencies = [ + "dashmap", + "lru", + "moka", + "thiserror 1.0.69", + "tokio", + "trait-variant", + "web-time", +] + +[[package]] +name = "atrium-xrpc" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944b35cc08732d40ddbb3356be9e38d11aed4b4c40c33f5b0f235e0650eff296" +dependencies = [ + "http", + "serde", + "serde_html_form", + "serde_json", + "thiserror 1.0.69", + "trait-variant", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -75,6 +151,28 @@ dependencies = [ "tracing", ] +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base256emoji" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" +dependencies = [ + "const-str", + "match-lookup", +] + +[[package]] +name = "base45" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240e56f4d3c453c36faacb695c535a4d5f8c7d23dac175014f32eb0a71012a03" + [[package]] name = "base64" version = "0.22.1" @@ -142,12 +240,104 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cid" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a304f95f84d169a6f31c4d0a30d784643aaa0bbc9c1e449a2c23e963ec4971" +dependencies = [ + "multibase", + "multihash", + "serde", + "serde_bytes", + "unsigned-varint", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" + +[[package]] +name = "data-encoding-macro" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3259c913752a86488b501ed8680446a5ed2d5aeac6e596cb23ba3800768ea32c" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" +dependencies = [ + "data-encoding", + "syn", +] + [[package]] name = "displaydoc" version = "0.2.6" @@ -159,12 +349,45 @@ dependencies = [ "syn", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -189,6 +412,17 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-task" version = "0.3.32" @@ -202,6 +436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "slab", @@ -229,11 +464,45 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "http" version = "1.4.2" @@ -466,6 +735,27 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "ipld-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090f624976d72f0b0bb71b86d58dc16c15e069193067cb3a3a09d655246cbbda" +dependencies = [ + "cid", + "serde", + "serde_bytes", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -489,6 +779,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "langtag" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed60c85f254d6ae8450cec15eedd921efbc4d1bdf6fcf6202b9a58b403f6f805" +dependencies = [ + "serde", +] + +[[package]] +name = "lexicons" +version = "0.1.0" +dependencies = [ + "atrium-api", + "atrium-xrpc", + "http", + "serde", + "serde_json", +] + [[package]] name = "libc" version = "0.2.186" @@ -501,18 +811,47 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +[[package]] +name = "lru" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "match-lookup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "matchit" version = "0.8.4" @@ -542,6 +881,49 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "moka" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" +dependencies = [ + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "event-listener", + "futures-util", + "parking_lot", + "portable-atomic", + "smallvec", + "tagptr", + "uuid", +] + +[[package]] +name = "multibase" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0e4a371cbf1dfd666b658ba137763edb23c45beb43cfe369b5593cd6b437b6" +dependencies = [ + "base-x", + "base256emoji", + "base45", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "577c63b00ad74d57e8c9aa870b5fccebf2fd64a308a5aee9f1bb88e4aea19447" +dependencies = [ + "serde", + "unsigned-varint", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -557,6 +939,35 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -569,6 +980,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + [[package]] name = "potential_utf" version = "0.1.5" @@ -603,7 +1020,7 @@ dependencies = [ "calendar-provider", "chrono", "reqwest", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -615,7 +1032,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -627,7 +1044,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -644,7 +1061,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -665,7 +1082,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -700,6 +1117,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.9.4" @@ -729,6 +1152,44 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + [[package]] name = "reqwest" version = "0.12.28" @@ -840,9 +1301,16 @@ version = "0.1.0" dependencies = [ "axum", "chrono", + "lexicons", "tokio", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.228" @@ -853,6 +1321,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -873,6 +1351,19 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_html_form" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" +dependencies = [ + "form_urlencoded", + "indexmap", + "itoa", + "ryu", + "serde_core", +] + [[package]] name = "serde_json" version = "1.0.150" @@ -980,13 +1471,39 @@ dependencies = [ "syn", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1127,6 +1644,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -1139,6 +1667,12 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "untrusted" version = "0.9.0" @@ -1163,6 +1697,17 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "uuid" +version = "1.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "want" version = "0.3.1" diff --git a/Justfile b/Justfile index b8cacf6..6f04c52 100644 --- a/Justfile +++ b/Justfile @@ -1,2 +1,10 @@ dev: cargo watch -x run + +install-esquema: + cargo install esquema-cli --locked --git https://github.com/fatfingers23/esquema.git + +gen: + find ./crates/lexicons/src -type f ! -name .gitkeep -delete + esquema-cli generate local --lexdir ./lexicons/ --outdir ./crates/lexicons/src + cargo fmt --package lexicons diff --git a/README.md b/README.md index 69ff9f2..69f8009 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ An AT Protocol based app for scheduling events. +## Dependencies + +Esquema. Install below with: + +```bash +cargo install esquema-cli --locked --git https://github.com/fatfingers23/esquema.git +``` + +or with `just install-esquema`. + ## Backend Data needs to be stored on a backend for Schedj to work properly - it cannot be entirely on-protocol due to the sensitive nature of connecting to calendars and exposing scheduled meetings. This may change with permissioned data. diff --git a/crates/lexicons/.gitignore b/crates/lexicons/.gitignore new file mode 100644 index 0000000..98df09d --- /dev/null +++ b/crates/lexicons/.gitignore @@ -0,0 +1,2 @@ +src/**/* +!src/.gitkeep diff --git a/crates/lexicons/Cargo.toml b/crates/lexicons/Cargo.toml new file mode 100644 index 0000000..4359aa6 --- /dev/null +++ b/crates/lexicons/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "lexicons" +version = "0.1.0" +edition = "2024" + +[dependencies] +atrium-api = "0.25.8" +atrium-xrpc = "0.12.4" +http = "1.4.0" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.150" diff --git a/crates/lexicons/README.md b/crates/lexicons/README.md new file mode 100644 index 0000000..520c3d1 --- /dev/null +++ b/crates/lexicons/README.md @@ -0,0 +1,3 @@ +# lexicons + +This package is generated from the AT Protocol lexicons using Esquema. You can install esquema with `just install-esquema` and then generate this package with `just gen`. diff --git a/crates/lexicons/src/.gitkeep b/crates/lexicons/src/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index 36bac8f..6b2fcda 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" axum = "0.8.9" chrono = "0.4.45" tokio = { version = "1.52.3", features = ["macros", "rt-multi-thread"] } +lexicons = { path = "../lexicons" } diff --git a/lexicons/com/schedj/actor/profile.json b/lexicons/com/schedj/actor/profile.json index 855da2e..fb71ded 100644 --- a/lexicons/com/schedj/actor/profile.json +++ b/lexicons/com/schedj/actor/profile.json @@ -1,38 +1,60 @@ { + "lexicon": 1, + "id": "com.schedj.actor.profile", "defs": { "main": { - "description": "TODO: describe purpose of this schema", - "key": "any", + "type": "record", + "description": "Public scheduling profile for a Schedj user. Calendar credentials and private booking data are never stored in this record.", + "key": "literal:self", "record": { + "type": "object", + "required": [ + "displayName", + "timeZone", + "bookingEnabled", + "createdAt" + ], "properties": { - "avatar": { - "accept": ["image/png", "image/jpeg"], - "maxSize": 2000000, - "type": "blob" - }, - "createdAt": { - "format": "datetime", - "type": "string" + "displayName": { + "type": "string", + "minLength": 1, + "maxLength": 640, + "maxGraphemes": 64, + "description": "Name shown on the actor's public scheduling page." }, "description": { - "maxGraphemes": 300, + "type": "string", "maxLength": 3000, - "type": "string" + "maxGraphemes": 300, + "description": "Short public introduction or scheduling guidance." }, - "name": { - "description": "TODO: title name of record; can not be empty", - "maxGraphemes": 64, - "maxLength": 640, + "avatar": { + "type": "blob", + "accept": [ + "image/png", + "image/jpeg", + "image/webp" + ], + "maxSize": 2000000, + "description": "Public profile image." + }, + "timeZone": { + "type": "string", "minLength": 1, - "type": "string" + "maxLength": 100, + "description": "IANA timezone name used to evaluate the actor's local availability rules." + }, + "bookingEnabled": { + "type": "boolean", + "description": "Whether the actor is currently accepting public bookings." + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Time at which this profile record was created." } - }, - "required": ["name", "createdAt"], - "type": "object" - }, - "type": "record" + } + } } - }, - "id": "com.schedj.actor.profile", - "lexicon": 1 + } } diff --git a/lexicons/com/schedj/book.json b/lexicons/com/schedj/book.json index e397f16..88a2196 100644 --- a/lexicons/com/schedj/book.json +++ b/lexicons/com/schedj/book.json @@ -1,33 +1,127 @@ { + "lexicon": 1, + "id": "com.schedj.book", "defs": { "main": { - "description": "TODO: description of this API endpoint", + "type": "procedure", + "description": "Books an available time on an actor's connected calendar. Attendee details and booking results are private backend data and are not written to the ATProto repository.", "input": { "encoding": "application/json", "schema": { + "type": "object", + "required": [ + "actor", + "start", + "end", + "attendeeName", + "attendeeEmail", + "idempotencyKey" + ], "properties": { - "subject": { + "actor": { + "type": "string", "format": "at-identifier", - "type": "string" + "description": "DID or handle of the actor whose calendar is being booked." + }, + "start": { + "type": "string", + "format": "datetime", + "description": "Inclusive start of the requested booking." + }, + "end": { + "type": "string", + "format": "datetime", + "description": "Exclusive end of the requested booking." + }, + "attendeeName": { + "type": "string", + "minLength": 1, + "maxLength": 200, + "maxGraphemes": 100, + "description": "Name displayed to the calendar owner." + }, + "attendeeEmail": { + "type": "string", + "minLength": 3, + "maxLength": 320, + "description": "Email address used for the calendar invitation and booking updates." + }, + "attendeeTimeZone": { + "type": "string", + "minLength": 1, + "maxLength": 100, + "description": "Optional IANA timezone name for attendee-facing confirmations." + }, + "message": { + "type": "string", + "maxLength": 2000, + "maxGraphemes": 1000, + "description": "Optional private note from the attendee to the calendar owner." + }, + "idempotencyKey": { + "type": "string", + "minLength": 16, + "maxLength": 128, + "description": "Client-generated key used to safely retry this booking request." } - }, - "required": [ - "subject" - ], - "type": "object" + } } }, "output": { "encoding": "application/json", "schema": { - "properties": {}, - "required": [], - "type": "object" + "type": "object", + "required": [ + "bookingId", + "status", + "start", + "end", + "createdAt" + ], + "properties": { + "bookingId": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "Opaque backend identifier for the booking." + }, + "status": { + "type": "string", + "knownValues": [ + "pending", + "confirmed" + ], + "description": "Current state of the booking." + }, + "start": { + "type": "string", + "format": "datetime" + }, + "end": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } } }, - "type": "procedure" + "errors": [ + { + "name": "InvalidRequest", + "description": "The requested range or attendee details are invalid." + }, + { + "name": "SlotUnavailable", + "description": "The requested time is no longer available." + }, + { + "name": "CalendarUnavailable", + "description": "The actor's calendar connection is temporarily unavailable." + } + ] } - }, - "id": "com.schedj.book", - "lexicon": 1 + } } diff --git a/lexicons/com/schedj/getAvailability.json b/lexicons/com/schedj/getAvailability.json index 5d214c4..dee697c 100644 --- a/lexicons/com/schedj/getAvailability.json +++ b/lexicons/com/schedj/getAvailability.json @@ -1,33 +1,96 @@ { + "lexicon": 1, + "id": "com.schedj.getAvailability", "defs": { "main": { - "description": "TODO: basic API endpoint", + "type": "query", + "description": "Returns bookable slots for an actor within a bounded time range.", + "parameters": { + "type": "params", + "required": [ + "actor", + "start", + "end" + ], + "properties": { + "actor": { + "type": "string", + "format": "at-identifier", + "description": "DID or handle of the actor whose availability is requested." + }, + "start": { + "type": "string", + "format": "datetime", + "description": "Inclusive start of the requested range." + }, + "end": { + "type": "string", + "format": "datetime", + "description": "Exclusive end of the requested range." + }, + "durationMinutes": { + "type": "integer", + "minimum": 1, + "maximum": 1440, + "description": "Requested slot duration. The server default is used when omitted." + } + } + }, "output": { "encoding": "application/json", "schema": { - "properties": { - "number": { - "type": "integer" - } - }, + "type": "object", "required": [ - "number" + "slots", + "generatedAt" ], - "type": "object" + "properties": { + "slots": { + "type": "array", + "maxLength": 1000, + "items": { + "type": "ref", + "ref": "#availabilitySlot" + } + }, + "generatedAt": { + "type": "string", + "format": "datetime", + "description": "Time at which the availability result was calculated." + } + } } }, - "parameters": { - "properties": { - "maximum": { - "description": "maximum size of response", - "type": "integer" - } + "errors": [ + { + "name": "InvalidRequest", + "description": "The requested range or duration is invalid." }, - "type": "params" - }, - "type": "query" + { + "name": "CalendarUnavailable", + "description": "The actor's calendar connection is temporarily unavailable." + } + ] + }, + "availabilitySlot": { + "type": "object", + "description": "A half-open time range that may be submitted to com.schedj.book.", + "required": [ + "start", + "end" + ], + "properties": { + "start": { + "type": "string", + "format": "datetime", + "description": "Inclusive start of the available slot." + }, + "end": { + "type": "string", + "format": "datetime", + "description": "Exclusive end of the available slot." + } + } } - }, - "id": "com.schedj.getAvailability", - "lexicon": 1 + } } diff --git a/lexicons/com/schedj/meetingType.json b/lexicons/com/schedj/meetingType.json deleted file mode 100644 index a622f2f..0000000 --- a/lexicons/com/schedj/meetingType.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "defs": { - "main": { - "description": "TODO: describe purpose of this schema", - "key": "any", - "record": { - "properties": { - "avatar": { - "accept": ["image/png", "image/jpeg"], - "maxSize": 2000000, - "type": "blob" - }, - "createdAt": { - "format": "datetime", - "type": "string" - }, - "description": { - "maxGraphemes": 300, - "maxLength": 3000, - "type": "string" - }, - "name": { - "description": "TODO: title name of record; can not be empty", - "maxGraphemes": 64, - "maxLength": 640, - "minLength": 1, - "type": "string" - } - }, - "required": ["name", "createdAt"], - "type": "object" - }, - "type": "record" - } - }, - "id": "com.schedj.meetingType", - "lexicon": 1 -} -- 2.51.2