Skip to content

Commit

Permalink
Merge pull request 99designs#239 from vektah/directive-args
Browse files Browse the repository at this point in the history
Directive args
  • Loading branch information
vektah authored Aug 2, 2018
2 parents 727f79a + c56cde9 commit b165407
Show file tree
Hide file tree
Showing 21 changed files with 268 additions and 148 deletions.
4 changes: 2 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion codegen/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ func (cfg *Config) bind() (*Build, error) {
if err != nil {
return nil, err
}
directives, err := cfg.buildDirectives(namedTypes)
if err != nil {
return nil, err
}

b := &Build{
PackageName: cfg.Exec.Package,
Expand All @@ -150,7 +154,7 @@ func (cfg *Config) bind() (*Build, error) {
Imports: imports.finalize(),
SchemaRaw: cfg.SchemaStr,
SchemaFilename: cfg.SchemaFilename,
Directives: cfg.buildDirectives(),
Directives: directives,
}

if cfg.schema.Query != nil {
Expand Down
28 changes: 28 additions & 0 deletions codegen/directive.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
package codegen

import (
"fmt"
"strconv"
"strings"
)

type Directive struct {
Name string
Args []FieldArgument
}

func (d *Directive) CallArgs() string {
args := []string{"ctx", "n"}

for _, arg := range d.Args {
args = append(args, "args["+strconv.Quote(arg.GQLName)+"].("+arg.Signature()+")")
}

return strings.Join(args, ", ")
}

func (d *Directive) Declaration() string {
res := ucFirst(d.Name) + " func(ctx context.Context, next graphql.Resolver"

for _, arg := range d.Args {
res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
}

res += ") (res interface{}, err error)"
return res
}
35 changes: 32 additions & 3 deletions codegen/directive_build.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
package codegen

func (cfg *Config) buildDirectives() (directives []*Directive) {
for name := range cfg.schema.Directives {
import "github.com/pkg/errors"

func (cfg *Config) buildDirectives(types NamedTypes) ([]*Directive, error) {
var directives []*Directive

for name, dir := range cfg.schema.Directives {
if name == "skip" || name == "include" || name == "deprecated" {
continue
}

var args []FieldArgument
for _, arg := range dir.Arguments {
newArg := FieldArgument{
GQLName: arg.Name,
Type: types.getType(arg.Type),
GoVarName: sanitizeGoName(arg.Name),
}

if !newArg.Type.IsInput && !newArg.Type.IsScalar {
return nil, errors.Errorf("%s cannot be used as argument of directive %s(%s) only input and scalar types are allowed", arg.Type, dir.Name, arg.Name)
}

if arg.DefaultValue != nil {
var err error
newArg.Default, err = arg.DefaultValue.Value(nil)
if err != nil {
return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error())
}
newArg.StripPtr()
}
args = append(args, newArg)
}

directives = append(directives, &Directive{
Name: name,
Args: args,
})
}
return directives
return directives, nil
}
4 changes: 4 additions & 0 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ func (f *Field) doWriteJson(val string, remainingMods []string, isPtr bool, dept
}
}

func (f *FieldArgument) Stream() bool {
return f.Object != nil && f.Object.Stream
}

func (os Objects) ByName(name string) *Object {
for i, o := range os {
if strings.EqualFold(o.GQLType, name) {
Expand Down
17 changes: 2 additions & 15 deletions codegen/templates/args.gotpl
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
{{- if . }}args := map[string]interface{}{} {{end}}
{{- range $i, $arg := . }}
var arg{{$i}} {{$arg.Signature }}
if tmp, ok := field.Args[{{$arg.GQLName|quote}}]; ok {
if tmp, ok := rawArgs[{{$arg.GQLName|quote}}]; ok {
var err error
{{$arg.Unmarshal (print "arg" $i) "tmp" }}
if err != nil {
ec.Error(ctx, err)
{{- if $arg.Object.Stream }}
return nil
{{- else }}
return graphql.Null
{{- end }}
}
} {{ if $arg.Default }} else {
var tmp interface{} = {{ $arg.Default | dump }}
var err error
{{$arg.Unmarshal (print "arg" $i) "tmp" }}
if err != nil {
ec.Error(ctx, err)
{{- if $arg.Object.Stream }}
{{- if $arg.Stream }}
return nil
{{- else }}
return graphql.Null
{{- end }}
}
}
{{end }}
args[{{$arg.GQLName|quote}}] = arg{{$i}}
{{- end -}}
6 changes: 3 additions & 3 deletions codegen/templates/data.go

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions codegen/templates/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

{{- if $object.Stream }}
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {
{{- template "args.gotpl" $field.Args }}
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
{{ template "args.gotpl" $field.Args }}
{{- end }}
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})
results, err := ec.resolvers.{{ $field.ShortInvocation }}
if err != nil {
Expand All @@ -22,7 +25,10 @@
}
{{ else }}
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {
{{- template "args.gotpl" $field.Args }}
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
{{ template "args.gotpl" $field.Args }}
{{- end }}

{{- if $field.IsConcurrent }}
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
Expand Down
8 changes: 6 additions & 2 deletions codegen/templates/generated.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type ResolverRoot interface {

type DirectiveRoot struct {
{{ range $directive := .Directives }}
{{$directive.Name|ucFirst}} graphql.FieldMiddleware
{{ $directive.Declaration }}
{{ end }}
}

Expand Down Expand Up @@ -155,9 +155,13 @@ func (ec *executionContext) FieldMiddleware(ctx context.Context, next graphql.Re
{{- range $directive := .Directives }}
case "{{$directive.Name}}":
if ec.directives.{{$directive.Name|ucFirst}} != nil {
{{- if $directive.Args }}
rawArgs := d.ArgumentMap(ec.Variables)
{{ template "args.gotpl" $directive.Args }}
{{- end }}
n := next
next = func(ctx context.Context) (interface{}, error) {
return ec.directives.{{$directive.Name|ucFirst}}(ctx, n)
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})
}
}
{{- end }}
Expand Down
22 changes: 14 additions & 8 deletions example/chat/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions example/config/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions example/dataloader/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b165407

Please sign in to comment.