porting all github actions from bluesky-social/indigo to tangled CI

add implementation of LexClient interface

Changed files
+87
atproto
client
+87
atproto/client/lexclient.go
··· 1 + package client 2 + 3 + import ( 4 + "bytes" 5 + "context" 6 + "encoding/json" 7 + "fmt" 8 + "io" 9 + 10 + "github.com/bluesky-social/indigo/atproto/syntax" 11 + ) 12 + 13 + // Implements the `LexClient` interface, for use with code-generated API helpers. 14 + func (c *APIClient) LexDo(ctx context.Context, kind string, inpenc string, method string, params map[string]any, bodyobj any, out any) error { 15 + // some of the code here is copied from indigo:xrpc/xrpc.go 16 + 17 + nsid, err := syntax.ParseNSID(method) 18 + if err != nil { 19 + return err 20 + } 21 + 22 + var body io.Reader 23 + if bodyobj != nil { 24 + if rr, ok := bodyobj.(io.Reader); ok { 25 + body = rr 26 + } else { 27 + b, err := json.Marshal(bodyobj) 28 + if err != nil { 29 + return err 30 + } 31 + 32 + body = bytes.NewReader(b) 33 + } 34 + } 35 + 36 + req := NewAPIRequest(kind, nsid, body) 37 + 38 + if bodyobj != nil && inpenc != "" { 39 + req.Headers.Set("Content-Type", inpenc) 40 + } 41 + 42 + if params != nil { 43 + qp, err := ParseParams(params) 44 + if err != nil { 45 + return err 46 + } 47 + req.QueryParams = qp 48 + } 49 + 50 + resp, err := c.Do(ctx, req) 51 + if err != nil { 52 + return err 53 + } 54 + defer resp.Body.Close() 55 + 56 + if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { 57 + var eb ErrorBody 58 + if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { 59 + return &APIError{StatusCode: resp.StatusCode} 60 + } 61 + return eb.APIError(resp.StatusCode) 62 + } 63 + 64 + if out == nil { 65 + return nil 66 + } 67 + 68 + if buf, ok := out.(*bytes.Buffer); ok { 69 + if resp.ContentLength < 0 { 70 + _, err := io.Copy(buf, resp.Body) 71 + if err != nil { 72 + return fmt.Errorf("reading response body: %w", err) 73 + } 74 + } else { 75 + n, err := io.CopyN(buf, resp.Body, resp.ContentLength) 76 + if err != nil { 77 + return fmt.Errorf("reading length delimited response body (%d < %d): %w", n, resp.ContentLength, err) 78 + } 79 + } 80 + } else { 81 + if err := json.NewDecoder(resp.Body).Decode(out); err != nil { 82 + return fmt.Errorf("failed decoding JSON response body: %w", err) 83 + } 84 + } 85 + 86 + return nil 87 + }