/// <summary> /// For the field name provided, determine if there are any similar field names /// that may be the result of a typo. /// </summary> private IEnumerable<string> getSuggestedFieldNames( IGraphType type, string fieldName) { if (type is IComplexGraphType) { var complexType = type as IComplexGraphType; return StringUtils.SuggestionList(fieldName, complexType.Fields.Select(x => x.Name)); } return Enumerable.Empty<string>(); }
/// <summary> /// if a variable defintion has a default value, it is effectively non-null. /// </summary> private GraphType effectiveType(IGraphType varType, VariableDefinition varDef) { if (varDef.DefaultValue == null || varType is NonNullGraphType) { return (GraphType)varType; } var type = varType.GetType(); var genericType = typeof(NonNullGraphType<>).MakeGenericType(type); var nonNull = (NonNullGraphType)Activator.CreateInstance(genericType); nonNull.ResolvedType = varType; return nonNull; }
private void Field(IGraphType type, Field field, ValidationContext context) { if (type == null) { return; } if (type.IsLeafType()) { if (field.SelectionSet != null && field.SelectionSet.Selections.Any()) { var error = new ValidationError(context.OriginalQuery, "5.2.3", NoSubselectionAllowedMessage(field.Name, context.Print(type)), field.SelectionSet); context.ReportError(error); } } else if(field.SelectionSet == null || !field.SelectionSet.Selections.Any()) { var error = new ValidationError(context.OriginalQuery, "5.2.3", RequiredSubselectionMessage(field.Name, context.Print(type)), field); context.ReportError(error); } }
/// <inheritdoc/> public virtual Task <bool> AllowField(IGraphType parent, IFieldType field) => parent.IsIntrospectionType() && (field.Name == "appliedDirectives" || field.Name == "isRepeatable") ? Forbidden : Allowed;
/// <inheritdoc cref="Create{TSourceType, TReturnType}(Type)"/> public static FieldBuilder <TSourceType, TReturnType> Create <TSourceType, TReturnType>(IGraphType type) => FieldBuilder <TSourceType, TReturnType> .Create(type);
/// <inheritdoc/> public override Task <bool> AllowField(IGraphType parent, IFieldType field) => Allowed;
public bool Matches(object value, IGraphType type) { return(value is Domain.Models.Variable); }
public static void ShouldBeOfNonNullableListType <TType>(this IGraphType type) where TType : GraphType { Assert.AreEqual(typeof(NonNullGraphType <ListGraphType <TType> >), type.GetType()); }
public static bool IsPossibleType(this IAbstractGraphType abstractType, IGraphType type) { return abstractType.PossibleTypes.Any(x => x.Equals(type)); }
/// <summary> /// Determines if the target graph type COULD BE spread into the active context graph type. /// </summary> /// <param name="schema">The target schema in case any additional graph types need to be accessed.</param> /// <param name="typeInContext">The graph type currently active on the context.</param> /// <param name="targetGraphType">The target graph type of the spread named fragment.</param> /// <returns><c>true</c> if the target type can be spread in context; otherwise, false.</returns> protected override bool CanAcceptGraphType(ISchema schema, IGraphType typeInContext, IGraphType targetGraphType) { // when spreading a framgent targeting an object into the context of another object // the two graph types must be the same return(typeInContext == targetGraphType); }
public static void Field( this IObjectGraphType obj, string name, IGraphType type, string description = null, QueryArguments arguments = null, Func<ResolveFieldContext, object> resolve = null) { var field = new FieldType(); field.Name = name; field.Description = description; field.Arguments = arguments; field.ResolvedType = type; field.Resolver = resolve != null ? new FuncFieldResolver<object>(resolve) : null; obj.AddField(field); }
private List <Conflict> FindConflictsBetweenSubSelectionSets( ValidationContext context, Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames, PairSet comparedFragmentPairs, bool areMutuallyExclusive, IGraphType parentType1, SelectionSet selectionSet1, IGraphType parentType2, SelectionSet selectionSet2) { var conflicts = new List <Conflict>(); var cachedField1 = GetFieldsAndFragmentNames( context, cachedFieldsAndFragmentNames, parentType1, selectionSet1); var fieldMap1 = cachedField1.NodeAndDef; var fragmentNames1 = cachedField1.Names; var cachedField2 = GetFieldsAndFragmentNames( context, cachedFieldsAndFragmentNames, parentType2, selectionSet2); var fieldMap2 = cachedField2.NodeAndDef; var fragmentNames2 = cachedField2.Names; // (H) First, collect all conflicts between these two collections of field. CollectConflictsBetween( context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, areMutuallyExclusive, fieldMap1, fieldMap2); // (I) Then collect conflicts between the first collection of fields and // those referenced by each fragment name associated with the second. if (fragmentNames2.Count != 0) { var comparedFragments = new ObjMap <bool>(); for (var j = 0; j < fragmentNames2.Count; j++) { CollectConflictsBetweenFieldsAndFragment( context, conflicts, cachedFieldsAndFragmentNames, comparedFragments, comparedFragmentPairs, areMutuallyExclusive, fieldMap1, fragmentNames2[j]); } } // (I) Then collect conflicts between the second collection of fields and // those referenced by each fragment name associated with the first. if (fragmentNames1.Count != 0) { var comparedFragments = new ObjMap <bool>(); for (var i = 0; i < fragmentNames1.Count; i++) { CollectConflictsBetweenFieldsAndFragment( context, conflicts, cachedFieldsAndFragmentNames, comparedFragments, comparedFragmentPairs, areMutuallyExclusive, fieldMap2, fragmentNames1[i]); } } // (J) Also collect conflicts between any fragment names by the first and // fragment names by the second. This compares each item in the first set of // names to each item in the second set of names. for (var i = 0; i < fragmentNames1.Count; i++) { for (var j = 0; j < fragmentNames2.Count; j++) { CollectConflictsBetweenFragments( context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, areMutuallyExclusive, fragmentNames1[i], fragmentNames2[j]); } } return(conflicts); }
public Dictionary<string, Fields> CollectFields( ExecutionContext context, IGraphType specificType, SelectionSet selectionSet, Dictionary<string, Fields> fields, List<string> visitedFragmentNames) { if (fields == null) { fields = new Dictionary<string, Fields>(); } selectionSet.Selections.Apply(selection => { if (selection is Field) { var field = (Field)selection; if (!ShouldIncludeNode(context, field.Directives)) { return; } var name = field.Alias ?? field.Name; if (!fields.ContainsKey(name)) { fields[name] = new Fields(); } fields[name].Add(field); } else if (selection is FragmentSpread) { var spread = (FragmentSpread)selection; if (visitedFragmentNames.Contains(spread.Name) || !ShouldIncludeNode(context, spread.Directives)) { return; } visitedFragmentNames.Add(spread.Name); var fragment = context.Fragments.FindDefinition(spread.Name); if (fragment == null || !ShouldIncludeNode(context, fragment.Directives) || !DoesFragmentConditionMatch(context, fragment.Type.Name, specificType)) { return; } CollectFields(context, specificType, fragment.SelectionSet, fields, visitedFragmentNames); } else if (selection is InlineFragment) { var inline = (InlineFragment)selection; var name = inline.Type != null ? inline.Type.Name : specificType.Name; if (!ShouldIncludeNode(context, inline.Directives) || !DoesFragmentConditionMatch(context, name, specificType)) { return; } CollectFields(context, specificType, inline.SelectionSet, fields, visitedFragmentNames); } }); return fields; }
public bool DoesFragmentConditionMatch(ExecutionContext context, string fragmentName, IGraphType type) { if (string.IsNullOrWhiteSpace(fragmentName)) { return true; } var conditionalType = context.Schema.FindType(fragmentName); if (conditionalType == null) { return false; } if (conditionalType.Equals(type)) { return true; } if (conditionalType is IAbstractGraphType) { var abstractType = (IAbstractGraphType)conditionalType; return abstractType.IsPossibleType(type); } return false; }
public object CoerceValue(ISchema schema, IGraphType type, IValue input, Variables variables = null) { if (type is NonNullGraphType) { var nonNull = type as NonNullGraphType; return CoerceValue(schema, nonNull.ResolvedType, input, variables); } if (input == null) { return null; } var variable = input as VariableReference; if (variable != null) { return variables != null ? variables.ValueFor(variable.Name) : null; } if (type is ListGraphType) { var listType = type as ListGraphType; var listItemType = listType.ResolvedType; var list = input as ListValue; return list != null ? list.Values.Map(item => CoerceValue(schema, listItemType, item, variables)).ToArray() : new[] { CoerceValue(schema, listItemType, input, variables) }; } if (type is IObjectGraphType || type is InputObjectGraphType) { var complexType = type as IComplexGraphType; var obj = new Dictionary<string, object>(); var objectValue = input as ObjectValue; if (objectValue == null) { return null; } complexType.Fields.Apply(field => { var objectField = objectValue.Field(field.Name); if (objectField != null) { var fieldValue = CoerceValue(schema, field.ResolvedType, objectField.Value, variables); fieldValue = fieldValue ?? field.DefaultValue; obj[field.Name] = fieldValue; } }); return obj; } if (type is ScalarGraphType) { var scalarType = type as ScalarGraphType; return scalarType.ParseLiteral(input); } return null; }
public bool IsValidValue(ISchema schema, IGraphType type, object input) { if (type is NonNullGraphType) { if (input == null) { return false; } var nonNullType = ((NonNullGraphType)type).ResolvedType; if (nonNullType is ScalarGraphType) { var val = ValueFromScalar((ScalarGraphType)nonNullType, input); return val != null; } return IsValidValue(schema, nonNullType, input); } if (input == null) { return true; } if (type is ListGraphType) { var listType = (ListGraphType)type; var listItemType = listType.ResolvedType; var list = input as IEnumerable; if (list != null && !(input is string)) { return list.All(item => IsValidValue(schema, listItemType, item)); } return IsValidValue(schema, listItemType, input); } if (type is IObjectGraphType || type is InputObjectGraphType) { var dict = input as Dictionary<string, object>; var complexType = type as IComplexGraphType; if (dict == null) { return false; } // ensure every provided field is defined if (type is InputObjectGraphType && dict.Keys.Any(key => complexType.Fields.FirstOrDefault(field => field.Name == key) == null)) { return false; } return complexType.Fields.All(field => { object fieldValue = null; dict.TryGetValue(field.Name, out fieldValue); return IsValidValue( schema, field.ResolvedType, fieldValue); }); } if (type is ScalarGraphType) { var scalar = (ScalarGraphType)type; var value = ValueFromScalar(scalar, input); return value != null; } return false; }
public async Task<object> CompleteValueAsync(ExecutionContext context, IGraphType fieldType, Fields fields, object result) { var field = fields != null ? fields.FirstOrDefault() : null; var fieldName = field != null ? field.Name : null; var nonNullType = fieldType as NonNullGraphType; if (nonNullType != null) { var type = nonNullType.ResolvedType; var completed = await CompleteValueAsync(context, type, fields, result).ConfigureAwait(false); if (completed == null) { var error = new ExecutionError("Cannot return null for non-null type. Field: {0}, Type: {1}!." .ToFormat(fieldName, type.Name)); error.AddLocation(field, context.Document); throw error; } return completed; } if (result == null) { return null; } if (fieldType is ScalarGraphType) { var scalarType = fieldType as ScalarGraphType; var coercedValue = scalarType.Serialize(result); return coercedValue; } if (fieldType is ListGraphType) { var list = result as IEnumerable; if (list == null) { var error = new ExecutionError("User error: expected an IEnumerable list though did not find one."); error.AddLocation(field, context.Document); throw error; } var listType = fieldType as ListGraphType; var itemType = listType.ResolvedType; var results = await list.MapAsync(async item => await CompleteValueAsync(context, itemType, fields, item).ConfigureAwait(false)).ConfigureAwait(false); return results; } var objectType = fieldType as IObjectGraphType; if (fieldType is IAbstractGraphType) { var abstractType = fieldType as IAbstractGraphType; objectType = abstractType.GetObjectType(result); if (objectType != null && !abstractType.IsPossibleType(objectType)) { var error = new ExecutionError( "Runtime Object type \"{0}\" is not a possible type for \"{1}\"" .ToFormat(objectType, abstractType)); error.AddLocation(field, context.Document); throw error; } } if (objectType == null) { return null; } if (objectType.IsTypeOf != null && !objectType.IsTypeOf(result)) { var error = new ExecutionError( "Expected value of type \"{0}\" but got: {1}." .ToFormat(objectType, result)); error.AddLocation(field, context.Document); throw error; } var subFields = new Dictionary<string, Fields>(); var visitedFragments = new List<string>(); fields.Apply(f => { subFields = CollectFields(context, objectType, f.SelectionSet, subFields, visitedFragments); }); return await ExecuteFieldsAsync(context, objectType, result, subFields).ConfigureAwait(false); }
public static bool IsCompositeType(this IGraphType type) { return(type is IObjectGraphType || type is IInterfaceGraphType || type is UnionGraphType); }
private bool isInterfaceType(IGraphType parentType) { return(parentType is IInterfaceGraphType); }
public static IValue AstFromValue(this object value, ISchema schema, IGraphType type) { if (type is NonNullGraphType nonnull) { return(AstFromValue(value, schema, nonnull.ResolvedType)); } if (value == null || type == null) { return(new NullValue()); } // Convert IEnumerable to GraphQL list. If the GraphQLType is a list, but // the value is not an IEnumerable, convert the value using the list's item type. if (type is ListGraphType listType) { var itemType = listType.ResolvedType; if (!(value is string) && value is IEnumerable list) { var values = list .Cast <object>() .Select(item => AstFromValue(item, schema, itemType)) .ToList(); return(new ListValue(values)); } return(AstFromValue(value, schema, itemType)); } // Populate the fields of the input object by creating ASTs from each value // in the dictionary according to the fields in the input type. if (type is IInputObjectGraphType input) { if (!(value is Dictionary <string, object> dict)) { return(null); } var fields = dict .Select(pair => { var fieldType = input.GetField(pair.Key)?.ResolvedType; return(new ObjectField(pair.Key, AstFromValue(pair.Value, schema, fieldType))); }) .ToList(); return(new ObjectValue(fields)); } Invariant.Check( type.IsInputType(), $"Must provide Input Type, cannot use: {type}"); var inputType = type as ScalarGraphType; // Since value is an internally represented value, it must be serialized // to an externally represented value before converting into an AST. var serialized = inputType.Serialize(value); if (serialized == null) { return(null); } if (serialized is bool b) { return(new BooleanValue(b)); } if (serialized is int i) { return(new IntValue(i)); } if (serialized is long l) { return(new LongValue(l)); } if (serialized is decimal @decimal) { return(new DecimalValue(@decimal)); } if (serialized is double d) { return(new FloatValue(d)); } if (serialized is DateTime time) { return(new DateTimeValue(time)); } if (serialized is Uri uri) { return(new UriValue(uri)); } if (serialized is DateTimeOffset offset) { return(new DateTimeOffsetValue(offset)); } if (serialized is TimeSpan span) { return(new TimeSpanValue(span)); } if (serialized is Guid guid) { return(new GuidValue(guid)); } if (serialized is short int16) { return(new ShortValue(int16)); } if (serialized is ushort uint16) { return(new UShortValue(uint16)); } if (serialized is uint uint32) { return(new UIntValue(uint32)); } if (serialized is ulong uint64) { return(new ULongValue(uint64)); } if (serialized is string) { if (type is EnumerationGraphType) { return(new EnumValue(serialized.ToString())); } return(new StringValue(serialized.ToString())); } var converter = schema.FindValueConverter(serialized, type); if (converter != null) { return(converter.Convert(serialized, type)); } throw new ExecutionError($"Cannot convert value to AST: {serialized}"); }
/// <summary> /// Go through all of the implementations of type, as well as the interfaces /// that they implement. If any of those types include the provided field, /// suggest them, sorted by how often the type is referenced, starting /// with Interfaces. /// </summary> private IEnumerable<string> getSuggestedTypeNames( ISchema schema, IGraphType type, string fieldName) { if (type is IAbstractGraphType) { var suggestedObjectTypes = new List<string>(); var interfaceUsageCount = new LightweightCache<string, int>(key => 0); var absType = type as IAbstractGraphType; absType.PossibleTypes.Apply(possibleType => { if (!possibleType.HasField(fieldName)) { return; } // This object defines this field. suggestedObjectTypes.Add(possibleType.Name); possibleType.ResolvedInterfaces.Apply(possibleInterface => { if (possibleInterface.HasField(fieldName)) { // This interface type defines this field. interfaceUsageCount[possibleInterface.Name] = interfaceUsageCount[possibleInterface.Name] + 1; } }); }); var suggestedInterfaceTypes = interfaceUsageCount.Keys.OrderBy(x => interfaceUsageCount[x]); return suggestedInterfaceTypes.Concat(suggestedObjectTypes); } return Enumerable.Empty<string>(); }
public void ApplyTypeReference(IGraphType type) { CheckSealed(); if (type is IComplexGraphType complexType) { foreach (var field in complexType.Fields) { field.ResolvedType = ConvertTypeReference(type, field.ResolvedType); if (field.Arguments == null) { continue; } foreach (var arg in field.Arguments) { arg.ResolvedType = ConvertTypeReference(type, arg.ResolvedType); } } } if (type is IObjectGraphType objectType) { objectType.ResolvedInterfaces = objectType .ResolvedInterfaces .Select(i => { var interfaceType = (IInterfaceGraphType)ConvertTypeReference(objectType, i); if (objectType.IsTypeOf == null && interfaceType.ResolveType == null) { throw new ExecutionError(( "Interface type {0} does not provide a \"resolveType\" function " + "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " + "There is no way to resolve this possible type during execution.") .ToFormat(interfaceType.Name, objectType.Name)); } interfaceType.AddPossibleType(objectType); return(interfaceType); }) .ToList(); } if (type is UnionGraphType union) { union.PossibleTypes = union .PossibleTypes .Select(t => { var unionType = ConvertTypeReference(union, t) as IObjectGraphType; if (union.ResolveType == null && unionType != null && unionType.IsTypeOf == null) { throw new ExecutionError(( "Union type {0} does not provide a \"resolveType\" function " + "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " + "There is no way to resolve this possible type during execution.") .ToFormat(union.Name, unionType.Name)); } return(unionType); }) .ToList(); } }
public ComplexGraphProperty(SerializableProperty property, IGraphType propertyType) { _property = property; _propertyType = propertyType; _args = property.CreateVisitArgs(); }
private List <Conflict> FindConflictsWithinSelectionSet( ValidationContext context, Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames, PairSet comparedFragmentPairs, IGraphType parentType, SelectionSet selectionSet) { var conflicts = new List <Conflict>(); CachedField cachedField = GetFieldsAndFragmentNames( context, cachedFieldsAndFragmentNames, parentType, selectionSet); var fieldMap = cachedField.NodeAndDef; var fragmentNames = cachedField.Names; CollectConflictsWithin( context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, fieldMap); if (fragmentNames.Count != 0) { // (B) Then collect conflicts between these fields and those represented by // each spread fragment name found. var comparedFragments = new ObjMap <bool>(); for (int i = 0; i < fragmentNames.Count; i++) { CollectConflictsBetweenFieldsAndFragment( context, conflicts, cachedFieldsAndFragmentNames, comparedFragments, comparedFragmentPairs, false, fieldMap, fragmentNames[i]); // (C) Then compare this fragment with all other fragments found in this // selection set to collect conflicts between fragments spread together. // This compares each item in the list of fragment names to every other // item in that same list (except for itself). for (int j = i + 1; j < fragmentNames.Count; j++) { CollectConflictsBetweenFragments( context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, false, fragmentNames[i], fragmentNames[j]); } } } return(conflicts); }
/// <summary> /// Creates a new instance of the indicated type, populating it with the dictionary. /// Can use any constructor of the indicated type, provided that there are keys in the /// dictionary that correspond (case sensitive) to the names of the constructor parameters. /// </summary> /// <param name="source">The source of values.</param> /// <param name="type">The type to create.</param> /// <param name="mappedType"> /// GraphType for matching dictionary keys with <paramref name="type"/> property names. /// GraphType contains information about this matching in Metadata property. /// In case of configuring field as Field(x => x.FName).Name("FirstName") source dictionary /// will have 'FirstName' key but its value should be set to 'FName' property of created object. /// </param> public static object ToObject(this IDictionary <string, object> source, Type type, IGraphType mappedType = null) { // Given Field(x => x.FName).Name("FirstName") and key == "FirstName" returns "FName" string GetPropertyName(string key, out FieldType field) { var complexType = mappedType.GetNamedType() as IComplexGraphType; // type may not contain mapping information field = complexType?.GetField(key); return(field?.GetMetadata(ComplexGraphType <object> .ORIGINAL_EXPRESSION_PROPERTY_NAME, key) ?? key); } // Returns keys from source that match constructor signature string[] MatchSourceKeys(ParameterInfo[] parameters) { // parameterless constructors are the most common use case if (parameters.Length == 0) { return(Array.Empty <string>()); } // otherwise we have to iterate over the parameters - worse performance but this is rather rare case List <string> keys = null; if (parameters.All(p => source.Any(keyValue => { bool matched = string.Equals(GetPropertyName(keyValue.Key, out var _), p.Name, StringComparison.InvariantCultureIgnoreCase); if (matched) { (keys ??= new List <string>()).Add(keyValue.Key); } return(matched); }))) { return(keys.ToArray()); } return(null); } if (source == null) { throw new ArgumentNullException(nameof(source)); } // force sourceType to be IDictionary<string, object> if (ValueConverter.TryConvertTo(source, type, out object result, typeof(IDictionary <string, object>))) { return(result); } // attempt to use the most specific constructor sorting in decreasing order of parameters number var ctorCandidates = _types.GetOrAdd(type, t => t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderByDescending(ctor => ctor.GetParameters().Length).ToArray()); ConstructorInfo targetCtor = null; ParameterInfo[] ctorParameters = null; string[] matchedKeys = null; foreach (var ctor in ctorCandidates) { var parameters = ctor.GetParameters(); matchedKeys = MatchSourceKeys(parameters); if (matchedKeys != null) { targetCtor = ctor; ctorParameters = parameters; break; } } if (targetCtor == null) { throw new ArgumentException($"Type '{type}' does not contain a constructor that could be used for current input arguments.", nameof(type)); } object[] ctorArguments = ctorParameters.Length == 0 ? Array.Empty <object>() : new object[ctorParameters.Length]; for (int i = 0; i < ctorParameters.Length; ++i) { object arg = GetPropertyValue(source[matchedKeys[i]], ctorParameters[i].ParameterType); ctorArguments[i] = arg; } object obj = targetCtor.Invoke(ctorArguments); foreach (var item in source) { // these parameters have already been used in the constructor, no need to set property if (matchedKeys.Length > 0 && matchedKeys.Any(k => k == item.Key)) { continue; } string propertyName = GetPropertyName(item.Key, out var field); PropertyInfo propertyInfo = null; try { propertyInfo = type.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); } catch (AmbiguousMatchException) { propertyInfo = type.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); } if (propertyInfo != null && propertyInfo.CanWrite) { object value = GetPropertyValue(item.Value, propertyInfo.PropertyType, field?.ResolvedType); propertyInfo.SetValue(obj, value, null); //issue: this works even if propertyInfo is ValueType and value is null } } return(obj); }
private bool isObjectType(IGraphType parentType) { return(parentType is IObjectGraphType); }
public void Enter(INode node) { _ancestorStack.Push(node); if (node is SelectionSet) { _parentTypeStack.Push(GetLastType()); return; } if (node is Field field) { var parentType = _parentTypeStack.Peek().GetNamedType(); var fieldType = GetFieldDef(_schema, parentType, field); _fieldDefStack.Push(fieldType); var targetType = fieldType?.ResolvedType; _typeStack.Push(targetType); return; } if (node is Directive directive) { _directive = _schema.FindDirective(directive.Name); } if (node is Operation op) { IGraphType type = null; if (op.OperationType == OperationType.Query) { type = _schema.Query; } else if (op.OperationType == OperationType.Mutation) { type = _schema.Mutation; } else if (op.OperationType == OperationType.Subscription) { type = _schema.Subscription; } _typeStack.Push(type); return; } if (node is FragmentDefinition def1) { var type = _schema.FindType(def1.Type.Name); _typeStack.Push(type); return; } if (node is InlineFragment def) { var type = def.Type != null?_schema.FindType(def.Type.Name) : GetLastType(); _typeStack.Push(type); return; } if (node is VariableDefinition varDef) { var inputType = varDef.Type.GraphTypeFromType(_schema); _inputTypeStack.Push(inputType); return; } if (node is Argument argAst) { QueryArgument argDef = null; IGraphType argType = null; var args = GetDirective() != null?GetDirective()?.Arguments : GetFieldDef()?.Arguments; if (args != null) { argDef = args.Find(argAst.Name); argType = argDef?.ResolvedType; } _argument = argDef; _inputTypeStack.Push(argType); } if (node is ListValue) { var type = GetInputType().GetNamedType(); _inputTypeStack.Push(type); } if (node is ObjectField objectField) { var objectType = GetInputType().GetNamedType(); IGraphType fieldType = null; if (objectType is IInputObjectGraphType complexType) { var inputField = complexType.GetField(objectField.Name); fieldType = inputField?.ResolvedType; } _inputTypeStack.Push(fieldType); } }
public IValue Convert(object value, IGraphType type) { return(new VariableValue((Domain.Models.Variable)value)); }
public IValue Convert(object value, IGraphType type) { return(new JsonValueNode(ParseJson(value))); }
public static void ShouldBeOfListType <TType>(this IGraphType type) where TType : GraphType { Assert.AreEqual(typeof(ListGraphType <TType>), type.GetType()); }
public bool Matches(object value, IGraphType type) { return(type is JsonGraphType); }
public SchemaBuilder RegisterType(IGraphType type) { _types[type.Name] = type; return(this); }
/// <summary> /// Indicates if the graph type is an input object graph type. /// </summary> public static bool IsInputObjectType(this IGraphType type) { var(namedType, namedType2) = type.GetNamedTypes(); return(namedType is IInputObjectGraphType || typeof(IInputObjectGraphType).IsAssignableFrom(namedType2)); }
/// <inheritdoc/> public override Task <bool> AllowType(IGraphType type) => Allowed;
internal static bool IsGraphQLTypeReference(this IGraphType type) { var(namedType, _) = type.GetNamedTypes(); return(namedType is GraphQLTypeReference); }
/// <inheritdoc/> public virtual Task <bool> AllowType(IGraphType type) => type is __AppliedDirective || type is __DirectiveArgument ? Forbidden : Allowed;
/// <summary> /// Determines if this graph type is an introspection type. /// </summary> internal static bool IsIntrospectionType(this IGraphType type) => type?.Name?.StartsWith("__", StringComparison.InvariantCulture) ?? false;
public static IEnumerable <string> IsValidLiteralValue(this IGraphType type, IValue valueAst, ISchema schema) { if (type is NonNullGraphType nonNull) { var ofType = nonNull.ResolvedType; if (valueAst == null || valueAst is NullValue) { if (ofType != null) { return(new[] { $"Expected \"{ofType.Name}!\", found null." }); } return(new[] { "Expected non-null value, found null" }); } return(IsValidLiteralValue(ofType, valueAst, schema)); } else if (valueAst is NullValue) { return(Array.Empty <string>()); } if (valueAst == null) { return(Array.Empty <string>()); } // This function only tests literals, and assumes variables will provide // values of the correct type. if (valueAst is VariableReference) { return(Array.Empty <string>()); } if (type is ListGraphType list) { var ofType = list.ResolvedType; if (valueAst is ListValue listValue) { return(listValue.Values .SelectMany(value => IsValidLiteralValue(ofType, value, schema) .Select((err, index) => $"In element #{index + 1}: {err}") ) .ToList()); } return(IsValidLiteralValue(ofType, valueAst, schema)); } if (type is IInputObjectGraphType inputType) { if (!(valueAst is ObjectValue objValue)) { return(new[] { $"Expected \"{inputType.Name}\", found not an object." }); } var fields = inputType.Fields.ToList(); var fieldAsts = objValue.ObjectFields.ToList(); var errors = new List <string>(); // ensure every provided field is defined foreach (var providedFieldAst in fieldAsts) { var found = fields.Find(x => x.Name == providedFieldAst.Name); if (found == null) { errors.Add($"In field \"{providedFieldAst.Name}\": Unknown field."); } } // ensure every defined field is valid foreach (var field in fields) { var fieldAst = fieldAsts.Find(x => x.Name == field.Name); var result = IsValidLiteralValue(field.ResolvedType, fieldAst?.Value, schema); errors.AddRange(result.Select(err => $"In field \"{field.Name}\": {err}")); } return(errors); } var scalar = (ScalarGraphType)type; var parseResult = scalar.ParseLiteral(valueAst); if (parseResult == null) { return(new[] { $"Expected type \"{type.Name}\", found {AstPrinter.Print(valueAst)}." }); } return(Array.Empty <string>()); }
/// <summary> /// Indicates if the graph type is a scalar graph type. /// </summary> public static bool IsLeafType(this IGraphType type) { var(namedType, namedType2) = type.GetNamedTypes(); return(namedType is ScalarGraphType || typeof(ScalarGraphType).IsAssignableFrom(namedType2)); }
public static bool IsLeafType(this IGraphType type) { var namedType = type.GetNamedType(); return(namedType is ScalarGraphType || namedType is EnumerationGraphType); }
public void AddType(IGraphType type, TypeCollectionContext context) { CheckSealed(); if (type == null || type is GraphQLTypeReference) { return; } if (type is NonNullGraphType || type is ListGraphType) { throw new ExecutionError("Only add root types."); } var name = type.CollectTypes(context).TrimGraphQLTypes(); lock (_lock) { SetGraphType(name, type); } if (type is IComplexGraphType complexType) { foreach (var field in complexType.Fields) { HandleField(type.GetType(), field, context); } } if (type is IObjectGraphType obj) { foreach (var objectInterface in obj.Interfaces) { AddTypeIfNotRegistered(objectInterface, context); if (this[objectInterface] is IInterfaceGraphType interfaceInstance) { obj.AddResolvedInterface(interfaceInstance); interfaceInstance.AddPossibleType(obj); if (interfaceInstance.ResolveType == null && obj.IsTypeOf == null) { throw new ExecutionError(( "Interface type {0} does not provide a \"resolveType\" function " + "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " + "There is no way to resolve this possible type during execution.") .ToFormat(interfaceInstance.Name, obj.Name)); } } } } if (type is UnionGraphType union) { if (!union.Types.Any() && !union.PossibleTypes.Any()) { throw new ExecutionError("Must provide types for Union {0}.".ToFormat(union)); } foreach (var unionedType in union.PossibleTypes) { AddTypeIfNotRegistered(unionedType, context); if (union.ResolveType == null && unionedType.IsTypeOf == null) { throw new ExecutionError(( "Union type {0} does not provide a \"resolveType\" function " + "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " + "There is no way to resolve this possible type during execution.") .ToFormat(union.Name, unionedType.Name)); } } foreach (var unionedType in union.Types) { AddTypeIfNotRegistered(unionedType, context); var objType = this[unionedType] as IObjectGraphType; if (union.ResolveType == null && objType != null && objType.IsTypeOf == null) { throw new ExecutionError(( "Union type {0} does not provide a \"resolveType\" function " + "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " + "There is no way to resolve this possible type during execution.") .ToFormat(union.Name, objType.Name)); } union.AddPossibleType(objType); } } }
public static bool IsInputObjectType(this IGraphType type) { var namedType = type.GetNamedType(); return(namedType is IInputObjectGraphType); }
public string Print(IGraphType type) { return SchemaPrinter.ResolveName(type); }