@@ -2,7 +2,9 @@ package resolver
22
33import (
44 "errors"
5+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
56 "maps"
7+ "strings"
68
79 "github.com/graphql-go/graphql"
810 "github.com/rs/zerolog/log"
@@ -15,6 +17,7 @@ const (
1517 NamespaceArg = "namespace"
1618 ObjectArg = "object"
1719 SubscribeToAllArg = "subscribeToAll"
20+ SortByArg = "sortBy"
1821)
1922
2023// FieldConfigArgumentsBuilder helps construct GraphQL field config arguments
@@ -29,15 +32,15 @@ func NewFieldConfigArguments() *FieldConfigArgumentsBuilder {
2932 }
3033}
3134
32- func (b * FieldConfigArgumentsBuilder ) WithNameArg () * FieldConfigArgumentsBuilder {
35+ func (b * FieldConfigArgumentsBuilder ) WithName () * FieldConfigArgumentsBuilder {
3336 b .arguments [NameArg ] = & graphql.ArgumentConfig {
3437 Type : graphql .NewNonNull (graphql .String ),
3538 Description : "The name of the object" ,
3639 }
3740 return b
3841}
3942
40- func (b * FieldConfigArgumentsBuilder ) WithNamespaceArg () * FieldConfigArgumentsBuilder {
43+ func (b * FieldConfigArgumentsBuilder ) WithNamespace () * FieldConfigArgumentsBuilder {
4144 b .arguments [NamespaceArg ] = & graphql.ArgumentConfig {
4245 Type : graphql .String ,
4346 Description : "The namespace in which to search for the objects" ,
@@ -46,23 +49,23 @@ func (b *FieldConfigArgumentsBuilder) WithNamespaceArg() *FieldConfigArgumentsBu
4649 return b
4750}
4851
49- func (b * FieldConfigArgumentsBuilder ) WithLabelSelectorArg () * FieldConfigArgumentsBuilder {
52+ func (b * FieldConfigArgumentsBuilder ) WithLabelSelector () * FieldConfigArgumentsBuilder {
5053 b .arguments [LabelSelectorArg ] = & graphql.ArgumentConfig {
5154 Type : graphql .String ,
5255 Description : "A label selector to filter the objects by" ,
5356 }
5457 return b
5558}
5659
57- func (b * FieldConfigArgumentsBuilder ) WithObjectArg (resourceInputType * graphql.InputObject ) * FieldConfigArgumentsBuilder {
60+ func (b * FieldConfigArgumentsBuilder ) WithObject (resourceInputType * graphql.InputObject ) * FieldConfigArgumentsBuilder {
5861 b .arguments [ObjectArg ] = & graphql.ArgumentConfig {
5962 Type : graphql .NewNonNull (resourceInputType ),
6063 Description : "The object to create or update" ,
6164 }
6265 return b
6366}
6467
65- func (b * FieldConfigArgumentsBuilder ) WithSubscribeToAllArg () * FieldConfigArgumentsBuilder {
68+ func (b * FieldConfigArgumentsBuilder ) WithSubscribeToAll () * FieldConfigArgumentsBuilder {
6669 b .arguments [SubscribeToAllArg ] = & graphql.ArgumentConfig {
6770 Type : graphql .Boolean ,
6871 DefaultValue : false ,
@@ -71,6 +74,15 @@ func (b *FieldConfigArgumentsBuilder) WithSubscribeToAllArg() *FieldConfigArgume
7174 return b
7275}
7376
77+ func (b * FieldConfigArgumentsBuilder ) WithSortBy () * FieldConfigArgumentsBuilder {
78+ b .arguments [SortByArg ] = & graphql.ArgumentConfig {
79+ Type : graphql .String ,
80+ Description : "The field to sort the results by" ,
81+ DefaultValue : "metadata.name" ,
82+ }
83+ return b
84+ }
85+
7486// Complete returns the constructed arguments and dereferences the builder
7587func (b * FieldConfigArgumentsBuilder ) Complete () graphql.FieldConfigArgument {
7688 return maps .Clone (b .arguments )
@@ -129,3 +141,22 @@ func getBoolArg(args map[string]interface{}, key string, required bool) (bool, e
129141func isResourceNamespaceScoped (resourceScope apiextensionsv1.ResourceScope ) bool {
130142 return resourceScope == apiextensionsv1 .NamespaceScoped
131143}
144+
145+ func validateSortBy (items []unstructured.Unstructured , fieldPath string ) error {
146+ if len (items ) == 0 {
147+ return nil // No items to validate against, assume valid
148+ }
149+
150+ sample := items [0 ]
151+ segments := strings .Split (fieldPath , "." )
152+
153+ _ , found , err := unstructured .NestedFieldNoCopy (sample .Object , segments ... )
154+ if ! found {
155+ return errors .New ("specified sortBy field does not exist" )
156+ }
157+ if err != nil {
158+ return errors .Join (errors .New ("error accessing specified sortBy field" ), err )
159+ }
160+
161+ return nil
162+ }
0 commit comments