Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
// Copyright © 2023 Ory Corp
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package configx
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
|
|
"github.com/knadh/koanf/maps"
|
|
"github.com/tidwall/gjson"
|
|
)
|
|
|
|
// KoanfConfmap implements a raw map[string]interface{} provider.
|
|
type KoanfConfmap struct {
|
|
tuples []tuple
|
|
}
|
|
|
|
// Provider returns a confmap Provider that takes a flat or nested
|
|
// map[string]interface{}. If a delim is provided, it indicates that the
|
|
// keys are flat and the map needs to be unflatted by delim.
|
|
func NewKoanfConfmap(tuples []tuple) *KoanfConfmap {
|
|
return &KoanfConfmap{tuples: jsonify(tuples)}
|
|
}
|
|
|
|
func jsonify(tuples []tuple) []tuple {
|
|
for k, t := range tuples {
|
|
var parsed interface{}
|
|
switch vt := t.Value.(type) {
|
|
case string:
|
|
if gjson.Valid(vt) && json.NewDecoder(bytes.NewBufferString(vt)).Decode(&parsed) == nil {
|
|
tuples[k].Value = parsed
|
|
}
|
|
continue
|
|
case []byte:
|
|
if gjson.ValidBytes(vt) && json.NewDecoder(bytes.NewBuffer(vt)).Decode(&parsed) == nil {
|
|
tuples[k].Value = parsed
|
|
}
|
|
continue
|
|
case json.RawMessage:
|
|
if gjson.ValidBytes(vt) && json.NewDecoder(bytes.NewBuffer(vt)).Decode(&parsed) == nil {
|
|
tuples[k].Value = parsed
|
|
}
|
|
continue
|
|
}
|
|
}
|
|
return tuples
|
|
}
|
|
|
|
// ReadBytes is not supported by the env provider.
|
|
func (e *KoanfConfmap) ReadBytes() ([]byte, error) {
|
|
return nil, errors.New("confmap provider does not support this method")
|
|
}
|
|
|
|
// Read returns the loaded map[string]interface{}.
|
|
func (e *KoanfConfmap) Read() (map[string]interface{}, error) {
|
|
values := map[string]interface{}{}
|
|
for _, t := range e.tuples {
|
|
values[t.Key] = t.Value
|
|
}
|
|
|
|
// Ensure any nested values are properly converted as well
|
|
cp := maps.Copy(values)
|
|
maps.IntfaceKeysToStrings(cp)
|
|
cp = maps.Unflatten(cp, Delimiter)
|
|
|
|
return cp, nil
|
|
}
|