forked from tangled.org/core
this repo has no description
1package knotclient 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "net/url" 10 "path" 11 "strconv" 12 13 "tangled.sh/tangled.sh/core/types" 14) 15 16type UnsignedClient struct { 17 Domain string 18 Dev bool 19 client *http.Client 20} 21 22func (u *UnsignedClient) scheme() string { 23 if u.Dev { 24 return "http" 25 } 26 27 return "https" 28} 29 30func (u *UnsignedClient) url() (*url.URL, error) { 31 return url.Parse(fmt.Sprintf("%s://%s", u.scheme(), u.Domain)) 32} 33 34type KnotRequest interface { 35 Method() string 36 Path() string 37 Query() url.Values 38 Body() []byte 39} 40 41func do[T any](u *UnsignedClient, method, path string, query url.Values, body []byte) (*T, error) { 42 // Create a copy of the base URL to avoid modifying the original 43 base, err := u.url() 44 if err != nil { 45 return nil, fmt.Errorf("failed to parse URL: %w", err) 46 } 47 48 // add path 49 base = base.JoinPath(path) 50 51 // add query 52 if query != nil { 53 base.RawQuery = query.Encode() 54 } 55 56 // Create the request 57 req, err := http.NewRequest(method, base.String(), bytes.NewReader(body)) 58 if err != nil { 59 return nil, err 60 } 61 62 resp, err := u.client.Do(req) 63 if err != nil { 64 return nil, err 65 } 66 defer resp.Body.Close() 67 68 body, err = io.ReadAll(resp.Body) 69 if err != nil { 70 return nil, err 71 } 72 73 var result T 74 err = json.Unmarshal(body, &result) 75 if err != nil { 76 return nil, err 77 } 78 79 return &result, nil 80} 81 82func (u *UnsignedClient) Index(ownerDid, repoName, ref string) (*types.RepoIndexResponse, error) { 83 method := http.MethodGet 84 endpoint := path.Join(ownerDid, repoName, "tree", ref) 85 if ref == "" { 86 endpoint = path.Join(ownerDid, repoName) 87 } 88 return do[types.RepoIndexResponse](u, method, endpoint, nil, nil) 89} 90 91func (u *UnsignedClient) Log(ownerDid, repoName, ref string, page int) (*types.RepoLogResponse, error) { 92 method := http.MethodGet 93 endpoint := fmt.Sprintf("/%s/%s/log/%s", ownerDid, repoName, url.PathEscape(ref)) 94 95 query := url.Values{} 96 query.Add("page", strconv.Itoa(page)) 97 query.Add("per_page", strconv.Itoa(60)) 98 99 return do[types.RepoLogResponse](u, method, endpoint, nil, nil) 100} 101 102func (u *UnsignedClient) Branches(ownerDid, repoName string) (*types.RepoBranchesResponse, error) { 103 method := http.MethodGet 104 endpoint := fmt.Sprintf("/%s/%s/branches", ownerDid, repoName) 105 106 return do[types.RepoBranchesResponse](u, method, endpoint, nil, nil) 107} 108 109func (u *UnsignedClient) Tags(ownerDid, repoName string) (*types.RepoTagsResponse, error) { 110 method := http.MethodGet 111 endpoint := fmt.Sprintf("/%s/%s/tags", ownerDid, repoName) 112 113 return do[types.RepoTagsResponse](u, method, endpoint, nil, nil) 114} 115 116func (u *UnsignedClient) Branch(ownerDid, repoName, branch string) (*types.RepoBranchResponse, error) { 117 method := http.MethodGet 118 endpoint := fmt.Sprintf("/%s/%s/branches/%s", ownerDid, repoName, url.PathEscape(branch)) 119 120 return do[types.RepoBranchResponse](u, method, endpoint, nil, nil) 121} 122 123func (u *UnsignedClient) DefaultBranch(ownerDid, repoName string) (*types.RepoDefaultBranchResponse, error) { 124 method := http.MethodGet 125 endpoint := fmt.Sprintf("/%s/%s/branches/default", ownerDid, repoName) 126 127 return do[types.RepoDefaultBranchResponse](u, method, endpoint, nil, nil) 128} 129 130func (u *UnsignedClient) Capabilities() (*types.Capabilities, error) { 131 method := http.MethodGet 132 endpoint := "capabilities" 133 134 return do[types.Capabilities](u, method, endpoint, nil, nil) 135} 136 137func (u *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoFormatPatchResponse, error) { 138 method := http.MethodGet 139 endpoint := fmt.Sprintf("/%s/%s/compare/%s/%s", ownerDid, repoName, url.PathEscape(rev1), url.PathEscape(rev2)) 140 141 return do[types.RepoFormatPatchResponse](u, method, endpoint, nil, nil) 142}