mod common; mod gitdata; mod kenshell; mod platform_events; mod properties; pub use common::{EventContext, action}; pub use properties::EventProperties; use serde_json::Value; use crate::EventKind; use crate::gateway::Subscription; /// 网关支持订阅的 (项目前缀, area, tag) 全集:本仓库事件来自 `EventKind`, /// kenshell 事件由对端仓库产生,这里是唯一的外来清单。 const KENSHELL: &[(&str, &str)] = &[ ("repo", "create"), ("repo", "update"), ("repo", "delete"), ("repo", "placement-change"), ("repo", "language-update"), ("ref", "create-branch"), ("ref", "update-branch"), ("ref", "delete-branch"), ("ref", "rename-branch"), ("ref", "set-default-branch"), ("ref", "create-tag"), ("ref", "delete-tag"), ("ref", "create-protection"), ("ref", "delete-protection"), ("commit", "sync"), ("commit", "set-status"), ("commit", "comment-create"), ("commit", "comment-update"), ("commit", "comment-delete"), ("lfs", "upload"), ("lfs", "unreference"), ("lfs", "purge"), ("archive", "create"), ("job", "enqueue"), ("job", "claim"), ("job", "progress"), ("job", "heartbeat"), ("job", "cancel"), ("job", "retry"), ("job", "finish"), ("node", "create"), ("node", "update"), ("node", "delete"), ("node", "probe"), ("volume", "create"), ("volume", "update"), ("volume", "delete"), ("volume", "mount"), ("volume", "unmount"), ("volume", "probe"), ]; pub(crate) fn catalog() -> impl Iterator { EventKind::ALL .iter() .flat_map(|kind| { kind.tags() .iter() .map(move |tag| ("gitdata", kind.topic(), *tag)) }) .chain(KENSHELL.iter().map(|(area, tag)| ("kenshell", *area, *tag))) } pub(crate) fn split_topic(topic: &str) -> Option<(&str, &str)> { config::event::consumer::DEFAULT_TOPIC_PREFIXES .iter() .find_map(|prefix| { topic .strip_prefix(prefix) .and_then(|rest| rest.strip_prefix('-')) .map(|area| (*prefix, area)) }) } pub(crate) fn identity_area(area: &str) -> bool { EventKind::ALL .iter() .any(|kind| kind.topic() == area && kind.identity()) } pub(crate) fn personal(area: &str, tag: &str) -> bool { EventKind::ALL .iter() .any(|kind| kind.topic() == area && kind.personal() && kind.tags().contains(&tag)) } /// 与 MQ 扇出一致的下行 payload 形状(可选附带命中的订阅列表)。 pub fn common_payload( topic: &str, tag: &str, event_user_id: Option, recipient_user_id: i64, properties: &EventProperties, body: &Value, destinations: Option>, ) -> Value { let mut value = serde_json::json!({ "topic": topic, "tag": tag, "user_id": event_user_id, "recipient_user_id": recipient_user_id, "properties": properties, "body": body, }); if let Some(destinations) = destinations { if let Ok(value_destinations) = serde_json::to_value(destinations) { value["destinations"] = value_destinations; } } value } /// topic/tag 是否属于本网关支持的事件族(平台定向投递与订阅校验共用)。 pub fn is_supported(topic: &str, tag: &str) -> bool { gitdata::is_supported(topic, tag) || kenshell::is_supported(topic, tag) || platform_events::is_supported(topic, tag) } pub fn is_personal_topic(topic: &str, tag: &str) -> bool { crate::gateway::is_personal(topic, tag) }