···2020api_bluesky = ["api", "jacquard-api/bluesky"]
2121# Bluesky API bindings, plus a curated selection of community lexicons
2222api_full = [
2323- "api",
2424- "jacquard-api/bluesky",
2323+ "api_bluesky",
2524 "jacquard-api/other",
2625 "jacquard-api/lexicon_community",
2726]
+1-1
crates/jacquard/src/moderation.rs
···38383939pub use decision::{ModerationIterExt, moderate, moderate_all};
4040#[cfg(feature = "api_bluesky")]
4141-pub use fetch::fetch_labeler_defs;
4141+pub use fetch::{fetch_labeler_defs, fetch_labeler_defs_direct};
4242pub use labeled::Labeled;
4343pub use moderatable::Moderateable;
4444pub use types::{
+55
crates/jacquard/src/moderation/fetch.rs
···11use super::LabelerDefs;
22+use crate::client::AgentSessionExt;
23use jacquard_api::app_bsky::labeler::get_services::{GetServices, GetServicesOutput};
44+use jacquard_api::app_bsky::labeler::service::Service;
35use jacquard_common::IntoStatic;
46use jacquard_common::error::ClientError;
57use jacquard_common::types::string::Did;
···77797880 Ok(defs)
7981}
8282+8383+/// Fetch labeler definitions directly from each labeler's PDS
8484+///
8585+/// This fetches the `app.bsky.labeler.service` record directly from the PDS where
8686+/// the labeler is hosted.
8787+///
8888+/// # Arguments
8989+///
9090+/// * `client` - Any XRPC client with fetch_record support (Agent, etc.)
9191+/// * `dids` - List of labeler DIDs to fetch definitions for
9292+///
9393+/// # Example
9494+///
9595+/// ```no_run
9696+/// # use jacquard::moderation::fetch_labeler_defs_direct;
9797+/// # use jacquard::client::BasicClient;
9898+/// # use jacquard::prelude::*;
9999+/// # use jacquard_common::types::string::Did;
100100+/// # #[tokio::main]
101101+/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
102102+/// # let client = BasicClient::unauthenticated();
103103+/// let labeler_did = Did::new_static("did:plc:ar7c4by46qjdydhdevvrndac").unwrap();
104104+/// let defs = fetch_labeler_defs_direct(&client, vec![labeler_did]).await?;
105105+/// # Ok(())
106106+/// # }
107107+/// ```
108108+pub async fn fetch_labeler_defs_direct(
109109+ client: &(impl AgentSessionExt + Sync),
110110+ dids: Vec<Did<'_>>,
111111+) -> Result<LabelerDefs<'static>, ClientError> {
112112+ #[cfg(feature = "tracing")]
113113+ let _span = tracing::debug_span!("fetch_labeler_defs_direct", count = dids.len()).entered();
114114+115115+ let mut defs = LabelerDefs::new();
116116+117117+ for did in dids {
118118+ let uri = format!("at://{}/app.bsky.labeler.service/self", did.as_str());
119119+ let record_uri = Service::uri(uri).map_err(|e| {
120120+ ClientError::Transport(jacquard_common::error::TransportError::Other(
121121+ format!("Invalid URI: {}", e).into(),
122122+ ))
123123+ })?;
124124+125125+ let output = client.fetch_record(&record_uri).await?;
126126+ let service: Service<'static> = output.value;
127127+128128+ if let Some(label_value_definitions) = service.policies.label_value_definitions {
129129+ defs.insert(did.into_static(), label_value_definitions);
130130+ }
131131+ }
132132+133133+ Ok(defs)
134134+}
+1-1
justfile
···7788# Check that jacquard-common compiles for wasm32
99check-wasm:
1010- cargo build --target wasm32-unknown-unknown -p jacquard-common --no-default-features --features websocket
1010+ cargo build --target wasm32-unknown-unknown -p jacquard-common --features websocket
11111212# Run 'cargo run' on the project
1313run *ARGS: