@@ -28,6 +28,7 @@ import (
28
28
"github.com/go-errors/errors"
29
29
"github.com/golang-jwt/jwt/v5"
30
30
"github.com/joho/godotenv"
31
+ "github.com/mitchellh/mapstructure"
31
32
"github.com/spf13/viper"
32
33
"golang.org/x/mod/semver"
33
34
@@ -136,13 +137,13 @@ type (
136
137
EdgeRuntime edgeRuntime `toml:"edge_runtime"`
137
138
Functions FunctionConfig `toml:"functions"`
138
139
Analytics analytics `toml:"analytics"`
139
- Experimental experimental `toml:"experimental" mapstructure:"-" `
140
+ Experimental experimental `toml:"experimental"`
140
141
}
141
142
142
143
config struct {
143
- baseConfig
144
- Overrides map [string ]interface {} `toml:"remotes"`
145
- Remotes map [string ]baseConfig `toml:"-"`
144
+ baseConfig `mapstructure:",squash"`
145
+ Overrides map [string ]interface {} `toml:"remotes"`
146
+ Remotes map [string ]baseConfig `toml:"-"`
146
147
}
147
148
148
149
db struct {
@@ -587,6 +588,29 @@ func (c *config) Eject(w io.Writer) error {
587
588
return nil
588
589
}
589
590
591
+ func (c * config ) loadFromEnv () error {
592
+ // Allow overriding base config object with automatic env
593
+ // Ref: https://github.com/spf13/viper/issues/761
594
+ envKeysMap := map [string ]interface {}{}
595
+ if dec , err := mapstructure .NewDecoder (& mapstructure.DecoderConfig {
596
+ Result : & envKeysMap ,
597
+ IgnoreUntaggedFields : true ,
598
+ }); err != nil {
599
+ return errors .Errorf ("failed to create decoder: %w" , err )
600
+ } else if err := dec .Decode (c .baseConfig ); err != nil {
601
+ return errors .Errorf ("failed to decode env: %w" , err )
602
+ }
603
+ v := viper .New ()
604
+ v .SetEnvKeyReplacer (strings .NewReplacer ("." , "_" ))
605
+ v .AutomaticEnv ()
606
+ if err := v .MergeConfigMap (envKeysMap ); err != nil {
607
+ return errors .Errorf ("failed to merge config: %w" , err )
608
+ } else if err := v .Unmarshal (c ); err != nil {
609
+ return errors .Errorf ("failed to parse env to config: %w" , err )
610
+ }
611
+ return nil
612
+ }
613
+
590
614
func (c * config ) Load (path string , fsys fs.FS ) error {
591
615
builder := NewPathBuilder (path )
592
616
// Load default values
@@ -614,9 +638,8 @@ func (c *config) Load(path string, fsys fs.FS) error {
614
638
// Load secrets from .env file
615
639
if err := loadDefaultEnv (); err != nil {
616
640
return err
617
- }
618
- if err := viper .Unmarshal (c ); err != nil {
619
- return errors .Errorf ("failed to parse env to config: %w" , err )
641
+ } else if err := c .loadFromEnv (); err != nil {
642
+ return err
620
643
}
621
644
// Generate JWT tokens
622
645
if len (c .Auth .AnonKey ) == 0 {
0 commit comments