1package configv2
2
3import (
4 "encoding/json"
5 "os"
6 "path/filepath"
7 "sync"
8
9 "github.com/charmbracelet/fur/pkg/client"
10 "github.com/charmbracelet/fur/pkg/provider"
11)
12
13var fur = client.New()
14
15var (
16 providerOnc sync.Once // Ensures the initialization happens only once
17 providerList []provider.Provider
18)
19
20func providersPath() string {
21 return filepath.Join(baseDataPath(), "providers.json")
22}
23
24func saveProviders(providers []provider.Provider) error {
25 path := providersPath()
26 dir := filepath.Dir(path)
27 if err := os.MkdirAll(dir, 0o755); err != nil {
28 return err
29 }
30
31 data, err := json.MarshalIndent(providers, "", " ")
32 if err != nil {
33 return err
34 }
35
36 return os.WriteFile(path, data, 0o644)
37}
38
39func loadProviders() ([]provider.Provider, error) {
40 path := providersPath()
41 data, err := os.ReadFile(path)
42 if err != nil {
43 return nil, err
44 }
45
46 var providers []provider.Provider
47 err = json.Unmarshal(data, &providers)
48 return providers, err
49}
50
51func Providers() []provider.Provider {
52 providerOnc.Do(func() {
53 // Try to get providers from upstream API
54 if providers, err := fur.GetProviders(); err == nil {
55 providerList = providers
56 // Save providers locally for future fallback
57 _ = saveProviders(providers)
58 } else {
59 // If upstream fails, try to load from local cache
60 if localProviders, localErr := loadProviders(); localErr == nil {
61 providerList = localProviders
62 } else {
63 // If both fail, return empty list
64 providerList = []provider.Provider{}
65 }
66 }
67 })
68 return providerList
69}