package config import ( "encoding/json" "fmt" "os" ) // Config is the application configuration loaded from JSON. type Config struct { Host string `json:"host"` APIPort int `json:"api_port"` AdminPort int `json:"admin_port"` // Port is deprecated; mapped to APIPort when api_port is unset. Port int `json:"port"` } // Default returns sensible defaults when no config file is used. func Default() *Config { return &Config{ Host: "127.0.0.1", APIPort: 8080, AdminPort: 8081, } } // Load reads and parses a JSON config file from path. func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("read config: %w", err) } cfg := Default() if err := json.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("parse config: %w", err) } cfg.applyLegacyPort() return cfg, nil } func (c *Config) applyLegacyPort() { if c.Port != 0 && c.APIPort == 8080 { c.APIPort = c.Port } } func (c *Config) APIAddr() string { return fmt.Sprintf("%s:%d", c.Host, c.APIPort) } func (c *Config) AdminAddr() string { return fmt.Sprintf("%s:%d", c.Host, c.AdminPort) }