Exemple #1
0
        /// <summary>
        /// Searches current api for true mutation container
        /// </summary>
        /// <param name="apiMutation">The mutation</param>
        /// <param name="apiRoot">The api root</param>
        /// <returns>The mutation container</returns>
        private static MergedField FindContainer(ApiMutation apiMutation, MergedApiRoot apiRoot)
        {
            var path = apiMutation.Name.Split('.').ToList();

            path.RemoveAt(path.Count - 1);
            MergedObjectType type  = apiRoot;
            MergedField      field = null;
            var queue = new Queue <string>(path);

            while (queue.Count > 0)
            {
                if (type == null)
                {
                    return(null);
                }

                var fieldName = queue.Dequeue();
                if (!type.Fields.TryGetValue(fieldName, out field))
                {
                    return(null);
                }

                type = field.Type as MergedObjectType;
            }

            return(field);
        }
Exemple #2
0
        /// <summary>
        /// Merges schemes from multiple APIs
        /// </summary>
        /// <param name="providers">
        /// The API providers descriptions
        /// </param>
        /// <param name="createdTypes">
        /// The list of created types.
        /// <remarks>
        /// This is the mutation dictionary and will be filled during creation process
        /// </remarks>
        /// </param>
        /// <returns>
        /// Merged API
        /// </returns>
        private static MergedApiRoot MergeApis(List <ApiProvider> providers, Dictionary <string, MergedType> createdTypes)
        {
            var apiRoot = new MergedApiRoot("api");

            apiRoot.AddProviders(providers.Select(p => new FieldProvider {
                Provider = p, FieldType = p.Description
            }));
            apiRoot.Category = providers.Count > 1
                                   ? MergedObjectType.EnCategory.MultipleApiType
                                   : MergedObjectType.EnCategory.SingleApiType;

            foreach (var provider in providers)
            {
                MergeFields(apiRoot, provider.Description.Fields, provider, new List <string>(), false, createdTypes);

                foreach (var apiMutation in provider.Description.Mutations)
                {
                    var mutationName =
                        $"{MergedType.EscapeName(provider.Description.ApiName)}_{MergedType.EscapeName(apiMutation.Name)}";
                    MergedField mutation = null;
                    switch (apiMutation.Type)
                    {
                    case ApiMutation.EnType.ConnectionCreate:
                    case ApiMutation.EnType.ConnectionUpdate:
                    case ApiMutation.EnType.ConnectionDelete:
                    case ApiMutation.EnType.Connection:
                        mutation = RegisterConnectionMutation(provider, apiMutation, apiRoot, createdTypes);
                        break;

                    case ApiMutation.EnType.Untyped:
                        mutation = RegisterUntypedMutation(provider, apiMutation, apiRoot, createdTypes);
                        break;
                    }

                    if (mutation != null)
                    {
                        apiRoot.Mutations[mutationName] = mutation;
                    }
                }
            }

            var nodeSearcher = new NodeSearcher(apiRoot);

            apiRoot.NodeSearher = nodeSearcher;
            return(apiRoot);
        }
Exemple #3
0
        /// <summary>
        /// Generates the list of used end-types
        /// </summary>
        /// <param name="providers">The list of defined api providers</param>
        /// <param name="types">The list of merged types</param>
        /// <param name="nodeInterface">The node interface (for relay compliance)</param>
        /// <param name="allInterfaces">The list of defined type interfaces</param>
        /// <param name="api">The api root element</param>
        /// <param name="mutationType">The type containing all mutation methods</param>
        /// <returns>The list of defined types</returns>
        private static Dictionary <string, IGraphType> GenerateApiTypes(
            List <ApiProvider> providers,
            List <MergedType> types,
            NodeInterface nodeInterface,
            Dictionary <string, IGraphType> allInterfaces,
            MergedApiRoot api,
            out IObjectGraphType mutationType)
        {
            var graphTypes = types.ToDictionary(
                type => type.ComplexTypeName,
                type => type.GenerateGraphType(nodeInterface, GetTypeInterfaces(type, providers, allInterfaces)));

            mutationType = api.GenerateMutationType();
            graphTypes[mutationType.Name] = mutationType;
            graphTypes.Values.OfType <IComplexGraphType>().SelectMany(a => a.Fields).ForEach(
                f =>
            {
                var fieldDescription = f.GetMetadata <MergedField>(MergedType.MetaDataTypeKey);
                if (fieldDescription == null)
                {
                    return;
                }

                SetFieldArguments(f, fieldDescription, graphTypes);
                f.ResolvedType = GetTypeForField(fieldDescription, graphTypes);

                if (f.Resolver == null)
                {
                    f.Resolver = fieldDescription.Resolver ?? fieldDescription.Type;
                }

                if (!string.IsNullOrWhiteSpace(fieldDescription.Description))
                {
                    f.Description = fieldDescription.Description;
                }
            });
            return(graphTypes);
        }
