package config import ( "encoding/json" "fmt" "log" "os" "sync" ) type Config struct { Backend struct { Port string `json:"port"` Host string `json:"host"` Auth struct { Required bool `json:"required"` Key string `json:"key"` } `json:"auth"` Database struct { Versions struct { Path string `json:"path"` } `json:"versions"` Bulletins struct { Path string `json:"path"` } `json:"bulletins"` Themes struct { Path string `json:"path"` } `json:"themes"` ThemesFiles struct { Path string `json:"path"` } `json:"themes_files"` } `json:"database"` Casdoor struct { Endpoint string `json:"endpoint"` ClientID string `json:"client_id"` ClientSecret string `json:"client_secret"` Certificate string `json:"certificate"` Organization string `json:"organization"` Application string `json:"application"` } `json:"casdoor"` } `json:"backend"` Frontend struct { Port string `json:"port"` Host string `json:"host"` Static struct { Path string `json:"path"` } `json:"static"` } `json:"frontend"` } var ( instance *Config once sync.Once loadErr error ) func createDefaultConfig() *Config { config := &Config{} config.Backend.Port = "8080" config.Backend.Host = "127.0.0.1" config.Backend.Auth.Required = false config.Backend.Auth.Key = "null" config.Backend.Database.Versions.Path = "./backend/data/versions.db" config.Backend.Database.Bulletins.Path = "./backend/data/bulletins.db" config.Backend.Database.Themes.Path = "./backend/data/themes.db" config.Backend.Database.ThemesFiles.Path = "./backend/data/themes_files" config.Backend.Casdoor.Endpoint = "http://127.0.0.1:8000" config.Backend.Casdoor.ClientID = "" config.Backend.Casdoor.ClientSecret = "" config.Backend.Casdoor.Certificate = "" config.Backend.Casdoor.Organization = "autolibrary" config.Backend.Casdoor.Application = "marketplace" config.Frontend.Port = "3000" config.Frontend.Host = "127.0.0.1" config.Frontend.Static.Path = "./frontend/dist" return config } func LoadConfig(configPath string, allowDefaults bool) (*Config, error) { once.Do(func() { data, err := os.ReadFile(configPath) if err != nil { loadErr = err return } cfg := createDefaultConfig() if err := json.Unmarshal(data, &cfg); err != nil { loadErr = fmt.Errorf("decode config %q: %w", configPath, err) return } if cfg == nil { loadErr = fmt.Errorf("config %q must be a JSON object", configPath) return } instance = cfg }) if loadErr != nil { if !allowDefaults { return nil, loadErr } log.Printf("[W] using default config: %v", loadErr) return createDefaultConfig(), nil } log.Printf("[I] config loaded successfully from: %s", configPath) return instance, nil } func GetConfig() *Config { if instance == nil { return createDefaultConfig() } return instance }