bring back yahoo pipes!
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 161 lines 3.9 kB view raw
1package config 2 3import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strconv" 8 9 "github.com/joho/godotenv" 10 "gopkg.in/yaml.v3" 11) 12 13type Config struct { 14 // Server 15 Origin string `yaml:"origin"` 16 Host string `yaml:"host"` 17 Port int `yaml:"port"` 18 Env string `yaml:"env"` 19 LogLevel string `yaml:"log_level"` 20 21 // Database 22 DatabasePath string `yaml:"db_path"` 23 24 // OAuth (Indiko) 25 IndikoURL string `yaml:"indiko_url"` 26 IndikoClientID string `yaml:"indiko_client_id"` 27 IndikoClientSecret string `yaml:"indiko_client_secret"` 28 OAuthCallbackURL string `yaml:"oauth_callback_url"` 29 30 // Session 31 SessionSecret string `yaml:"session_secret"` 32 SessionCookieName string `yaml:"session_cookie_name"` 33} 34 35// Default returns a Config with sensible defaults 36func Default() *Config { 37 return &Config{ 38 Origin: "http://localhost:3001", 39 Host: "localhost", 40 Port: 3001, 41 Env: "development", 42 LogLevel: "info", 43 DatabasePath: "pipes.db", 44 IndikoURL: "http://localhost:3000", 45 OAuthCallbackURL: "http://localhost:3001/auth/callback", 46 SessionCookieName: "pipes_session", 47 } 48} 49 50// Load loads configuration from YAML file (if provided) and environment variables 51func Load(path string) (*Config, error) { 52 cfg := Default() 53 54 // Load .env file if it exists (silently ignore if not found) 55 if envPath := findEnvFile(path); envPath != "" { 56 _ = godotenv.Load(envPath) 57 } 58 59 // Load from YAML config file if provided 60 if path != "" { 61 data, err := os.ReadFile(path) 62 if err != nil { 63 return nil, fmt.Errorf("failed to read config file: %w", err) 64 } 65 66 // Expand environment variables in YAML (e.g., ${DATABASE_PATH}) 67 expanded := os.Expand(string(data), func(key string) string { 68 return os.Getenv(key) 69 }) 70 71 if err := yaml.Unmarshal([]byte(expanded), cfg); err != nil { 72 return nil, fmt.Errorf("failed to parse config file: %w", err) 73 } 74 } 75 76 // Apply environment variable overrides 77 applyEnvOverrides(cfg) 78 79 if err := cfg.Validate(); err != nil { 80 return nil, err 81 } 82 83 return cfg, nil 84} 85 86func (c *Config) Validate() error { 87 if c.SessionSecret == "" { 88 return fmt.Errorf("session_secret is required (set SESSION_SECRET env var)") 89 } 90 91 if c.IndikoClientID == "" { 92 return fmt.Errorf("indiko_client_id is required (set INDIKO_CLIENT_ID env var)") 93 } 94 95 if c.IndikoURL == "" { 96 return fmt.Errorf("indiko_url is required (set INDIKO_URL env var)") 97 } 98 99 return nil 100} 101 102// findEnvFile looks for .env file in the config file's directory or current directory 103func findEnvFile(configPath string) string { 104 // If config path provided, look in its directory 105 if configPath != "" { 106 dir := filepath.Dir(configPath) 107 envPath := filepath.Join(dir, ".env") 108 if _, err := os.Stat(envPath); err == nil { 109 return envPath 110 } 111 } 112 113 // Look in current directory 114 if _, err := os.Stat(".env"); err == nil { 115 return ".env" 116 } 117 118 return "" 119} 120 121// applyEnvOverrides applies environment variable overrides to config 122func applyEnvOverrides(cfg *Config) { 123 if v := os.Getenv("ORIGIN"); v != "" { 124 cfg.Origin = v 125 } 126 if v := os.Getenv("HOST"); v != "" { 127 cfg.Host = v 128 } 129 if v := os.Getenv("PORT"); v != "" { 130 if port, err := strconv.Atoi(v); err == nil { 131 cfg.Port = port 132 } 133 } 134 if v := os.Getenv("NODE_ENV"); v != "" { 135 cfg.Env = v 136 } 137 if v := os.Getenv("LOG_LEVEL"); v != "" { 138 cfg.LogLevel = v 139 } 140 if v := os.Getenv("DATABASE_PATH"); v != "" { 141 cfg.DatabasePath = v 142 } 143 if v := os.Getenv("INDIKO_URL"); v != "" { 144 cfg.IndikoURL = v 145 } 146 if v := os.Getenv("INDIKO_CLIENT_ID"); v != "" { 147 cfg.IndikoClientID = v 148 } 149 if v := os.Getenv("INDIKO_CLIENT_SECRET"); v != "" { 150 cfg.IndikoClientSecret = v 151 } 152 if v := os.Getenv("OAUTH_CALLBACK_URL"); v != "" { 153 cfg.OAuthCallbackURL = v 154 } 155 if v := os.Getenv("SESSION_SECRET"); v != "" { 156 cfg.SessionSecret = v 157 } 158 if v := os.Getenv("SESSION_COOKIE_NAME"); v != "" { 159 cfg.SessionCookieName = v 160 } 161}