diff --git a/src/Tgstation.Server.Host/Extensions/QueryContextExtensions.cs b/src/Tgstation.Server.Host/Extensions/QueryContextExtensions.cs index cd8e9e2ed0..3a4bacb966 100644 --- a/src/Tgstation.Server.Host/Extensions/QueryContextExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/QueryContextExtensions.cs @@ -12,6 +12,48 @@ namespace Tgstation.Server.Host.Extensions /// static class QueryContextExtensions { + /// + /// Convert a to an equivalent one that operates on a given of the original . + /// + /// The parent . + /// The child . + /// The to transform. + /// A new for that is functionally identical to the original . + public static QueryContext UpcastFrom(this QueryContext queryContext) + where TChild : TParent + { + ArgumentNullException.ThrowIfNull(queryContext); + + var parameter = Expression.Parameter(typeof(TChild), "child"); + Expression>? selector = null; + if (queryContext.Selector != null) + { + Expression> upcast = parent => (TChild)parent!; + selector = Expression.Lambda>( + Expression.Invoke( + upcast, + Expression.Invoke( + queryContext.Selector, + parameter)), + parameter); + } + + Expression>? predicate = null; + if (queryContext.Predicate != null) + predicate = Expression.Lambda>( + queryContext.Predicate, + parameter); + + SortDefinition? sortDefinition = null; + if (queryContext.Sorting?.Operations.Length > 0) + throw new NotImplementedException(); + + return new QueryContext( + selector, + predicate, + sortDefinition); + } + /// /// Translate a given into one with the target wrapped in an . /// diff --git a/src/Tgstation.Server.Host/GraphQL/Types/User.cs b/src/Tgstation.Server.Host/GraphQL/Types/User.cs index 8b6a08c5db..16917f1086 100644 --- a/src/Tgstation.Server.Host/GraphQL/Types/User.cs +++ b/src/Tgstation.Server.Host/GraphQL/Types/User.cs @@ -127,7 +127,7 @@ namespace Tgstation.Server.Host.GraphQL.Types /// The that created this , if any. public async ValueTask CreatedBy( [Service] IGraphQLAuthorityInvoker userAuthority, - QueryContext? queryContext, + QueryContext? queryContext, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(userAuthority); @@ -135,7 +135,7 @@ namespace Tgstation.Server.Host.GraphQL.Types // This one is particular and cannot be data-loaded due to necessitating a different parameter var user = await userAuthority.InvokeTransformable( authority => authority.GetId(CreatedById, true, cancellationToken), - queryContext); + queryContext?.UpcastFrom()); if (user == null) throw new InvalidOperationException($"Query for created by of user ID {CreatedById} returned null!");