1+ package config
2+
3+ import (
4+ "os"
5+ "strconv"
6+ "strings"
7+
8+ middlewares "github.com/codeshelldev/secured-signal-api/internals/proxy/middlewares"
9+ utils "github.com/codeshelldev/secured-signal-api/utils"
10+ log "github.com/codeshelldev/secured-signal-api/utils/logger"
11+
12+ "github.com/knadh/koanf/parsers/dotenv"
13+ "github.com/knadh/koanf/parsers/yaml"
14+ "github.com/knadh/koanf/providers/confmap"
15+ "github.com/knadh/koanf/providers/env"
16+ "github.com/knadh/koanf/providers/file"
17+ "github.com/knadh/koanf/v2"
18+ )
19+
20+ type ENV_ struct {
21+ CONFIG_PATH string
22+ DEFAULTS_PATH string
23+ TOKENS_DIR string
24+ PORT string
25+ API_URL string
26+ API_TOKENS []string
27+ BLOCKED_ENDPOINTS []string
28+ VARIABLES map [string ]any
29+ MESSAGE_ALIASES []middlewares.MessageAlias
30+ }
31+
32+ var ENV ENV_ = ENV_ {
33+ CONFIG_PATH : os .Getenv ("CONFIG_PATH" ),
34+ DEFAULTS_PATH : os .Getenv ("DEFAULTS_PATH" ),
35+ TOKENS_DIR : os .Getenv ("TOKENS_DIR" ),
36+ }
37+
38+ var config = koanf .New ("." )
39+
40+ func LoadIntoENV () {
41+ ENV .PORT = strconv .Itoa (config .Int ("server.port" ))
42+
43+ ENV .API_URL = config .String ("api.url" )
44+ ENV .API_TOKENS = config .Strings ("api.tokens" )
45+
46+ ENV .BLOCKED_ENDPOINTS = config .Strings ("blockedendpoints" )
47+
48+ ENV .VARIABLES = config .Get ("variables" ).(map [string ]any )
49+ ENV .MESSAGE_ALIASES = config .Get ("messagealiases" ).([]middlewares.MessageAlias )
50+
51+ ENV .VARIABLES ["NUMBER" ] = config .String ("number" )
52+ ENV .VARIABLES ["RECIPIENTS" ] = config .Strings ("recipients" )
53+ }
54+
55+ func Load () {
56+ LoadFile (ENV .DEFAULTS_PATH , yaml .Parser ())
57+ LoadFile (ENV .CONFIG_PATH , yaml .Parser ())
58+
59+ LoadDotEnv ()
60+
61+ normalizeKeys ()
62+
63+ LoadIntoENV ()
64+ }
65+
66+ func LoadFile (path string , parser koanf.Parser ) (* file.File ) {
67+ f := file .Provider (path )
68+
69+ err := config .Load (f , parser )
70+
71+ if err != nil {
72+ log .Fatal ("Error loading " , path , ": " , err .Error ())
73+ }
74+
75+ f .Watch (func (event interface {}, err error ) {
76+ if err != nil {
77+ return
78+ }
79+
80+ log .Info ("Config changed, Reloading..." )
81+
82+ Load ()
83+ })
84+
85+ return f
86+ }
87+
88+ func LoadDotEnv () (* env.Env ) {
89+ e := env .ProviderWithValue ("" , "." , normalizeEnv )
90+
91+ err := config .Load (e , dotenv .Parser ())
92+
93+ if err != nil {
94+ log .Fatal ("Error loading env: " , err .Error ())
95+ }
96+
97+ return e
98+ }
99+
100+ func normalizeKeys () {
101+ data := map [string ]any {}
102+
103+ for _ , key := range config .Keys () {
104+ lower := strings .ToLower (key )
105+
106+ data [lower ] = config .Get (key )
107+ }
108+ config .Load (confmap .Provider (data , "." ), nil )
109+ }
110+
111+ func normalizeEnv (key string , value string ) (string , any ) {
112+ key = strings .ToLower (strings .ReplaceAll (key , "__" , "." ))
113+
114+ if strings .HasPrefix (value , "{" ) || strings .HasPrefix (value , "[" ) {
115+ data , err := utils.GetJsonSafe [any ](value )
116+
117+ if data != nil && err == nil {
118+ return key , data
119+ }
120+ }
121+
122+ if strings .Contains (value , "," ) {
123+ items := utils .StringToArray (value )
124+
125+ return key , items
126+ }
127+
128+ intValue , intErr := strconv .Atoi (value )
129+
130+ if intErr == nil {
131+ return key , intValue
132+ }
133+
134+ return key , value
135+ }
0 commit comments