| | 1 | | using System.Reflection; |
| | 2 | | using Scalar.AspNetCore; |
| | 3 | | using Microsoft.OpenApi.Any; |
| | 4 | | using Microsoft.OpenApi.Models; |
| | 5 | | using Microsoft.OpenApi.Interfaces; |
| | 6 | |
|
| | 7 | | namespace Syki.Back.Configs; |
| | 8 | |
|
| | 9 | | public static class DocsConfigs |
| | 10 | | { |
| | 11 | | public static void AddDocsConfigs(this WebApplicationBuilder builder) |
| | 12 | | { |
| 2 | 13 | | builder.Services.AddSwaggerGen(options => |
| 2 | 14 | | { |
| 2 | 15 | | options.SwaggerDoc("v1", new OpenApiInfo |
| 2 | 16 | | { |
| 2 | 17 | | Title = "Syki API Docs", |
| 2 | 18 | | Description = ReadResource("api-intro.md"), |
| 2 | 19 | | Extensions = new Dictionary<string, IOpenApiExtension> |
| 2 | 20 | | { |
| 2 | 21 | | { "x-logo", new OpenApiObject |
| 2 | 22 | | { |
| 2 | 23 | | { "url", new OpenApiString("/syki-logo.png") }, |
| 2 | 24 | | }} |
| 2 | 25 | | }, |
| 2 | 26 | | }); |
| 2 | 27 | |
|
| 2 | 28 | | options.EnableAnnotations(); |
| 2 | 29 | |
|
| 2 | 30 | | options.TagActionsBy(api => |
| 2 | 31 | | { |
| 0 | 32 | | var group = api.RelativePath.Split("/")[0]; |
| 0 | 33 | | if (group == "academic") return ["🏫 Academic"]; |
| 0 | 34 | | if (group == "student") return ["👩🏻🎓 Student"]; |
| 0 | 35 | | if (group == "teacher") return ["👨🏻🏫 Teacher"]; |
| 0 | 36 | | if (group == "adm") return ["🛡️ Adm"]; |
| 0 | 37 | | return ["🧱 Cross"]; |
| 2 | 38 | | }); |
| 2 | 39 | | options.DocInclusionPredicate((name, api) => true); |
| 2 | 40 | |
|
| 2 | 41 | | options.SchemaFilter<EnumSchemaFilter>(); |
| 2 | 42 | | options.OperationFilter<AuthOperationsFilter>(); |
| 2 | 43 | | options.OperationFilter<IdParameterExamplesFilter>(); |
| 2 | 44 | | options.OperationFilter<ExamplesOperationsFilterFilter>(); |
| 2 | 45 | | options.DocumentFilter<HttpMethodSorterDocumentFilter>(); |
| 2 | 46 | |
|
| 2 | 47 | | options.ExampleFilters(); |
| 2 | 48 | |
|
| 2 | 49 | | options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme |
| 2 | 50 | | { |
| 2 | 51 | | In = ParameterLocation.Header, |
| 2 | 52 | | Description = "Please enter a valid token", |
| 2 | 53 | | Name = "Authorization", |
| 2 | 54 | | Type = SecuritySchemeType.Http, |
| 2 | 55 | | BearerFormat = "JWT", |
| 2 | 56 | | Scheme = "bearer", |
| 2 | 57 | | }); |
| 2 | 58 | |
|
| 2 | 59 | | options.DescribeAllParametersInCamelCase(); |
| 2 | 60 | |
|
| 2 | 61 | | var xmlPath = Path.Combine(AppContext.BaseDirectory, "Back.xml"); |
| 2 | 62 | | options.IncludeXmlComments(xmlPath, includeControllerXmlComments: true); |
| 2 | 63 | |
|
| 2 | 64 | | var xmlPath2 = Path.Combine(AppContext.BaseDirectory, "Shared.xml"); |
| 2 | 65 | | options.IncludeXmlComments(xmlPath2, includeControllerXmlComments: true); |
| 4 | 66 | | }); |
| | 67 | |
|
| 2 | 68 | | builder.Services.AddSwaggerExamplesFromAssemblyOf(typeof(Program)); |
| 2 | 69 | | builder.Services.AddOpenApi(); |
| 2 | 70 | | } |
| | 71 | |
|
| | 72 | | public static void MapScalarDocs(this IEndpointRouteBuilder options) |
| | 73 | | { |
| 2 | 74 | | options.MapScalarApiReference("/docs", options => |
| 2 | 75 | | { |
| 2 | 76 | | options.WithModels(false); |
| 2 | 77 | | options.WithTitle("Syki API Docs"); |
| 2 | 78 | | options.WithDocumentDownloadType(DocumentDownloadType.Json); |
| 2 | 79 | | options.WithOpenApiRoutePattern("/swagger/{documentName}/swagger.json"); |
| 2 | 80 | | options |
| 2 | 81 | | .AddPreferredSecuritySchemes("Bearer") |
| 4 | 82 | | .AddHttpAuthentication("Bearer", x => x.Token = "your.bearer.token"); |
| 2 | 83 | |
|
| 2 | 84 | | options.CustomCss = @" |
| 2 | 85 | | :root { |
| 2 | 86 | | --scalar-sidebar-width: 300px; |
| 2 | 87 | | } |
| 2 | 88 | | "; |
| 4 | 89 | | }); |
| 2 | 90 | | } |
| | 91 | |
|
| | 92 | | public static void UseDocs(this IApplicationBuilder app) |
| | 93 | | { |
| 2 | 94 | | app.UseStaticFiles(); |
| 2 | 95 | | app.UseSwagger(); |
| 2 | 96 | | } |
| | 97 | |
|
| | 98 | | private static string ReadResource(string name) |
| | 99 | | { |
| 2 | 100 | | var assembly = Assembly.GetExecutingAssembly(); |
| 4 | 101 | | var resourcePath = assembly.GetManifestResourceNames().Single(str => str.EndsWith(name)); |
| | 102 | |
|
| 2 | 103 | | using Stream stream = assembly.GetManifestResourceStream(resourcePath)!; |
| 2 | 104 | | using StreamReader reader = new(stream); |
| | 105 | |
|
| 2 | 106 | | return reader.ReadToEnd(); |
| 2 | 107 | | } |
| | 108 | | } |