public static IEnumerable <IArgumentValue> AllArgumentsSafely(this IResolverContext?context)
        {
            var argNames = AllArgumentSchemaNamesSafely(context);

            var argPairs = argNames.Select(n =>
            {
                try
                {
                    var argLiteral = context?.ArgumentLiteral <IValueNode>(n);
                    var argValue   = argLiteral != null && argLiteral.Location != null && argLiteral.Value != null
                            ? argLiteral.Value
                            : null;

                    return(new ArgumentValue(n, argValue));
                }
                catch
                {
                    //Do nothing, if exception is thrown, as Argument just doesn't exist as expected.
                }

                return(new ArgumentValue(n, null));
            }
                                           )
                           .Where(a => a.Value != null);

            return(argPairs);
        }
示例#2
0
        public static List <ISortOrderField>?GetSortingArgsSafely(this IResolverContext context, string sortOrderArgName = null !)
        {
            var results = new List <ISortOrderField>();

            //Unfortunately the Try/Catch is required to make this safe for easier coding when the argument is not specified,
            //  because the ResolverContext doesn't expose a method to check if an argument exists...
            try
            {
                var sortArgName = sortOrderArgName ?? SortConventionDefinition.DefaultArgumentName;

                //Get Sort Argument Fields and current Values...
                //NOTE: In order to correctly be able to Map names from GraphQL Schema to property/member names
                //      we need to get both the Fields (Schema) and the current order values...
                //NOTE: Not all Queries have Fields (e.g. no Selections, just a literal result), so .Field may
                //      throw internal NullReferenceException, hence we have the wrapper Try/Catch.
                IInputField     sortArgField = context.Field.Arguments[sortArgName];
                ObjectValueNode sortArgValue = context.ArgumentLiteral <ObjectValueNode>(sortArgName);

                //Validate that we have some sort args specified and that the Type is correct (ListType of SortInputType values)...
                //NOTE: The Following processing logic was adapted from 'QueryableSortProvider' implementation in HotChocolate.Data core.
                //FIX: The types changed in v11.0.1/v11.0.2 the Sort Field types need to be checked with IsNull() method, and
                //      then against NonNullType.NamedType() is ISortInputType instead.
                if (!sortArgValue.IsNull() &&
                    sortArgField.Type is ListType lt &&
                    lt.ElementType is NonNullType nn &&
                    nn.NamedType() is ISortInputType sortInputType)
                {
                    //Create a Lookup for the Fields...
                    var sortFieldLookup = sortInputType.Fields.OfType <SortField>().ToLookup(f => f.Name.ToString().ToLower());

                    //Now only process the values provided, but initialize with the corresponding Field (metadata) for each value...
                    var sortOrderFields = sortArgValue.Fields.Select(
                        f => new SortOrderField(
                            sortFieldLookup[f.Name.ToString().ToLower()].FirstOrDefault(),
                            f.Value.ToString()
                            )
                        );

                    results.AddRange(sortOrderFields);
                }

                return(results);
            }
            catch
            {
                //Always safely return at least an Empty List to help minimize Null Reference issues.
                return(results);
            }
        }
        public VariableValue Resolve(
            IResolverContext context,
            ScopedVariableNode variable,
            IInputType targetType)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (variable == null)
            {
                throw new ArgumentNullException(nameof(variable));
            }

            if (!ScopeNames.Arguments.Equals(variable.Scope.Value))
            {
                throw new ArgumentException(
                          StitchingResources.ArgumentScopedVariableResolver_CannotHandleVariable,
                          nameof(variable));
            }

            IInputField?argument = context.Field.Arguments.FirstOrDefault(
                t => t.Name.Value.EqualsOrdinal(variable.Name.Value));

            if (argument == null)
            {
                throw new QueryException(ErrorBuilder.New()
                                         .SetMessage(
                                             StitchingResources.ArgumentScopedVariableResolver_InvalidArgumentName,
                                             variable.Name.Value)
                                         .SetCode(ErrorCodes.Stitching.ArgumentNotDefined)
                                         .SetPath(context.Path)
                                         .AddLocation(context.FieldSelection)
                                         .Build());
            }

            return(new VariableValue
                   (
                       variable.ToVariableName(),
                       argument.Type.ToTypeNode(),
                       context.ArgumentLiteral <IValueNode>(variable.Name.Value),
                       argument.Type.IsNonNullType() && argument.DefaultValue.IsNull()
                    ? null
                    : argument.DefaultValue
                   ));
        }
