Skip to content

Commit

Permalink
v8.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Abraham committed Mar 8, 2024
1 parent e50db7a commit 3bbd166
Show file tree
Hide file tree
Showing 59 changed files with 670 additions and 579 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_expression_bodied_lambdas = true:suggestion
csharp_style_expression_bodied_local_functions = true:suggestion
csharp_style_prefer_primary_constructors = true:suggestion

[*.vb]
# Modifier preferences
Expand Down
4 changes: 2 additions & 2 deletions src/TypeCache.GraphQL/Data/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public Connection()

public Connection(uint offset, T[] items)
{
offset += 1;
int o = (int)offset + 1;
this.Items = items;
this.Edges = items.Select((row, i) => new Edge<T>((int)offset + i, row)).ToArray();
this.Edges = items.Select((row, i) => new Edge<T>(o + i, row)).ToArray();
}

[GraphQLDescription("The total number of records available. Returns `null` if the total number is unknown.")]
Expand Down
4 changes: 2 additions & 2 deletions src/TypeCache.GraphQL/Extensions/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ public static class EnumExtensions
=> @this switch
{
ScalarType.Boolean => typeof(GraphQLScalarType<bool>),
ScalarType.Byte => typeof(GraphQLScalarType<byte>),
ScalarType.SByte => typeof(GraphQLScalarType<sbyte>),
ScalarType.Int16 => typeof(GraphQLScalarType<short>),
ScalarType.Int32 or ScalarType.Index => typeof(GraphQLScalarType<int>),
ScalarType.Int64 => typeof(GraphQLScalarType<long>),
ScalarType.IntPtr => typeof(GraphQLScalarType<nint>),
ScalarType.Int128 => typeof(GraphQLScalarType<Int128>),
ScalarType.BigInteger => typeof(GraphQLScalarType<BigInteger>),
ScalarType.Byte => typeof(GraphQLScalarType<byte>),
ScalarType.UInt16 => typeof(GraphQLScalarType<ushort>),
ScalarType.UInt32 => typeof(GraphQLScalarType<uint>),
ScalarType.UInt64 => typeof(GraphQLScalarType<ulong>),
ScalarType.UIntPtr => typeof(GraphQLScalarType<UIntPtr>),
ScalarType.UInt128 => typeof(GraphQLScalarType<UInt128>),
ScalarType.SByte => typeof(GraphQLScalarType<sbyte>),
ScalarType.Half => typeof(GraphQLScalarType<Half>),
ScalarType.Single => typeof(GraphQLScalarType<float>),
ScalarType.Double => typeof(GraphQLScalarType<char>),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public static class GraphQLAttributeExtensions
=> @this.GetCustomAttribute<GraphQLDescriptionAttribute>()?.Description switch
{
null => null,
var description when @this is Type type && type.IsGenericType => string.Format(InvariantCulture, description, type.GenericTypeArguments.Select(_ => _.GraphQLName()).ToArray()),
var description when @this is Type type && type.IsGenericType =>
string.Format(InvariantCulture, description, type.GenericTypeArguments.Select(_ => _.GraphQLName()).ToArray()),
var description => description
};

Expand Down Expand Up @@ -57,9 +58,11 @@ public static string GraphQLName(this MemberInfo @this)
public static string GraphQLName(this ParameterInfo @this)
=> @this.GetCustomAttribute<GraphQLNameAttribute>()?.Name ?? @this.Name();

[MethodImpl(AggressiveInlining), DebuggerHidden]
public static Type? GraphQLType(this MemberInfo @this)
=> @this.GetCustomAttribute<GraphQLTypeAttribute>()?.GetType().GenericTypeArguments[0];

[MethodImpl(AggressiveInlining), DebuggerHidden]
public static Type? GraphQLType(this ParameterInfo @this)
=> @this.GetCustomAttribute<GraphQLTypeAttribute>()?.GetType().GenericTypeArguments[0];
}
39 changes: 20 additions & 19 deletions src/TypeCache.GraphQL/Extensions/GraphQLExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ public static Type ToGraphQLInterfaceType(this Type @this)
/// </summary>
[MethodImpl(AggressiveInlining), DebuggerHidden]
public static Type ToGraphQLObjectType(this Type @this)
=> @this.IsValueType && @this.IsNullable()
? typeof(GraphQLObjectType<>).MakeGenericType(@this.GenericTypeArguments[0])
: typeof(GraphQLObjectType<>).MakeGenericType(@this);
=> typeof(GraphQLObjectType<>).MakeGenericType(@this);

