-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththreadsync.go
More file actions
140 lines (124 loc) · 3.4 KB
/
Copy paththreadsync.go
File metadata and controls
140 lines (124 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package threadsync
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const (
DefaultBaseURL = "https://api.threadsync.io/v1"
Version = "0.1.0"
)
type Client struct {
token string
baseURL string
httpClient *http.Client
Connections *ConnectionsService
Sync *SyncService
}
type Connection struct {
ID string `json:"id"`
Provider string `json:"provider"`
Name string `json:"name"`
Status string `json:"status"`
}
type SyncConfig struct {
Source Endpoint `json:"source"`
Destination Endpoint `json:"destination"`
Schedule string `json:"schedule"`
}
type Endpoint struct {
Connection string `json:"connection"`
Object string `json:"object,omitempty"`
Table string `json:"table,omitempty"`
}
type SyncResult struct {
ID string `json:"id"`
Status string `json:"status"`
RecordsSynced int `json:"records_synced,omitempty"`
}
func New(token string) *Client {
if token == "" {
token = os.Getenv("THREADSYNC_API_TOKEN")
}
c := &Client{
token: token,
baseURL: DefaultBaseURL,
httpClient: &http.Client{},
}
c.Connections = &ConnectionsService{client: c}
c.Sync = &SyncService{client: c}
return c
}
func (c *Client) request(method, path string, body interface{}) ([]byte, error) {
var bodyReader io.Reader
if body != nil {
b, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("threadsync: marshal error: %w", err)
}
bodyReader = bytes.NewReader(b)
}
req, err := http.NewRequest(method, c.baseURL+path, bodyReader)
if err != nil {
return nil, fmt.Errorf("threadsync: request error: %w", err)
}
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "threadsync-go/"+Version)
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("threadsync: request failed: %w", err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("threadsync: read body: %w", err)
}
if resp.StatusCode >= 400 {
return nil, fmt.Errorf("threadsync: API error %d: %s", resp.StatusCode, string(data))
}
return data, nil
}
// ConnectionsService handles connection-related API calls.
type ConnectionsService struct{ client *Client }
func (s *ConnectionsService) Create(provider string, options map[string]interface{}) (*Connection, error) {
body := map[string]interface{}{"provider": provider}
for k, v := range options {
body[k] = v
}
data, err := s.client.request("POST", "/connections", body)
if err != nil {
return nil, err
}
var conn Connection
return &conn, json.Unmarshal(data, &conn)
}
func (s *ConnectionsService) Get(id string) (*Connection, error) {
data, err := s.client.request("GET", "/connections/"+id, nil)
if err != nil {
return nil, err
}
var conn Connection
return &conn, json.Unmarshal(data, &conn)
}
// SyncService handles sync-related API calls.
type SyncService struct{ client *Client }
func (s *SyncService) Create(config *SyncConfig) (*SyncResult, error) {
data, err := s.client.request("POST", "/syncs", config)
if err != nil {
return nil, err
}
var sync SyncResult
return &sync, json.Unmarshal(data, &sync)
}
func (s *SyncService) Get(id string) (*SyncResult, error) {
data, err := s.client.request("GET", "/syncs/"+id, nil)
if err != nil {
return nil, err
}
var sync SyncResult
return &sync, json.Unmarshal(data, &sync)
}