diff options
Diffstat (limited to 'vendor/github.com/graphql-go/graphql/definition.go')
-rw-r--r-- | vendor/github.com/graphql-go/graphql/definition.go | 1340 |
1 files changed, 0 insertions, 1340 deletions
diff --git a/vendor/github.com/graphql-go/graphql/definition.go b/vendor/github.com/graphql-go/graphql/definition.go deleted file mode 100644 index dffea080..00000000 --- a/vendor/github.com/graphql-go/graphql/definition.go +++ /dev/null @@ -1,1340 +0,0 @@ -package graphql - -import ( - "context" - "fmt" - "reflect" - "regexp" - - "github.com/graphql-go/graphql/language/ast" -) - -// Type interface for all of the possible kinds of GraphQL types -type Type interface { - Name() string - Description() string - String() string - Error() error -} - -var _ Type = (*Scalar)(nil) -var _ Type = (*Object)(nil) -var _ Type = (*Interface)(nil) -var _ Type = (*Union)(nil) -var _ Type = (*Enum)(nil) -var _ Type = (*InputObject)(nil) -var _ Type = (*List)(nil) -var _ Type = (*NonNull)(nil) -var _ Type = (*Argument)(nil) - -// Input interface for types that may be used as input types for arguments and directives. -type Input interface { - Name() string - Description() string - String() string - Error() error -} - -var _ Input = (*Scalar)(nil) -var _ Input = (*Enum)(nil) -var _ Input = (*InputObject)(nil) -var _ Input = (*List)(nil) -var _ Input = (*NonNull)(nil) - -// IsInputType determines if given type is a GraphQLInputType -func IsInputType(ttype Type) bool { - named := GetNamed(ttype) - if _, ok := named.(*Scalar); ok { - return true - } - if _, ok := named.(*Enum); ok { - return true - } - if _, ok := named.(*InputObject); ok { - return true - } - return false -} - -// IsOutputType determines if given type is a GraphQLOutputType -func IsOutputType(ttype Type) bool { - name := GetNamed(ttype) - if _, ok := name.(*Scalar); ok { - return true - } - if _, ok := name.(*Object); ok { - return true - } - if _, ok := name.(*Interface); ok { - return true - } - if _, ok := name.(*Union); ok { - return true - } - if _, ok := name.(*Enum); ok { - return true - } - return false -} - -// Leaf interface for types that may be leaf values -type Leaf interface { - Name() string - Description() string - String() string - Error() error - Serialize(value interface{}) interface{} -} - -var _ Leaf = (*Scalar)(nil) -var _ Leaf = (*Enum)(nil) - -// IsLeafType determines if given type is a leaf value -func IsLeafType(ttype Type) bool { - named := GetNamed(ttype) - if _, ok := named.(*Scalar); ok { - return true - } - if _, ok := named.(*Enum); ok { - return true - } - return false -} - -// Output interface for types that may be used as output types as the result of fields. -type Output interface { - Name() string - Description() string - String() string - Error() error -} - -var _ Output = (*Scalar)(nil) -var _ Output = (*Object)(nil) -var _ Output = (*Interface)(nil) -var _ Output = (*Union)(nil) -var _ Output = (*Enum)(nil) -var _ Output = (*List)(nil) -var _ Output = (*NonNull)(nil) - -// Composite interface for types that may describe the parent context of a selection set. -type Composite interface { - Name() string - Description() string - String() string - Error() error -} - -var _ Composite = (*Object)(nil) -var _ Composite = (*Interface)(nil) -var _ Composite = (*Union)(nil) - -// IsCompositeType determines if given type is a GraphQLComposite type -func IsCompositeType(ttype interface{}) bool { - if _, ok := ttype.(*Object); ok { - return true - } - if _, ok := ttype.(*Interface); ok { - return true - } - if _, ok := ttype.(*Union); ok { - return true - } - return false -} - -// Abstract interface for types that may describe the parent context of a selection set. -type Abstract interface { - Name() string -} - -var _ Abstract = (*Interface)(nil) -var _ Abstract = (*Union)(nil) - -func IsAbstractType(ttype interface{}) bool { - if _, ok := ttype.(*Interface); ok { - return true - } - if _, ok := ttype.(*Union); ok { - return true - } - return false -} - -// Nullable interface for types that can accept null as a value. -type Nullable interface { -} - -var _ Nullable = (*Scalar)(nil) -var _ Nullable = (*Object)(nil) -var _ Nullable = (*Interface)(nil) -var _ Nullable = (*Union)(nil) -var _ Nullable = (*Enum)(nil) -var _ Nullable = (*InputObject)(nil) -var _ Nullable = (*List)(nil) - -// GetNullable returns the Nullable type of the given GraphQL type -func GetNullable(ttype Type) Nullable { - if ttype, ok := ttype.(*NonNull); ok { - return ttype.OfType - } - return ttype -} - -// Named interface for types that do not include modifiers like List or NonNull. -type Named interface { - String() string -} - -var _ Named = (*Scalar)(nil) -var _ Named = (*Object)(nil) -var _ Named = (*Interface)(nil) -var _ Named = (*Union)(nil) -var _ Named = (*Enum)(nil) -var _ Named = (*InputObject)(nil) - -// GetNamed returns the Named type of the given GraphQL type -func GetNamed(ttype Type) Named { - unmodifiedType := ttype - for { - if ttype, ok := unmodifiedType.(*List); ok { - unmodifiedType = ttype.OfType - continue - } - if ttype, ok := unmodifiedType.(*NonNull); ok { - unmodifiedType = ttype.OfType - continue - } - break - } - return unmodifiedType -} - -// Scalar Type Definition -// -// The leaf values of any request and input values to arguments are -// Scalars (or Enums) and are defined with a name and a series of functions -// used to parse input from ast or variables and to ensure validity. -// -// Example: -// -// var OddType = new Scalar({ -// name: 'Odd', -// serialize(value) { -// return value % 2 === 1 ? value : null; -// } -// }); -// -type Scalar struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - - scalarConfig ScalarConfig - err error -} - -// SerializeFn is a function type for serializing a GraphQLScalar type value -type SerializeFn func(value interface{}) interface{} - -// ParseValueFn is a function type for parsing the value of a GraphQLScalar type -type ParseValueFn func(value interface{}) interface{} - -// ParseLiteralFn is a function type for parsing the literal value of a GraphQLScalar type -type ParseLiteralFn func(valueAST ast.Value) interface{} - -// ScalarConfig options for creating a new GraphQLScalar -type ScalarConfig struct { - Name string `json:"name"` - Description string `json:"description"` - Serialize SerializeFn - ParseValue ParseValueFn - ParseLiteral ParseLiteralFn -} - -// NewScalar creates a new GraphQLScalar -func NewScalar(config ScalarConfig) *Scalar { - st := &Scalar{} - err := invariant(config.Name != "", "Type must be named.") - if err != nil { - st.err = err - return st - } - - err = assertValidName(config.Name) - if err != nil { - st.err = err - return st - } - - st.PrivateName = config.Name - st.PrivateDescription = config.Description - - err = invariantf( - config.Serialize != nil, - `%v must provide "serialize" function. If this custom Scalar is `+ - `also used as an input type, ensure "parseValue" and "parseLiteral" `+ - `functions are also provided.`, st, - ) - if err != nil { - st.err = err - return st - } - if config.ParseValue != nil || config.ParseLiteral != nil { - err = invariantf( - config.ParseValue != nil && config.ParseLiteral != nil, - `%v must provide both "parseValue" and "parseLiteral" functions.`, st, - ) - if err != nil { - st.err = err - return st - } - } - - st.scalarConfig = config - return st -} -func (st *Scalar) Serialize(value interface{}) interface{} { - if st.scalarConfig.Serialize == nil { - return value - } - return st.scalarConfig.Serialize(value) -} -func (st *Scalar) ParseValue(value interface{}) interface{} { - if st.scalarConfig.ParseValue == nil { - return value - } - return st.scalarConfig.ParseValue(value) -} -func (st *Scalar) ParseLiteral(valueAST ast.Value) interface{} { - if st.scalarConfig.ParseLiteral == nil { - return nil - } - return st.scalarConfig.ParseLiteral(valueAST) -} -func (st *Scalar) Name() string { - return st.PrivateName -} -func (st *Scalar) Description() string { - return st.PrivateDescription - -} -func (st *Scalar) String() string { - return st.PrivateName -} -func (st *Scalar) Error() error { - return st.err -} - -// Object Type Definition -// -// Almost all of the GraphQL types you define will be object Object types -// have a name, but most importantly describe their fields. -// Example: -// -// var AddressType = new Object({ -// name: 'Address', -// fields: { -// street: { type: String }, -// number: { type: Int }, -// formatted: { -// type: String, -// resolve(obj) { -// return obj.number + ' ' + obj.street -// } -// } -// } -// }); -// -// When two types need to refer to each other, or a type needs to refer to -// itself in a field, you can use a function expression (aka a closure or a -// thunk) to supply the fields lazily. -// -// Example: -// -// var PersonType = new Object({ -// name: 'Person', -// fields: () => ({ -// name: { type: String }, -// bestFriend: { type: PersonType }, -// }) -// }); -// -// / -type Object struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - IsTypeOf IsTypeOfFn - - typeConfig ObjectConfig - initialisedFields bool - fields FieldDefinitionMap - initialisedInterfaces bool - interfaces []*Interface - // Interim alternative to throwing an error during schema definition at run-time - err error -} - -// IsTypeOfParams Params for IsTypeOfFn() -type IsTypeOfParams struct { - // Value that needs to be resolve. - // Use this to decide which GraphQLObject this value maps to. - Value interface{} - - // Info is a collection of information about the current execution state. - Info ResolveInfo - - // Context argument is a context value that is provided to every resolve function within an execution. - // It is commonly - // used to represent an authenticated user, or request-specific caches. - Context context.Context -} - -type IsTypeOfFn func(p IsTypeOfParams) bool - -type InterfacesThunk func() []*Interface - -type ObjectConfig struct { - Name string `json:"name"` - Interfaces interface{} `json:"interfaces"` - Fields interface{} `json:"fields"` - IsTypeOf IsTypeOfFn `json:"isTypeOf"` - Description string `json:"description"` -} - -type FieldsThunk func() Fields - -func NewObject(config ObjectConfig) *Object { - objectType := &Object{} - - err := invariant(config.Name != "", "Type must be named.") - if err != nil { - objectType.err = err - return objectType - } - err = assertValidName(config.Name) - if err != nil { - objectType.err = err - return objectType - } - - objectType.PrivateName = config.Name - objectType.PrivateDescription = config.Description - objectType.IsTypeOf = config.IsTypeOf - objectType.typeConfig = config - - return objectType -} -func (gt *Object) AddFieldConfig(fieldName string, fieldConfig *Field) { - if fieldName == "" || fieldConfig == nil { - return - } - switch gt.typeConfig.Fields.(type) { - case Fields: - gt.typeConfig.Fields.(Fields)[fieldName] = fieldConfig - gt.initialisedFields = false - } -} -func (gt *Object) Name() string { - return gt.PrivateName -} -func (gt *Object) Description() string { - return "" -} -func (gt *Object) String() string { - return gt.PrivateName -} -func (gt *Object) Fields() FieldDefinitionMap { - if gt.initialisedFields { - return gt.fields - } - - var configureFields Fields - switch gt.typeConfig.Fields.(type) { - case Fields: - configureFields = gt.typeConfig.Fields.(Fields) - case FieldsThunk: - configureFields = gt.typeConfig.Fields.(FieldsThunk)() - } - - fields, err := defineFieldMap(gt, configureFields) - gt.err = err - gt.fields = fields - gt.initialisedFields = true - return gt.fields -} - -func (gt *Object) Interfaces() []*Interface { - if gt.initialisedInterfaces { - return gt.interfaces - } - - var configInterfaces []*Interface - switch gt.typeConfig.Interfaces.(type) { - case InterfacesThunk: - configInterfaces = gt.typeConfig.Interfaces.(InterfacesThunk)() - case []*Interface: - configInterfaces = gt.typeConfig.Interfaces.([]*Interface) - case nil: - default: - gt.err = fmt.Errorf("Unknown Object.Interfaces type: %T", gt.typeConfig.Interfaces) - gt.initialisedInterfaces = true - return nil - } - - interfaces, err := defineInterfaces(gt, configInterfaces) - gt.err = err - gt.interfaces = interfaces - gt.initialisedInterfaces = true - return gt.interfaces -} - -func (gt *Object) Error() error { - return gt.err -} - -func defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, error) { - ifaces := []*Interface{} - - if len(interfaces) == 0 { - return ifaces, nil - } - for _, iface := range interfaces { - err := invariantf( - iface != nil, - `%v may only implement Interface types, it cannot implement: %v.`, ttype, iface, - ) - if err != nil { - return ifaces, err - } - if iface.ResolveType != nil { - err = invariantf( - iface.ResolveType != nil, - `Interface Type %v does not provide a "resolveType" function `+ - `and implementing Type %v does not provide a "isTypeOf" `+ - `function. There is no way to resolve this implementing type `+ - `during execution.`, iface, ttype, - ) - if err != nil { - return ifaces, err - } - } - ifaces = append(ifaces, iface) - } - - return ifaces, nil -} - -func defineFieldMap(ttype Named, fieldMap Fields) (FieldDefinitionMap, error) { - resultFieldMap := FieldDefinitionMap{} - - err := invariantf( - len(fieldMap) > 0, - `%v fields must be an object with field names as keys or a function which return such an object.`, ttype, - ) - if err != nil { - return resultFieldMap, err - } - - for fieldName, field := range fieldMap { - if field == nil { - continue - } - err = invariantf( - field.Type != nil, - `%v.%v field type must be Output Type but got: %v.`, ttype, fieldName, field.Type, - ) - if err != nil { - return resultFieldMap, err - } - if field.Type.Error() != nil { - return resultFieldMap, field.Type.Error() - } - err = assertValidName(fieldName) - if err != nil { - return resultFieldMap, err - } - fieldDef := &FieldDefinition{ - Name: fieldName, - Description: field.Description, - Type: field.Type, - Resolve: field.Resolve, - DeprecationReason: field.DeprecationReason, - } - - fieldDef.Args = []*Argument{} - for argName, arg := range field.Args { - err := assertValidName(argName) - if err != nil { - return resultFieldMap, err - } - err = invariantf( - arg != nil, - `%v.%v args must be an object with argument names as keys.`, ttype, fieldName, - ) - if err != nil { - return resultFieldMap, err - } - err = invariantf( - arg.Type != nil, - `%v.%v(%v:) argument type must be Input Type but got: %v.`, ttype, fieldName, argName, arg.Type, - ) - if err != nil { - return resultFieldMap, err - } - fieldArg := &Argument{ - PrivateName: argName, - PrivateDescription: arg.Description, - Type: arg.Type, - DefaultValue: arg.DefaultValue, - } - fieldDef.Args = append(fieldDef.Args, fieldArg) - } - resultFieldMap[fieldName] = fieldDef - } - return resultFieldMap, nil -} - -// ResolveParams Params for FieldResolveFn() -type ResolveParams struct { - // Source is the source value - Source interface{} - - // Args is a map of arguments for current GraphQL request - Args map[string]interface{} - - // Info is a collection of information about the current execution state. - Info ResolveInfo - - // Context argument is a context value that is provided to every resolve function within an execution. - // It is commonly - // used to represent an authenticated user, or request-specific caches. - Context context.Context -} - -type FieldResolveFn func(p ResolveParams) (interface{}, error) - -type ResolveInfo struct { - FieldName string - FieldASTs []*ast.Field - ReturnType Output - ParentType Composite - Schema Schema - Fragments map[string]ast.Definition - RootValue interface{} - Operation ast.Definition - VariableValues map[string]interface{} -} - -type Fields map[string]*Field - -type Field struct { - Name string `json:"name"` // used by graphlql-relay - Type Output `json:"type"` - Args FieldConfigArgument `json:"args"` - Resolve FieldResolveFn `json:"-"` - DeprecationReason string `json:"deprecationReason"` - Description string `json:"description"` -} - -type FieldConfigArgument map[string]*ArgumentConfig - -type ArgumentConfig struct { - Type Input `json:"type"` - DefaultValue interface{} `json:"defaultValue"` - Description string `json:"description"` -} - -type FieldDefinitionMap map[string]*FieldDefinition -type FieldDefinition struct { - Name string `json:"name"` - Description string `json:"description"` - Type Output `json:"type"` - Args []*Argument `json:"args"` - Resolve FieldResolveFn `json:"-"` - DeprecationReason string `json:"deprecationReason"` -} - -type FieldArgument struct { - Name string `json:"name"` - Type Type `json:"type"` - DefaultValue interface{} `json:"defaultValue"` - Description string `json:"description"` -} - -type Argument struct { - PrivateName string `json:"name"` - Type Input `json:"type"` - DefaultValue interface{} `json:"defaultValue"` - PrivateDescription string `json:"description"` -} - -func (st *Argument) Name() string { - return st.PrivateName -} -func (st *Argument) Description() string { - return st.PrivateDescription - -} -func (st *Argument) String() string { - return st.PrivateName -} -func (st *Argument) Error() error { - return nil -} - -// Interface Type Definition -// -// When a field can return one of a heterogeneous set of types, a Interface type -// is used to describe what types are possible, what fields are in common across -// all types, as well as a function to determine which type is actually used -// when the field is resolved. -// -// Example: -// -// var EntityType = new Interface({ -// name: 'Entity', -// fields: { -// name: { type: String } -// } -// }); -// -// -type Interface struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - ResolveType ResolveTypeFn - - typeConfig InterfaceConfig - initialisedFields bool - fields FieldDefinitionMap - err error -} -type InterfaceConfig struct { - Name string `json:"name"` - Fields interface{} `json:"fields"` - ResolveType ResolveTypeFn - Description string `json:"description"` -} - -// ResolveTypeParams Params for ResolveTypeFn() -type ResolveTypeParams struct { - // Value that needs to be resolve. - // Use this to decide which GraphQLObject this value maps to. - Value interface{} - - // Info is a collection of information about the current execution state. - Info ResolveInfo - - // Context argument is a context value that is provided to every resolve function within an execution. - // It is commonly - // used to represent an authenticated user, or request-specific caches. - Context context.Context -} - -type ResolveTypeFn func(p ResolveTypeParams) *Object - -func NewInterface(config InterfaceConfig) *Interface { - it := &Interface{} - - err := invariant(config.Name != "", "Type must be named.") - if err != nil { - it.err = err - return it - } - err = assertValidName(config.Name) - if err != nil { - it.err = err - return it - } - it.PrivateName = config.Name - it.PrivateDescription = config.Description - it.ResolveType = config.ResolveType - it.typeConfig = config - - return it -} - -func (it *Interface) AddFieldConfig(fieldName string, fieldConfig *Field) { - if fieldName == "" || fieldConfig == nil { - return - } - switch it.typeConfig.Fields.(type) { - case Fields: - it.typeConfig.Fields.(Fields)[fieldName] = fieldConfig - it.initialisedFields = false - } -} - -func (it *Interface) Name() string { - return it.PrivateName -} - -func (it *Interface) Description() string { - return it.PrivateDescription -} - -func (it *Interface) Fields() (fields FieldDefinitionMap) { - if it.initialisedFields { - return it.fields - } - - var configureFields Fields - switch it.typeConfig.Fields.(type) { - case Fields: - configureFields = it.typeConfig.Fields.(Fields) - case FieldsThunk: - configureFields = it.typeConfig.Fields.(FieldsThunk)() - } - - fields, err := defineFieldMap(it, configureFields) - it.err = err - it.fields = fields - it.initialisedFields = true - return it.fields -} - -func (it *Interface) String() string { - return it.PrivateName -} - -func (it *Interface) Error() error { - return it.err -} - -// Union Type Definition -// -// When a field can return one of a heterogeneous set of types, a Union type -// is used to describe what types are possible as well as providing a function -// to determine which type is actually used when the field is resolved. -// -// Example: -// -// var PetType = new Union({ -// name: 'Pet', -// types: [ DogType, CatType ], -// resolveType(value) { -// if (value instanceof Dog) { -// return DogType; -// } -// if (value instanceof Cat) { -// return CatType; -// } -// } -// }); -type Union struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - ResolveType ResolveTypeFn - - typeConfig UnionConfig - types []*Object - possibleTypes map[string]bool - - err error -} -type UnionConfig struct { - Name string `json:"name"` - Types []*Object `json:"types"` - ResolveType ResolveTypeFn - Description string `json:"description"` -} - -func NewUnion(config UnionConfig) *Union { - objectType := &Union{} - - err := invariant(config.Name != "", "Type must be named.") - if err != nil { - objectType.err = err - return objectType - } - err = assertValidName(config.Name) - if err != nil { - objectType.err = err - return objectType - } - objectType.PrivateName = config.Name - objectType.PrivateDescription = config.Description - objectType.ResolveType = config.ResolveType - - err = invariantf( - len(config.Types) > 0, - `Must provide Array of types for Union %v.`, config.Name, - ) - if err != nil { - objectType.err = err - return objectType - } - for _, ttype := range config.Types { - err := invariantf( - ttype != nil, - `%v may only contain Object types, it cannot contain: %v.`, objectType, ttype, - ) - if err != nil { - objectType.err = err - return objectType - } - if objectType.ResolveType == nil { - err = invariantf( - ttype.IsTypeOf != nil, - `Union Type %v does not provide a "resolveType" function `+ - `and possible Type %v does not provide a "isTypeOf" `+ - `function. There is no way to resolve this possible type `+ - `during execution.`, objectType, ttype, - ) - if err != nil { - objectType.err = err - return objectType - } - } - } - objectType.types = config.Types - objectType.typeConfig = config - - return objectType -} -func (ut *Union) Types() []*Object { - return ut.types -} -func (ut *Union) String() string { - return ut.PrivateName -} -func (ut *Union) Name() string { - return ut.PrivateName -} -func (ut *Union) Description() string { - return ut.PrivateDescription -} -func (ut *Union) Error() error { - return ut.err -} - -// Enum Type Definition -// -// Some leaf values of requests and input values are Enums. GraphQL serializes -// Enum values as strings, however internally Enums can be represented by any -// kind of type, often integers. -// -// Example: -// -// var RGBType = new Enum({ -// name: 'RGB', -// values: { -// RED: { value: 0 }, -// GREEN: { value: 1 }, -// BLUE: { value: 2 } -// } -// }); -// -// Note: If a value is not provided in a definition, the name of the enum value -// will be used as its internal value. - -type Enum struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - - enumConfig EnumConfig - values []*EnumValueDefinition - valuesLookup map[interface{}]*EnumValueDefinition - nameLookup map[string]*EnumValueDefinition - - err error -} -type EnumValueConfigMap map[string]*EnumValueConfig -type EnumValueConfig struct { - Value interface{} `json:"value"` - DeprecationReason string `json:"deprecationReason"` - Description string `json:"description"` -} -type EnumConfig struct { - Name string `json:"name"` - Values EnumValueConfigMap `json:"values"` - Description string `json:"description"` -} -type EnumValueDefinition struct { - Name string `json:"name"` - Value interface{} `json:"value"` - DeprecationReason string `json:"deprecationReason"` - Description string `json:"description"` -} - -func NewEnum(config EnumConfig) *Enum { - gt := &Enum{} - gt.enumConfig = config - - err := assertValidName(config.Name) - if err != nil { - gt.err = err - return gt - } - - gt.PrivateName = config.Name - gt.PrivateDescription = config.Description - gt.values, err = gt.defineEnumValues(config.Values) - if err != nil { - gt.err = err - return gt - } - - return gt -} -func (gt *Enum) defineEnumValues(valueMap EnumValueConfigMap) ([]*EnumValueDefinition, error) { - values := []*EnumValueDefinition{} - - err := invariantf( - len(valueMap) > 0, - `%v values must be an object with value names as keys.`, gt, - ) - if err != nil { - return values, err - } - - for valueName, valueConfig := range valueMap { - err := invariantf( - valueConfig != nil, - `%v.%v must refer to an object with a "value" key `+ - `representing an internal value but got: %v.`, gt, valueName, valueConfig, - ) - if err != nil { - return values, err - } - err = assertValidName(valueName) - if err != nil { - return values, err - } - value := &EnumValueDefinition{ - Name: valueName, - Value: valueConfig.Value, - DeprecationReason: valueConfig.DeprecationReason, - Description: valueConfig.Description, - } - if value.Value == nil { - value.Value = valueName - } - values = append(values, value) - } - return values, nil -} -func (gt *Enum) Values() []*EnumValueDefinition { - return gt.values -} -func (gt *Enum) Serialize(value interface{}) interface{} { - v := value - if reflect.ValueOf(v).Kind() == reflect.Ptr { - v = reflect.Indirect(reflect.ValueOf(v)).Interface() - } - if enumValue, ok := gt.getValueLookup()[v]; ok { - return enumValue.Name - } - return nil -} -func (gt *Enum) ParseValue(value interface{}) interface{} { - var v string - - switch value := value.(type) { - case string: - v = value - case *string: - v = *value - default: - return nil - } - if enumValue, ok := gt.getNameLookup()[v]; ok { - return enumValue.Value - } - return nil -} -func (gt *Enum) ParseLiteral(valueAST ast.Value) interface{} { - if valueAST, ok := valueAST.(*ast.EnumValue); ok { - if enumValue, ok := gt.getNameLookup()[valueAST.Value]; ok { - return enumValue.Value - } - } - return nil -} -func (gt *Enum) Name() string { - return gt.PrivateName -} -func (gt *Enum) Description() string { - return gt.PrivateDescription -} -func (gt *Enum) String() string { - return gt.PrivateName -} -func (gt *Enum) Error() error { - return gt.err -} -func (gt *Enum) getValueLookup() map[interface{}]*EnumValueDefinition { - if len(gt.valuesLookup) > 0 { - return gt.valuesLookup - } - valuesLookup := map[interface{}]*EnumValueDefinition{} - for _, value := range gt.Values() { - valuesLookup[value.Value] = value - } - gt.valuesLookup = valuesLookup - return gt.valuesLookup -} - -func (gt *Enum) getNameLookup() map[string]*EnumValueDefinition { - if len(gt.nameLookup) > 0 { - return gt.nameLookup - } - nameLookup := map[string]*EnumValueDefinition{} - for _, value := range gt.Values() { - nameLookup[value.Name] = value - } - gt.nameLookup = nameLookup - return gt.nameLookup -} - -// InputObject Type Definition -// -// An input object defines a structured collection of fields which may be -// supplied to a field argument. -// -// Using `NonNull` will ensure that a value must be provided by the query -// -// Example: -// -// var GeoPoint = new InputObject({ -// name: 'GeoPoint', -// fields: { -// lat: { type: new NonNull(Float) }, -// lon: { type: new NonNull(Float) }, -// alt: { type: Float, defaultValue: 0 }, -// } -// }); -type InputObject struct { - PrivateName string `json:"name"` - PrivateDescription string `json:"description"` - - typeConfig InputObjectConfig - fields InputObjectFieldMap - init bool - err error -} -type InputObjectFieldConfig struct { - Type Input `json:"type"` - DefaultValue interface{} `json:"defaultValue"` - Description string `json:"description"` -} -type InputObjectField struct { - PrivateName string `json:"name"` - Type Input `json:"type"` - DefaultValue interface{} `json:"defaultValue"` - PrivateDescription string `json:"description"` -} - -func (st *InputObjectField) Name() string { - return st.PrivateName -} -func (st *InputObjectField) Description() string { - return st.PrivateDescription - -} -func (st *InputObjectField) String() string { - return st.PrivateName -} -func (st *InputObjectField) Error() error { - return nil -} - -type InputObjectConfigFieldMap map[string]*InputObjectFieldConfig -type InputObjectFieldMap map[string]*InputObjectField -type InputObjectConfigFieldMapThunk func() InputObjectConfigFieldMap -type InputObjectConfig struct { - Name string `json:"name"` - Fields interface{} `json:"fields"` - Description string `json:"description"` -} - -func NewInputObject(config InputObjectConfig) *InputObject { - gt := &InputObject{} - err := invariant(config.Name != "", "Type must be named.") - if err != nil { - gt.err = err - return gt - } - - gt.PrivateName = config.Name - gt.PrivateDescription = config.Description - gt.typeConfig = config - //gt.fields = gt.defineFieldMap() - return gt -} - -func (gt *InputObject) defineFieldMap() InputObjectFieldMap { - var fieldMap InputObjectConfigFieldMap - switch gt.typeConfig.Fields.(type) { - case InputObjectConfigFieldMap: - fieldMap = gt.typeConfig.Fields.(InputObjectConfigFieldMap) - case InputObjectConfigFieldMapThunk: - fieldMap = gt.typeConfig.Fields.(InputObjectConfigFieldMapThunk)() - } - resultFieldMap := InputObjectFieldMap{} - - err := invariantf( - len(fieldMap) > 0, - `%v fields must be an object with field names as keys or a function which return such an object.`, gt, - ) - if err != nil { - gt.err = err - return resultFieldMap - } - - for fieldName, fieldConfig := range fieldMap { - if fieldConfig == nil { - continue - } - err := assertValidName(fieldName) - if err != nil { - continue - } - err = invariantf( - fieldConfig.Type != nil, - `%v.%v field type must be Input Type but got: %v.`, gt, fieldName, fieldConfig.Type, - ) - if err != nil { - gt.err = err - return resultFieldMap - } - field := &InputObjectField{} - field.PrivateName = fieldName - field.Type = fieldConfig.Type - field.PrivateDescription = fieldConfig.Description - field.DefaultValue = fieldConfig.DefaultValue - resultFieldMap[fieldName] = field - } - gt.init = true - return resultFieldMap -} - -func (gt *InputObject) Fields() InputObjectFieldMap { - if !gt.init { - gt.fields = gt.defineFieldMap() - } - return gt.fields -} -func (gt *InputObject) Name() string { - return gt.PrivateName -} -func (gt *InputObject) Description() string { - return gt.PrivateDescription -} -func (gt *InputObject) String() string { - return gt.PrivateName -} -func (gt *InputObject) Error() error { - return gt.err -} - -// List Modifier -// -// A list is a kind of type marker, a wrapping type which points to another -// type. Lists are often created within the context of defining the fields of -// an object type. -// -// Example: -// -// var PersonType = new Object({ -// name: 'Person', -// fields: () => ({ -// parents: { type: new List(Person) }, -// children: { type: new List(Person) }, -// }) -// }) -// -type List struct { - OfType Type `json:"ofType"` - - err error -} - -func NewList(ofType Type) *List { - gl := &List{} - - err := invariantf(ofType != nil, `Can only create List of a Type but got: %v.`, ofType) - if err != nil { - gl.err = err - return gl - } - - gl.OfType = ofType - return gl -} -func (gl *List) Name() string { - return fmt.Sprintf("%v", gl.OfType) -} -func (gl *List) Description() string { - return "" -} -func (gl *List) String() string { - if gl.OfType != nil { - return fmt.Sprintf("[%v]", gl.OfType) - } - return "" -} -func (gl *List) Error() error { - return gl.err -} - -// NonNull Modifier -// -// A non-null is a kind of type marker, a wrapping type which points to another -// type. Non-null types enforce that their values are never null and can ensure -// an error is raised if this ever occurs during a request. It is useful for -// fields which you can make a strong guarantee on non-nullability, for example -// usually the id field of a database row will never be null. -// -// Example: -// -// var RowType = new Object({ -// name: 'Row', -// fields: () => ({ -// id: { type: new NonNull(String) }, -// }) -// }) -// -// Note: the enforcement of non-nullability occurs within the executor. -type NonNull struct { - OfType Type `json:"ofType"` - - err error -} - -func NewNonNull(ofType Type) *NonNull { - gl := &NonNull{} - - _, isOfTypeNonNull := ofType.(*NonNull) - err := invariantf(ofType != nil && !isOfTypeNonNull, `Can only create NonNull of a Nullable Type but got: %v.`, ofType) - if err != nil { - gl.err = err - return gl - } - gl.OfType = ofType - return gl -} -func (gl *NonNull) Name() string { - return fmt.Sprintf("%v!", gl.OfType) -} -func (gl *NonNull) Description() string { - return "" -} -func (gl *NonNull) String() string { - if gl.OfType != nil { - return gl.Name() - } - return "" -} -func (gl *NonNull) Error() error { - return gl.err -} - -var NameRegExp, _ = regexp.Compile("^[_a-zA-Z][_a-zA-Z0-9]*$") - -func assertValidName(name string) error { - return invariantf( - NameRegExp.MatchString(name), - `Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "%v" does not.`, name) - -} |