Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using DistributedCache.Extensions;
using DistributedCache.Options;
using FluentMinimalApiMapper;
using Microsoft.AspNetCore.Mvc;
using SharedKernel.Demo;
using SharedKernel.Demo2;
using ResponseCrafter.Enums;
using ResponseCrafter.Extensions;
using SharedKernel.Extensions;
Expand All @@ -18,7 +17,7 @@
AssemblyRegistry.Add(typeof(Program).Assembly);

builder
.AddPandaVault()
// .AddPandaVault()
.AddSerilog()
.AddResponseCrafter(NamingConvention.ToSnakeCase)
.AddOpenApi()
Expand Down Expand Up @@ -48,14 +47,15 @@
.UseOpenApi()
.MapControllers();


app.MapPost("/params", ([AsParameters] TestTypes testTypes) => TypedResults.Ok(testTypes));
app.MapPost("/body", ([FromBody] TestTypes testTypes) => TypedResults.Ok(testTypes));


app.LogStartSuccess();
app.Run();

namespace SharedKernel.Demo
namespace SharedKernel.Demo2
{
public class TestTypes
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"launchBrowser": false,
"applicationUrl": "http://localhost:80",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
26 changes: 26 additions & 0 deletions Shared.Kernel.Demo/Shared.Kernel.Demo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\SharedKernel\SharedKernel.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="appsettings.json">
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
<Content Update="appsettings.Development.json">
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>

</Project>
14 changes: 7 additions & 7 deletions SharedKernel.sln
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedKernel", "src\SharedK
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedKernel.Tests", "test\SharedKernel.Tests\SharedKernel.Tests.csproj", "{0305E58F-1C47-454C-B10B-A223F2561A85}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedKernel.Demo", "test\SharedKernel.Demo\SharedKernel.Demo.csproj", "{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F8A6DCFE-8924-49A4-B3E9-2034593F54E5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FEE159A2-74A0-4469-9B93-52987CA1A3CA}"
Expand All @@ -19,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Kernel.Demo", "Shared.Kernel.Demo\Shared.Kernel.Demo.csproj", "{1CD76A30-4A74-4F54-AC0C-AEDD92408553}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -33,14 +33,14 @@ Global
{0305E58F-1C47-454C-B10B-A223F2561A85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0305E58F-1C47-454C-B10B-A223F2561A85}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0305E58F-1C47-454C-B10B-A223F2561A85}.Release|Any CPU.Build.0 = Release|Any CPU
{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE}.Release|Any CPU.Build.0 = Release|Any CPU
{1CD76A30-4A74-4F54-AC0C-AEDD92408553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CD76A30-4A74-4F54-AC0C-AEDD92408553}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CD76A30-4A74-4F54-AC0C-AEDD92408553}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CD76A30-4A74-4F54-AC0C-AEDD92408553}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{25001943-A870-4E17-A9B9-0D190CEC819B} = {F8A6DCFE-8924-49A4-B3E9-2034593F54E5}
{8A6AA36D-1CEF-4018-9C9D-7D029F3EAECE} = {FEE159A2-74A0-4469-9B93-52987CA1A3CA}
{0305E58F-1C47-454C-B10B-A223F2561A85} = {FEE159A2-74A0-4469-9B93-52987CA1A3CA}
{1CD76A30-4A74-4F54-AC0C-AEDD92408553} = {FEE159A2-74A0-4469-9B93-52987CA1A3CA}
EndGlobalSection
EndGlobal
65 changes: 65 additions & 0 deletions src/SharedKernel/OpenApi/EmbeddedFilesExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

namespace SharedKernel.OpenApi;

internal static class EmbeddedFilesExtension
{
private static readonly HashSet<string> AllowedResources = new(StringComparer.OrdinalIgnoreCase)
{
"panda-style.css",
"panda-style.js",
"favicon.svg",
"logo.svg",
"logo-wording.svg"
};

internal static WebApplication MapSwaggerUiAssetEndpoint(this WebApplication app)
{
app.Map("/swagger-resources/{resourceName}", async (HttpContext context, string resourceName) =>
{
if (!AllowedResources.Contains(resourceName))
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
await context.Response.WriteAsync($"Resource '{resourceName}' not found.");
return;
}

var assembly = typeof(EmbeddedFilesExtension).Assembly;
var resourcePath = assembly.GetManifestResourceNames()
.FirstOrDefault(x => x.EndsWith(resourceName, StringComparison.OrdinalIgnoreCase));

if (resourcePath == null)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync($"Resource '{resourceName}' not found in assembly.");
return;
}

await using var stream = assembly.GetManifestResourceStream(resourcePath);
if (stream == null)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync($"Failed to load resource '{resourceName}'.");
return;
}

context.Response.ContentType = GetContentType(resourceName);
await stream.CopyToAsync(context.Response.Body);
})
.WithGroupName("SwaggerUiAssetEndpoint");

return app;
}

