From a2a50f3de0c428c5a61e6a449191be3c4ded86ac Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Thu, 19 Jul 2018 14:15:50 +0200 Subject: webui: add a primitive graphql handler --- .../graphql-go/graphql/language/printer/printer.go | 821 +++++++++++++++++++++ 1 file changed, 821 insertions(+) create mode 100644 vendor/github.com/graphql-go/graphql/language/printer/printer.go (limited to 'vendor/github.com/graphql-go/graphql/language/printer') diff --git a/vendor/github.com/graphql-go/graphql/language/printer/printer.go b/vendor/github.com/graphql-go/graphql/language/printer/printer.go new file mode 100644 index 00000000..3add3852 --- /dev/null +++ b/vendor/github.com/graphql-go/graphql/language/printer/printer.go @@ -0,0 +1,821 @@ +package printer + +import ( + "fmt" + "strings" + + "github.com/graphql-go/graphql/language/ast" + "github.com/graphql-go/graphql/language/visitor" + "reflect" +) + +func getMapValue(m map[string]interface{}, key string) interface{} { + tokens := strings.Split(key, ".") + valMap := m + for _, token := range tokens { + v, ok := valMap[token] + if !ok { + return nil + } + switch v := v.(type) { + case []interface{}: + return v + case map[string]interface{}: + valMap = v + continue + default: + return v + } + } + return valMap +} +func getMapSliceValue(m map[string]interface{}, key string) []interface{} { + tokens := strings.Split(key, ".") + valMap := m + for _, token := range tokens { + v, ok := valMap[token] + if !ok { + return []interface{}{} + } + switch v := v.(type) { + case []interface{}: + return v + default: + return []interface{}{} + } + } + return []interface{}{} +} +func getMapValueString(m map[string]interface{}, key string) string { + tokens := strings.Split(key, ".") + valMap := m + for _, token := range tokens { + v, ok := valMap[token] + if !ok { + return "" + } + if v == nil { + return "" + } + switch v := v.(type) { + case map[string]interface{}: + valMap = v + continue + case string: + return v + default: + return fmt.Sprintf("%v", v) + } + } + return "" +} + +func toSliceString(slice interface{}) []string { + if slice == nil { + return []string{} + } + res := []string{} + switch reflect.TypeOf(slice).Kind() { + case reflect.Slice: + s := reflect.ValueOf(slice) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + elemInterface := elem.Interface() + if elem, ok := elemInterface.(string); ok { + res = append(res, elem) + } + } + return res + default: + return res + } +} + +func join(str []string, sep string) string { + ss := []string{} + // filter out empty strings + for _, s := range str { + if s == "" { + continue + } + ss = append(ss, s) + } + return strings.Join(ss, sep) +} + +func wrap(start, maybeString, end string) string { + if maybeString == "" { + return maybeString + } + return start + maybeString + end +} + +// Given array, print each item on its own line, wrapped in an indented "{ }" block. +func block(maybeArray interface{}) string { + s := toSliceString(maybeArray) + if len(s) == 0 { + return "{}" + } + return indent("{\n"+join(s, "\n")) + "\n}" +} + +func indent(maybeString interface{}) string { + if maybeString == nil { + return "" + } + switch str := maybeString.(type) { + case string: + return strings.Replace(str, "\n", "\n ", -1) + } + return "" +} + +var printDocASTReducer = map[string]visitor.VisitFunc{ + "Name": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Name: + return visitor.ActionUpdate, node.Value + case map[string]interface{}: + return visitor.ActionUpdate, getMapValue(node, "Value") + } + return visitor.ActionNoChange, nil + }, + "Variable": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Variable: + return visitor.ActionUpdate, fmt.Sprintf("$%v", node.Name) + case map[string]interface{}: + return visitor.ActionUpdate, "$" + getMapValueString(node, "Name") + } + return visitor.ActionNoChange, nil + }, + + // Document + "Document": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Document: + definitions := toSliceString(node.Definitions) + return visitor.ActionUpdate, join(definitions, "\n\n") + "\n" + case map[string]interface{}: + definitions := toSliceString(getMapValue(node, "Definitions")) + return visitor.ActionUpdate, join(definitions, "\n\n") + "\n" + } + return visitor.ActionNoChange, nil + }, + "OperationDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.OperationDefinition: + op := string(node.Operation) + name := fmt.Sprintf("%v", node.Name) + + varDefs := wrap("(", join(toSliceString(node.VariableDefinitions), ", "), ")") + directives := join(toSliceString(node.Directives), " ") + selectionSet := fmt.Sprintf("%v", node.SelectionSet) + // Anonymous queries with no directives or variable definitions can use + // the query short form. + str := "" + if name == "" && directives == "" && varDefs == "" && op == ast.OperationTypeQuery { + str = selectionSet + } else { + str = join([]string{ + op, + join([]string{name, varDefs}, ""), + directives, + selectionSet, + }, " ") + } + return visitor.ActionUpdate, str + case map[string]interface{}: + + op := getMapValueString(node, "Operation") + name := getMapValueString(node, "Name") + + varDefs := wrap("(", join(toSliceString(getMapValue(node, "VariableDefinitions")), ", "), ")") + directives := join(toSliceString(getMapValue(node, "Directives")), " ") + selectionSet := getMapValueString(node, "SelectionSet") + str := "" + if name == "" && directives == "" && varDefs == "" && op == ast.OperationTypeQuery { + str = selectionSet + } else { + str = join([]string{ + op, + join([]string{name, varDefs}, ""), + directives, + selectionSet, + }, " ") + } + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "VariableDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.VariableDefinition: + variable := fmt.Sprintf("%v", node.Variable) + ttype := fmt.Sprintf("%v", node.Type) + defaultValue := fmt.Sprintf("%v", node.DefaultValue) + + return visitor.ActionUpdate, variable + ": " + ttype + wrap(" = ", defaultValue, "") + case map[string]interface{}: + + variable := getMapValueString(node, "Variable") + ttype := getMapValueString(node, "Type") + defaultValue := getMapValueString(node, "DefaultValue") + + return visitor.ActionUpdate, variable + ": " + ttype + wrap(" = ", defaultValue, "") + + } + return visitor.ActionNoChange, nil + }, + "SelectionSet": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.SelectionSet: + str := block(node.Selections) + return visitor.ActionUpdate, str + case map[string]interface{}: + selections := getMapValue(node, "Selections") + str := block(selections) + return visitor.ActionUpdate, str + + } + return visitor.ActionNoChange, nil + }, + "Field": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Argument: + name := fmt.Sprintf("%v", node.Name) + value := fmt.Sprintf("%v", node.Value) + return visitor.ActionUpdate, name + ": " + value + case map[string]interface{}: + + alias := getMapValueString(node, "Alias") + name := getMapValueString(node, "Name") + args := toSliceString(getMapValue(node, "Arguments")) + directives := toSliceString(getMapValue(node, "Directives")) + selectionSet := getMapValueString(node, "SelectionSet") + + str := join( + []string{ + wrap("", alias, ": ") + name + wrap("(", join(args, ", "), ")"), + join(directives, " "), + selectionSet, + }, + " ", + ) + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "Argument": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.FragmentSpread: + name := fmt.Sprintf("%v", node.Name) + directives := toSliceString(node.Directives) + return visitor.ActionUpdate, "..." + name + wrap(" ", join(directives, " "), "") + case map[string]interface{}: + name := getMapValueString(node, "Name") + value := getMapValueString(node, "Value") + return visitor.ActionUpdate, name + ": " + value + } + return visitor.ActionNoChange, nil + }, + + // Fragments + "FragmentSpread": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.InlineFragment: + typeCondition := fmt.Sprintf("%v", node.TypeCondition) + directives := toSliceString(node.Directives) + selectionSet := fmt.Sprintf("%v", node.SelectionSet) + return visitor.ActionUpdate, "... on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet + case map[string]interface{}: + name := getMapValueString(node, "Name") + directives := toSliceString(getMapValue(node, "Directives")) + return visitor.ActionUpdate, "..." + name + wrap(" ", join(directives, " "), "") + } + return visitor.ActionNoChange, nil + }, + "InlineFragment": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case map[string]interface{}: + typeCondition := getMapValueString(node, "TypeCondition") + directives := toSliceString(getMapValue(node, "Directives")) + selectionSet := getMapValueString(node, "SelectionSet") + return visitor.ActionUpdate, + join([]string{ + "...", + wrap("on ", typeCondition, ""), + join(directives, " "), + selectionSet, + }, " ") + } + return visitor.ActionNoChange, nil + }, + "FragmentDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.FragmentDefinition: + name := fmt.Sprintf("%v", node.Name) + typeCondition := fmt.Sprintf("%v", node.TypeCondition) + directives := toSliceString(node.Directives) + selectionSet := fmt.Sprintf("%v", node.SelectionSet) + return visitor.ActionUpdate, "fragment " + name + " on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet + case map[string]interface{}: + name := getMapValueString(node, "Name") + typeCondition := getMapValueString(node, "TypeCondition") + directives := toSliceString(getMapValue(node, "Directives")) + selectionSet := getMapValueString(node, "SelectionSet") + return visitor.ActionUpdate, "fragment " + name + " on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet + } + return visitor.ActionNoChange, nil + }, + + // Value + "IntValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.IntValue: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value) + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Value") + } + return visitor.ActionNoChange, nil + }, + "FloatValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.FloatValue: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value) + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Value") + } + return visitor.ActionNoChange, nil + }, + "StringValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.StringValue: + return visitor.ActionUpdate, `"` + fmt.Sprintf("%v", node.Value) + `"` + case map[string]interface{}: + return visitor.ActionUpdate, `"` + getMapValueString(node, "Value") + `"` + } + return visitor.ActionNoChange, nil + }, + "BooleanValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.BooleanValue: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value) + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Value") + } + return visitor.ActionNoChange, nil + }, + "EnumValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.EnumValue: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value) + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Value") + } + return visitor.ActionNoChange, nil + }, + "ListValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.ListValue: + return visitor.ActionUpdate, "[" + join(toSliceString(node.Values), ", ") + "]" + case map[string]interface{}: + return visitor.ActionUpdate, "[" + join(toSliceString(getMapValue(node, "Values")), ", ") + "]" + } + return visitor.ActionNoChange, nil + }, + "ObjectValue": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.ObjectValue: + return visitor.ActionUpdate, "{" + join(toSliceString(node.Fields), ", ") + "}" + case map[string]interface{}: + return visitor.ActionUpdate, "{" + join(toSliceString(getMapValue(node, "Fields")), ", ") + "}" + } + return visitor.ActionNoChange, nil + }, + "ObjectField": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.ObjectField: + name := fmt.Sprintf("%v", node.Name) + value := fmt.Sprintf("%v", node.Value) + return visitor.ActionUpdate, name + ": " + value + case map[string]interface{}: + name := getMapValueString(node, "Name") + value := getMapValueString(node, "Value") + return visitor.ActionUpdate, name + ": " + value + } + return visitor.ActionNoChange, nil + }, + + // Directive + "Directive": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Directive: + name := fmt.Sprintf("%v", node.Name) + args := toSliceString(node.Arguments) + return visitor.ActionUpdate, "@" + name + wrap("(", join(args, ", "), ")") + case map[string]interface{}: + name := getMapValueString(node, "Name") + args := toSliceString(getMapValue(node, "Arguments")) + return visitor.ActionUpdate, "@" + name + wrap("(", join(args, ", "), ")") + } + return visitor.ActionNoChange, nil + }, + + // Type + "Named": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.Named: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Name) + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Name") + } + return visitor.ActionNoChange, nil + }, + "List": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.List: + return visitor.ActionUpdate, "[" + fmt.Sprintf("%v", node.Type) + "]" + case map[string]interface{}: + return visitor.ActionUpdate, "[" + getMapValueString(node, "Type") + "]" + } + return visitor.ActionNoChange, nil + }, + "NonNull": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.NonNull: + return visitor.ActionUpdate, fmt.Sprintf("%v", node.Type) + "!" + case map[string]interface{}: + return visitor.ActionUpdate, getMapValueString(node, "Type") + "!" + } + return visitor.ActionNoChange, nil + }, + + // Type System Definitions + "SchemaDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.SchemaDefinition: + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "schema", + join(directives, " "), + block(node.OperationTypes), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + operationTypes := toSliceString(getMapValue(node, "OperationTypes")) + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "schema", + join(directives, " "), + block(operationTypes), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "OperationTypeDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.OperationTypeDefinition: + str := fmt.Sprintf("%v: %v", node.Operation, node.Type) + return visitor.ActionUpdate, str + case map[string]interface{}: + operation := getMapValueString(node, "Operation") + ttype := getMapValueString(node, "Type") + str := fmt.Sprintf("%v: %v", operation, ttype) + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "ScalarDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.ScalarDefinition: + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "scalar", + fmt.Sprintf("%v", node.Name), + join(directives, " "), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "scalar", + name, + join(directives, " "), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "ObjectDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.ObjectDefinition: + name := fmt.Sprintf("%v", node.Name) + interfaces := toSliceString(node.Interfaces) + fields := node.Fields + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "type", + name, + wrap("implements ", join(interfaces, ", "), ""), + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + interfaces := toSliceString(getMapValue(node, "Interfaces")) + fields := getMapValue(node, "Fields") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "type", + name, + wrap("implements ", join(interfaces, ", "), ""), + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "FieldDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.FieldDefinition: + name := fmt.Sprintf("%v", node.Name) + ttype := fmt.Sprintf("%v", node.Type) + args := toSliceString(node.Arguments) + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := name + wrap("(", join(args, ", "), ")") + ": " + ttype + wrap(" ", join(directives, " "), "") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + ttype := getMapValueString(node, "Type") + args := toSliceString(getMapValue(node, "Arguments")) + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := name + wrap("(", join(args, ", "), ")") + ": " + ttype + wrap(" ", join(directives, " "), "") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "InputValueDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.InputValueDefinition: + name := fmt.Sprintf("%v", node.Name) + ttype := fmt.Sprintf("%v", node.Type) + defaultValue := fmt.Sprintf("%v", node.DefaultValue) + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + name + ": " + ttype, + wrap("= ", defaultValue, ""), + join(directives, " "), + }, " ") + + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + ttype := getMapValueString(node, "Type") + defaultValue := getMapValueString(node, "DefaultValue") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + name + ": " + ttype, + wrap("= ", defaultValue, ""), + join(directives, " "), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "InterfaceDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.InterfaceDefinition: + name := fmt.Sprintf("%v", node.Name) + fields := node.Fields + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "interface", + name, + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + fields := getMapValue(node, "Fields") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "interface", + name, + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "UnionDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.UnionDefinition: + name := fmt.Sprintf("%v", node.Name) + types := toSliceString(node.Types) + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "union", + name, + join(directives, " "), + "= " + join(types, " | "), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + types := toSliceString(getMapValue(node, "Types")) + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "union", + name, + join(directives, " "), + "= " + join(types, " | "), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "EnumDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.EnumDefinition: + name := fmt.Sprintf("%v", node.Name) + values := node.Values + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "enum", + name, + join(directives, " "), + block(values), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + values := getMapValue(node, "Values") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "enum", + name, + join(directives, " "), + block(values), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "EnumValueDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.EnumValueDefinition: + name := fmt.Sprintf("%v", node.Name) + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + name, + join(directives, " "), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + name, + join(directives, " "), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "InputObjectDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.InputObjectDefinition: + name := fmt.Sprintf("%v", node.Name) + fields := node.Fields + directives := []string{} + for _, directive := range node.Directives { + directives = append(directives, fmt.Sprintf("%v", directive.Name)) + } + str := join([]string{ + "input", + name, + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + fields := getMapValue(node, "Fields") + directives := []string{} + for _, directive := range getMapSliceValue(node, "Directives") { + directives = append(directives, fmt.Sprintf("%v", directive)) + } + str := join([]string{ + "input", + name, + join(directives, " "), + block(fields), + }, " ") + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "TypeExtensionDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.TypeExtensionDefinition: + definition := fmt.Sprintf("%v", node.Definition) + str := "extend " + definition + return visitor.ActionUpdate, str + case map[string]interface{}: + definition := getMapValueString(node, "Definition") + str := "extend " + definition + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, + "DirectiveDefinition": func(p visitor.VisitFuncParams) (string, interface{}) { + switch node := p.Node.(type) { + case *ast.DirectiveDefinition: + args := wrap("(", join(toSliceString(node.Arguments), ", "), ")") + str := fmt.Sprintf("directive @%v%v on %v", node.Name, args, join(toSliceString(node.Locations), " | ")) + return visitor.ActionUpdate, str + case map[string]interface{}: + name := getMapValueString(node, "Name") + locations := toSliceString(getMapValue(node, "Locations")) + args := toSliceString(getMapValue(node, "Arguments")) + argsStr := wrap("(", join(args, ", "), ")") + str := fmt.Sprintf("directive @%v%v on %v", name, argsStr, join(locations, " | ")) + return visitor.ActionUpdate, str + } + return visitor.ActionNoChange, nil + }, +} + +func Print(astNode ast.Node) (printed interface{}) { + defer func() interface{} { + if r := recover(); r != nil { + return fmt.Sprintf("%v", astNode) + } + return printed + }() + printed = visitor.Visit(astNode, &visitor.VisitorOptions{ + LeaveKindMap: printDocASTReducer, + }, nil) + return printed +} -- cgit