diff --git a/content/graphql.go b/content/graphql.go index ae9296f..c933eb0 100644 --- a/content/graphql.go +++ b/content/graphql.go @@ -91,7 +91,7 @@ func (s *Service) translateNode(node interface{}, graphqlObjects map[string]cued dataSet, _ := s.engine.GetDataSet(node.(*cuedb.DagNode).Name) var objectFields graphql.Fields - objectFields, err := cuedb.CueValueToGraphQlField(graphqlObjects, dataSet.GetSchemaCue()) + objectFields, err := cuedb.CueValueToGraphQlField(graphqlObjects, dataSet, dataSet.GetSchemaCue()) if err != nil { cobra.CheckErr(err) } @@ -148,7 +148,7 @@ func (s *Service) translateNode(node interface{}, graphqlObjects map[string]cued Resolve: resolver, } - graphqlFields[fmt.Sprintf("all%vs", dataSet.GetExternalName())] = &graphql.Field{ + graphqlFields[fmt.Sprintf("all%v", dataSet.GetPluralName())] = &graphql.Field{ Type: graphql.NewList(objType), Resolve: func(p graphql.ResolveParams) (interface{}, error) { dataSetName := p.Info.ReturnType.Name() diff --git a/internal/cuedb/dataset.go b/internal/cuedb/dataset.go index d466414..b90a6b5 100644 --- a/internal/cuedb/dataset.go +++ b/internal/cuedb/dataset.go @@ -52,6 +52,10 @@ func (d *DataSet) GetDataMapCue() string { ) } +func (d *DataSet) GetPluralName() string { + return strings.Title(d.metadata.Plural) +} + func (d *DataSet) GetExternalName() string { return strings.Replace(d.name, "#", "", 1) } diff --git a/internal/cuedb/graphql.go b/internal/cuedb/graphql.go index b02d272..40357fe 100644 --- a/internal/cuedb/graphql.go +++ b/internal/cuedb/graphql.go @@ -14,7 +14,7 @@ type GraphQlObjectGlue struct { Resolver func(p graphql.ResolveParams) (interface{}, error) } -func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueValue cue.Value) (graphql.Fields, error) { +func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, dataSet DataSet, cueValue cue.Value) (graphql.Fields, error) { fields, err := cueValue.Fields(cue.All()) if err != nil { return nil, err @@ -36,13 +36,14 @@ func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueVal switch fields.Value().IncompleteKind() { case cue.StructKind: - subFields, err := CueValueToGraphQlField(existingObjects, fields.Value()) + subFields, err := CueValueToGraphQlField(existingObjects, dataSet, fields.Value()) if err != nil { return nil, err } graphQlFields[fields.Label()] = &graphql.Field{ Type: graphql.NewObject(graphql.ObjectConfig{ + Name: fmt.Sprintf("%s%s", dataSet.GetExternalName(), strings.Title(fields.Label())), Fields: subFields, }), } @@ -94,13 +95,13 @@ func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueVal } // List of non-scalar types - subFields, err := CueValueToGraphQlField(existingObjects, listOf.Value()) + subFields, err := CueValueToGraphQlField(existingObjects, dataSet, listOf.Value()) // No error, so we know this is a simple value or struct if err == nil { graphQlFields[fields.Label()] = &graphql.Field{ Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{ - Name: fields.Label(), + Name: fmt.Sprintf("%s%s", dataSet.GetExternalName(), strings.Title(fields.Label())), Fields: subFields, })}, } diff --git a/internal/cuedb/graphql_test.go b/internal/cuedb/graphql_test.go index 632e3d3..53abdd4 100644 --- a/internal/cuedb/graphql_test.go +++ b/internal/cuedb/graphql_test.go @@ -11,66 +11,98 @@ import ( func TestGraphqlGeneration(t *testing.T) { type test struct { cueLiteral string + dataSet *DataSet expected graphql.Fields } tests := []test{ - {cueLiteral: "t1: string", expected: graphql.Fields{ - "t1": {Type: &graphql.NonNull{OfType: graphql.String}}, - }}, - {cueLiteral: "t2: int", expected: graphql.Fields{ - "t2": {Type: &graphql.NonNull{OfType: graphql.Int}}, - }}, - {cueLiteral: "t3: [...int]", expected: graphql.Fields{ - "t3": {Type: &graphql.List{OfType: graphql.Int}}, - }}, - {cueLiteral: "t4: [...string]", expected: graphql.Fields{ - "t4": {Type: &graphql.List{OfType: graphql.String}}, - }}, - {cueLiteral: "t5: string, t6?: int", expected: graphql.Fields{ - "t5": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t6": {Type: graphql.Int}, - }}, - {cueLiteral: "{ t7: string, t8: { t9: string, t10: string} }", expected: graphql.Fields{ - "t7": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t8": {Type: graphql.NewObject(graphql.ObjectConfig{ - Fields: graphql.Fields{ - "t9": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t10": {Type: &graphql.NonNull{OfType: graphql.String}}, - }, - })}, - }}, - {cueLiteral: "{ t11: string, t12: { t13: string, t14: string, t15: { t16: int } } }", expected: graphql.Fields{ - "t11": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t12": {Type: graphql.NewObject(graphql.ObjectConfig{ - Fields: graphql.Fields{ - "t13": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t14": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t15": {Type: graphql.NewObject(graphql.ObjectConfig{ - Fields: graphql.Fields{ - "t16": {Type: &graphql.NonNull{OfType: graphql.Int}}, - }, - })}, - }, - })}, - }}, - {cueLiteral: "{ #Test: { t19: string}\nt17: string, t18: #Test }", expected: graphql.Fields{ - "t17": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t18": {Type: graphql.NewObject(graphql.ObjectConfig{ - Fields: graphql.Fields{ - "t19": {Type: &graphql.NonNull{OfType: graphql.String}}, - }, - })}, - }}, - {cueLiteral: "{ #Test: { t20: string}\n t21: string, t22: [ ... #Test ] }", expected: graphql.Fields{ - "t21": {Type: &graphql.NonNull{OfType: graphql.String}}, - "t22": {Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{ - Name: "t22", - Fields: graphql.Fields{ - "t20": {Type: &graphql.NonNull{OfType: graphql.String}}, - }, - })}}, - }}, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "t1: string", expected: graphql.Fields{ + "t1": {Type: &graphql.NonNull{OfType: graphql.String}}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "t2: int", expected: graphql.Fields{ + "t2": {Type: &graphql.NonNull{OfType: graphql.Int}}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "t3: [...int]", expected: graphql.Fields{ + "t3": {Type: &graphql.List{OfType: graphql.Int}}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "t4: [...string]", expected: graphql.Fields{ + "t4": {Type: &graphql.List{OfType: graphql.String}}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "t5: string, t6?: int", expected: graphql.Fields{ + "t5": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t6": {Type: graphql.Int}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "{ t7: string, t8: { t9: string, t10: string} }", expected: graphql.Fields{ + "t7": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t8": {Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "TypeT8", + Fields: graphql.Fields{ + "t9": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t10": {Type: &graphql.NonNull{OfType: graphql.String}}, + }, + })}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "{ t11: string, t12: { t13: string, t14: string, t15: { t16: int } } }", expected: graphql.Fields{ + "t11": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t12": {Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "TypeT12", + Fields: graphql.Fields{ + "t13": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t14": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t15": {Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "TypeT15", + Fields: graphql.Fields{ + "t16": {Type: &graphql.NonNull{OfType: graphql.Int}}, + }, + })}, + }, + })}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "{ #Test: { t19: string}\nt17: string, t18: #Test }", expected: graphql.Fields{ + "t17": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t18": {Type: graphql.NewObject(graphql.ObjectConfig{ + Name: "TypeT18", + Fields: graphql.Fields{ + "t19": {Type: &graphql.NonNull{OfType: graphql.String}}, + }, + })}, + }, + }, + { + dataSet: &DataSet{name: "Type"}, + cueLiteral: "{ #Test: { t20: string}\n t21: string, t22: [ ... #Test ] }", expected: graphql.Fields{ + "t21": {Type: &graphql.NonNull{OfType: graphql.String}}, + "t22": {Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{ + Name: "TypeT22", + Fields: graphql.Fields{ + "t20": {Type: &graphql.NonNull{OfType: graphql.String}}, + }, + })}}, + }, + }, // WIP // Aim is to "flatten" disjunctions into a single struct // {cueLiteral: "{ #A: {t23: string}\n#B: { t24?: string}\n t25: string, t26: [ ... #A | #B ] }", expected: graphql.Fields{ @@ -92,7 +124,7 @@ func TestGraphqlGeneration(t *testing.T) { graphqlObjects := make(map[string]GraphQlObjectGlue) - graphQlObject, err := CueValueToGraphQlField(graphqlObjects, cueValue) + graphQlObject, err := CueValueToGraphQlField(graphqlObjects, *tc.dataSet, cueValue) assert.Equal(t, nil, err) assert.EqualValues(t, tc.expected, graphQlObject) }