Skip to content

Commit

Permalink
feat: upgrade graphql-go-tools to add support directive @skipVariable…
Browse files Browse the repository at this point in the history
…, and make selection field print full hash.
  • Loading branch information
xufeixiang committed Jul 8, 2024
1 parent 5c3c4a8 commit 901ed6f
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 37 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ replace (
github.com/flowchartsman/handlebars/v3 => github.com/fireboomio/handlebars/v3 v3.0.0-20230407011829-1693185f0572
github.com/getkin/kin-openapi => github.com/fireboomio/kin-openapi v0.0.0-20240110095352-e1b4433e41a8
github.com/prisma/prisma-client-go => github.com/fireboomio/prisma-client-go v0.0.0-20240614073744-961bb930abe4
github.com/wundergraph/graphql-go-tools => github.com/fireboomio/graphql-go-tools v0.0.0-20240703072500-fc69278ee0b1
github.com/wundergraph/graphql-go-tools => github.com/fireboomio/graphql-go-tools v0.0.0-20240708121000-974ee4a81bb3
github.com/wundergraph/wundergraph => ./wundergraphGitSubmodule

)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fireboomio/graphql-go-tools v0.0.0-20240703072500-fc69278ee0b1 h1:ni147HmVTMkt2G6mnsXb/ovMgrlImQc2vYBMEPQJbYg=
github.com/fireboomio/graphql-go-tools v0.0.0-20240703072500-fc69278ee0b1/go.mod h1:8Lj3WnDT5m+QGamBlqAqwn++OVcL30FXG+o6kf810bc=
github.com/fireboomio/graphql-go-tools v0.0.0-20240708121000-974ee4a81bb3 h1:SVsFfja4ZX7Lq6Tl4j+KuTue8y/i7ErprceNPtofUTg=
github.com/fireboomio/graphql-go-tools v0.0.0-20240708121000-974ee4a81bb3/go.mod h1:8Lj3WnDT5m+QGamBlqAqwn++OVcL30FXG+o6kf810bc=
github.com/fireboomio/handlebars/v3 v3.0.0-20230407011829-1693185f0572 h1:utP3HLcMr38qlFFzMwjQeUWM0jxg+MPgktKucOQ2t4I=
github.com/fireboomio/handlebars/v3 v3.0.0-20230407011829-1693185f0572/go.mod h1:zdeQ3Qna7Bd2JQiobPXuZKDOG3j7Byo6uXDaMLXHVAw=
github.com/fireboomio/kin-openapi v0.0.0-20240110095352-e1b4433e41a8 h1:KaancvImcVJEnUVUxDwugkP6F7Yvb2FgasDuVkknZeU=
Expand Down
83 changes: 51 additions & 32 deletions pkg/engine/build/engine_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,38 @@ func init() {
})
}

type engineConfiguration struct {
modelName string
engineConfig *wgpb.EngineConfiguration
typeConfigurationFlags map[string]bool
fieldArgumentTypeNames map[string][]string
}
type (
rootDefinitionInfo struct {
definition *ast.Definition
fieldIndexes map[string]int
}
engineConfiguration struct {
modelName string
engineConfig *wgpb.EngineConfiguration
typeConfigurationFlags map[string]bool
fieldArgumentTypeNames map[string][]string
rootDefinitionInfos map[string]*rootDefinitionInfo
}
)

