diff --git a/graphql_test.go b/graphql_test.go index 8c49e42a6c5..2a1cd4abae7 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -519,6 +519,50 @@ func TestDeprecatedDirective(t *testing.T) { } `, }, + { + Schema: graphql.MustParseSchema(` + schema { + query: Query + } + + type Query { + } + + enum Test { + A + B @deprecated + C @deprecated(reason: "We don't like it") + } + `, &testDeprecatedDirectiveResolver{}), + Query: ` + { + __type(name: "Test") { + enumValues { + name + } + allEnumValues: enumValues(includeDeprecated: true) { + name + isDeprecated + deprecationReason + } + } + } + `, + ExpectedResult: ` + { + "__type": { + "enumValues": [ + { "name": "A" } + ], + "allEnumValues": [ + { "name": "A", "isDeprecated": false, "deprecationReason": null }, + { "name": "B", "isDeprecated": true, "deprecationReason": "No longer supported" }, + { "name": "C", "isDeprecated": true, "deprecationReason": "We don't like it" } + ] + } + } + `, + }, }) } diff --git a/internal/schema/schema.go b/internal/schema/schema.go index 45dcc56fbe6..2c422774c70 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -18,6 +18,7 @@ type Schema struct { entryPointNames map[string]string objects []*Object unions []*Union + enums []*Enum } func (s *Schema) Resolve(name string) common.Type { @@ -68,8 +69,9 @@ type Enum struct { } type EnumValue struct { - Name string - Desc string + Name string + Directives map[string]common.DirectiveArgs + Desc string } type InputObject struct { @@ -208,6 +210,14 @@ func (s *Schema) Parse(schemaString string) error { } } + for _, enum := range s.enums { + for _, value := range enum.Values { + if err := resolveDirectives(s, value.Directives); err != nil { + return err + } + } + } + return nil } @@ -239,7 +249,14 @@ func resolveField(s *Schema, f *Field) error { return err } f.Type = t - for name, args := range f.Directives { + if err := resolveDirectives(s, f.Directives); err != nil { + return err + } + return resolveInputObject(s, &f.Args) +} + +func resolveDirectives(s *Schema, directives map[string]common.DirectiveArgs) error { + for name, args := range directives { d, ok := s.Directives[name] if !ok { return errors.Errorf("directive %q not found", name) @@ -255,7 +272,7 @@ func resolveField(s *Schema, f *Field) error { } } } - return resolveInputObject(s, &f.Args) + return nil } func resolveInputObject(s *Schema, io *common.InputMap) error { @@ -300,6 +317,7 @@ func parseSchema(s *Schema, l *lexer.Lexer) { enum := parseEnumDecl(l) enum.Desc = desc s.Types[enum.Name] = enum + s.enums = append(s.enums, enum) case "input": input := parseInputDecl(l) input.Desc = desc @@ -378,6 +396,7 @@ func parseEnumDecl(l *lexer.Lexer) *Enum { v := &EnumValue{} v.Desc = l.DescComment() v.Name = l.ConsumeIdent() + v.Directives = common.ParseDirectives(l) enum.Values = append(enum.Values, v) } l.ConsumeToken('}') diff --git a/introspection/introspection.go b/introspection/introspection.go index 09ddcadbb72..8a3e407bace 100644 --- a/introspection/introspection.go +++ b/introspection/introspection.go @@ -162,9 +162,11 @@ func (r *Type) EnumValues(args *struct{ IncludeDeprecated bool }) *[]*EnumValue return nil } - l := make([]*EnumValue, len(t.Values)) - for i, v := range t.Values { - l[i] = &EnumValue{v} + var l []*EnumValue + for _, v := range t.Values { + if _, ok := v.Directives["deprecated"]; !ok || args.IncludeDeprecated { + l = append(l, &EnumValue{v}) + } } return &l } @@ -277,11 +279,17 @@ func (r *EnumValue) Description() *string { } func (r *EnumValue) IsDeprecated() bool { - return false + _, ok := r.value.Directives["deprecated"] + return ok } func (r *EnumValue) DeprecationReason() *string { - return nil + args, ok := r.value.Directives["deprecated"] + if !ok { + return nil + } + reason := args["reason"].(string) + return &reason } type Directive struct {