Compare commits

..

No commits in common. "master" and "v0.0.1" have entirely different histories.

12 changed files with 67 additions and 199 deletions

View File

@ -7,7 +7,7 @@ on:
env: env:
PROJECT_PATH: 'BlazorOpenApi/BlazorOpenApi.csproj' PROJECT_PATH: 'BlazorOpenApi/BlazorOpenApi.csproj'
PACKAGE_OUTPUT_DIRECTORY: ${{ github.workspace }}/output PACKAGE_OUTPUT_DIRECTORY: ${{ github.workspace }}\output
NUGET_SOURCE_URL: 'https://api.nuget.org/v3/index.json' NUGET_SOURCE_URL: 'https://api.nuget.org/v3/index.json'
jobs: jobs:
@ -34,7 +34,7 @@ jobs:
uses: battila7/get-version-action@v2 uses: battila7/get-version-action@v2
- name: 'Pack project' - name: 'Pack project'
run: dotnet pack ${{ env.PROJECT_PATH }} --no-restore --no-build --configuration Release -p:PackageVersion=${{ steps.version.outputs.version-without-v }} --output ${{ env.PACKAGE_OUTPUT_DIRECTORY }} run: dotnet pack ${{ env.PROJECT_PATH }} --no-restore --no-build --configuration Release --include-symbols -p:PackageVersion=${{ steps.version.outputs.version-without-v }} --output ${{ env.PACKAGE_OUTPUT_DIRECTORY }}
- name: 'Push package' - name: 'Push package'
run: dotnet nuget push ${{ env.PACKAGE_OUTPUT_DIRECTORY }}/*.nupkg -k ${{ secrets.NUGET_AUTH_TOKEN }} -s ${{ env.NUGET_SOURCE_URL }} run: dotnet nuget push ${{ env.PACKAGE_OUTPUT_DIRECTORY }}\*.nupkg -k ${{ secrets.NUGET_AUTH_TOKEN }} -s ${{ env.NUGET_SOURCE_URL }}

View File

@ -10,7 +10,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
LICENSE.txt = LICENSE.txt LICENSE.txt = LICENSE.txt
.github\workflows\nuget.yml = .github\workflows\nuget.yml
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject

View File

@ -7,7 +7,6 @@
</Description> </Description>
<PackageProjectUrl>https://github.com/unclshura/BlazorOpenApi</PackageProjectUrl> <PackageProjectUrl>https://github.com/unclshura/BlazorOpenApi</PackageProjectUrl>
<PackageTags>openapi, c#, blazor, api, ui, rest, web</PackageTags> <PackageTags>openapi, c#, blazor, api, ui, rest, web</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -17,9 +16,4 @@
<PackageReference Include="System.Text.Json" /> <PackageReference Include="System.Text.Json" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="../README.md" Pack="true" PackagePath="\"/>
<None Include="../docs/**" Pack="true" PackagePath="\docs\"/>
</ItemGroup>
</Project> </Project>

View File

@ -7,7 +7,7 @@
@foreach (var (name, val) in Value.Schemas) @foreach (var (name, val) in Value.Schemas)
{ {
<h4>@name</h4> <h4>@name</h4>
<SchemaControl Value="@val" Collapsed="false"/> <SchemaControl Value="@val"/>
} }
</TocMember> </TocMember>
} }

View File

@ -54,9 +54,7 @@
} }
else else
{ {
var ex = GenerateExampleFromSchema(parameter.Schema); exampleData[parameter.Name] = GenerateExampleFromSchema(parameter.Schema);
if (ex != null)
exampleData[parameter.Name] = ex;
} }
} }

View File

@ -5,24 +5,9 @@
@if (Value.Type == "array") @if (Value.Type == "array")
{ {
<Expander HeaderClass="s-type" Class="s-bg-odd" Title="@ArrayText" Collapsed="@Collapsed"> <Expander HeaderClass="s-type" Class="s-bg-odd" Title="@ArrayText" Collapsed="@Collapsed">
@if (Value.Items?.Type == "object" && SchemaControl.Resolve(Value.Items, Api)?.Properties != null)
{
@* Skip one level *@
<div class="s-props s-nested">
<table class="schema">
@foreach (var p in SchemaControl.Resolve(Value.Items, Api)!.Properties)
{
<SchemaChildControl Value="@p.Value" Title="@p.Key" Required="@IsRequired(p.Key)" />
}
</table>
</div>
}
else
{
<div class="s-nested"> <div class="s-nested">
<SchemaControl Value="@Value.Items" /> <SchemaControl Value="@Value.Items" />
</div> </div>
}
</Expander> </Expander>
} }
else if (Value.Type == "object") else if (Value.Type == "object")
@ -70,8 +55,6 @@
} }
@code { @code {
[CascadingParameter]
public OpenApiDocument? Api { get; set; }
[Parameter] [Parameter]
public OpenApiSchema? Value { get; set; } public OpenApiSchema? Value { get; set; }
[Parameter] [Parameter]
@ -90,15 +73,11 @@
if (Value?.Type != "array") if (Value?.Type != "array")
return ""; return "";
string arrayType = Value.Items?.Type ?? "";
if ( Value.Items?.Type != "array" && Value.Items?.Type != "object")
arrayType = Value.Items?.Type ?? "array";
var nullable = Value.Nullable ? "?" : ""; var nullable = Value.Nullable ? "?" : "";
if (Value.MinItems != null || Value.MaxItems != null) if (Value.MinItems != null || Value.MaxItems != null)
return $"{arrayType}{nullable} [{(Value.MinItems == null ? "" : Value.MinItems.Value)}..{(Value.MaxItems == null ? "" : Value.MaxItems.Value)}]"; return $"array{nullable} [{(Value.MinItems == null ? "" : Value.MinItems.Value)}..{(Value.MaxItems == null ? "" : Value.MaxItems.Value)}]";
return $"{arrayType}{nullable} []"; return $"array{nullable} []";
} }
} }

View File

@ -19,17 +19,15 @@
[CascadingParameter] [CascadingParameter]
public OpenApiDocument? Api { get; set; } public OpenApiDocument? Api { get; set; }
private OpenApiSchema? ResolvedValue => Resolve(Value, Api) ?? Value; private OpenApiSchema? ResolvedValue
public static OpenApiSchema? Resolve(OpenApiSchema? schema, OpenApiDocument? api)
{ {
if (schema == null) get
return null;
if (schema.Reference != null && api != null)
{ {
if (api.Components.Schemas.TryGetValue(schema.Reference.Id, out var resolved)) if (Api == null || Value?.Reference == null )
return Value;
if (!Api.Components.Schemas.TryGetValue(Value.Reference.Id, out var resolved))
return Value;
return resolved; return resolved;
} }
return schema;
} }
} }

View File

@ -17,7 +17,6 @@
<TableOfContents Tree="@_tree" /> <TableOfContents Tree="@_tree" />
</Expander> </Expander>
<div class="oa-main-content">
<HeaderControl Value="@_api.Info" DownloadUrl="@Url" /> <HeaderControl Value="@_api.Info" DownloadUrl="@Url" />
<ServersControl Value="@_api.Servers" /> <ServersControl Value="@_api.Servers" />
@if (_api.Paths?.Count > 0) @if (_api.Paths?.Count > 0)
@ -40,7 +39,7 @@
<ComponentsControl Value="@_api.Components" /> <ComponentsControl Value="@_api.Components" />
</TocMember> </TocMember>
} }
</div>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>

View File

@ -1,70 +1,3 @@
# Blazor OpenAPI UI # Blazor OpenAPI UI
Author: *unclshura* Blazor implementation of SwaggerUI-like interface.
This is a Blazor implementation of a SwaggerUI-like interface. It allows you to view your OpenAPI
specifications in a user-friendly way. The motication of this project is to provide a Blazor component that can be used in Blazor applications
to display OpenAPI specifications. Unlike SwaggerUI, this project does not require any JavaScript dependencies.
It is a pure Blazor implementation.
## Installation
You can install the package from NuGet:
```bash
dotnet add package BlazorOpenApi
```
Source code:
```bash
Github: https://github.com/unclshura/BlazorOpenApi
HTTPS: https://github.com/unclshura/BlazorOpenApi.git
SSH: git@github.com:unclshura/BlazorOpenApi.git
```
## Features
- View OpenAPI specifications in a user-friendly way
- Dark and light themes
- Fully customizable color palette
- Separate CSS styles for every element
- Examples generation
- Pure Blazor implementation
## Usage
To use the component, add the following line to your `_Imports.razor` file:
```razor
@using BlazorOpenApi
@using BlazorOpenApi.Controls
```
Then, you can use the component in your Blazor application:
```razor
<OpenAPIUIControl Url="https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml" />
```
To customize the palette you can use something like this:
```razor
<OpenAPIUIControl Url="@Url" Palette="@TestPalette"/>
@code {
[Parameter]
[SupplyParameterFromQuery(Name = "url")]
public string Url { get; set; } = "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.json";
private OpenApiUiPalette TestPalette
{
get
{
var p = new OpenApiUiPalette().Clone();
p.Foreground[7] = "blue";
return p;
}
}
}
```
The demo application is available in the `Demo` folder - https://github.com/unclshura/BlazorOpenApi/tree/master/Demo.
# LICENSE
MIT

View File

@ -9,7 +9,7 @@ internal class TableOfContentsTree : ITableOfContentsTree
private readonly Dictionary<string, TocTreeNode> _nodes = new(); private readonly Dictionary<string, TocTreeNode> _nodes = new();
private readonly List<string> _order = new(); private readonly List<string> _order = new();
public event EventHandler? Changed; public event EventHandler Changed;
public void Clear() public void Clear()
{ {

View File

@ -162,7 +162,7 @@
height: fit-content; height: fit-content;
width: fit-content; width: fit-content;
margin-right: 5px; margin-right: 5px;
border-radius: 3px; border-radius: 5px;
margin-top: 3px; margin-top: 3px;
padding-left: 3px; padding-left: 3px;
padding-right: 3px; padding-right: 3px;
@ -314,30 +314,16 @@
.openapi-ui h1 { .openapi-ui h1 {
margin-top: 24px; margin-top: 24px;
border-left-width: 5px;
border-color: var(--oa-bg-7);
padding-left: 5px;
margin-bottom: 3px;
} }
.openapi-ui h2 { .openapi-ui h2 {
margin-top: 18px; margin-top: 18px;
margin-bottom: 3px;
color: var(--oa-fg-7);
border-bottom-width: 4px;
border-color: var(--oa-bg-7);
} }
.openapi-ui h3 { .openapi-ui h3 {
margin-top: 12px; margin-top: 12px;
margin-bottom: 3px;
border-bottom-width: 1px;
border-color: var(--oa-bg-7);
} }
.openapi-ui h4 { .openapi-ui h4 {
margin-top: 8px; margin-top: 8px;
margin-bottom: 3px;
border-bottom-width: 1px;
border-color: var(--oa-bg-1);
} }
.openapi-ui .tooltip { .openapi-ui .tooltip {
@ -346,16 +332,6 @@
border-bottom: 1px dotted black; border-bottom: 1px dotted black;
} }
.openapi-ui a {
text-decoration: none;
cursor: pointer;
color: var(--oa-fg-link);
}
.openapi-ui a:hover {
color: var(--oa-fg-link-hover);
}
.openapi-ui .tooltip .tooltiptext { .openapi-ui .tooltip .tooltiptext {
visibility: hidden; visibility: hidden;
width: fit-content; width: fit-content;
@ -399,17 +375,16 @@
vertical-align: top; vertical-align: top;
} }
.openapi-ui { .openapi-ui {
--oa-bg-lighter: #0000001f; --oa-bg-lighter: #0000001f;
--oa-bg-darker: #00000055; --oa-bg-darker: #00000055;
--oa-bg-darkest: #000000AA; --oa-bg-darkest: #000000AA;
--oa-fg-normal: #e4e4e4; --oa-fg-normal: #e4e4e4;
--oa-fg-lighter: #ffffff; --oa-fg-lighter: #ffffff;
--oa-fg-darker: #A0A0A0; --oa-fg-darker: #A0A0A0;
--oa-fg-darkest: #808080; --oa-fg-darkest: #808080;
--oa-fg-link: var(--oa-fg-1);
--oa-fg-link-hover: var(--oa-bg-1);
--oa-bg-1: #3655a3; --oa-bg-1: #3655a3;
--oa-bg-2: #7a7620; --oa-bg-2: #7a7620;
--oa-bg-3: #9f4b1e; --oa-bg-3: #9f4b1e;
@ -418,6 +393,7 @@
--oa-bg-6: #851192; --oa-bg-6: #851192;
--oa-bg-7: #266b67; --oa-bg-7: #266b67;
--oa-bg-8: #456f2b; --oa-bg-8: #456f2b;
--oa-fg-1: #7d98de; --oa-fg-1: #7d98de;
--oa-fg-2: #ded971; --oa-fg-2: #ded971;
--oa-fg-3: #eda279; --oa-fg-3: #eda279;
@ -426,8 +402,10 @@
--oa-fg-6: #e571f2; --oa-fg-6: #e571f2;
--oa-fg-7: #98e6e1; --oa-fg-7: #98e6e1;
--oa-fg-8: #54b319; --oa-fg-8: #54b319;
--oa-bg-tag: var(--oa-bg-1); --oa-bg-tag: var(--oa-bg-1);
--oa-fg-tag: var(--oa-fg-lighter); --oa-fg-tag: var(--oa-fg-lighter);
--oa-bg-op-get: var(--oa-bg-1); --oa-bg-op-get: var(--oa-bg-1);
--oa-bg-op-put: var(--oa-bg-2); --oa-bg-op-put: var(--oa-bg-2);
--oa-bg-op-post: var(--oa-bg-3); --oa-bg-op-post: var(--oa-bg-3);
@ -436,17 +414,20 @@
--oa-bg-op-head: var(--oa-bg-6); --oa-bg-op-head: var(--oa-bg-6);
--oa-bg-op-patch: var(--oa-bg-7); --oa-bg-op-patch: var(--oa-bg-7);
--oa-bg-op-trace: var(--oa-bg-8); --oa-bg-op-trace: var(--oa-bg-8);
--oa-bg-header: var(--oa-bg-6); --oa-bg-header: var(--oa-bg-6);
--oa-bg-form: var(--oa-bg-7); --oa-bg-form: var(--oa-bg-7);
--oa-bg-path: var(--oa-bg-8); --oa-bg-path: var(--oa-bg-8);
--oa-bg-cookie: var(--oa-bg-1); --oa-bg-cookie: var(--oa-bg-1);
--oa-bg-query: var(--oa-bg-2); --oa-bg-query: var(--oa-bg-2);
--oa-bg-matrix: var(--oa-bg-6); --oa-bg-matrix: var(--oa-bg-6);
--oa-bg-label: var(--oa-bg-7); --oa-bg-label: var(--oa-bg-7);
--oa-bg-simple: var(--oa-bg-8); --oa-bg-simple: var(--oa-bg-8);
--oa-bg-spacedelimited: var(--oa-bg-1); --oa-bg-spacedelimited: var(--oa-bg-1);
--oa-bg-pipedelimited: var(--oa-bg-2); --oa-bg-pipedelimited: var(--oa-bg-2);
--oa-bg-deepobject: var(--oa-bg-3); --oa-bg-deepobject: var(--oa-bg-3);
--oa-font-small: 12px; --oa-font-small: 12px;
--oa-font-smaller: 10px; --oa-font-smaller: 10px;
--oa-font-large: 16px; --oa-font-large: 16px;

View File

@ -1,7 +1,5 @@
# Blazor OpenAPI UI # Blazor OpenAPI UI
Author: *unclshura*
This is a Blazor implementation of a SwaggerUI-like interface. It allows you to view your OpenAPI This is a Blazor implementation of a SwaggerUI-like interface. It allows you to view your OpenAPI
specifications in a user-friendly way. The motication of this project is to provide a Blazor component that can be used in Blazor applications specifications in a user-friendly way. The motication of this project is to provide a Blazor component that can be used in Blazor applications
to display OpenAPI specifications. Unlike SwaggerUI, this project does not require any JavaScript dependencies. to display OpenAPI specifications. Unlike SwaggerUI, this project does not require any JavaScript dependencies.
@ -9,17 +7,9 @@ It is a pure Blazor implementation.
## Screenshots ## Screenshots
Light theme: [Light mode](docs/light.png)
[Dark mode](docs/dark.png)
![Light mode](https://raw.githubusercontent.com/unclshura/BlazorOpenApi/master/docs/light.png) [Examples generation](docs/example-data.png)]
Dark Theme:
![Dark mode](https://raw.githubusercontent.com/unclshura/BlazorOpenApi/master/docs/dark.png)
Examples generation:
![Examples generation](https://raw.githubusercontent.com/unclshura/BlazorOpenApi/master/docs/example-data.png)
## Installation ## Installation
@ -28,15 +18,12 @@ You can install the package from NuGet:
dotnet add package BlazorOpenApi dotnet add package BlazorOpenApi
``` ```
## Source code Source code:
```bash
|What |Where | Github: https://github.com/unclshura/BlazorOpenApi
|--------|------------------------------------------------| HTTPS: https://github.com/unclshura/BlazorOpenApi.git
| Github | https://github.com/unclshura/BlazorOpenApi | SSH: git@github.com:unclshura/BlazorOpenApi.git
| HTTPS | https://github.com/unclshura/BlazorOpenApi.git | ```
| SSH | git@github.com:unclshura/BlazorOpenApi.git |
| NuGet | https://www.nuget.org/packages/BlazorOpenApi/ |
## Features ## Features
@ -55,12 +42,12 @@ To use the component, add the following line to your `_Imports.razor` file:
@using BlazorOpenApi.Controls @using BlazorOpenApi.Controls
``` ```
Then, you can use the component in your Blazor application: Then, you can use the component in your Blazor application:
```c# ```razor
<OpenAPIUIControl Url="https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml" /> <OpenAPIUIControl Url="https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml" />
``` ```
To customize the palette you can use something like this: To customize the palette you can use something like this:
```c# ```razor
<OpenAPIUIControl Url="@Url" Palette="@TestPalette"/> <OpenAPIUIControl Url="@Url" Palette="@TestPalette"/>
@code { @code {