1package userutil
2
3import (
4 "regexp"
5 "strings"
6)
7
8var (
9 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])?$`)
10 didRegex = regexp.MustCompile(`^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$`)
11)
12
13func IsHandle(s string) bool {
14 // ref: https://atproto.com/specs/handle
15 return handleRegex.MatchString(s)
16}
17
18// IsDid checks if the given string is a standard DID.
19func IsDid(s string) bool {
20 return didRegex.MatchString(s)
21}
22
23func UnflattenDid(s string) string {
24 if !IsFlattenedDid(s) {
25 return s
26 }
27
28 return strings.Replace(s, "-", ":", 2)
29}
30
31// IsFlattenedDid checks if the given string is a flattened DID.
32func IsFlattenedDid(s string) bool {
33 // Check if the string starts with "did-"
34 if !strings.HasPrefix(s, "did-") {
35 return false
36 }
37
38 // Reconstruct as a standard DID format using Replace
39 // Example: "did-plc-xyz-abc" becomes "did:plc:xyz-abc"
40 reconstructed := strings.Replace(s, "-", ":", 2)
41
42 return didRegex.MatchString(reconstructed)
43}
44
45// FlattenDid converts a DID to a flattened format.
46// A flattened DID is a DID with the :s swapped to -s to satisfy certain
47// application requirements, such as Go module naming conventions.
48func FlattenDid(s string) string {
49 if IsDid(s) {
50 return strings.Replace(s, ":", "-", 2)
51 }
52 return s
53}
54
55var subdomainRegex = regexp.MustCompile(`^[a-z0-9]([a-z0-9-]{2,61}[a-z0-9])?$`)
56
57func IsValidSubdomain(name string) bool {
58 return len(name) >= 4 && len(name) <= 63 && subdomainRegex.MatchString(name)
59}