/// <summary> /// Initializes a new instance of the <see cref="MergedConnectionMutationResultType"/> class. /// </summary> /// <param name="nodeType"> /// The node type. /// </param> /// <param name="root"> /// The root. /// </param> /// <param name="errorType"> /// The error type. /// </param> /// <param name="provider"> /// The provider. /// </param> public MergedConnectionMutationResultType( MergedObjectType nodeType, MergedApiRoot root, MergedType errorType, ApiProvider provider) : base(nodeType.OriginalTypeName) { this.EdgeType = new MergedEdgeType(nodeType.OriginalTypeName, provider, nodeType); this.root = root; this.ErrorType = errorType; this.Provider = provider; }
/// <summary> /// Initializes a new instance of the <see cref="MergedUntypedMutationResult"/> class. /// </summary> /// <param name="originalReturnType"> /// The original mutation return type. /// </param> /// <param name="root"> /// The root. /// </param> /// <param name="provider"> /// The provider. /// </param> /// <param name="field"> /// The original field description /// </param> public MergedUntypedMutationResult( MergedType originalReturnType, MergedApiRoot root, ApiProvider provider, ApiField field) : base(originalReturnType.OriginalTypeName) { this.OriginalReturnType = originalReturnType; this.root = root; this.field = field; this.Provider = provider; }
/// <summary> /// Initializes a new instance of the <see cref="MergedField"/> class. /// </summary> /// <param name="name"> /// The field name. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="provider"> /// The api provider for the field /// </param> /// <param name="field">The original field description</param> /// <param name="flags"> /// The flags. /// </param> /// <param name="arguments"> /// The field arguments (in case the field is method). /// </param> /// <param name="description"> /// The field description /// </param> public MergedField( string name, MergedType type, ApiProvider provider, ApiField field, EnFieldFlags flags = EnFieldFlags.None, IReadOnlyDictionary <string, MergedField> arguments = null, string description = null) { this.FieldName = name; this.Type = type; this.Flags = flags; this.Arguments = (arguments ?? new Dictionary <string, MergedField>()).ToImmutableDictionary(); this.Description = description; this.AddProvider(provider, field); }
/// <summary> /// Gets the list of requested fields from parent /// <seealso cref="Field"/> /// </summary> /// <param name="selectionSet"> /// The parent field selection set /// </param> /// <param name="context"> /// The request context /// </param> /// <param name="type"> /// The type containing the fields /// </param> /// <returns> /// The list of fields /// </returns> public static IEnumerable <Field> GetRequestedFields( SelectionSet selectionSet, ResolveFieldContext context, MergedType type) { var directFields = selectionSet.Selections.OfType <Field>(); foreach (var field in directFields) { yield return(field); } var typeNames = type.GetPossibleFragmentTypeNames().ToList(); var inlineFragments = selectionSet.Selections.OfType <InlineFragment>().Where(f => typeNames.Contains(f.Type.Name)); foreach (var fragment in inlineFragments) { foreach (var field in GetRequestedFields(fragment.SelectionSet, context, type)) { yield return(field); } } var fragmentsUsed = selectionSet.Selections.OfType <FragmentSpread>() .Select(fs => context.Fragments.FindDefinition(fs.Name)) .Where(f => typeNames.Contains(f.Type.Name)); foreach (var fragment in fragmentsUsed) { foreach (var field in GetRequestedFields(fragment.SelectionSet, context, type)) { yield return(field); } } }
/// <summary> /// Creates virtual field /// </summary> /// <param name="name"> /// The field name /// </param> /// <param name="type"> /// The field type /// </param> /// <param name="resolver"> /// The field resolver /// </param> /// <param name="flags"> /// The field flags. /// </param> /// <returns> /// The field /// </returns> private FieldType CreateField(string name, MergedType type, IFieldResolver resolver = null, EnFieldFlags flags = EnFieldFlags.None) { var mergedField = new MergedField(name, type, this.Provider, null, flags); return(this.ConvertApiField(new KeyValuePair <string, MergedField>(name, mergedField), resolver)); }
/// <summary> /// Initializes a new instance of the <see cref="ResultResolver"/> class. /// </summary> /// <param name="resultType"> /// The result type. /// </param> public ResultResolver(MergedType resultType) { this.resultType = resultType; }
/// <summary> /// Performs node search request /// </summary> /// <param name="context">The request context</param> /// <returns>The searched node</returns> private async Task <JObject> SearchNode(ResolveFieldContext context) { var arguments = context.FieldAst.Arguments.ToJson(context); var packedId = arguments?.Property("id")?.Value?.ToObject <string>(); var serializedId = packedId?.UnpackGlobalId(); if (string.IsNullOrWhiteSpace(serializedId)) { return(null); } List <GlobalId> globalId; try { globalId = JsonConvert.DeserializeObject <List <GlobalId> >(serializedId); } catch { return(null); } var queue = new Queue <GlobalId>(globalId); MergedType mergedType = this.apiRoot; var typesList = new List <MergedType>(); while (queue.Count > 0) { var field = queue.Dequeue(); var objectType = mergedType as MergedObjectType; var connectionType = mergedType as MergedConnectionType; if (objectType != null) { MergedField mergedField; if (!objectType.Fields.TryGetValue(field.FieldName, out mergedField)) { return(null); } mergedType = mergedField.Type; typesList.Add(mergedType); } else if (connectionType != null) { MergedField mergedField; if (!connectionType.ElementType.Fields.TryGetValue(field.FieldName, out mergedField)) { return(null); } mergedType = mergedField.Type; typesList.Add(mergedType); } else { return(null); } } var finalType = (mergedType as MergedConnectionType)?.ElementType ?? mergedType as MergedObjectType; if (finalType == null) { return(null); } List <string> path = new List <string>(); var result = new JObject(); if (finalType.Category == MergedObjectType.EnCategory.MultipleApiType) { if (typesList.Any(t => !(t is MergedObjectType))) { return(null); } foreach (var provider in this.apiRoot.Providers) { var tailRequests = finalType.GatherMultipleApiRequest(provider.Provider, context.FieldAst, context).ToList(); if (tailRequests.Count == 0) { continue; } path = new List <string>(); var requests = CreateRequest(globalId, typesList, path, tailRequests); result.Merge(await provider.Provider.GetData(requests, context.UserContext as RequestContext)); } } else { var tailRequests = finalType.GatherSingleApiRequest(context.FieldAst, context).ToList(); var provider = finalType.Providers.First().Provider; tailRequests = CreateRequest(globalId, typesList, path, tailRequests); result = await provider.GetData(tailRequests, context.UserContext as RequestContext); } var item = result.SelectToken(string.Join(".", path)) as JObject; if (item == null) { return(null); } item.Add("__resolvedType", finalType.ComplexTypeName); item.Add(MergedObjectType.GlobalIdPropertyName, JArray.Parse(serializedId)); return(item); }