1// Package client provides a client for interacting with the fur service.
2package client
3
4import (
5 "encoding/json"
6 "fmt"
7 "net/http"
8 "os"
9
10 "github.com/charmbracelet/crush/internal/fur/provider"
11)
12
13const defaultURL = "https://fur.charm.sh"
14
15// Client represents a client for the fur service.
16type Client struct {
17 baseURL string
18 httpClient *http.Client
19}
20
21// New creates a new client instance
22// Uses FUR_URL environment variable or falls back to localhost:8080.
23func New() *Client {
24 baseURL := os.Getenv("FUR_URL")
25 if baseURL == "" {
26 baseURL = defaultURL
27 }
28
29 return &Client{
30 baseURL: baseURL,
31 httpClient: &http.Client{},
32 }
33}
34
35// NewWithURL creates a new client with a specific URL.
36func NewWithURL(url string) *Client {
37 return &Client{
38 baseURL: url,
39 httpClient: &http.Client{},
40 }
41}
42
43// GetProviders retrieves all available providers from the service.
44func (c *Client) GetProviders() ([]provider.Provider, error) {
45 url := fmt.Sprintf("%s/providers", c.baseURL)
46
47 resp, err := c.httpClient.Get(url) //nolint:noctx
48 if err != nil {
49 return nil, fmt.Errorf("failed to make request: %w", err)
50 }
51 defer resp.Body.Close() //nolint:errcheck
52
53 if resp.StatusCode != http.StatusOK {
54 return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
55 }
56
57 var providers []provider.Provider
58 if err := json.NewDecoder(resp.Body).Decode(&providers); err != nil {
59 return nil, fmt.Errorf("failed to decode response: %w", err)
60 }
61
62 return providers, nil
63}