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}