@@ -24,12 +24,16 @@ type QueryParamParser struct {
24
24
// Parsed is a map of all query params that were parsed. This is useful
25
25
// for checking if extra query params were passed in.
26
26
Parsed map [string ]bool
27
+ // RequiredParams is a map of all query params that are required. This is useful
28
+ // for forcing a value to be provided.
29
+ RequiredParams map [string ]bool
27
30
}
28
31
29
32
func NewQueryParamParser ()* QueryParamParser {
30
33
return & QueryParamParser {
31
- Errors : []codersdk.ValidationError {},
32
- Parsed :map [string ]bool {},
34
+ Errors : []codersdk.ValidationError {},
35
+ Parsed :map [string ]bool {},
36
+ RequiredParams :map [string ]bool {},
33
37
}
34
38
}
35
39
@@ -51,6 +55,20 @@ func (p *QueryParamParser) addParsed(key string) {
51
55
p .Parsed [key ]= true
52
56
}
53
57
58
+ func (p * QueryParamParser )UInt (vals url.Values ,def uint64 ,queryParam string )uint64 {
59
+ v ,err := parseQueryParam (p ,vals ,func (v string ) (uint64 ,error ) {
60
+ return strconv .ParseUint (v ,10 ,64 )
61
+ },def ,queryParam )
62
+ if err != nil {
63
+ p .Errors = append (p .Errors , codersdk.ValidationError {
64
+ Field :queryParam ,
65
+ Detail :fmt .Sprintf ("Query param %q must be a valid positive integer (%s)" ,queryParam ,err .Error ()),
66
+ })
67
+ return 0
68
+ }
69
+ return v
70
+ }
71
+
54
72
func (p * QueryParamParser )Int (vals url.Values ,def int ,queryParam string )int {
55
73
v ,err := parseQueryParam (p ,vals ,strconv .Atoi ,def ,queryParam )
56
74
if err != nil {
@@ -62,6 +80,11 @@ func (p *QueryParamParser) Int(vals url.Values, def int, queryParam string) int
62
80
return v
63
81
}
64
82
83
+ func (p * QueryParamParser )Required (queryParam string )* QueryParamParser {
84
+ p .RequiredParams [queryParam ]= true
85
+ return p
86
+ }
87
+
65
88
func (p * QueryParamParser )UUIDorMe (vals url.Values ,def uuid.UUID ,me uuid.UUID ,queryParam string ) uuid.UUID {
66
89
return ParseCustom (p ,vals ,def ,queryParam ,func (v string ) (uuid.UUID ,error ) {
67
90
if v == "me" {
@@ -178,6 +201,16 @@ func ParseCustomList[T any](parser *QueryParamParser, vals url.Values, def []T,
178
201
179
202
func parseQueryParam [T any ](parser * QueryParamParser ,vals url.Values ,parse func (v string ) (T ,error ),def T ,queryParam string ) (T ,error ) {
180
203
parser .addParsed (queryParam )
204
+ // If the query param is required and not present, return an error.
205
+ if parser .RequiredParams [queryParam ]&& (! vals .Has (queryParam )) {
206
+ parser .Errors = append (parser .Errors , codersdk.ValidationError {
207
+ Field :queryParam ,
208
+ Detail :fmt .Sprintf ("Query param %q is required" ,queryParam ),
209
+ })
210
+ return def ,nil
211
+ }
212
+
213
+ // If the query param is not present, return the default value.
181
214
if ! vals .Has (queryParam )|| vals .Get (queryParam )== "" {
182
215
return def ,nil
183
216
}