// Package config loads application configuration from environment variables, // optionally populated from a .env file in the working directory. package config import ( "fmt" "os" "strconv" "github.com/joho/godotenv" ) type Config struct { DatabaseURL string Auth0Domain string Auth0ClientID string Auth0ClientSecret string Auth0CallbackURL string EtsyAPIKeystring string EtsyAPISharedSecret string // DevAuthEnabled, when true, exposes a route that mints a local // login session for any user_id without going through Auth0. Must // never be true outside local development. DevAuthEnabled bool } // Load reads a .env file, if present, into the process environment, then // reads the required configuration values from the environment. func Load() (Config, error) { if err := godotenv.Load(); err != nil && !os.IsNotExist(err) { return Config{}, fmt.Errorf("failed to load .env file: %w", err) } var ( cfg Config missing []string ) required := func(key string) string { v := os.Getenv(key) if v == "" { missing = append(missing, key) } return v } cfg.DatabaseURL = required("DATABASE_URL") cfg.Auth0Domain = required("AUTH0_DOMAIN") cfg.Auth0ClientID = required("AUTH0_CLIENT_ID") cfg.Auth0ClientSecret = required("AUTH0_CLIENT_SECRET") cfg.Auth0CallbackURL = required("AUTH0_CALLBACK_URL") cfg.EtsyAPIKeystring = required("ETSY_API_KEYSTRING") cfg.EtsyAPISharedSecret = required("ETSY_API_SHARED_SECRET") if len(missing) > 0 { return Config{}, fmt.Errorf( "missing required environment variables: %v (see .env.example)", missing, ) } if raw := os.Getenv("DEV_AUTH_ENABLED"); raw != "" { devAuthEnabled, err := strconv.ParseBool(raw) if err != nil { return Config{}, fmt.Errorf("invalid DEV_AUTH_ENABLED value %q: %w", raw, err) } cfg.DevAuthEnabled = devAuthEnabled } return cfg, nil }