Main coves client
1/// Utility functions for community handle formatting and resolution.
2///
3/// Coves communities use atProto handles in the format:
4/// - DNS format: `gaming.community.coves.social`
5/// - Display format: `!gaming@coves.social`
6class CommunityHandleUtils {
7 /// Converts a DNS-style community handle to display format
8 ///
9 /// Transforms `gaming.community.coves.social` → `!gaming@coves.social`
10 /// by removing the `.community.` segment
11 ///
12 /// Returns null if the handle is null or doesn't contain `.community.`
13 static String? formatHandleForDisplay(String? handle) {
14 if (handle == null || handle.isEmpty) {
15 return null;
16 }
17
18 // Expected format: name.community.instance.domain
19 // e.g., gaming.community.coves.social
20 final parts = handle.split('.');
21
22 // Must have at least 4 parts: [name, community, instance, domain]
23 if (parts.length < 4 || parts[1] != 'community') {
24 return null;
25 }
26
27 // Extract community name (first part)
28 final communityName = parts[0];
29
30 // Extract instance domain (everything after .community.)
31 final instanceDomain = parts.sublist(2).join('.');
32
33 // Format as !name@instance
34 return '!$communityName@$instanceDomain';
35 }
36
37 /// Converts a display-style community handle to DNS format
38 ///
39 /// Transforms `!gaming@coves.social` → `gaming.community.coves.social`
40 /// by inserting `.community.` between the name and instance
41 ///
42 /// Returns null if the handle is null or doesn't match expected format
43 static String? formatHandleForDNS(String? displayHandle) {
44 if (displayHandle == null || displayHandle.isEmpty) {
45 return null;
46 }
47
48 // Remove leading ! if present
49 final cleaned =
50 displayHandle.startsWith('!')
51 ? displayHandle.substring(1)
52 : displayHandle;
53
54 // Expected format: name@instance.domain
55 if (!cleaned.contains('@')) {
56 return null;
57 }
58
59 final parts = cleaned.split('@');
60 if (parts.length != 2) {
61 return null;
62 }
63
64 final communityName = parts[0];
65 final instanceDomain = parts[1];
66
67 // Format as name.community.instance.domain
68 return '$communityName.community.$instanceDomain';
69 }
70}