Exemple #4
0
        /// <summary>
        /// Register the mutation
        /// </summary>
        /// <param name="provider">The mutation api provider</param>
        /// <param name="apiMutation">The mutation description</param>
        /// <param name="apiRoot">The api root</param>
        /// <param name="typesCreated">The list of created types</param>
        /// <returns>The mutation as merged field </returns>
        private static MergedField RegisterConnectionMutation(
            ApiProvider provider,
            ApiMutation apiMutation,
            MergedApiRoot apiRoot,
            Dictionary <string, MergedType> typesCreated)
        {
            var field          = FindContainer(apiMutation, apiRoot);
            var connectionType = field?.Type as MergedConnectionType;

            if (connectionType == null)
            {
                return(null);
            }

            var errorDescriptionApiType =
                provider.Description.Types.FirstOrDefault(t => t.TypeName == "ErrorDescription") as ApiObjectType;
            MergedType errorDescriptionType = null;

            if (errorDescriptionApiType != null)
            {
                errorDescriptionType = CreateConnectionType(errorDescriptionApiType, provider, typesCreated);
            }

            var returnType = new MergedConnectionMutationResultType(
                connectionType.ElementType,
                apiRoot,
                errorDescriptionType,
                provider);

            typesCreated[returnType.ComplexTypeName] = returnType;

            var inputType = new MergedInputType(apiMutation.Name);

            inputType.AddProvider(
                new FieldProvider {
                Provider = provider, FieldType = new ApiObjectType(apiMutation.Name)
            });
            typesCreated[inputType.ComplexTypeName] = inputType;

            foreach (var apiField in apiMutation.Arguments)
            {
                inputType.Fields.Add(
                    apiField.Name,
                    new MergedField(
                        apiField.Name,
                        CreateMergedType(provider, apiField, null, new List <string>(), true, typesCreated),
                        provider,
                        apiMutation,
                        apiMutation.Flags,
                        description: apiField.Description));
            }

            inputType.Fields["clientMutationId"] = new MergedField(
                "clientMutationId",
                CreateScalarType(EnScalarType.String, typesCreated),
                provider,
                apiMutation);

            var arguments = new Dictionary <string, MergedField>
            {
                {
                    "input",
                    new MergedField(
                        "input",
                        inputType,
                        provider,
                        apiMutation)
                }
            };

            return(new MergedField(
                       apiMutation.Name,
                       returnType,
                       provider,
                       apiMutation,
                       apiMutation.Flags,
                       arguments,
                       apiMutation.Description));
        }
Exemple #5
0
        /// <summary>
        /// Register the mutation
        /// </summary>
        /// <param name="provider">The mutation api provider</param>
        /// <param name="apiMutation">The mutation description</param>
        /// <param name="apiRoot">The api root</param>
        /// <param name="typesCreated">The list of created types</param>
        /// <returns>The mutation as merged field </returns>
        private static MergedField RegisterUntypedMutation(
            ApiProvider provider,
            ApiMutation apiMutation,
            MergedApiRoot apiRoot,
            Dictionary <string, MergedType> typesCreated)
        {
            var returnType = CreateMergedType(provider, apiMutation, null, new List <string>(), false, typesCreated);

            var inputType = new MergedInputType(apiMutation.Name);

            inputType.AddProvider(
                new FieldProvider {
                Provider = provider, FieldType = new ApiObjectType(apiMutation.Name)
            });
            typesCreated[inputType.ComplexTypeName] = inputType;

            foreach (var apiField in apiMutation.Arguments)
            {
                inputType.Fields.Add(
                    apiField.Name,
                    new MergedField(
                        apiField.Name,
                        CreateMergedType(provider, apiField, null, new List <string>(), true, typesCreated),
                        provider,
                        apiMutation.Clone(),
                        apiMutation.Flags,
                        description: apiField.Description));
            }

            inputType.Fields["clientMutationId"] = new MergedField(
                "clientMutationId",
                CreateScalarType(EnScalarType.String, typesCreated),
                provider,
                apiMutation);

            var arguments = new Dictionary <string, MergedField>
            {
                {
                    "input",
                    new MergedField(
                        "input",
                        inputType,
                        provider,
                        apiMutation)
                }
            };

            var payload = new MergedUntypedMutationResult(returnType, apiRoot, provider, apiMutation);

            typesCreated[payload.ComplexTypeName] = payload;

            var untypedMutation = new MergedField(
                apiMutation.Name,
                payload,
                provider,
                apiMutation,
                apiMutation.Flags,
                arguments,
                apiMutation.Description);

            return(untypedMutation);
        }