this repo has no description
1package knotclient 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "log" 9 "net/http" 10 "net/url" 11 "strconv" 12 "time" 13 14 "tangled.sh/tangled.sh/core/types" 15) 16 17type UnsignedClient struct { 18 Url *url.URL 19 client *http.Client 20} 21 22func NewUnsignedClient(domain string, dev bool) (*UnsignedClient, error) { 23 client := &http.Client{ 24 Timeout: 5 * time.Second, 25 } 26 27 scheme := "https" 28 if dev { 29 scheme = "http" 30 } 31 url, err := url.Parse(fmt.Sprintf("%s://%s", scheme, domain)) 32 if err != nil { 33 return nil, err 34 } 35 36 unsignedClient := &UnsignedClient{ 37 client: client, 38 Url: url, 39 } 40 41 return unsignedClient, nil 42} 43 44func (us *UnsignedClient) newRequest(method, endpoint string, query url.Values, body []byte) (*http.Request, error) { 45 reqUrl := us.Url.JoinPath(endpoint) 46 47 // add query parameters 48 if query != nil { 49 reqUrl.RawQuery = query.Encode() 50 } 51 52 return http.NewRequest(method, reqUrl.String(), bytes.NewReader(body)) 53} 54 55func (us *UnsignedClient) Index(ownerDid, repoName, ref string) (*http.Response, error) { 56 const ( 57 Method = "GET" 58 ) 59 60 endpoint := fmt.Sprintf("/%s/%s/tree/%s", ownerDid, repoName, ref) 61 if ref == "" { 62 endpoint = fmt.Sprintf("/%s/%s", ownerDid, repoName) 63 } 64 65 req, err := us.newRequest(Method, endpoint, nil, nil) 66 if err != nil { 67 return nil, err 68 } 69 70 return us.client.Do(req) 71} 72 73func (us *UnsignedClient) Log(ownerDid, repoName, ref string, page int) (*http.Response, error) { 74 const ( 75 Method = "GET" 76 ) 77 78 endpoint := fmt.Sprintf("/%s/%s/log/%s", ownerDid, repoName, url.PathEscape(ref)) 79 80 query := url.Values{} 81 query.Add("page", strconv.Itoa(page)) 82 query.Add("per_page", strconv.Itoa(60)) 83 84 req, err := us.newRequest(Method, endpoint, query, nil) 85 if err != nil { 86 return nil, err 87 } 88 89 return us.client.Do(req) 90} 91 92func (us *UnsignedClient) Branches(ownerDid, repoName string) (*http.Response, error) { 93 const ( 94 Method = "GET" 95 ) 96 97 endpoint := fmt.Sprintf("/%s/%s/branches", ownerDid, repoName) 98 99 req, err := us.newRequest(Method, endpoint, nil, nil) 100 if err != nil { 101 return nil, err 102 } 103 104 return us.client.Do(req) 105} 106 107func (us *UnsignedClient) Tags(ownerDid, repoName string) (*types.RepoTagsResponse, error) { 108 const ( 109 Method = "GET" 110 ) 111 112 endpoint := fmt.Sprintf("/%s/%s/tags", ownerDid, repoName) 113 114 req, err := us.newRequest(Method, endpoint, nil, nil) 115 if err != nil { 116 return nil, err 117 } 118 119 resp, err := us.client.Do(req) 120 if err != nil { 121 return nil, err 122 } 123 124 body, err := io.ReadAll(resp.Body) 125 if err != nil { 126 return nil, err 127 } 128 129 var result types.RepoTagsResponse 130 err = json.Unmarshal(body, &result) 131 if err != nil { 132 return nil, err 133 } 134 135 return &result, nil 136} 137 138func (us *UnsignedClient) Branch(ownerDid, repoName, branch string) (*http.Response, error) { 139 const ( 140 Method = "GET" 141 ) 142 143 endpoint := fmt.Sprintf("/%s/%s/branches/%s", ownerDid, repoName, url.PathEscape(branch)) 144 145 req, err := us.newRequest(Method, endpoint, nil, nil) 146 if err != nil { 147 return nil, err 148 } 149 150 return us.client.Do(req) 151} 152 153func (us *UnsignedClient) DefaultBranch(ownerDid, repoName string) (*types.RepoDefaultBranchResponse, error) { 154 const ( 155 Method = "GET" 156 ) 157 158 endpoint := fmt.Sprintf("/%s/%s/branches/default", ownerDid, repoName) 159 160 req, err := us.newRequest(Method, endpoint, nil, nil) 161 if err != nil { 162 return nil, err 163 } 164 165 resp, err := us.client.Do(req) 166 if err != nil { 167 return nil, err 168 } 169 defer resp.Body.Close() 170 171 var defaultBranch types.RepoDefaultBranchResponse 172 if err := json.NewDecoder(resp.Body).Decode(&defaultBranch); err != nil { 173 return nil, err 174 } 175 176 return &defaultBranch, nil 177} 178 179func (us *UnsignedClient) Capabilities() (*types.Capabilities, error) { 180 const ( 181 Method = "GET" 182 Endpoint = "/capabilities" 183 ) 184 185 req, err := us.newRequest(Method, Endpoint, nil, nil) 186 if err != nil { 187 return nil, err 188 } 189 190 resp, err := us.client.Do(req) 191 if err != nil { 192 return nil, err 193 } 194 defer resp.Body.Close() 195 196 var capabilities types.Capabilities 197 if err := json.NewDecoder(resp.Body).Decode(&capabilities); err != nil { 198 return nil, err 199 } 200 201 return &capabilities, nil 202} 203 204func (us *UnsignedClient) Compare(ownerDid, repoName, rev1, rev2 string) (*types.RepoFormatPatchResponse, error) { 205 const ( 206 Method = "GET" 207 ) 208 209 endpoint := fmt.Sprintf("/%s/%s/compare/%s/%s", ownerDid, repoName, url.PathEscape(rev1), url.PathEscape(rev2)) 210 211 req, err := us.newRequest(Method, endpoint, nil, nil) 212 if err != nil { 213 return nil, fmt.Errorf("Failed to create request.") 214 } 215 216 compareResp, err := us.client.Do(req) 217 if err != nil { 218 return nil, fmt.Errorf("Failed to create request.") 219 } 220 defer compareResp.Body.Close() 221 222 switch compareResp.StatusCode { 223 case 404: 224 case 400: 225 return nil, fmt.Errorf("Branch comparisons not supported on this knot.") 226 } 227 228 respBody, err := io.ReadAll(compareResp.Body) 229 if err != nil { 230 log.Println("failed to compare across branches") 231 return nil, fmt.Errorf("Failed to compare branches.") 232 } 233 defer compareResp.Body.Close() 234 235 var formatPatchResponse types.RepoFormatPatchResponse 236 err = json.Unmarshal(respBody, &formatPatchResponse) 237 if err != nil { 238 log.Println("failed to unmarshal format-patch response", err) 239 return nil, fmt.Errorf("failed to compare branches.") 240 } 241 242 return &formatPatchResponse, nil 243}