示例#4
0
        public VariableValue Resolve(
            IResolverContext context,
            ScopedVariableNode variable,
            IInputType targetType)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (variable is null)
            {
                throw new ArgumentNullException(nameof(variable));
            }

            if (!ScopeNames.Arguments.Equals(variable.Scope.Value))
            {
                throw new ArgumentException(
                          ArgumentScopedVariableResolver_CannotHandleVariable,
                          nameof(variable));
            }

            IInputField?argument = context.Field.Arguments.FirstOrDefault(
                t => t.Name.Value.EqualsOrdinal(variable.Name.Value));

            if (argument is null)
            {
                throw ArgumentScopedVariableResolver_InvalidArgumentName(
                          variable.Name.Value,
                          context.FieldSelection,
                          context.Path);
            }

            return(new VariableValue
                   (
                       variable.ToVariableName(),
                       argument.Type.ToTypeNode(),
                       context.ArgumentLiteral <IValueNode>(variable.Name.Value),
                       argument.Type.IsNonNullType() && argument.DefaultValue.IsNull()
                    ? null
                    : argument.DefaultValue
                   ));
        }
示例#5
0
        public ScopedVariableValue Resolve(
            IResolverContext context,
            ScopedVariableNode variable,
            IInputType targetType)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (variable is null)
            {
                throw new ArgumentNullException(nameof(variable));
            }

            if (!ScopeNames.Arguments.Equals(variable.Scope.Value))
            {
                throw new ArgumentException(
                          ArgumentScopedVariableResolver_CannotHandleVariable,
                          nameof(variable));
            }

            if (!context.Selection.Field.Arguments.TryGetField(
                    variable.Name.Value,
                    out IInputField? argument))
            {
                throw ArgumentScopedVariableResolver_InvalidArgumentName(
                          variable.Name.Value,
                          context.Selection.SyntaxNode,
                          context.Path);
            }

            return(new ScopedVariableValue
                   (
                       variable.ToVariableName(),
                       argument.Type.ToTypeNode(),
                       context.ArgumentLiteral <IValueNode>(variable.Name.Value),
                       argument.Type.IsNonNullType() && argument.DefaultValue.IsNull()
                    ? null
                    : argument.DefaultValue
                   ));
        }
示例#6
0
    private static async ValueTask <object?> ResolveSingleNode(
        IResolverContext context,
        IIdSerializer serializer,
        NameString argumentName)
    {
        StringValueNode nodeId         = context.ArgumentLiteral <StringValueNode>(argumentName);
        IdValue         deserializedId = serializer.Deserialize(nodeId.Value);
        NameString      typeName       = deserializedId.TypeName;

        context.SetLocalValue(NodeId, nodeId.Value);
        context.SetLocalValue(InternalId, deserializedId.Value);
        context.SetLocalValue(InternalType, typeName);
        context.SetLocalValue(WellKnownContextData.IdValue, deserializedId);

        if (context.Schema.TryGetType <ObjectType>(typeName, out ObjectType? type) &&
            type.ContextData.TryGetValue(NodeResolver, out var o) &&
            o is FieldResolverDelegate resolver)
        {
            return(await resolver.Invoke(context).ConfigureAwait(false));
        }

        return(null);
    }
示例#7
0
    private static async ValueTask <object?> ResolveManyNode(
        IResolverContext context,
        IIdSerializer serializer)
    {
        if (context.ArgumentKind(Ids) == ValueKind.List)
        {
            ListValueNode    list  = context.ArgumentLiteral <ListValueNode>(Ids);
            Task <object?>[] tasks = ArrayPool <Task <object?> > .Shared.Rent(list.Items.Count);

            var result = new object?[list.Items.Count];

            try
            {
                for (var i = 0; i < list.Items.Count; i++)
                {
                    context.RequestAborted.ThrowIfCancellationRequested();

                    // it is guaranteed that this is always a string literal.
                    StringValueNode nodeId         = (StringValueNode)list.Items[i];
                    IdValue         deserializedId = serializer.Deserialize(nodeId.Value);
                    NameString      typeName       = deserializedId.TypeName;

                    context.SetLocalValue(NodeId, nodeId.Value);
                    context.SetLocalValue(InternalId, deserializedId.Value);
                    context.SetLocalValue(InternalType, typeName);
                    context.SetLocalValue(WellKnownContextData.IdValue, deserializedId);

                    tasks[i] =
                        context.Schema.TryGetType <ObjectType>(typeName, out ObjectType? type) &&
                        type.ContextData.TryGetValue(NodeResolver, out var o) &&
                        o is FieldResolverDelegate resolver
                            ? resolver.Invoke(context).AsTask()
                            : _nullTask;
                }

                for (var i = 0; i < list.Items.Count; i++)
                {
                    context.RequestAborted.ThrowIfCancellationRequested();

                    Task <object?> task = tasks[i];
                    if (task.IsCompleted)
                    {
                        if (task.Exception is null)
                        {
                            result[i] = task.Result;
                        }
                        else
                        {
                            result[i] = null;
                            ReportError(context, i, task.Exception);
                        }
                    }
                    else
                    {
                        try
                        {
                            result[i] = await task;
                        }
                        catch (Exception ex)
                        {
                            result[i] = null;
                            ReportError(context, i, ex);
                        }
                    }
                }

                return(result);
            }
            finally
            {
                ArrayPool <Task <object?> > .Shared.Return(tasks);
            }
        }
        else
        {
            var result = new object?[1];
            result[0] = await ResolveSingleNode(context, serializer, Ids);

            return(result);
        }
    }