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