aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/graphql-go/graphql/values.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-07-29 18:58:42 +0200
committerMichael Muré <batolettre@gmail.com>2018-07-29 18:58:42 +0200
commit8fa0b258ac89781dae269790a4bde09cbcd2f324 (patch)
treeb9bcf0826f5739f128de52123447cede23291c02 /vendor/github.com/graphql-go/graphql/values.go
parent6363518c85cbd8247a5f6507b8a1dd3903cfb71d (diff)
downloadgit-bug-8fa0b258ac89781dae269790a4bde09cbcd2f324.tar.gz
cleaning
Diffstat (limited to 'vendor/github.com/graphql-go/graphql/values.go')
-rw-r--r--vendor/github.com/graphql-go/graphql/values.go476
1 files changed, 0 insertions, 476 deletions
diff --git a/vendor/github.com/graphql-go/graphql/values.go b/vendor/github.com/graphql-go/graphql/values.go
deleted file mode 100644
index 36cba6ec..00000000
--- a/vendor/github.com/graphql-go/graphql/values.go
+++ /dev/null
@@ -1,476 +0,0 @@
-package graphql
-
-import (
- "encoding/json"
- "fmt"
- "math"
- "reflect"
- "strings"
-
- "github.com/graphql-go/graphql/gqlerrors"
- "github.com/graphql-go/graphql/language/ast"
- "github.com/graphql-go/graphql/language/kinds"
- "github.com/graphql-go/graphql/language/printer"
- "sort"
-)
-
-// Prepares an object map of variableValues of the correct type based on the
-// provided variable definitions and arbitrary input. If the input cannot be
-// parsed to match the variable definitions, a GraphQLError will be returned.
-func getVariableValues(schema Schema, definitionASTs []*ast.VariableDefinition, inputs map[string]interface{}) (map[string]interface{}, error) {
- values := map[string]interface{}{}
- for _, defAST := range definitionASTs {
- if defAST == nil || defAST.Variable == nil || defAST.Variable.Name == nil {
- continue
- }
- varName := defAST.Variable.Name.Value
- varValue, err := getVariableValue(schema, defAST, inputs[varName])
- if err != nil {
- return values, err
- }
- values[varName] = varValue
- }
- return values, nil
-}
-
-// Prepares an object map of argument values given a list of argument
-// definitions and list of argument AST nodes.
-func getArgumentValues(argDefs []*Argument, argASTs []*ast.Argument, variableVariables map[string]interface{}) (map[string]interface{}, error) {
-
- argASTMap := map[string]*ast.Argument{}
- for _, argAST := range argASTs {
- if argAST.Name != nil {
- argASTMap[argAST.Name.Value] = argAST
- }
- }
- results := map[string]interface{}{}
- for _, argDef := range argDefs {
-
- name := argDef.PrivateName
- var valueAST ast.Value
- if argAST, ok := argASTMap[name]; ok {
- valueAST = argAST.Value
- }
- value := valueFromAST(valueAST, argDef.Type, variableVariables)
- if isNullish(value) {
- value = argDef.DefaultValue
- }
- if !isNullish(value) {
- results[name] = value
- }
- }
- return results, nil
-}
-
-// Given a variable definition, and any value of input, return a value which
-// adheres to the variable definition, or throw an error.
-func getVariableValue(schema Schema, definitionAST *ast.VariableDefinition, input interface{}) (interface{}, error) {
- ttype, err := typeFromAST(schema, definitionAST.Type)
- if err != nil {
- return nil, err
- }
- variable := definitionAST.Variable
-
- if ttype == nil || !IsInputType(ttype) {
- return "", gqlerrors.NewError(
- fmt.Sprintf(`Variable "$%v" expected value of type `+
- `"%v" which cannot be used as an input type.`, variable.Name.Value, printer.Print(definitionAST.Type)),
- []ast.Node{definitionAST},
- "",
- nil,
- []int{},
- nil,
- )
- }
-
- isValid, messages := isValidInputValue(input, ttype)
- if isValid {
- if isNullish(input) {
- defaultValue := definitionAST.DefaultValue
- if defaultValue != nil {
- variables := map[string]interface{}{}
- val := valueFromAST(defaultValue, ttype, variables)
- return val, nil
- }
- }
- return coerceValue(ttype, input), nil
- }
- if isNullish(input) {
- return "", gqlerrors.NewError(
- fmt.Sprintf(`Variable "$%v" of required type `+
- `"%v" was not provided.`, variable.Name.Value, printer.Print(definitionAST.Type)),
- []ast.Node{definitionAST},
- "",
- nil,
- []int{},
- nil,
- )
- }
- // convert input interface into string for error message
- inputStr := ""
- b, err := json.Marshal(input)
- if err == nil {
- inputStr = string(b)
- }
- messagesStr := ""
- if len(messages) > 0 {
- messagesStr = "\n" + strings.Join(messages, "\n")
- }
-
- return "", gqlerrors.NewError(
- fmt.Sprintf(`Variable "$%v" got invalid value `+
- `%v.%v`, variable.Name.Value, inputStr, messagesStr),
- []ast.Node{definitionAST},
- "",
- nil,
- []int{},
- nil,
- )
-}
-
-// Given a type and any value, return a runtime value coerced to match the type.
-func coerceValue(ttype Input, value interface{}) interface{} {
- if ttype, ok := ttype.(*NonNull); ok {
- return coerceValue(ttype.OfType, value)
- }
- if isNullish(value) {
- return nil
- }
- if ttype, ok := ttype.(*List); ok {
- itemType := ttype.OfType
- valType := reflect.ValueOf(value)
- if valType.Kind() == reflect.Slice {
- values := []interface{}{}
- for i := 0; i < valType.Len(); i++ {
- val := valType.Index(i).Interface()
- v := coerceValue(itemType, val)
- values = append(values, v)
- }
- return values
- }
- val := coerceValue(itemType, value)
- return []interface{}{val}
- }
- if ttype, ok := ttype.(*InputObject); ok {
-
- valueMap, ok := value.(map[string]interface{})
- if !ok {
- valueMap = map[string]interface{}{}
- }
-
- obj := map[string]interface{}{}
- for fieldName, field := range ttype.Fields() {
- value, _ := valueMap[fieldName]
- fieldValue := coerceValue(field.Type, value)
- if isNullish(fieldValue) {
- fieldValue = field.DefaultValue
- }
- if !isNullish(fieldValue) {
- obj[fieldName] = fieldValue
- }
- }
- return obj
- }
-
- switch ttype := ttype.(type) {
- case *Scalar:
- parsed := ttype.ParseValue(value)
- if !isNullish(parsed) {
- return parsed
- }
- case *Enum:
- parsed := ttype.ParseValue(value)
- if !isNullish(parsed) {
- return parsed
- }
- }
- return nil
-}
-
-// graphql-js/src/utilities.js`
-// TODO: figure out where to organize utils
-// TODO: change to *Schema
-func typeFromAST(schema Schema, inputTypeAST ast.Type) (Type, error) {
- switch inputTypeAST := inputTypeAST.(type) {
- case *ast.List:
- innerType, err := typeFromAST(schema, inputTypeAST.Type)
- if err != nil {
- return nil, err
- }
- return NewList(innerType), nil
- case *ast.NonNull:
- innerType, err := typeFromAST(schema, inputTypeAST.Type)
- if err != nil {
- return nil, err
- }
- return NewNonNull(innerType), nil
- case *ast.Named:
- nameValue := ""
- if inputTypeAST.Name != nil {
- nameValue = inputTypeAST.Name.Value
- }
- ttype := schema.Type(nameValue)
- return ttype, nil
- default:
- return nil, invariant(inputTypeAST.GetKind() == kinds.Named, "Must be a named type.")
- }
-}
-
-// isValidInputValue alias isValidJSValue
-// Given a value and a GraphQL type, determine if the value will be
-// accepted for that type. This is primarily useful for validating the
-// runtime values of query variables.
-func isValidInputValue(value interface{}, ttype Input) (bool, []string) {
- if ttype, ok := ttype.(*NonNull); ok {
- if isNullish(value) {
- if ttype.OfType.Name() != "" {
- return false, []string{fmt.Sprintf(`Expected "%v!", found null.`, ttype.OfType.Name())}
- }
- return false, []string{"Expected non-null value, found null."}
- }
- return isValidInputValue(value, ttype.OfType)
- }
-
- if isNullish(value) {
- return true, nil
- }
-
- switch ttype := ttype.(type) {
- case *List:
- itemType := ttype.OfType
- valType := reflect.ValueOf(value)
- if valType.Kind() == reflect.Ptr {
- valType = valType.Elem()
- }
- if valType.Kind() == reflect.Slice {
- messagesReduce := []string{}
- for i := 0; i < valType.Len(); i++ {
- val := valType.Index(i).Interface()
- _, messages := isValidInputValue(val, itemType)
- for idx, message := range messages {
- messagesReduce = append(messagesReduce, fmt.Sprintf(`In element #%v: %v`, idx+1, message))
- }
- }
- return (len(messagesReduce) == 0), messagesReduce
- }
- return isValidInputValue(value, itemType)
-
- case *InputObject:
- messagesReduce := []string{}
-
- valueMap, ok := value.(map[string]interface{})
- if !ok {
- return false, []string{fmt.Sprintf(`Expected "%v", found not an object.`, ttype.Name())}
- }
- fields := ttype.Fields()
-
- // to ensure stable order of field evaluation
- fieldNames := []string{}
- valueMapFieldNames := []string{}
-
- for fieldName := range fields {
- fieldNames = append(fieldNames, fieldName)
- }
- sort.Strings(fieldNames)
-
- for fieldName := range valueMap {
- valueMapFieldNames = append(valueMapFieldNames, fieldName)
- }
- sort.Strings(valueMapFieldNames)
-
- // Ensure every provided field is defined.
- for _, fieldName := range valueMapFieldNames {
- if _, ok := fields[fieldName]; !ok {
- messagesReduce = append(messagesReduce, fmt.Sprintf(`In field "%v": Unknown field.`, fieldName))
- }
- }
-
- // Ensure every defined field is valid.
- for _, fieldName := range fieldNames {
- _, messages := isValidInputValue(valueMap[fieldName], fields[fieldName].Type)
- if messages != nil {
- for _, message := range messages {
- messagesReduce = append(messagesReduce, fmt.Sprintf(`In field "%v": %v`, fieldName, message))
- }
- }
- }
- return (len(messagesReduce) == 0), messagesReduce
- }
-
- switch ttype := ttype.(type) {
- case *Scalar:
- parsedVal := ttype.ParseValue(value)
- if isNullish(parsedVal) {
- return false, []string{fmt.Sprintf(`Expected type "%v", found "%v".`, ttype.Name(), value)}
- }
- return true, nil
-
- case *Enum:
- parsedVal := ttype.ParseValue(value)
- if isNullish(parsedVal) {
- return false, []string{fmt.Sprintf(`Expected type "%v", found "%v".`, ttype.Name(), value)}
- }
- return true, nil
- }
- return true, nil
-}
-
-// Returns true if a value is null, undefined, or NaN.
-func isNullish(value interface{}) bool {
- if value, ok := value.(*string); ok {
- if value == nil {
- return true
- }
- return *value == ""
- }
- if value, ok := value.(int); ok {
- return math.IsNaN(float64(value))
- }
- if value, ok := value.(*int); ok {
- if value == nil {
- return true
- }
- return math.IsNaN(float64(*value))
- }
- if value, ok := value.(float32); ok {
- return math.IsNaN(float64(value))
- }
- if value, ok := value.(*float32); ok {
- if value == nil {
- return true
- }
- return math.IsNaN(float64(*value))
- }
- if value, ok := value.(float64); ok {
- return math.IsNaN(value)
- }
- if value, ok := value.(*float64); ok {
- if value == nil {
- return true
- }
- return math.IsNaN(*value)
- }
- return value == nil
-}
-
-/**
- * Produces a value given a GraphQL Value AST.
- *
- * A GraphQL type must be provided, which will be used to interpret different
- * GraphQL Value literals.
- *
- * | GraphQL Value | JSON Value |
- * | -------------------- | ------------- |
- * | Input Object | Object |
- * | List | Array |
- * | Boolean | Boolean |
- * | String / Enum Value | String |
- * | Int / Float | Number |
- *
- */
-func valueFromAST(valueAST ast.Value, ttype Input, variables map[string]interface{}) interface{} {
-
- if ttype, ok := ttype.(*NonNull); ok {
- val := valueFromAST(valueAST, ttype.OfType, variables)
- return val
- }
-
- if valueAST == nil {
- return nil
- }
-
- if valueAST, ok := valueAST.(*ast.Variable); ok && valueAST.Kind == kinds.Variable {
- if valueAST.Name == nil {
- return nil
- }
- if variables == nil {
- return nil
- }
- variableName := valueAST.Name.Value
- variableVal, ok := variables[variableName]
- if !ok {
- return nil
- }
- // Note: we're not doing any checking that this variable is correct. We're
- // assuming that this query has been validated and the variable usage here
- // is of the correct type.
- return variableVal
- }
-
- if ttype, ok := ttype.(*List); ok {
- itemType := ttype.OfType
- if valueAST, ok := valueAST.(*ast.ListValue); ok && valueAST.Kind == kinds.ListValue {
- values := []interface{}{}
- for _, itemAST := range valueAST.Values {
- v := valueFromAST(itemAST, itemType, variables)
- values = append(values, v)
- }
- return values
- }
- v := valueFromAST(valueAST, itemType, variables)
- return []interface{}{v}
- }
-
- if ttype, ok := ttype.(*InputObject); ok {
- valueAST, ok := valueAST.(*ast.ObjectValue)
- if !ok {
- return nil
- }
- fieldASTs := map[string]*ast.ObjectField{}
- for _, fieldAST := range valueAST.Fields {
- if fieldAST.Name == nil {
- continue
- }
- fieldName := fieldAST.Name.Value
- fieldASTs[fieldName] = fieldAST
-
- }
- obj := map[string]interface{}{}
- for fieldName, field := range ttype.Fields() {
- fieldAST, ok := fieldASTs[fieldName]
- fieldValue := field.DefaultValue
- if !ok || fieldAST == nil {
- if fieldValue == nil {
- continue
- }
- } else {
- fieldValue = valueFromAST(fieldAST.Value, field.Type, variables)
- }
- if isNullish(fieldValue) {
- fieldValue = field.DefaultValue
- }
- if !isNullish(fieldValue) {
- obj[fieldName] = fieldValue
- }
- }
- return obj
- }
-
- switch ttype := ttype.(type) {
- case *Scalar:
- parsed := ttype.ParseLiteral(valueAST)
- if !isNullish(parsed) {
- return parsed
- }
- case *Enum:
- parsed := ttype.ParseLiteral(valueAST)
- if !isNullish(parsed) {
- return parsed
- }
- }
- return nil
-}
-
-func invariant(condition bool, message string) error {
- if !condition {
- return gqlerrors.NewFormattedError(message)
- }
- return nil
-}
-
-func invariantf(condition bool, format string, a ...interface{}) error {
- if !condition {
- return gqlerrors.NewFormattedError(fmt.Sprintf(format, a...))
- }
- return nil
-}