File: format_query.go

package info (click to toggle)
golang-github-nicholas-fedor-shoutrrr 0.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 4,432 kB
  • sloc: sh: 74; makefile: 5
file content (94 lines) | stat: -rw-r--r-- 2,589 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package format

import (
	"net/url"
	"strings"

	"github.com/nicholas-fedor/shoutrrr/pkg/types"
)

// BuildQuery converts the fields of a config object to a delimited query string.
func BuildQuery(cqr types.ConfigQueryResolver) string {
	return BuildQueryWithCustomFields(cqr, url.Values{}).Encode()
}

// escaping any custom fields that share the same key as a config prop using a "__" prefix.
func BuildQueryWithCustomFields(cqr types.ConfigQueryResolver, query url.Values) url.Values {
	fields := cqr.QueryFields()
	skipEscape := len(query) < 1

	pkr, isPkr := cqr.(*PropKeyResolver)

	for _, key := range fields {
		if !skipEscape {
			// Escape any webhook query keys using the same name as service props
			escValues := query[key]
			if len(escValues) > 0 {
				query.Del(key)
				query[EscapeKey(key)] = escValues
			}
		}

		if isPkr && !pkr.KeyIsPrimary(key) {
			continue
		}

		value, err := cqr.Get(key)
		if err != nil || isPkr && pkr.IsDefault(key, value) {
			continue
		}

		query.Set(key, value)
	}

	return query
}

// SetConfigPropsFromQuery iterates over all the config prop keys and sets the config prop to the corresponding
// query value based on the key.
// SetConfigPropsFromQuery returns a non-nil url.Values query with all config prop keys removed, even if any of
// them could not be used to set a config field, and with any escaped keys unescaped.
// The error returned is the first error that occurred, subsequent errors are just discarded.
func SetConfigPropsFromQuery(cqr types.ConfigQueryResolver, query url.Values) (url.Values, error) {
	var firstError error

	if query == nil {
		return url.Values{}, nil
	}

	for _, key := range cqr.QueryFields() {
		// Retrieve the service-related prop value
		values := query[key]
		if len(values) > 0 {
			if err := cqr.Set(key, values[0]); err != nil && firstError == nil {
				firstError = err
			}
		}
		// Remove it from the query Values
		query.Del(key)

		// If an escaped version of the key exist, unescape it
		escKey := EscapeKey(key)
		escValues := query[escKey]

		if len(escValues) > 0 {
			query.Del(escKey)
			query[key] = escValues
		}
	}

	return query, firstError
}

// EscapeKey adds the KeyPrefix to custom URL query keys that conflict with service config prop keys.
func EscapeKey(key string) string {
	return KeyPrefix + key
}

// UnescapeKey removes the KeyPrefix from custom URL query keys that conflict with service config prop keys.
func UnescapeKey(key string) string {
	return strings.TrimPrefix(key, KeyPrefix)
}

// consisting of two underscore characters ("__").
const KeyPrefix = "__"