public static Type ToGraphQLType(this ParameterInfo @this)
{
Expand All @@ -116,26 +114,29 @@ public static Type ToGraphQLType(this PropertyInfo @this, bool isInputType)

public static Type ToGraphQLType(this Type @this, bool isInputType)
{
if (@this.Is(typeof(Nullable<>)))
return @this.GenericTypeArguments[0].ToGraphQLType(isInputType);

if (@this.IsEnum)
return @this.ToGraphQLEnumType();

var objectType = @this.GetObjectType();
(objectType is ObjectType.Delegate).AssertFalse();
(objectType is ObjectType.Object).AssertFalse();

var scalarGraphType = @this.GetScalarType().ToGraphType();
if (scalarGraphType is not null)
return scalarGraphType;

var collectionType = @this.GetCollectionType();
if (collectionType.IsDictionary())
return typeof(KeyValuePair<,>).MakeGenericType(@this.GenericTypeArguments).ToGraphQLType(isInputType).ToNonNullGraphType().ToListGraphType();

if (@this.IsEnum)
return @this.ToGraphQLEnumType();

if (objectType is ObjectType.Task || objectType is ObjectType.ValueTask)
return @this.IsGenericType
? @this.GenericTypeArguments.First()!.ToGraphQLType(false)
: throw new ArgumentOutOfRangeException(nameof(@this), Invariant($"{nameof(Task)} and {nameof(ValueTask)} are not allowed as GraphQL types."));

var scalarGraphType = @this.GetScalarType().ToGraphType();
if (scalarGraphType is not null)
return scalarGraphType;

if (@this.HasElementType)
{
var elementType = @this.GetElementType()!.ToGraphQLType(isInputType);
Expand Down Expand Up @@ -193,20 +194,20 @@ public static FieldType ToFieldType(this PropertyInfo @this)
arguments.Add("null", type, description: "Return this value instead of null.");

if (@this.PropertyType.IsAssignableTo<IFormattable>())
arguments.Add<GraphQLScalarType<string>>("format", description: "Use .NET format specifiers to format the data.");
arguments.Add<string>("format", nullable: true, description: "Use .NET format specifiers to format the data.");

if (type.Is<GraphQLScalarType<DateTime>>() || type.Is<NonNullGraphType<GraphQLScalarType<DateTime>>>())
arguments.Add<GraphQLScalarType<string>>("timeZone", description: Invariant($"{typeof(TimeZoneInfo).Namespace}.{nameof(TimeZoneInfo)}.{nameof(TimeZoneInfo.ConvertTimeBySystemTimeZoneId)}(value, [..., ...] | [UTC, ...])"));
arguments.Add<string>("timeZone", nullable: true, description: Invariant($"{typeof(TimeZoneInfo).Namespace}.{nameof(TimeZoneInfo)}.{nameof(TimeZoneInfo.ConvertTimeBySystemTimeZoneId)}(value, [..., ...] | [UTC, ...])"));
else if (type.Is<GraphQLScalarType<DateTimeOffset>>() || type.Is<NonNullGraphType<GraphQLScalarType<DateTimeOffset>>>())
arguments.Add<GraphQLScalarType<string>>("timeZone", description: Invariant($"{typeof(TimeZoneInfo).Namespace}.{nameof(TimeZoneInfo)}.{nameof(TimeZoneInfo.ConvertTimeBySystemTimeZoneId)}(value, ...)"));
arguments.Add<string>("timeZone", nullable: true, description: Invariant($"{typeof(TimeZoneInfo).Namespace}.{nameof(TimeZoneInfo)}.{nameof(TimeZoneInfo.ConvertTimeBySystemTimeZoneId)}(value, ...)"));
else if (type.Is<GraphQLScalarType<string>>() || type.Is<NonNullGraphType<GraphQLScalarType<string>>>())
{
arguments.Add<GraphQLEnumType<StringCase>>("case", description: "Convert string value to upper or lower case.");
arguments.Add<GraphQLScalarType<int>>("length", description: "Exclude the rest of the string value if it exceeds this length.");
arguments.Add<GraphQLScalarType<string>>("match", description: "Returns the matching result based on the specified regular expression pattern, null if no match.");
arguments.Add<GraphQLScalarType<string>>("trim", description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.Trim)}(value)"));
arguments.Add<GraphQLScalarType<string>>("trimEnd", description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.TrimEnd)}(value)"));
arguments.Add<GraphQLScalarType<string>>("trimStart", description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.TrimStart)}(value)"));
arguments.Add<StringCase>("case", nullable: true, description: "Convert string value to upper or lower case.");
arguments.Add<int>("length", nullable: true, description: "Exclude the rest of the string value if it exceeds this length.");
arguments.Add<string>("match", nullable: true, description: "Returns the matching result based on the specified regular expression pattern, null if no match.");
arguments.Add<string>("trim", nullable: true, description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.Trim)}(value)"));
arguments.Add<string>("trimEnd", nullable: true, description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.TrimEnd)}(value)"));
arguments.Add<string>("trimStart", nullable: true, description: Invariant($"{typeof(string).Namespace}.{nameof(String)}.{nameof(string.TrimStart)}(value)"));
}

