diff --git a/atrium-api/src/agent.rs b/atrium-api/src/agent.rs index 831acd10..3d003986 100644 --- a/atrium-api/src/agent.rs +++ b/atrium-api/src/agent.rs @@ -220,10 +220,12 @@ mod tests { body.extend(serde_json::to_vec( &crate::com::atproto::server::refresh_session::Output { access_jwt: String::from("access"), + active: None, did: "did:web:example.com".parse().expect("valid"), did_doc: None, handle: "example.com".parse().expect("valid"), refresh_jwt: String::from("refresh"), + status: None, }, )?); } @@ -267,6 +269,7 @@ mod tests { fn session() -> Session { Session { access_jwt: String::from("access"), + active: None, did: "did:web:example.com".parse().expect("valid"), did_doc: None, email: None, @@ -274,6 +277,7 @@ mod tests { email_confirmed: None, handle: "example.com".parse().expect("valid"), refresh_jwt: String::from("refresh"), + status: None, } } @@ -330,12 +334,14 @@ mod tests { let client = MockClient { responses: MockResponses { get_session: Some(crate::com::atproto::server::get_session::Output { + active: session.active.clone(), did: session.did.clone(), did_doc: session.did_doc.clone(), email: session.email.clone(), email_auth_factor: session.email_auth_factor, email_confirmed: session.email_confirmed, handle: session.handle.clone(), + status: session.status.clone(), }), ..Default::default() }, @@ -362,12 +368,14 @@ mod tests { let client = MockClient { responses: MockResponses { get_session: Some(crate::com::atproto::server::get_session::Output { + active: session.active.clone(), did: session.did.clone(), did_doc: session.did_doc.clone(), email: session.email.clone(), email_auth_factor: session.email_auth_factor, email_confirmed: session.email_confirmed, handle: session.handle.clone(), + status: session.status.clone(), }), ..Default::default() }, @@ -402,12 +410,14 @@ mod tests { let client = MockClient { responses: MockResponses { get_session: Some(crate::com::atproto::server::get_session::Output { + active: session.active.clone(), did: session.did.clone(), did_doc: session.did_doc.clone(), email: session.email.clone(), email_auth_factor: session.email_auth_factor, email_confirmed: session.email_confirmed, handle: session.handle.clone(), + status: session.status.clone(), }), ..Default::default() }, @@ -455,12 +465,14 @@ mod tests { let client = MockClient { responses: MockResponses { get_session: Some(crate::com::atproto::server::get_session::Output { + active: session.active.clone(), did: session.did.clone(), did_doc: session.did_doc.clone(), email: session.email.clone(), email_auth_factor: session.email_auth_factor, email_confirmed: session.email_confirmed, handle: session.handle.clone(), + status: session.status.clone(), }), ..Default::default() }, @@ -502,12 +514,14 @@ mod tests { let client = MockClient { responses: MockResponses { get_session: Some(crate::com::atproto::server::get_session::Output { + active: session.active.clone(), did: session.did.clone(), did_doc: session.did_doc.clone(), email: session.email.clone(), email_auth_factor: session.email_auth_factor, email_confirmed: session.email_confirmed, handle: session.handle.clone(), + status: session.status.clone(), }), ..Default::default() }, diff --git a/atrium-api/src/app/bsky/actor/defs.rs b/atrium-api/src/app/bsky/actor/defs.rs index cddd5990..c7052b24 100644 --- a/atrium-api/src/app/bsky/actor/defs.rs +++ b/atrium-api/src/app/bsky/actor/defs.rs @@ -47,6 +47,13 @@ pub struct InterestsPref { ///A list of tags which describe the account owner's interests gathered during onboarding. pub tags: Vec, } +///The subject's followers whom you also follow +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct KnownFollowers { + pub count: i64, + pub followers: Vec, +} #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct LabelerPrefItem { @@ -208,6 +215,8 @@ pub struct ViewerState { #[serde(skip_serializing_if = "Option::is_none")] pub following: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub known_followers: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub muted: Option, #[serde(skip_serializing_if = "Option::is_none")] pub muted_by_list: Option, diff --git a/atrium-api/src/app/bsky/feed/defs.rs b/atrium-api/src/app/bsky/feed/defs.rs index df2d63b6..825f2fba 100644 --- a/atrium-api/src/app/bsky/feed/defs.rs +++ b/atrium-api/src/app/bsky/feed/defs.rs @@ -181,6 +181,8 @@ pub struct ViewerState { pub reply_disabled: Option, #[serde(skip_serializing_if = "Option::is_none")] pub repost: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub thread_muted: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "$type")] diff --git a/atrium-api/src/app/bsky/graph.rs b/atrium-api/src/app/bsky/graph.rs index c972bc77..a1276105 100644 --- a/atrium-api/src/app/bsky/graph.rs +++ b/atrium-api/src/app/bsky/graph.rs @@ -6,6 +6,7 @@ pub mod follow; pub mod get_blocks; pub mod get_followers; pub mod get_follows; +pub mod get_known_followers; pub mod get_list; pub mod get_list_blocks; pub mod get_list_mutes; @@ -18,8 +19,10 @@ pub mod listblock; pub mod listitem; pub mod mute_actor; pub mod mute_actor_list; +pub mod mute_thread; pub mod unmute_actor; pub mod unmute_actor_list; +pub mod unmute_thread; #[derive(Debug)] pub struct Block; impl crate::types::Collection for Block { diff --git a/atrium-api/src/app/bsky/graph/get_known_followers.rs b/atrium-api/src/app/bsky/graph/get_known_followers.rs new file mode 100644 index 00000000..c525e109 --- /dev/null +++ b/atrium-api/src/app/bsky/graph/get_known_followers.rs @@ -0,0 +1,28 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `app.bsky.graph.getKnownFollowers` namespace. +pub const NSID: &str = "app.bsky.graph.getKnownFollowers"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Parameters { + pub actor: crate::types::string::AtIdentifier, + #[serde(skip_serializing_if = "Option::is_none")] + pub cursor: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub limit: Option>, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Output { + #[serde(skip_serializing_if = "Option::is_none")] + pub cursor: Option, + pub followers: Vec, + pub subject: crate::app::bsky::actor::defs::ProfileView, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error {} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} diff --git a/atrium-api/src/app/bsky/graph/mute_thread.rs b/atrium-api/src/app/bsky/graph/mute_thread.rs new file mode 100644 index 00000000..2ff7d900 --- /dev/null +++ b/atrium-api/src/app/bsky/graph/mute_thread.rs @@ -0,0 +1,16 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `app.bsky.graph.muteThread` namespace. +pub const NSID: &str = "app.bsky.graph.muteThread"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Input { + pub root: String, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error {} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} diff --git a/atrium-api/src/app/bsky/graph/unmute_thread.rs b/atrium-api/src/app/bsky/graph/unmute_thread.rs new file mode 100644 index 00000000..f0212d51 --- /dev/null +++ b/atrium-api/src/app/bsky/graph/unmute_thread.rs @@ -0,0 +1,16 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `app.bsky.graph.unmuteThread` namespace. +pub const NSID: &str = "app.bsky.graph.unmuteThread"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Input { + pub root: String, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error {} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} diff --git a/atrium-api/src/chat/bsky/convo/defs.rs b/atrium-api/src/chat/bsky/convo/defs.rs index 4cac98a6..6f7c8376 100644 --- a/atrium-api/src/chat/bsky/convo/defs.rs +++ b/atrium-api/src/chat/bsky/convo/defs.rs @@ -114,6 +114,6 @@ pub enum MessageInputEmbedRefs { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "$type")] pub enum MessageViewEmbedRefs { - #[serde(rename = "app.bsky.embed.record")] - AppBskyEmbedRecordMain(Box), + #[serde(rename = "app.bsky.embed.record#view")] + AppBskyEmbedRecordView(Box), } diff --git a/atrium-api/src/client.rs b/atrium-api/src/client.rs index 5bbda15c..5ac2172e 100644 --- a/atrium-api/src/client.rs +++ b/atrium-api/src/client.rs @@ -275,6 +275,7 @@ pub mod tools { { pub communication: communication::Service, pub moderation: moderation::Service, + pub server: server::Service, pub(crate) _phantom: core::marker::PhantomData, } pub mod communication { @@ -295,6 +296,15 @@ pub mod tools { pub(crate) _phantom: core::marker::PhantomData, } } + pub mod server { + pub struct Service + where + T: atrium_xrpc::XrpcClient + Send + Sync, + { + pub(crate) xrpc: std::sync::Arc, + pub(crate) _phantom: core::marker::PhantomData, + } + } } } impl self::Service @@ -1189,6 +1199,36 @@ where _ => Err(atrium_xrpc::Error::UnexpectedResponseType), } } + ///Enumerates accounts which follow a specified account (actor) and are followed by the viewer. + pub async fn get_known_followers( + &self, + params: crate::app::bsky::graph::get_known_followers::Parameters, + ) -> atrium_xrpc::Result< + crate::app::bsky::graph::get_known_followers::Output, + crate::app::bsky::graph::get_known_followers::Error, + > { + let response = self + .xrpc + .send_xrpc::< + _, + (), + _, + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::GET, + nsid: crate::app::bsky::graph::get_known_followers::NSID.into(), + parameters: Some(params), + input: None, + encoding: None, + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Data(data) => Ok(data), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } ///Gets a 'view' (with additional context) of a specified list. pub async fn get_list( &self, @@ -1454,6 +1494,33 @@ where _ => Err(atrium_xrpc::Error::UnexpectedResponseType), } } + ///Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Bluesky. Requires auth. + pub async fn mute_thread( + &self, + input: crate::app::bsky::graph::mute_thread::Input, + ) -> atrium_xrpc::Result<(), crate::app::bsky::graph::mute_thread::Error> { + let response = self + .xrpc + .send_xrpc::< + (), + _, + (), + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::POST, + nsid: crate::app::bsky::graph::mute_thread::NSID.into(), + parameters: None, + input: Some(atrium_xrpc::InputDataOrBytes::Data(input)), + encoding: Some(String::from("application/json")), + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Bytes(_) => Ok(()), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } ///Unmutes the specified account. Requires auth. pub async fn unmute_actor( &self, @@ -1508,6 +1575,33 @@ where _ => Err(atrium_xrpc::Error::UnexpectedResponseType), } } + ///Unmutes the specified thread. Requires auth. + pub async fn unmute_thread( + &self, + input: crate::app::bsky::graph::unmute_thread::Input, + ) -> atrium_xrpc::Result<(), crate::app::bsky::graph::unmute_thread::Error> { + let response = self + .xrpc + .send_xrpc::< + (), + _, + (), + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::POST, + nsid: crate::app::bsky::graph::unmute_thread::NSID.into(), + parameters: None, + input: Some(atrium_xrpc::InputDataOrBytes::Data(input)), + encoding: Some(String::from("application/json")), + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Bytes(_) => Ok(()), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } } #[cfg(feature = "namespace-appbsky")] impl app::bsky::labeler::Service @@ -2693,6 +2787,36 @@ where _ => Err(atrium_xrpc::Error::UnexpectedResponseType), } } + ///Get list of accounts that matches your search query. + pub async fn search_accounts( + &self, + params: crate::com::atproto::admin::search_accounts::Parameters, + ) -> atrium_xrpc::Result< + crate::com::atproto::admin::search_accounts::Output, + crate::com::atproto::admin::search_accounts::Error, + > { + let response = self + .xrpc + .send_xrpc::< + _, + (), + _, + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::GET, + nsid: crate::com::atproto::admin::search_accounts::NSID.into(), + parameters: Some(params), + input: None, + encoding: None, + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Data(data) => Ok(data), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } ///Send email to a user's account email address. pub async fn send_email( &self, @@ -4366,6 +4490,36 @@ where _ => Err(atrium_xrpc::Error::UnexpectedResponseType), } } + ///Get the hosting status for a repository, on this server. Expected to be implemented by PDS and Relay. + pub async fn get_repo_status( + &self, + params: crate::com::atproto::sync::get_repo_status::Parameters, + ) -> atrium_xrpc::Result< + crate::com::atproto::sync::get_repo_status::Output, + crate::com::atproto::sync::get_repo_status::Error, + > { + let response = self + .xrpc + .send_xrpc::< + _, + (), + _, + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::GET, + nsid: crate::com::atproto::sync::get_repo_status::NSID.into(), + parameters: Some(params), + input: None, + encoding: None, + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Data(data) => Ok(data), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } ///List blob CIDso for an account, since some repo revision. Does not require auth; implemented by PDS. pub async fn list_blobs( &self, @@ -4610,6 +4764,7 @@ where moderation: tools::ozone::moderation::Service::new( std::sync::Arc::clone(&xrpc), ), + server: tools::ozone::server::Service::new(std::sync::Arc::clone(&xrpc)), _phantom: core::marker::PhantomData, } } @@ -4973,3 +5128,45 @@ where } } } +#[cfg(feature = "namespace-toolsozone")] +impl tools::ozone::server::Service +where + T: atrium_xrpc::XrpcClient + Send + Sync, +{ + #[allow(unused_variables)] + pub(crate) fn new(xrpc: std::sync::Arc) -> Self { + Self { + xrpc, + _phantom: core::marker::PhantomData, + } + } + ///Get details about ozone's server configuration. + pub async fn get_config( + &self, + ) -> atrium_xrpc::Result< + crate::tools::ozone::server::get_config::Output, + crate::tools::ozone::server::get_config::Error, + > { + let response = self + .xrpc + .send_xrpc::< + (), + (), + _, + _, + >( + &atrium_xrpc::XrpcRequest { + method: http::Method::GET, + nsid: crate::tools::ozone::server::get_config::NSID.into(), + parameters: None, + input: None, + encoding: None, + }, + ) + .await?; + match response { + atrium_xrpc::OutputDataOrBytes::Data(data) => Ok(data), + _ => Err(atrium_xrpc::Error::UnexpectedResponseType), + } + } +} diff --git a/atrium-api/src/com/atproto/admin.rs b/atrium-api/src/com/atproto/admin.rs index e6e8216e..a91b0b87 100644 --- a/atrium-api/src/com/atproto/admin.rs +++ b/atrium-api/src/com/atproto/admin.rs @@ -9,6 +9,7 @@ pub mod get_account_info; pub mod get_account_infos; pub mod get_invite_codes; pub mod get_subject_status; +pub mod search_accounts; pub mod send_email; pub mod update_account_email; pub mod update_account_handle; diff --git a/atrium-api/src/com/atproto/admin/defs.rs b/atrium-api/src/com/atproto/admin/defs.rs index bab5279a..0ad2f6b5 100644 --- a/atrium-api/src/com/atproto/admin/defs.rs +++ b/atrium-api/src/com/atproto/admin/defs.rs @@ -3,6 +3,8 @@ #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AccountView { + #[serde(skip_serializing_if = "Option::is_none")] + pub deactivated_at: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub email: Option, diff --git a/atrium-api/src/com/atproto/admin/get_subject_status.rs b/atrium-api/src/com/atproto/admin/get_subject_status.rs index feb9d31d..e32dd291 100644 --- a/atrium-api/src/com/atproto/admin/get_subject_status.rs +++ b/atrium-api/src/com/atproto/admin/get_subject_status.rs @@ -14,6 +14,8 @@ pub struct Parameters { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Output { + #[serde(skip_serializing_if = "Option::is_none")] + pub deactivated: Option, pub subject: crate::types::Union, #[serde(skip_serializing_if = "Option::is_none")] pub takedown: Option, diff --git a/atrium-api/src/com/atproto/admin/search_accounts.rs b/atrium-api/src/com/atproto/admin/search_accounts.rs new file mode 100644 index 00000000..f22ca2b6 --- /dev/null +++ b/atrium-api/src/com/atproto/admin/search_accounts.rs @@ -0,0 +1,28 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `com.atproto.admin.searchAccounts` namespace. +pub const NSID: &str = "com.atproto.admin.searchAccounts"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Parameters { + #[serde(skip_serializing_if = "Option::is_none")] + pub cursor: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub email: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub limit: Option>, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Output { + pub accounts: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + pub cursor: Option, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error {} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} diff --git a/atrium-api/src/com/atproto/admin/update_subject_status.rs b/atrium-api/src/com/atproto/admin/update_subject_status.rs index 3a3184d0..6815b56e 100644 --- a/atrium-api/src/com/atproto/admin/update_subject_status.rs +++ b/atrium-api/src/com/atproto/admin/update_subject_status.rs @@ -4,6 +4,8 @@ pub const NSID: &str = "com.atproto.admin.updateSubjectStatus"; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Input { + #[serde(skip_serializing_if = "Option::is_none")] + pub deactivated: Option, pub subject: crate::types::Union, #[serde(skip_serializing_if = "Option::is_none")] pub takedown: Option, diff --git a/atrium-api/src/com/atproto/server/create_app_password.rs b/atrium-api/src/com/atproto/server/create_app_password.rs index c676fbc6..97663bc4 100644 --- a/atrium-api/src/com/atproto/server/create_app_password.rs +++ b/atrium-api/src/com/atproto/server/create_app_password.rs @@ -6,6 +6,9 @@ pub const NSID: &str = "com.atproto.server.createAppPassword"; pub struct Input { ///A short name for the App Password, to help distinguish them. pub name: String, + ///If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients. + #[serde(skip_serializing_if = "Option::is_none")] + pub privileged: Option, } pub type Output = AppPassword; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] @@ -32,4 +35,6 @@ pub struct AppPassword { pub created_at: crate::types::string::Datetime, pub name: String, pub password: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub privileged: Option, } diff --git a/atrium-api/src/com/atproto/server/create_session.rs b/atrium-api/src/com/atproto/server/create_session.rs index 9667c82f..c6ff499d 100644 --- a/atrium-api/src/com/atproto/server/create_session.rs +++ b/atrium-api/src/com/atproto/server/create_session.rs @@ -14,6 +14,8 @@ pub struct Input { #[serde(rename_all = "camelCase")] pub struct Output { pub access_jwt: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub active: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub did_doc: Option, @@ -25,6 +27,9 @@ pub struct Output { pub email_confirmed: Option, pub handle: crate::types::string::Handle, pub refresh_jwt: String, + ///If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] diff --git a/atrium-api/src/com/atproto/server/get_session.rs b/atrium-api/src/com/atproto/server/get_session.rs index d1453ccd..45d62788 100644 --- a/atrium-api/src/com/atproto/server/get_session.rs +++ b/atrium-api/src/com/atproto/server/get_session.rs @@ -4,6 +4,8 @@ pub const NSID: &str = "com.atproto.server.getSession"; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Output { + #[serde(skip_serializing_if = "Option::is_none")] + pub active: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub did_doc: Option, @@ -14,6 +16,9 @@ pub struct Output { #[serde(skip_serializing_if = "Option::is_none")] pub email_confirmed: Option, pub handle: crate::types::string::Handle, + ///If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] diff --git a/atrium-api/src/com/atproto/server/list_app_passwords.rs b/atrium-api/src/com/atproto/server/list_app_passwords.rs index 139dea6b..7778af05 100644 --- a/atrium-api/src/com/atproto/server/list_app_passwords.rs +++ b/atrium-api/src/com/atproto/server/list_app_passwords.rs @@ -29,4 +29,6 @@ impl std::fmt::Display for Error { pub struct AppPassword { pub created_at: crate::types::string::Datetime, pub name: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub privileged: Option, } diff --git a/atrium-api/src/com/atproto/server/refresh_session.rs b/atrium-api/src/com/atproto/server/refresh_session.rs index ab860377..c932cd25 100644 --- a/atrium-api/src/com/atproto/server/refresh_session.rs +++ b/atrium-api/src/com/atproto/server/refresh_session.rs @@ -5,11 +5,16 @@ pub const NSID: &str = "com.atproto.server.refreshSession"; #[serde(rename_all = "camelCase")] pub struct Output { pub access_jwt: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub active: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub did_doc: Option, pub handle: crate::types::string::Handle, pub refresh_jwt: String, + ///Hosting status of the account. If not specified, then assume 'active'. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] diff --git a/atrium-api/src/com/atproto/sync.rs b/atrium-api/src/com/atproto/sync.rs index 83e4c3c4..b5eb1cae 100644 --- a/atrium-api/src/com/atproto/sync.rs +++ b/atrium-api/src/com/atproto/sync.rs @@ -7,6 +7,7 @@ pub mod get_head; pub mod get_latest_commit; pub mod get_record; pub mod get_repo; +pub mod get_repo_status; pub mod list_blobs; pub mod list_repos; pub mod notify_of_update; diff --git a/atrium-api/src/com/atproto/sync/get_blob.rs b/atrium-api/src/com/atproto/sync/get_blob.rs index f3d76eb1..95cbdab1 100644 --- a/atrium-api/src/com/atproto/sync/get_blob.rs +++ b/atrium-api/src/com/atproto/sync/get_blob.rs @@ -11,9 +11,47 @@ pub struct Parameters { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] -pub enum Error {} +pub enum Error { + BlobNotFound(Option), + RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), +} impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::BlobNotFound(msg) => { + write!(_f, "BlobNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } Ok(()) } } diff --git a/atrium-api/src/com/atproto/sync/get_blocks.rs b/atrium-api/src/com/atproto/sync/get_blocks.rs index a79a63bc..3879c352 100644 --- a/atrium-api/src/com/atproto/sync/get_blocks.rs +++ b/atrium-api/src/com/atproto/sync/get_blocks.rs @@ -10,9 +10,47 @@ pub struct Parameters { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] -pub enum Error {} +pub enum Error { + BlockNotFound(Option), + RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), +} impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::BlockNotFound(msg) => { + write!(_f, "BlockNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } Ok(()) } } diff --git a/atrium-api/src/com/atproto/sync/get_latest_commit.rs b/atrium-api/src/com/atproto/sync/get_latest_commit.rs index fb32d897..746b7087 100644 --- a/atrium-api/src/com/atproto/sync/get_latest_commit.rs +++ b/atrium-api/src/com/atproto/sync/get_latest_commit.rs @@ -17,6 +17,9 @@ pub struct Output { #[serde(tag = "error", content = "message")] pub enum Error { RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), } impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { @@ -27,6 +30,24 @@ impl std::fmt::Display for Error { write!(_f, ": {msg}")?; } } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } } Ok(()) } diff --git a/atrium-api/src/com/atproto/sync/get_record.rs b/atrium-api/src/com/atproto/sync/get_record.rs index d92bab2e..e6b1abb2 100644 --- a/atrium-api/src/com/atproto/sync/get_record.rs +++ b/atrium-api/src/com/atproto/sync/get_record.rs @@ -15,9 +15,47 @@ pub struct Parameters { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] -pub enum Error {} +pub enum Error { + RecordNotFound(Option), + RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), +} impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::RecordNotFound(msg) => { + write!(_f, "RecordNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } Ok(()) } } diff --git a/atrium-api/src/com/atproto/sync/get_repo.rs b/atrium-api/src/com/atproto/sync/get_repo.rs index 34b54dd2..41076d68 100644 --- a/atrium-api/src/com/atproto/sync/get_repo.rs +++ b/atrium-api/src/com/atproto/sync/get_repo.rs @@ -12,9 +12,40 @@ pub struct Parameters { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] -pub enum Error {} +pub enum Error { + RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), +} impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } Ok(()) } } diff --git a/atrium-api/src/com/atproto/sync/get_repo_status.rs b/atrium-api/src/com/atproto/sync/get_repo_status.rs new file mode 100644 index 00000000..b8e2af84 --- /dev/null +++ b/atrium-api/src/com/atproto/sync/get_repo_status.rs @@ -0,0 +1,39 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `com.atproto.sync.getRepoStatus` namespace. +pub const NSID: &str = "com.atproto.sync.getRepoStatus"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Parameters { + ///The DID of the repo. + pub did: crate::types::string::Did, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Output { + pub active: bool, + pub did: crate::types::string::Did, + ///Optional field, the current rev of the repo, if active=true + #[serde(skip_serializing_if = "Option::is_none")] + pub rev: Option, + ///If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error { + RepoNotFound(Option), +} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } + Ok(()) + } +} diff --git a/atrium-api/src/com/atproto/sync/list_blobs.rs b/atrium-api/src/com/atproto/sync/list_blobs.rs index e4ae49ed..c4b887e9 100644 --- a/atrium-api/src/com/atproto/sync/list_blobs.rs +++ b/atrium-api/src/com/atproto/sync/list_blobs.rs @@ -23,9 +23,40 @@ pub struct Output { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "error", content = "message")] -pub enum Error {} +pub enum Error { + RepoNotFound(Option), + RepoTakendown(Option), + RepoSuspended(Option), + RepoDeactivated(Option), +} impl std::fmt::Display for Error { fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::RepoNotFound(msg) => { + write!(_f, "RepoNotFound")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoTakendown(msg) => { + write!(_f, "RepoTakendown")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoSuspended(msg) => { + write!(_f, "RepoSuspended")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + Error::RepoDeactivated(msg) => { + write!(_f, "RepoDeactivated")?; + if let Some(msg) = msg { + write!(_f, ": {msg}")?; + } + } + } Ok(()) } } diff --git a/atrium-api/src/com/atproto/sync/list_repos.rs b/atrium-api/src/com/atproto/sync/list_repos.rs index 39914d7e..87bb14a8 100644 --- a/atrium-api/src/com/atproto/sync/list_repos.rs +++ b/atrium-api/src/com/atproto/sync/list_repos.rs @@ -27,8 +27,13 @@ impl std::fmt::Display for Error { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Repo { + #[serde(skip_serializing_if = "Option::is_none")] + pub active: Option, pub did: crate::types::string::Did, ///Current repo commit CID pub head: crate::types::string::Cid, pub rev: String, + ///If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, } diff --git a/atrium-api/src/com/atproto/sync/subscribe_repos.rs b/atrium-api/src/com/atproto/sync/subscribe_repos.rs index d01f1cc1..4d033307 100644 --- a/atrium-api/src/com/atproto/sync/subscribe_repos.rs +++ b/atrium-api/src/com/atproto/sync/subscribe_repos.rs @@ -34,6 +34,19 @@ impl std::fmt::Display for Error { Ok(()) } } +///Represents a change to an account's status on a host (eg, PDS or Relay). The semantics of this event are that the status is at the host which emitted the event, not necessarily that at the currently active PDS. Eg, a Relay takedown would emit a takedown with active=false, even if the PDS is still active. +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Account { + ///Indicates that the account has a repository which can be fetched from the host that emitted this event. + pub active: bool, + pub did: crate::types::string::Did, + pub seq: i64, + ///If active=false, this optional field indicates a reason for why the account is not active. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, + pub time: crate::types::string::Datetime, +} ///Represents an update of repository state. Note that empty commits are allowed, which include no repo data changes, but an update to rev and signature. #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] @@ -64,7 +77,7 @@ pub struct Commit { ///Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data. pub too_big: bool, } -///Represents an update of the account's handle, or transition to/from invalid state. NOTE: Will be deprecated in favor of #identity. +///DEPRECATED -- Use #identity event instead #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Handle { @@ -78,6 +91,9 @@ pub struct Handle { #[serde(rename_all = "camelCase")] pub struct Identity { pub did: crate::types::string::Did, + ///The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details. + #[serde(skip_serializing_if = "Option::is_none")] + pub handle: Option, pub seq: i64, pub time: crate::types::string::Datetime, } @@ -88,7 +104,7 @@ pub struct Info { pub message: Option, pub name: String, } -///Represents an account moving from one PDS instance to another. NOTE: not implemented; account migration uses #identity instead +///DEPRECATED -- Use #account event instead #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Migrate { @@ -108,7 +124,7 @@ pub struct RepoOp { pub cid: Option, pub path: String, } -///Indicates that an account has been deleted. NOTE: may be deprecated in favor of #identity or a future #account event +///DEPRECATED -- Use #account event instead #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Tombstone { @@ -123,6 +139,8 @@ pub enum Message { Commit(Box), #[serde(rename = "com.atproto.sync.subscribeRepos#identity")] Identity(Box), + #[serde(rename = "com.atproto.sync.subscribeRepos#account")] + Account(Box), #[serde(rename = "com.atproto.sync.subscribeRepos#handle")] Handle(Box), #[serde(rename = "com.atproto.sync.subscribeRepos#migrate")] diff --git a/atrium-api/src/tools/ozone.rs b/atrium-api/src/tools/ozone.rs index fb0ae973..07942ff6 100644 --- a/atrium-api/src/tools/ozone.rs +++ b/atrium-api/src/tools/ozone.rs @@ -2,3 +2,4 @@ //!Definitions for the `tools.ozone` namespace. pub mod communication; pub mod moderation; +pub mod server; diff --git a/atrium-api/src/tools/ozone/moderation/defs.rs b/atrium-api/src/tools/ozone/moderation/defs.rs index 54d42577..18ce24b7 100644 --- a/atrium-api/src/tools/ozone/moderation/defs.rs +++ b/atrium-api/src/tools/ozone/moderation/defs.rs @@ -219,6 +219,8 @@ pub struct RecordViewNotFound { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct RepoView { + #[serde(skip_serializing_if = "Option::is_none")] + pub deactivated_at: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub email: Option, @@ -236,6 +238,8 @@ pub struct RepoView { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct RepoViewDetail { + #[serde(skip_serializing_if = "Option::is_none")] + pub deactivated_at: Option, pub did: crate::types::string::Did, #[serde(skip_serializing_if = "Option::is_none")] pub email: Option, diff --git a/atrium-api/src/tools/ozone/server.rs b/atrium-api/src/tools/ozone/server.rs new file mode 100644 index 00000000..95909efb --- /dev/null +++ b/atrium-api/src/tools/ozone/server.rs @@ -0,0 +1,3 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `tools.ozone.server` namespace. +pub mod get_config; diff --git a/atrium-api/src/tools/ozone/server/get_config.rs b/atrium-api/src/tools/ozone/server/get_config.rs new file mode 100644 index 00000000..6f46bf7d --- /dev/null +++ b/atrium-api/src/tools/ozone/server/get_config.rs @@ -0,0 +1,37 @@ +// This file is generated by atrium-codegen. DO NOT EDIT. +//!Definitions for the `tools.ozone.server.getConfig` namespace. +pub const NSID: &str = "tools.ozone.server.getConfig"; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Output { + #[serde(skip_serializing_if = "Option::is_none")] + pub appview: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub blob_divert: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub chat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub pds: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub viewer: Option, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "error", content = "message")] +pub enum Error {} +impl std::fmt::Display for Error { + fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ServiceConfig { + #[serde(skip_serializing_if = "Option::is_none")] + pub url: Option, +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ViewerConfig { + #[serde(skip_serializing_if = "Option::is_none")] + pub role: Option, +} diff --git a/bsky-sdk/src/agent/builder.rs b/bsky-sdk/src/agent/builder.rs index 566f8c0c..67ebcf18 100644 --- a/bsky-sdk/src/agent/builder.rs +++ b/bsky-sdk/src/agent/builder.rs @@ -120,6 +120,7 @@ mod tests { fn session() -> Session { Session { access_jwt: String::new(), + active: None, did: "did:fake:handle.test".parse().expect("invalid did"), did_doc: None, email: None, @@ -127,6 +128,7 @@ mod tests { email_confirmed: None, handle: "handle.test".parse().expect("invalid handle"), refresh_jwt: String::new(), + status: None, } } diff --git a/bsky-sdk/src/moderation/tests/behaviors.rs b/bsky-sdk/src/moderation/tests/behaviors.rs index ee8b8d26..5f3468bb 100644 --- a/bsky-sdk/src/moderation/tests/behaviors.rs +++ b/bsky-sdk/src/moderation/tests/behaviors.rs @@ -116,6 +116,7 @@ impl TestUser { }, followed_by: None, following: None, + known_followers: None, muted: if def.muted || def.muted_by_list { Some(true) } else {