예제 #1
0
func (ctx *ValidationContext) VariableUsages(node HasSelectionSet) []*VariableUsage {
	if usages, ok := ctx.variableUsages[node]; ok && usages != nil {
		return usages
	}
	usages := []*VariableUsage{}
	typeInfo := NewTypeInfo(&TypeInfoConfig{
		Schema: ctx.schema,
	})

	visitor.Visit(node, visitor.VisitWithTypeInfo(typeInfo, &visitor.VisitorOptions{
		KindFuncMap: map[string]visitor.NamedVisitFuncs{
			kinds.VariableDefinition: visitor.NamedVisitFuncs{
				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
					return visitor.ActionSkip, nil
				},
			},
			kinds.Variable: visitor.NamedVisitFuncs{
				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
					if node, ok := p.Node.(*ast.Variable); ok && node != nil {
						usages = append(usages, &VariableUsage{
							Node: node,
							Type: typeInfo.InputType(),
						})
					}
					return visitor.ActionNoChange, nil
				},
			},
		},
	}), nil)

	ctx.variableUsages[node] = usages
	return usages
}
예제 #2
0
// VisitUsingRules This uses a specialized visitor which runs multiple visitors in parallel,
// while maintaining the visitor skip and break API.
//
// @internal
// Had to expose it to unit test experimental customizable validation feature,
// but not meant for public consumption
func VisitUsingRules(schema *Schema, typeInfo *TypeInfo, astDoc *ast.Document, rules []ValidationRuleFn) []gqlerrors.FormattedError {

	context := NewValidationContext(schema, astDoc, typeInfo)
	visitors := []*visitor.VisitorOptions{}

	for _, rule := range rules {
		instance := rule(context)
		visitors = append(visitors, instance.VisitorOpts)
	}

	// Visit the whole document with each instance of all provided rules.
	visitor.Visit(astDoc, visitor.VisitWithTypeInfo(typeInfo, visitor.VisitInParallel(visitors...)), nil)
	return context.Errors()
}