func (e *engineConfiguration) Resolve(builder *Builder) (err error) {
e.engineConfig = &wgpb.EngineConfiguration{}
e.typeConfigurationFlags = make(map[string]bool, math.MaxUint8)
e.fieldArgumentTypeNames = make(map[string][]string, math.MaxUint8)

sources := models.DatasourceRoot.ListByCondition(func(item *models.Datasource) bool { return item.Enabled })
if len(sources) == 0 {
logger.Warn("empty datasource")
return
}

directiveMap := make(map[string]*ast.DirectiveDefinition)
rootDefinitionMap, otherDefinitionMap := make(map[string]*ast.Definition), make(map[string]*ast.Definition, math.MaxInt8)
e.engineConfig = &wgpb.EngineConfiguration{}
e.typeConfigurationFlags = make(map[string]bool, math.MaxUint8)
e.fieldArgumentTypeNames = make(map[string][]string, math.MaxUint8)
e.rootDefinitionInfos = make(map[string]*rootDefinitionInfo)
directiveMap, otherDefinitionMap := make(map[string]*ast.DirectiveDefinition), make(map[string]*ast.Definition, math.MaxInt8)
// 添加根类型Query/Mutation/Subscription
for _, name := range datasource.RootObjectNames {
rootDefinitionMap[name] = &ast.Definition{Kind: ast.Object, Name: name}
e.rootDefinitionInfos[name] = &rootDefinitionInfo{
definition: &ast.Definition{Kind: ast.Object, Name: name},
fieldIndexes: make(map[string]int),
}
}

var itemAction datasource.Action
Expand Down Expand Up @@ -114,8 +123,11 @@ func (e *engineConfiguration) Resolve(builder *Builder) (err error) {
itemDefinitionName = itemRootOperation
}

if root, ok := rootDefinitionMap[itemDefinitionName]; ok {
root.Fields = append(root.Fields, itemDefinition.Fields...)
if rootDefInfo, ok := e.rootDefinitionInfos[itemDefinitionName]; ok {
for _, field := range itemDefinition.Fields {
rootDefInfo.fieldIndexes[field.Name] = len(rootDefInfo.definition.Fields)
rootDefInfo.definition.Fields = append(rootDefInfo.definition.Fields, field)
}
continue
}

Expand All @@ -138,12 +150,12 @@ func (e *engineConfiguration) Resolve(builder *Builder) (err error) {
var operationTypes ast.OperationTypeDefinitionList
definitions := make(ast.DefinitionList, 0, len(otherDefinitionMap)+len(datasource.RootObjectNames))
for _, name := range datasource.RootObjectNames {
rootDefinition := rootDefinitionMap[name]
if len(rootDefinition.Fields) == 0 {
rootDefInfo := e.rootDefinitionInfos[name]
if len(rootDefInfo.definition.Fields) == 0 {
continue
}

definitions = append(definitions, rootDefinition)
definitions = append(definitions, rootDefInfo.definition)
operationTypes = append(operationTypes, &ast.OperationTypeDefinition{
Type: name, Operation: ast.Operation(strings.ToLower(name)),
})
Expand Down Expand Up @@ -292,33 +304,40 @@ func (e *engineConfiguration) calculateRootFieldHash(builder *Builder, fieldDefi
dsConfig := e.engineConfig.DatasourceConfigurations[dsIndex]
for nodeIndex := range dsConfig.RootNodes {
rootNode := dsConfig.RootNodes[nodeIndex]
rootDefInfo, rootDefFound := e.rootDefinitionInfos[rootNode.TypeName]
if !rootDefFound {
continue
}
for i := range rootNode.FieldNames {
fieldIndex, fieldName := i, rootNode.FieldNames[i]
rootFieldIndex, rootFieldFound := rootDefInfo.fieldIndexes[fieldName]
if !rootFieldFound {
continue
}
builder.FieldHashes.Store(fieldName, &LazyFieldHash{
lazyFunc: func() string {
buf := pool.GetBytesBuffer()
defer pool.PutBytesBuffer(buf)
document := &ast.SchemaDocument{}
format := formatter.NewFormatter(buf, formatter.WithIndent(""))
fieldConfigNames := []string{utils.JoinStringWithDot(rootNode.TypeName, fieldName)}
definitionNames := e.fieldArgumentTypeNames[utils.JoinStringWithDot(rootNode.TypeName, fieldName)]
if quotes, ok := rootNode.Quotes[int32(fieldIndex)]; ok {
for _, quoteIndex := range quotes.Indexes {
childNode := dsConfig.ChildNodes[quoteIndex]
document.Definitions = append(document.Definitions, fieldDefinitions[childNode.TypeName])
definitionNames = append(definitionNames, childNode.TypeName)
for _, childFieldName := range childNode.FieldNames {
fieldConfigNames = append(fieldConfigNames, utils.JoinStringWithDot(childNode.TypeName, childFieldName))
definitionNames = append(definitionNames, e.fieldArgumentTypeNames[utils.JoinStringWithDot(childNode.TypeName, childFieldName)]...)
}
}
}
for _, fieldConfigName := range fieldConfigNames {
for _, argTypeName := range e.fieldArgumentTypeNames[fieldConfigName] {
if argTypeDefinition := fieldDefinitions[argTypeName]; !slices.Contains(document.Definitions, argTypeDefinition) {
document.Definitions = append(document.Definitions, argTypeDefinition)
}

document := &ast.SchemaDocument{Definitions: []*ast.Definition{{
Kind: ast.Object, Name: rootNode.TypeName, Fields: []*ast.FieldDefinition{rootDefInfo.definition.Fields[rootFieldIndex]},
}}}
for _, name := range definitionNames {
if definition, ok := fieldDefinitions[name]; ok && !slices.Contains(document.Definitions, definition) {
document.Definitions = append(document.Definitions, definition)
}
}
format.FormatSchemaDocument(document)
buf.WriteString(fieldName)
buf := pool.GetBytesBuffer()
defer pool.PutBytesBuffer(buf)
formatter.NewFormatter(buf, formatter.WithIndent("")).FormatSchemaDocument(document)
return fmt.Sprintf("%x", md5.Sum(buf.Bytes()))
},
})
Expand Down
46 changes: 46 additions & 0 deletions pkg/engine/directives/selection_skipvariable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Package directives
/*
实现VariableDirective接口,只能定义在LocationVariableDefinition上
Resolve 标识参数内部传递,与@export组合使用
*/
package directives

import (
"fireboom-server/pkg/common/consts"
"fireboom-server/pkg/plugins/i18n"
"github.com/vektah/gqlparser/v2/ast"
)

const (
skipVariableName = "skipVariable"
skipVariableArgName = "variables"
)

type skipVariable struct{}

func (s *skipVariable) Directive() *ast.DirectiveDefinition {
return &ast.DirectiveDefinition{
Description: prependMockAllowed(appendIfExistExampleGraphql(i18n.SkipVariableDesc.String())),
Name: skipVariableName,
Locations: []ast.DirectiveLocation{ast.LocationField},
Arguments: ast.ArgumentDefinitionList{{
Name: skipVariableArgName,
Type: ast.NonNullListType(&ast.Type{NamedType: consts.ScalarString}, nil),
}, {
Name: argIfRuleName,
Type: ast.NonNullNamedType(consts.ScalarString, nil),
}},
}
}

func (s *skipVariable) Definitions() ast.DefinitionList {
return nil
}

func (s *skipVariable) Resolve(resolver *SelectionResolver) (err error) {
return includeDirective.Resolve(resolver)
}

func init() {
registerDirective(skipVariableName, &skipVariable{})
}
1 change: 1 addition & 0 deletions pkg/plugins/i18n/directive.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,4 @@ const InjectRuleValueDesc Directive = iota + 11101

const DisallowParallelDesc Directive = iota + 11201
const CustomizedFieldDesc Directive = iota + 11301
const SkipVariableDesc Directive = iota + 11401
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SkipVariableDesc = "作用于标量选择集上,根据条件跳过参数填充"
4 changes: 3 additions & 1 deletion pkg/plugins/i18n/directive_i18n_string.go

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

2 changes: 1 addition & 1 deletion wundergraphGitSubmodule
Submodule wundergraphGitSubmodule updated 2 files
+1 −1 go.mod
+2 −2 go.sum

0 comments on commit 901ed6f

Please sign in to comment.