private static string GetContentType(string resourceName) =>
Path.GetExtension(resourceName).ToLowerInvariant() switch
{
".css" => "text/css",
".js" => "application/javascript",
".svg" => "image/svg+xml",
".png" => "image/png",
".jpg" or ".jpeg" => "image/jpeg",
_ => "application/octet-stream"
};
}
9 changes: 3 additions & 6 deletions src/SharedKernel/OpenApi/OpenApiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static class OpenApiExtensions
public static WebApplicationBuilder AddOpenApi(this WebApplicationBuilder builder,
Action<OpenApiOptions>? configureOptions = null)
{

var openApiConfiguration = builder.Configuration
.GetSection("OpenApi")
.Get<OpenApiConfig>();
Expand Down Expand Up @@ -51,14 +52,10 @@ public static WebApplication UseOpenApi(this WebApplication app)
return app;
}

app.MapStaticAssets();
app.MapOpenApi();
app.MapSwaggerUiAssetEndpoint();
app.MapSwaggerUi(openApiConfiguration);
app.MapScalarApiReference(options =>
{
options.Theme = ScalarTheme.Kepler;
options.Favicon = "/assets/images/favicon.svg";
});
app.MapScalarUi();
return app;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ element.style {

.swagger-ui .topbar-wrapper .link::before {
content: "";
background: url("../images/logo.svg") no-repeat center;
background: url("/swagger-resources/logo.svg") no-repeat center;
background-size: contain;
width: 36.402px;
height: 28.8px;
Expand All @@ -69,7 +69,7 @@ element.style {
/* Add your second image */
.swagger-ui .topbar-wrapper .link::after {
content: "";
background: url("../images/logo-wording.svg") no-repeat center;
background: url("/swagger-resources/logo-wording.svg") no-repeat center;
background-size: contain;
width: 90.0276px;
height: 20.2044px;
Expand Down
29 changes: 29 additions & 0 deletions src/SharedKernel/OpenApi/UiAssets/panda-style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
document.addEventListener('DOMContentLoaded', function () {

const faviconPath = "/swagger-resources/favicon.svg";

const existingLink = document.querySelector("link[rel*='icon']");
if (existingLink) {
existingLink.href = faviconPath;
} else {
const newLink = document.createElement("link");
newLink.type = "image/svg+xml";
newLink.rel = "icon";
newLink.href = faviconPath;
document.head.appendChild(newLink);
}

// Scroll modal to top when it appears
const observer = new MutationObserver(() => {
const modal = document.querySelector('.modal-ux-content');
if (modal) {
modal.scrollTop = 0;
observer.disconnect();
}
});

observer.observe(document.body, {
childList: true,
subtree: true,
});
});
17 changes: 6 additions & 11 deletions src/SharedKernel/OpenApi/UiExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Scalar.AspNetCore;
using SharedKernel.Extensions;
using SharedKernel.OpenApi.Options;
using Swashbuckle.AspNetCore.SwaggerUI;

Expand Down Expand Up @@ -50,7 +52,7 @@ internal static WebApplication MapScalarUi(this WebApplication app)
options.Theme = ScalarTheme.Kepler;
if (scalarConfig?.FaviconPath is not null)
{
options.Favicon = "/assets/images/favicon.svg";
options.Favicon = "/swagger-resources/favicon.svg";
}
});
return app;
Expand All @@ -68,16 +70,9 @@ private static SwaggerUIOptions AddPandaOptions(this SwaggerUIOptions options, S
{
return options;
}

foreach (var cssPath in swaggerUiConfig.InjectedCssPaths)
{
options.InjectStylesheet(cssPath);
}

foreach (var jsPath in swaggerUiConfig.InjectedJsPaths)
{
options.InjectJavascript(jsPath);
}

options.InjectStylesheet("/swagger-resources/panda-style.css");
options.InjectJavascript("/swagger-resources/panda-style.js");

return options;
}
Expand Down
8 changes: 6 additions & 2 deletions src/SharedKernel/SharedKernel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<Authors>Pandatech</Authors>
<Copyright>MIT</Copyright>
<Version>1.0.4</Version>
<Version>1.0.5</Version>
<PackageId>Pandatech.SharedKernel</PackageId>
<Title>Pandatech Shared Kernel Library</Title>
<PackageTags>Pandatech, shared kernel, library, OpenAPI, Swagger, utilities, scalar</PackageTags>
Expand All @@ -22,6 +22,10 @@
<None Include="..\..\Readme.md" Pack="true" PackagePath="\"/>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="OpenApi\UiAssets\**\*" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Prometheus.Metrics" Version="8.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="8.0.1" />
Expand All @@ -47,7 +51,7 @@
<PackageReference Include="Pandatech.PandaVaultClient" Version="4.0.0" />
<PackageReference Include="Pandatech.RegexBox" Version="3.0.0" />
<PackageReference Include="Pandatech.ResponseCrafter" Version="5.0.2" />
<PackageReference Include="Scalar.AspNetCore" Version="1.2.43" />
<PackageReference Include="Scalar.AspNetCore" Version="1.2.44" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.0.0" />
</ItemGroup>
Expand Down
46 changes: 0 additions & 46 deletions test/SharedKernel.Demo/SharedKernel.Demo.csproj

This file was deleted.

24 changes: 0 additions & 24 deletions test/SharedKernel.Demo/wwwroot/assets/js/docs.js

This file was deleted.