porting all github actions from bluesky-social/indigo to tangled CI
at main 2.2 kB view raw
1package syntax 2 3import ( 4 "errors" 5 "fmt" 6 "regexp" 7 "strings" 8) 9 10var ( 11 handleRegex = regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$`) 12 13 // special handle string constant indicating that handle resolution failed 14 HandleInvalid = Handle("handle.invalid") 15) 16 17// String type which represents a syntaxtually valid handle identifier, as would pass Lexicon syntax validation. 18// 19// Always use [ParseHandle] instead of wrapping strings directly, especially when working with input. 20// 21// Syntax specification: https://atproto.com/specs/handle 22type Handle string 23 24func ParseHandle(raw string) (Handle, error) { 25 if raw == "" { 26 return "", errors.New("expected handle, got empty string") 27 } 28 if len(raw) > 253 { 29 return "", errors.New("handle is too long (253 chars max)") 30 } 31 if !handleRegex.MatchString(raw) { 32 return "", fmt.Errorf("handle syntax didn't validate via regex: %s", raw) 33 } 34 return Handle(raw), nil 35} 36 37// Some top-level domains (TLDs) are disallowed for registration across the atproto ecosystem. The *syntax* is valid, but these should never be considered acceptable handles for account registration or linking. 38// 39// The reserved '.test' TLD is allowed, for testing and development. It is expected that '.test' domain resolution will fail in a real-world network. 40func (h Handle) AllowedTLD() bool { 41 switch h.TLD() { 42 case "local", 43 "arpa", 44 "invalid", 45 "localhost", 46 "internal", 47 "example", 48 "onion", 49 "alt": 50 return false 51 } 52 return true 53} 54 55func (h Handle) TLD() string { 56 parts := strings.Split(string(h.Normalize()), ".") 57 return parts[len(parts)-1] 58} 59 60// Is this the special "handle.invalid" handle? 61func (h Handle) IsInvalidHandle() bool { 62 return h.Normalize() == HandleInvalid 63} 64 65func (h Handle) Normalize() Handle { 66 return Handle(strings.ToLower(string(h))) 67} 68 69func (h Handle) AtIdentifier() AtIdentifier { 70 return AtIdentifier{Inner: h} 71} 72 73func (h Handle) String() string { 74 return string(h) 75} 76 77func (h Handle) MarshalText() ([]byte, error) { 78 return []byte(h.String()), nil 79} 80 81func (h *Handle) UnmarshalText(text []byte) error { 82 handle, err := ParseHandle(string(text)) 83 if err != nil { 84 return err 85 } 86 *h = handle 87 return nil 88}