return new()
Expand Down
44 changes: 41 additions & 3 deletions src/TypeCache.GraphQL/Extensions/QueryArgumentsExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,58 @@
// Copyright (c) 2021 Samuel Abraham

using System;
using System.Collections.Generic;
using GraphQL.Types;
using TypeCache.Extensions;
using TypeCache.GraphQL.Types;

namespace TypeCache.GraphQL.Extensions;

public static class QueryArgumentsExtensions
{
public static void Add<T>(this QueryArguments @this, string name, object? defaultValue = null, string? description = null)
where T : IGraphType
=> @this.Add(new QueryArgument<T>
public static void Add<T>(this QueryArguments @this, string name, bool nullable = false, object? defaultValue = null, string? description = null)
{
if (typeof(T).Implements(typeof(IGraphType)))
{
@this.Add(new QueryArgument(typeof(T))
{
Name = name,
DefaultValue = defaultValue,
Description = description
});
return;
}

var isList = typeof(T).IsArray || typeof(T).Implements(typeof(IEnumerable<>).MakeGenericType(typeof(T)));
var type = typeof(T) switch
{
{ IsArray: true } => typeof(T).GetElementType()!,
_ when isList => typeof(T).GenericTypeArguments[0],
_ => typeof(T)
};

var graphType = type switch
{
{ IsEnum: true } => typeof(GraphQLEnumType<>),
_ when type.Implements(typeof(ISpanParsable<>)) => typeof(GraphQLScalarType<>),
_ => typeof(GraphQLInputType<>)
};

type = graphType.MakeGenericType(type);

if (isList)
type = type.ToListGraphType();

if (!nullable)
type = type.ToNonNullGraphType();

@this.Add(new QueryArgument(type)
{
Name = name,
DefaultValue = defaultValue,
Description = description
});
}

public static void Add(this QueryArguments @this, string name, Type type, object? defaultValue = null, string? description = null)
=> @this.Add(new(type)
Expand Down
19 changes: 6 additions & 13 deletions src/TypeCache.GraphQL/Extensions/ResolveFieldContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using GraphQL;
using GraphQLParser.AST;
using TypeCache.Data;
using TypeCache.Extensions;
using static System.FormattableString;
using static System.Runtime.CompilerServices.MethodImplOptions;

namespace TypeCache.GraphQL.Extensions;

Expand Down Expand Up @@ -41,16 +38,12 @@ public static DataTable GetArgumentAsDataTable(this IResolveFieldContext @this,
return table;
}

/// <summary>
/// <c>=&gt; @<paramref name="this"/>.GetArguments(<see langword="typeof"/>(<typeparamref name="TSource"/>), <paramref name="methodInfo"/>);</c>
/// </summary>
/// <typeparam name="TSource">Source object type.</typeparam>
[MethodImpl(AggressiveInlining), DebuggerHidden]
public static IEnumerable<object?> GetArguments<TSource>(this IResolveFieldContext @this, MethodInfo methodInfo)
=> @this.GetArguments(typeof(TSource), methodInfo);

public static IEnumerable<object?> GetArguments(this IResolveFieldContext @this, Type? sourceType, MethodInfo methodInfo)
public static IEnumerable<object?> GetArguments(this IResolveFieldContext @this, MethodInfo methodInfo)
{
var sourceType = @this.Source?.GetType();
if (sourceType == typeof(object))
sourceType = null;

var parameterInfos = methodInfo.GetParameters()
.Where(parameterInfo => !parameterInfo.IsOut && !parameterInfo.IsRetval)
.OrderBy(parameterInfo => parameterInfo.Position);
Expand All @@ -62,7 +55,7 @@ public static DataTable GetArgumentAsDataTable(this IResolveFieldContext @this,
{
_ when parameterInfo.GraphQLIgnore() => null,
_ when parameterInfo.ParameterType.Is<IResolveFieldContext>() => @this,
_ when parameterInfo.ParameterType.Is(sourceType!) && !parameterInfo.ParameterType.Is<object>() => @this.Source,
_ when sourceType is not null && parameterInfo.ParameterType.Is(sourceType) => @this.Source,
IDictionary<string, object?> dictionary when !parameterInfo.ParameterType.Is<IDictionary<string, object?>>() =>
dictionary.MapTo(parameterInfo.ParameterType.Create()!),
_ => argument
Expand Down
Loading

0 comments on commit 3bbd166

Please sign in to comment.