| | | 1 | | using LoxSmoke.DocXml; |
| | | 2 | | using Microsoft.AspNetCore.Mvc.ApiExplorer; |
| | | 3 | | using Microsoft.OpenApi; |
| | | 4 | | using Plainquire.Filter.Abstractions; |
| | | 5 | | using Plainquire.Filter.Swashbuckle.Models; |
| | | 6 | | using System; |
| | | 7 | | using System.Collections.Generic; |
| | | 8 | | using System.Diagnostics.CodeAnalysis; |
| | | 9 | | using System.Linq; |
| | | 10 | | using System.Reflection; |
| | | 11 | | using System.Text.Json.Nodes; |
| | | 12 | | |
| | | 13 | | namespace Plainquire.Filter.Swashbuckle; |
| | | 14 | | |
| | | 15 | | internal static class OpenApiParameterExtensions |
| | | 16 | | { |
| | | 17 | | internal const string ENTITY_EXTENSION_PREFIX = "x-entity-filter-"; |
| | | 18 | | |
| | | 19 | | [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract", Justification = "Paramet |
| | | 20 | | public static bool IsEntityFilterParameter(this ApiParameterDescription description) |
| | 61 | 21 | | => description.ParameterDescriptor != null && description.ParameterDescriptor.ParameterType.IsGenericEntityFilte |
| | | 22 | | |
| | | 23 | | [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "Para |
| | | 24 | | public static bool IsEntityFilterSetParameter(this ApiParameterDescription description) |
| | 42 | 25 | | => description.ParameterDescriptor?.ParameterType.GetCustomAttribute<EntityFilterSetAttribute>() != null; |
| | | 26 | | |
| | | 27 | | public static void ReplaceFilterParameters(this IList<IOpenApiParameter> parameters, List<FilterParameterReplaceInfo |
| | | 28 | | { |
| | 18 | 29 | | foreach (var replacement in parameterReplacements) |
| | | 30 | | { |
| | 3 | 31 | | if (!replacement.Parameters.Any()) |
| | | 32 | | continue; |
| | | 33 | | |
| | 3 | 34 | | var parameterIndex = parameters.IndexOf(replacement.Parameters[0]); |
| | | 35 | | |
| | 46 | 36 | | foreach (var parameter in replacement.Parameters) |
| | 20 | 37 | | parameters.Remove(parameter); |
| | | 38 | | |
| | 3 | 39 | | var propertyParameters = replacement |
| | 3 | 40 | | .EntityFilters |
| | 3 | 41 | | .SelectMany(entityFilterType => entityFilterType |
| | 3 | 42 | | .GenericTypeArguments[0] |
| | 3 | 43 | | .ExpandToPropertyParameters(docXmlReaders) |
| | 3 | 44 | | ) |
| | 3 | 45 | | .ToList(); |
| | | 46 | | |
| | 22 | 47 | | foreach (var parameter in propertyParameters) |
| | 8 | 48 | | parameters.Insert(parameterIndex++, parameter); |
| | | 49 | | } |
| | 6 | 50 | | } |
| | | 51 | | |
| | | 52 | | private static List<OpenApiParameter> ExpandToPropertyParameters(this Type filteredType, IReadOnlyCollection<DocXmlR |
| | | 53 | | { |
| | 3 | 54 | | var filterableProperties = filteredType.GetFilterableProperties(); |
| | 3 | 55 | | var entityFilterAttribute = filteredType.GetCustomAttribute<EntityFilterAttribute>(); |
| | | 56 | | |
| | 3 | 57 | | return filterableProperties |
| | 3 | 58 | | .Select(property => new OpenApiParameter |
| | 3 | 59 | | { |
| | 3 | 60 | | Name = property.GetFilterParameterName(entityFilterAttribute?.Prefix), |
| | 3 | 61 | | Description = docXmlReaders.GetXmlDocumentationSummary(property), |
| | 3 | 62 | | Schema = new OpenApiSchema { Type = JsonSchemaType.String }, |
| | 3 | 63 | | In = ParameterLocation.Query, |
| | 3 | 64 | | Extensions = new Dictionary<string, IOpenApiExtension>(StringComparer.Ordinal) |
| | 3 | 65 | | { |
| | 3 | 66 | | [ENTITY_EXTENSION_PREFIX + "property-type"] = new JsonNodeExtension(JsonValue.Create(property.Proper |
| | 3 | 67 | | } |
| | 3 | 68 | | }) |
| | 3 | 69 | | .ToList(); |
| | | 70 | | } |
| | | 71 | | |
| | | 72 | | private static string? GetXmlDocumentationSummary(this IEnumerable<DocXmlReader> docXmlReaders, MemberInfo member) |
| | 8 | 73 | | => docXmlReaders.Select(x => x.GetMemberComment(member)).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)); |
| | | 74 | | } |