mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-05 04:53:01 +00:00
small fix, don't worry about it
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Env string
|
||||
AppName string
|
||||
HTTP HTTPConfig
|
||||
CORS CORSConfig
|
||||
Postgres PostgresConfig
|
||||
Cache CacheConfig
|
||||
Auth AuthConfig
|
||||
TMDB TMDBConfig
|
||||
IGDB IGDBConfig
|
||||
}
|
||||
|
||||
type HTTPConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
ReadTimeout time.Duration
|
||||
WriteTimeout time.Duration
|
||||
}
|
||||
|
||||
type CORSConfig struct {
|
||||
AllowedOrigins []string
|
||||
AllowedMethods []string
|
||||
AllowedHeaders []string
|
||||
ExposedHeaders []string
|
||||
AllowCredentials bool
|
||||
MaxAge time.Duration
|
||||
}
|
||||
|
||||
type PostgresConfig struct {
|
||||
URL string
|
||||
MaxConns int32
|
||||
MinConns int32
|
||||
}
|
||||
|
||||
type CacheConfig struct {
|
||||
Addr string
|
||||
Password string
|
||||
DB int
|
||||
}
|
||||
|
||||
type AuthConfig struct {
|
||||
AccessTokenTTLMinutes int
|
||||
RefreshTokenTTLHours int
|
||||
JWTSecret string
|
||||
}
|
||||
|
||||
type TMDBConfig struct {
|
||||
APIKey string
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
type IGDBConfig struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
BaseURL string
|
||||
TokenURL string
|
||||
}
|
||||
|
||||
func Load() Config {
|
||||
_ = godotenv.Load()
|
||||
|
||||
return Config{
|
||||
Env: getString("SEEN_ENV", "development"),
|
||||
AppName: getString("SEEN_APP_NAME", "seen"),
|
||||
HTTP: HTTPConfig{
|
||||
Host: getString("SEEN_HTTP_HOST", "0.0.0.0"),
|
||||
Port: getInt("SEEN_HTTP_PORT", 8081),
|
||||
ReadTimeout: getDuration("SEEN_HTTP_READ_TIMEOUT", 15*time.Second),
|
||||
WriteTimeout: getDuration("SEEN_HTTP_WRITE_TIMEOUT", 15*time.Second),
|
||||
},
|
||||
CORS: CORSConfig{
|
||||
AllowedOrigins: getCSV("SEEN_CORS_ALLOWED_ORIGINS", []string{}),
|
||||
AllowedMethods: getCSV("SEEN_CORS_ALLOWED_METHODS", []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}),
|
||||
AllowedHeaders: getCSV("SEEN_CORS_ALLOWED_HEADERS", []string{"Accept", "Authorization", "Content-Type", "X-Request-ID"}),
|
||||
ExposedHeaders: getCSV("SEEN_CORS_EXPOSED_HEADERS", []string{"X-Request-ID"}),
|
||||
AllowCredentials: getBool("SEEN_CORS_ALLOW_CREDENTIALS", false),
|
||||
MaxAge: getDuration("SEEN_CORS_MAX_AGE", 24*time.Hour),
|
||||
},
|
||||
Postgres: PostgresConfig{
|
||||
URL: getString("SEEN_POSTGRES_URL", "postgres://seen:seen@localhost:5432/seen?sslmode=disable"),
|
||||
MaxConns: int32(getInt("SEEN_POSTGRES_MAX_CONNS", 10)),
|
||||
MinConns: int32(getInt("SEEN_POSTGRES_MIN_CONNS", 2)),
|
||||
},
|
||||
Cache: CacheConfig{
|
||||
Addr: getString("SEEN_CACHE_ADDR", "localhost:6379"),
|
||||
Password: getString("SEEN_CACHE_PASSWORD", ""),
|
||||
DB: getInt("SEEN_CACHE_DB", 0),
|
||||
},
|
||||
Auth: AuthConfig{
|
||||
AccessTokenTTLMinutes: getInt("SEEN_AUTH_ACCESS_TOKEN_TTL_MINUTES", 30),
|
||||
RefreshTokenTTLHours: getInt("SEEN_AUTH_REFRESH_TOKEN_TTL_HOURS", 24*30),
|
||||
JWTSecret: getString("SEEN_AUTH_JWT_SECRET", "replace-in-production"),
|
||||
},
|
||||
TMDB: TMDBConfig{
|
||||
APIKey: getString("SEEN_TMDB_API_KEY", ""),
|
||||
BaseURL: getString("SEEN_TMDB_BASE_URL", "https://api.themoviedb.org/3"),
|
||||
},
|
||||
IGDB: IGDBConfig{
|
||||
ClientID: getString("SEEN_IGDB_CLIENT_ID", ""),
|
||||
ClientSecret: getString("SEEN_IGDB_CLIENT_SECRET", ""),
|
||||
BaseURL: getString("SEEN_IGDB_BASE_URL", "https://api.igdb.com/v4"),
|
||||
TokenURL: getString("SEEN_IGDB_TOKEN_URL", "https://id.twitch.tv/oauth2/token"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c HTTPConfig) Addr() string {
|
||||
return fmt.Sprintf("%s:%d", c.Host, c.Port)
|
||||
}
|
||||
|
||||
func getString(key string, fallback string) string {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func getInt(key string, fallback int) int {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return fallback
|
||||
}
|
||||
|
||||
parsed, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
func getDuration(key string, fallback time.Duration) time.Duration {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return fallback
|
||||
}
|
||||
|
||||
parsed, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
func getBool(key string, fallback bool) bool {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return fallback
|
||||
}
|
||||
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "1", "true", "yes", "on":
|
||||
return true
|
||||
case "0", "false", "no", "off":
|
||||
return false
|
||||
default:
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
func getCSV(key string, fallback []string) []string {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return slices.Clone(fallback)
|
||||
}
|
||||
|
||||
parts := strings.Split(value, ",")
|
||||
items := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
trimmed := strings.TrimSpace(part)
|
||||
if trimmed == "" {
|
||||
continue
|
||||
}
|
||||
items = append(items, trimmed)
|
||||
}
|
||||
|
||||
if len(items) == 0 {
|
||||
return slices.Clone(fallback)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
Reference in New Issue
Block a user