diff --git a/internal/glance/config-fields.go b/internal/glance/config-fields.go index f3c836e..966b366 100644 --- a/internal/glance/config-fields.go +++ b/internal/glance/config-fields.go @@ -219,3 +219,55 @@ func (p *proxyOptionsField) UnmarshalYAML(node *yaml.Node) error { return nil } + +type queryParametersField map[string][]string + +func (q *queryParametersField) UnmarshalYAML(node *yaml.Node) error { + var decoded map[string]any + + if err := node.Decode(&decoded); err != nil { + return err + } + + *q = make(queryParametersField) + + for key, value := range decoded { + switch v := value.(type) { + case string: + (*q)[key] = []string{v} + case int, int8, int16, int32, int64, float32, float64: + (*q)[key] = []string{fmt.Sprintf("%v", v)} + case []string: + (*q)[key] = append((*q)[key], v...) + case []any: + for _, item := range v { + switch item := item.(type) { + case string: + (*q)[key] = append((*q)[key], item) + case int, int8, int16, int32, int64, float32, float64: + (*q)[key] = append((*q)[key], fmt.Sprintf("%v", item)) + case bool: + (*q)[key] = append((*q)[key], fmt.Sprintf("%t", item)) + default: + return fmt.Errorf("invalid query parameter value type: %T", item) + } + } + default: + return fmt.Errorf("invalid query parameter value type: %T", value) + } + } + + return nil +} + +func (q *queryParametersField) toQueryString() string { + query := url.Values{} + + for key, values := range *q { + for _, value := range values { + query.Add(key, value) + } + } + + return query.Encode() +} diff --git a/internal/glance/widget-custom-api.go b/internal/glance/widget-custom-api.go index 6866c1e..f7830ce 100644 --- a/internal/glance/widget-custom-api.go +++ b/internal/glance/widget-custom-api.go @@ -10,7 +10,6 @@ import ( "log/slog" "math" "net/http" - "net/url" "time" "github.com/tidwall/gjson" @@ -20,14 +19,14 @@ var customAPIWidgetTemplate = mustParseTemplate("custom-api.html", "widget-base. type customAPIWidget struct { widgetBase `yaml:",inline"` - URL string `yaml:"url"` - Template string `yaml:"template"` - Frameless bool `yaml:"frameless"` - Headers map[string]string `yaml:"headers"` - Parameters map[string]interface{} `yaml:"parameters"` - APIRequest *http.Request `yaml:"-"` - compiledTemplate *template.Template `yaml:"-"` - CompiledHTML template.HTML `yaml:"-"` + URL string `yaml:"url"` + Template string `yaml:"template"` + Frameless bool `yaml:"frameless"` + Headers map[string]string `yaml:"headers"` + Parameters queryParametersField `yaml:"parameters"` + APIRequest *http.Request `yaml:"-"` + compiledTemplate *template.Template `yaml:"-"` + CompiledHTML template.HTML `yaml:"-"` } func (widget *customAPIWidget) initialize() error { @@ -53,31 +52,7 @@ func (widget *customAPIWidget) initialize() error { return err } - query := url.Values{} - - for key, value := range widget.Parameters { - switch v := value.(type) { - case string: - query.Add(key, v) - case int, int8, int16, int32, int64, float32, float64: - query.Add(key, fmt.Sprintf("%v", v)) - case []string: - for _, item := range v { - query.Add(key, item) - } - case []interface{}: - for _, item := range v { - switch item := item.(type) { - case string: - query.Add(key, item) - case int, int8, int16, int32, int64, float32, float64: - query.Add(key, fmt.Sprintf("%v", item)) - } - } - } - } - - req.URL.RawQuery = query.Encode() + req.URL.RawQuery = widget.Parameters.toQueryString() for key, value := range widget.Headers { req.Header.Add(key, value)