ident.go
1// Package ident maps forge repositories to the DIDs that identify them in
2// Tangled records: did:web:<forge-host>:<repo> (DESIGN.md ยง4).
3package ident
4
5import (
6 "fmt"
7 "regexp"
8 "strings"
9)
10
11var repoName = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]*$`)
12
13// RepoDID returns the DID of repo on the forge at host.
14func RepoDID(host, repo string) string {
15 return "did:web:" + strings.ReplaceAll(host, ":", "%3A") + ":" + repo
16}
17
18// ParseRepoDID splits a repo DID into forge host and repo name.
19func ParseRepoDID(did string) (host, repo string, err error) {
20 rest, ok := strings.CutPrefix(did, "did:web:")
21 if !ok {
22 return "", "", fmt.Errorf("%q is not a did:web", did)
23 }
24 host, repo, ok = strings.Cut(rest, ":")
25 if !ok || host == "" || !repoName.MatchString(repo) {
26 return "", "", fmt.Errorf("%q is not a repo DID (did:web:<host>:<repo>)", did)
27 }
28 return strings.ReplaceAll(host, "%3A", ":"), repo, nil
29}
30
31// ServiceDID returns the did:web of a service at host.
32func ServiceDID(host string) string {
33 return "did:web:" + strings.ReplaceAll(host, ":", "%3A")
34}