diff --git a/codegen/field.go b/codegen/field.go index d1eceb002e..3a90530b9a 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -89,6 +89,11 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) { if err != nil { errret = err } + for _, dir := range obj.Directives { + if dir.IsLocation(ast.LocationInputObject) { + dirs = append(dirs, dir) + } + } f.Directives = append(dirs, f.Directives...) } }() @@ -420,7 +425,8 @@ func (f *Field) ImplDirectives() []*Directive { loc = ast.LocationInputFieldDefinition } for i := range f.Directives { - if !f.Directives[i].Builtin && f.Directives[i].IsLocation(loc, ast.LocationObject) { + if !f.Directives[i].Builtin && + (f.Directives[i].IsLocation(loc, ast.LocationObject) || f.Directives[i].IsLocation(loc, ast.LocationInputObject)) { d = append(d, f.Directives[i]) } } diff --git a/codegen/testserver/directive.graphql b/codegen/testserver/directive.graphql index f878c4d5cf..8cf2470986 100644 --- a/codegen/testserver/directive.graphql +++ b/codegen/testserver/directive.graphql @@ -5,6 +5,7 @@ directive @logged(id: UUID!) on FIELD directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT directive @unimplemented on FIELD_DEFINITION directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT @@ -30,7 +31,7 @@ extend type Subscription { directiveUnimplemented: String @unimplemented } -input InputDirectives { +input InputDirectives @directive3 { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull inner: InnerDirectives! diff --git a/codegen/testserver/directive_test.go b/codegen/testserver/directive_test.go index 56786f5803..a35a288988 100644 --- a/codegen/testserver/directive_test.go +++ b/codegen/testserver/directive_test.go @@ -162,6 +162,9 @@ func TestDirectives(t *testing.T) { Directive2: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { return next(ctx) }, + Directive3: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, Order1: func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) { order := []string{location} res, err = next(ctx) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 376764a3a4..7995011c09 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -60,6 +60,7 @@ type DirectiveRoot struct { Custom func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Directive1 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Directive2 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Directive3 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Length func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int, message *string) (res interface{}, err error) Logged func(ctx context.Context, obj interface{}, next graphql.Resolver, id string) (res interface{}, err error) MakeNil func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) @@ -1914,6 +1915,7 @@ directive @logged(id: UUID!) on FIELD directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT directive @unimplemented on FIELD_DEFINITION directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT @@ -1939,7 +1941,7 @@ extend type Subscription { directiveUnimplemented: String @unimplemented } -input InputDirectives { +input InputDirectives @directive3 { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull inner: InnerDirectives! @@ -10298,6 +10300,12 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("text")) directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { min, err := ec.unmarshalNInt2int(ctx, 0) if err != nil { return nil, err @@ -10313,10 +10321,10 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o if ec.directives.Length == nil { return nil, errors.New("directive length is not implemented") } - return ec.directives.Length(ctx, obj, directive0, min, max, message) + return ec.directives.Length(ctx, obj, directive1, min, max, message) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } @@ -10332,13 +10340,19 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nullableText")) directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOString2ᚖstring(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { if ec.directives.ToNull == nil { return nil, errors.New("directive toNull is not implemented") } - return ec.directives.ToNull(ctx, obj, directive0) + return ec.directives.ToNull(ctx, obj, directive1) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } @@ -10354,17 +10368,53 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) - it.Inner, err = ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.Inner = data + } else if tmp == nil { + it.Inner = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } case "innerNullable": var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("innerNullable")) - it.InnerNullable, err = ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.InnerNullable = data + } else if tmp == nil { + it.InnerNullable = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } case "thirdParty": var err error @@ -10374,6 +10424,12 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o return ec.unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐThirdParty(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { min, err := ec.unmarshalNInt2int(ctx, 0) if err != nil { return nil, err @@ -10385,10 +10441,10 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o if ec.directives.Length == nil { return nil, errors.New("directive length is not implemented") } - return ec.directives.Length(ctx, obj, directive0, min, max, nil) + return ec.directives.Length(ctx, obj, directive1, min, max, nil) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index ff7ad36e8b..4c0ea402cd 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -1920,9 +1920,23 @@ func (ec *executionContext) unmarshalInputTodoInput(ctx context.Context, obj int var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("text")) - it.Text, err = ec.unmarshalNString2string(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.InputLogging == nil { + return nil, errors.New("directive inputLogging is not implemented") + } + return ec.directives.InputLogging(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + it.Text = data + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } } }