Signed-off-by: Vincent Biret <vibiret@microsoft.com>
This commit is contained in:
Vincent Biret 2023-07-17 14:49:21 -04:00
Родитель ead341baee
Коммит e9f694019e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 32426322EDFFB7E3
52 изменённых файлов: 0 добавлений и 3385 удалений

Просмотреть файл

@ -76,7 +76,6 @@ stages:
- pwsh: |
Copy-Item $(Build.ArtifactStagingDirectory)/AppSettings/appsettings.json $(Build.SourcesDirectory)/src/kiota/appsettings.json -Force -Verbose
Copy-Item $(Build.ArtifactStagingDirectory)/AppSettings/appsettings.json $(Build.SourcesDirectory)/src/Kiota.Web/wwwroot/appsettings.json -Force -Verbose
displayName: Copy the appsettings.json
- task: UseDotNet@2
@ -148,14 +147,6 @@ stages:
projects: '$(Build.SourcesDirectory)\kiota.sln'
arguments: "--configuration $(BuildConfiguration) --no-build"
# removing kiota web files before signing as they don't need to be signed
# removing triggers to credscan
- pwsh: |
Remove-Item -r src\Kiota.Web\bin -ErrorAction SilentlyContinue -Verbose
Remove-Item tests\Kiota.Web.Tests\bin\Release\net7.0\.playwright\package\ThirdPartyNotices.txt -ErrorAction SilentlyContinue -Verbose
Remove-Item src\Kiota.Web\README.md -ErrorAction SilentlyContinue -Verbose
workingDirectory: $(Build.SourcesDirectory)
# CredScan
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
displayName: "Run CredScan - Src"
@ -349,7 +340,6 @@ stages:
- pwsh: |
Copy-Item $(Build.ArtifactStagingDirectory)/AppSettings/appsettings.json $(Build.SourcesDirectory)/src/kiota/appsettings.json -Force -Verbose
Copy-Item $(Build.ArtifactStagingDirectory)/AppSettings/appsettings.json $(Build.SourcesDirectory)/src/Kiota.Web/wwwroot/appsettings.json -Force -Verbose
displayName: Copy the appsettings.json
- pwsh: $(Build.SourcesDirectory)/scripts/get-prerelease-version.ps1 -currentBranch $(Build.SourceBranch) -previewBranch $(previewBranch) -excludeHeadingDash

31
.github/workflows/deploy-kiota-dev.yml поставляемый
Просмотреть файл

@ -1,31 +0,0 @@
name: Deploy kiota.dev
on:
push:
tags:
- "v*"
jobs:
publish_kiota_dev:
# we don't have a preview environment for kiota.dev
if: ${{ !contains(github.ref, '-preview') }}
name: Publish kiota.dev
environment:
name: kiota.dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Publish kiota.dev
run: dotnet publish -c Release
working-directory: ./src/Kiota.Web
- uses: LanceMcCarthy/Action-AzureBlobUpload@v2
name: Azure Blob Upload with Destination folder defined
with:
connection_string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
container_name: "$web"
source_folder: src/Kiota.Web/bin/Release/net7.0/publish/wwwroot
delete_if_exists: true

Просмотреть файл

@ -17,10 +17,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kiota.Tests", "tests\Kiota.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EAAC5CEA-33B8-495D-9CD0-B36794B8AFE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kiota.Web", "src\Kiota.Web\Kiota.Web.csproj", "{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kiota.Web.Tests", "tests\Kiota.Web.Tests\Kiota.Web.Tests.csproj", "{A2584ED3-5C92-4BC7-9120-D97F5404B52C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiotaGenerated", "src\Kiota.Generated\KiotaGenerated.csproj", "{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}"
EndProject
Global
@ -49,14 +45,6 @@ Global
{E4C108A5-A13F-4C3F-B32A-86210A4EC52A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4C108A5-A13F-4C3F-B32A-86210A4EC52A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4C108A5-A13F-4C3F-B32A-86210A4EC52A}.Release|Any CPU.Build.0 = Release|Any CPU
{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600}.Release|Any CPU.Build.0 = Release|Any CPU
{A2584ED3-5C92-4BC7-9120-D97F5404B52C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A2584ED3-5C92-4BC7-9120-D97F5404B52C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A2584ED3-5C92-4BC7-9120-D97F5404B52C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A2584ED3-5C92-4BC7-9120-D97F5404B52C}.Release|Any CPU.Build.0 = Release|Any CPU
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -70,8 +58,6 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E4C108A5-A13F-4C3F-B32A-86210A4EC52A} = {2DF34BB8-B19F-4623-9E3D-9F59A14C0660}
{C27E6F75-8E64-4F3D-8EA0-E632BFAFF600} = {EAAC5CEA-33B8-495D-9CD0-B36794B8AFE7}
{A2584ED3-5C92-4BC7-9120-D97F5404B52C} = {2DF34BB8-B19F-4623-9E3D-9F59A14C0660}
{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8} = {EAAC5CEA-33B8-495D-9CD0-B36794B8AFE7}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -183,6 +183,4 @@ foreach ($languageName in ($appSettings.Languages | Get-Member -MemberType NoteP
# Write the updated appsettings.json file
$appSettings | ConvertTo-Json -Depth 100 | Set-Content -Path $mainSettings
$additionalSettingsPath = Join-Path -Path $scriptPath -ChildPath "..\src\Kiota.Web\wwwroot\appsettings.json"
$appSettings | ConvertTo-Json -Depth 100 | Set-Content -Path $additionalSettingsPath

Просмотреть файл

@ -1,14 +0,0 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<ApplicationInsightsComponent />

Просмотреть файл

@ -1,87 +0,0 @@
using System.Net.Http.Headers;
using System.Net.Http.Json;
using Kiota.Builder.SearchProviders.GitHub.Authentication;
using Microsoft.Kiota.Abstractions.Authentication;
namespace Kiota.Web.Authentication.GitHub;
public class BrowserAccessTokenProvider : IAccessTokenProvider
{
public AllowedHostsValidator AllowedHostsValidator { get; set; } = new();
public required string ClientId
{
get; init;
}
public required string Scope
{
get; init;
}
public required Uri RedirectUri
{
get; init;
}
public required HttpClient HttpClient
{
get; init;
}
public required Func<Uri, string, CancellationToken, Task> RedirectCallback
{
get; init;
}
public required Func<CancellationToken, Task<string>> GetAccessCodeCallback
{
get; init;
}
internal string BaseLoginUrl { get; init; } = "https://github.com/login";
public Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object>? additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
{
if (!AllowedHostsValidator.IsUrlHostValid(uri))
return Task.FromResult(string.Empty);
if (!uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("Only https is supported");
return GetAuthorizationTokenInternalAsync(cancellationToken);
}
private async Task<string> GetAuthorizationTokenInternalAsync(CancellationToken cancellationToken)
{
var authorizationCode = await GetAccessCodeCallback(cancellationToken);
if (string.IsNullOrEmpty(authorizationCode))
{
var state = Guid.NewGuid();
await RedirectCallback(GetAuthorizeUrl(state), state.ToString(), cancellationToken);
return string.Empty;
}
else
{
var tokenResponse = await GetTokenAsync(authorizationCode, cancellationToken);
return tokenResponse?.AccessToken ?? string.Empty;
}
}
private Uri GetAuthorizeUrl(Guid state)
{
var authorizeUrl = $"{BaseLoginUrl}/oauth/authorize?client_id={ClientId}&scope={Scope}&redirect_uri={RedirectUri}&state={state}";
return new Uri(authorizeUrl);
}
private async Task<AccessCodeResponse?> GetTokenAsync(string authorizationCode, CancellationToken cancellationToken)
{
using var tokenRequest = new HttpRequestMessage(HttpMethod.Post, $"{BaseLoginUrl}/oauth/access_token")
{
Content = new FormUrlEncodedContent(new Dictionary<string, string> {
{ "client_id", ClientId },
{ "code", authorizationCode },
// acquisition doesn't work because the endpoint doesn't support CORS or PKCE, and requires a secret
// we're leaving the code in place as we hope that GitHub will eventually support this and it'll be a matter of updating the parameters and calling AddBrowserCodeAuthentication
})
};
tokenRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using var tokenResponse = await HttpClient.SendAsync(tokenRequest, cancellationToken);
tokenResponse.EnsureSuccessStatusCode();
var result = await tokenResponse.Content.ReadFromJsonAsync<AccessCodeResponse>(cancellationToken: cancellationToken);
if ("authorization_pending".Equals(result?.Error, StringComparison.OrdinalIgnoreCase))
return null;
else if (!string.IsNullOrEmpty(result?.Error))
throw new InvalidOperationException($"Error while getting token: {result.Error} - {result.ErrorDescription}");
else
return result;
}
}

Просмотреть файл

@ -1,24 +0,0 @@
using Kiota.Builder.SearchProviders.GitHub.Authentication;
using Microsoft.Kiota.Abstractions.Authentication;
namespace Kiota.Web.Authentication.GitHub;
public class BrowserAuthenticationProvider : BaseAuthenticationProvider<BrowserAccessTokenProvider>
{
public BrowserAuthenticationProvider(string clientId, string scope, IEnumerable<string> validHosts, HttpClient httpClient, Func<Uri, string, CancellationToken, Task> redirectCallback, Func<CancellationToken, Task<string>> getAccessCodeCallback, ILogger logger, Uri redirectUri) :
base(clientId, scope, validHosts, logger, (clientId, scope, validHosts) => new BrowserAccessTokenProvider
{
ClientId = clientId,
HttpClient = httpClient,
RedirectCallback = redirectCallback,
GetAccessCodeCallback = getAccessCodeCallback,
Scope = scope,
AllowedHostsValidator = new AllowedHostsValidator(validHosts),
RedirectUri = redirectUri,
})
{
ArgumentNullException.ThrowIfNull(httpClient);
ArgumentNullException.ThrowIfNull(redirectCallback);
ArgumentNullException.ThrowIfNull(redirectUri);
}
}

Просмотреть файл

@ -1,31 +0,0 @@

using Blazored.LocalStorage;
using Kiota.Builder.SearchProviders.GitHub.Authentication;
namespace Kiota.Web.Authentication.GitHub;
public class LocalStorageTokenStorageService : ITokenStorageService
{
private const string PATKey = "github-pat";
public required ILocalStorageService LocalStorageService
{
get; init;
}
public async Task<string?> GetTokenAsync(CancellationToken cancellationToken)
{
return await LocalStorageService.GetItemAsync<string>(PATKey, cancellationToken).ConfigureAwait(false);
}
public async Task SetTokenAsync(string value, CancellationToken cancellationToken)
{
await LocalStorageService.SetItemAsync(PATKey, value, cancellationToken).ConfigureAwait(false);
}
public async Task<bool> IsTokenPresentAsync(CancellationToken cancellationToken)
{
return !string.IsNullOrEmpty(await GetTokenAsync(cancellationToken).ConfigureAwait(false));
}
public async Task<bool> DeleteTokenAsync(CancellationToken cancellationToken)
{
await LocalStorageService.RemoveItemAsync(PATKey, cancellationToken).ConfigureAwait(false);
return true;
}
}

Просмотреть файл

@ -1,24 +0,0 @@
using Microsoft.AspNetCore.Components;
namespace Kiota.Web;
public abstract class ComponentWithCancellationToken : ComponentBase, IDisposable
{
private readonly CancellationTokenSource _cancellationTokenSource = new();
protected CancellationToken ComponentDetached => _cancellationTokenSource.Token;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing)
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
}
}
}

Просмотреть файл

@ -1,97 +0,0 @@
using Blazored.LocalStorage;
using Kiota.Builder;
using Kiota.Builder.Configuration;
using Kiota.Builder.SearchProviders.GitHub.Authentication;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Kiota.Abstractions.Authentication;
namespace Kiota.Web.Authentication.GitHub;
public static class IServiceCollectionExtensions
{
private const string GitHubStateKey = "github-authentication-state";
public static void AddBrowserCodeAuthentication(this IServiceCollection services, string baseAddress)
{
services.AddBlazoredLocalStorage();
services.AddScoped(sp =>
{
var configObject = sp.GetRequiredService<KiotaConfiguration>();
return new TempFolderCachingAccessTokenProvider
{
Logger = sp.GetRequiredService<ILoggerFactory>().CreateLogger<TempFolderCachingAccessTokenProvider>()!,
ApiBaseUrl = configObject.Search.GitHub.ApiBaseUrl,
Concrete = null,
AppId = configObject.Search.GitHub.AppId,
};
});
services.AddScoped<IAuthenticationProvider>(sp =>
{
var configObject = sp.GetRequiredService<KiotaConfiguration>();
var navManager = sp.GetRequiredService<NavigationManager>();
return new BrowserAuthenticationProvider(
configObject.Search.GitHub.AppId,
"repo",
new string[] { configObject.Search.GitHub.ApiBaseUrl.Host },
sp.GetRequiredService<HttpClient>(),
async (uri, state, c) =>
{
var localStorage = sp.GetRequiredService<ILocalStorageService>();
await localStorage.SetItemAsync(GitHubStateKey, state, c).ConfigureAwait(false);
navManager.NavigateTo(uri.ToString());
},
async (c) =>
{
var localStorage = sp.GetRequiredService<ILocalStorageService>();
var stateValue = await localStorage.GetItemAsync<string>(GitHubStateKey, c).ConfigureAwait(false);
var uri = navManager.ToAbsoluteUri(navManager.Uri);
var queryStrings = QueryHelpers.ParseQuery(uri.Query);
if (queryStrings.TryGetValue("state", out var state) &&
stateValue.Equals(state, StringComparison.OrdinalIgnoreCase) &&
queryStrings.TryGetValue("code", out var code) && code.FirstOrDefault() is string codeValue)
return codeValue;
await localStorage.RemoveItemAsync(GitHubStateKey, c).ConfigureAwait(false);
return string.Empty;
},
sp.GetRequiredService<ILoggerFactory>().CreateLogger<BrowserAuthenticationProvider>(),
new Uri($"{baseAddress}GitHubAuth")
);
});
}
public static void AddPatAuthentication(this IServiceCollection services)
{
services.AddBlazoredLocalStorage();
services.AddScoped<ITokenStorageService>(sp =>
{
var localStorage = sp.GetRequiredService<ILocalStorageService>();
return new LocalStorageTokenStorageService
{
LocalStorageService = localStorage,
};
});
services.AddScoped<IAuthenticationProvider>(sp =>
{
var configObject = sp.GetRequiredService<KiotaConfiguration>();
return new PatAuthenticationProvider(
configObject.Search.GitHub.AppId,
"repo",
new string[] { configObject.Search.GitHub.ApiBaseUrl.Host },
sp.GetRequiredService<ILoggerFactory>().CreateLogger<PatAuthenticationProvider>(),
sp.GetRequiredService<ITokenStorageService>()
);
});
}
public static void AddSearchService(this IServiceCollection services)
{
services.AddScoped(sp =>
{
var configObject = sp.GetRequiredService<KiotaConfiguration>();
var patService = sp.GetRequiredService<ITokenStorageService>();
return new KiotaSearcher(sp.GetRequiredService<ILoggerFactory>().CreateLogger<KiotaSearcher>(),
configObject.Search,
sp.GetRequiredService<HttpClient>(),
sp.GetRequiredService<IAuthenticationProvider>(),
(c) => patService.IsTokenPresentAsync(c));
});
}
}

Просмотреть файл

@ -1,71 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<ImplicitUsings>enable</ImplicitUsings>
<SonarQubeExclude>true</SonarQubeExclude>
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
<RunAOTCompilation>true</RunAOTCompilation> <!-- https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-6.0#ahead-of-time-aot-compilation https://github.com/microsoft/fast-blazor/issues/214-->
<PublishTrimmed>true</PublishTrimmed> <!-- https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained -->
<!-- <WasmEnableThreads>true</WasmEnableThreads> https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-rc-2/ -->
<!-- <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> -->
<PublishFluentEmojiAssets>false</PublishFluentEmojiAssets>
<PublishFluentIconAssets>true</PublishFluentIconAssets>
<FluentIconSizes>16,20,24,48</FluentIconSizes>
<FluentIconVariants>Regular</FluentIconVariants>
</PropertyGroup>
<ItemGroup>
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BlazorApplicationInsights" Version="2.2.0" />
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="markdig" Version="0.31.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.9" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.9" />
<PackageReference Include="Microsoft.Fast.Components.FluentUI" Version="2.4.1" />
<!-- <PackageReference Include="Microsoft.NET.WebAssembly.Threading" Version="7.0.0-rc.2.22472.3" /> -->
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Kiota.Builder\Kiota.Builder.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Pages\Index.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Index.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Pages\Generate.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Generate.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Pages\Show.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Show.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Pages\Update.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Update.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Shared\NavMenu.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>NavMenu.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Shared\GitHubSignIn.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>GitHubSignIn.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
</Project>

Просмотреть файл

@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - générer un client OpenAPI</value>
</data>
<data name="Generate" xml:space="preserve">
<value>Générer un client</value>
</data>
<data name="DescriptionUrl" xml:space="preserve">
<value>URL de la description OpenAPI</value>
</data>
<data name="NamespacePrefix" xml:space="preserve">
<value>Préfixe de l'espace de noms</value>
</data>
<data name="ClientClassName" xml:space="preserve">
<value>Nom de la class principale</value>
</data>
<data name="IncludePatterns" xml:space="preserve">
<value>Filtres des segments à include</value>
</data>
<data name="ExcludePatterns" xml:space="preserve">
<value>Filtres des segments à exclure</value>
</data>
<data name="Language" xml:space="preserve">
<value>Langage</value>
</data>
<data name="AdditionalData" xml:space="preserve">
<value>Inclure une propriété additionelle dans les modèles pour les valeurs n'appartenant pas à une propriété connue.</value>
</data>
<data name="BackingStore" xml:space="preserve">
<value>Inclure une propriété pour le stockage déporté des valeurs.</value>
</data>
<data name="Download" xml:space="preserve">
<value>Télécharger le client généré</value>
</data>
<data name="Dependencies" xml:space="preserve">
<value>Dépendances</value>
</data>
<data name="GenerateAction" xml:space="preserve">
<value>Générer</value>
</data>
<data name="Logs" xml:space="preserve">
<value>Logs de génération</value>
</data>
</root>

Просмотреть файл

@ -1,296 +0,0 @@
@page "/generate"
@using Kiota.Builder
@using Kiota.Builder.Configuration
@using Kiota.Builder.Logging
@using System.Linq
@using System.IO
@using System.IO.Compression
@using System.Security.Cryptography
@using System.Text
@using System.Text.Json
@using System.Text.Json.Serialization;
@using System.Threading
@using Microsoft.Fast.Components.FluentUI
@using Microsoft.Kiota.Abstractions.Authentication;
@inject HttpClient Http
@inject ILoggerFactory LoggerFactory
@inject IJSRuntime JSRuntime
@using System.Globalization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<Generate> Loc
<PageTitle>@Loc["PageTitle"]</PageTitle>
<h1>@Loc["Generate"]</h1>
<div>
<FluentTextField Required="true" class="full-width-field" @bind-Value=@DescriptionUrl>@Loc["DescriptionUrl"]</FluentTextField>
<FluentTextField Required="true" class="full-width-field" @bind-Value=@NamespaceName>@Loc["NamespacePrefix"]</FluentTextField>
<FluentTextField Required="true" class="full-width-field" @bind-Value=@ClientClassName>@Loc["ClientClassName"]</FluentTextField>
<FluentTextArea class="full-width-field" @bind-Value=@IncludePatterns Placeholder="**/messages/**" Rows="10" Resize="TextAreaResize.Vertical">
<span>@Loc["IncludePatterns"]</span>
</FluentTextArea>
<FluentTextArea class="full-width-field" @bind-Value=@ExcludePatterns Placeholder="**/users/**" Rows="10" Resize="TextAreaResize.Vertical">
<span>@Loc["ExcludePatterns"]</span>
</FluentTextArea>
<label for="language">@Loc["Language"]</label><br />
<FluentSelect
TOption="GenerationLanguage?"
Id="language"
@bind-SelectedOption="@Language"
Required=@true
Items="Enum.GetValues<GenerationLanguage>().Select(static x => new Nullable<GenerationLanguage>(x)).OrderBy(static x => x.ToString(), StringComparer.OrdinalIgnoreCase)"
OptionText="@(x => (configuration?.Languages?.TryGetValue(x!.ToString()!, out var languageInfo) ?? false) ? $"{x} - {languageInfo.MaturityLevel}" : x.ToString())" />
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<FluentCheckbox @bind-Value=@AdditionalData>@Loc["AdditionalData"]</FluentCheckbox>
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<FluentCheckbox @bind-Value=@BackingStore>@Loc["BackingStore"]</FluentCheckbox>
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<FluentButton @onclick="GenerateClient" Appearance="Appearance.Accent" Disabled="@(string.IsNullOrEmpty(DescriptionUrl) || IsLoading)">@Loc["GenerateAction"]</FluentButton>
<FluentButton @onclick="DownloadClient" Appearance="Appearance.Neutral" Disabled="@string.IsNullOrEmpty(DownloadUrl)">@Loc["Download"]</FluentButton>
@if(IsLoading) {
<FluentProgress></FluentProgress>
}
</div>
@if(!string.IsNullOrEmpty(Dependencies)) {
<div class="log-container">
<h2>@Loc["Dependencies"]</h2>
<pre class="log-box">@Dependencies</pre>
</div>
}
@if(!string.IsNullOrEmpty(Logs)) {
<div class="log-container">
<h2>@Loc["Logs"]</h2>
<pre class="log-box">@Logs</pre>
</div>
}
@code {
[Parameter]
[SupplyParameterFromQuery(Name = "k")]
public string? SearchTermFromQuery { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "v")]
public string? VersionFromQuery { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "c")]
public string? ClientClassNameFromQuery { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "n")]
public string? NamespaceNameFromQuery { get; set; }
private string? ClientClassName { get; set; }
private string? NamespaceName { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "b")]
public string? BackingStoreFromQuery { get; set; }
private bool BackingStore { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "ad")]
public string? AdditionalDataFromQuery { get; set; }
private bool AdditionalData { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "d")]
public string? DescriptionUrlFromQuery { get; set; }
private string? DescriptionUrl { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "i")]
public string? IncludePatternsFromQuery { get; set; }
private string? IncludePatterns { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "e")]
public string? ExcludePatternsFromQuery { get; set; }
private string? ExcludePatterns { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "l")]
public string? LanguageFromQuery { get; set; }
private GenerationLanguage? Language { get; set; }
private string? OutputPath { get; set; }
private string? DownloadUrl { get; set; }
private bool IsLoading { get; set; }
private string? Dependencies { get; set; }
private string? Logs { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name="s")]
public string? SerializersFromQuery { get; set; }
private HashSet<string> Serializers { get; set; } = new(StringComparer.OrdinalIgnoreCase);
[Parameter]
[SupplyParameterFromQuery(Name="ds")]
public string? DeserializersFromQuery { get; set; }
private HashSet<string> Deserializers { get; set; } = new(StringComparer.OrdinalIgnoreCase);
[Parameter]
[SupplyParameterFromQuery(Name="m")]
public string? StructuredMimeTypesFromQuery { get; set; }
private HashSet<string> StructuredMimeTypes { get; set; } = new(StringComparer.OrdinalIgnoreCase);
protected override async Task OnParametersSetAsync() {
if(!string.IsNullOrEmpty(DescriptionUrlFromQuery))
DescriptionUrl = DescriptionUrlFromQuery;
if(!string.IsNullOrEmpty(IncludePatternsFromQuery))
IncludePatterns = string.Join(Environment.NewLine, IncludePatternsFromQuery.Split(',', StringSplitOptions.RemoveEmptyEntries));
if(!string.IsNullOrEmpty(ExcludePatternsFromQuery))
ExcludePatterns = string.Join(Environment.NewLine, ExcludePatternsFromQuery.Split(',', StringSplitOptions.RemoveEmptyEntries));
var defaultConfiguration = new GenerationConfiguration();
if(!string.IsNullOrEmpty(AdditionalDataFromQuery) && bool.TryParse(AdditionalDataFromQuery, out var additionalData))
AdditionalData = additionalData;
else
AdditionalData = defaultConfiguration.IncludeAdditionalData;
if(!string.IsNullOrEmpty(BackingStoreFromQuery) && bool.TryParse(BackingStoreFromQuery, out var backingStore))
BackingStore = backingStore;
else
BackingStore = defaultConfiguration.UsesBackingStore;
if(!string.IsNullOrEmpty(ClientClassNameFromQuery))
ClientClassName = ClientClassNameFromQuery;
else
ClientClassName = defaultConfiguration.ClientClassName;
if(!string.IsNullOrEmpty(NamespaceNameFromQuery))
NamespaceName = NamespaceNameFromQuery;
else
NamespaceName = defaultConfiguration.ClientNamespaceName;
if(!string.IsNullOrEmpty(LanguageFromQuery) && Enum.TryParse<GenerationLanguage>(LanguageFromQuery, true, out var language))
Language = language;
else
Language = defaultConfiguration.Language;
if(!string.IsNullOrEmpty(SerializersFromQuery))
Serializers = new HashSet<string>(SerializersFromQuery.Split(',', StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
else
Serializers = defaultConfiguration.Serializers;
if(!string.IsNullOrEmpty(DeserializersFromQuery))
Deserializers = new HashSet<string>(DeserializersFromQuery.Split(',', StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
else
Deserializers = defaultConfiguration.Deserializers;
if(!string.IsNullOrEmpty(StructuredMimeTypesFromQuery))
StructuredMimeTypes = new HashSet<string>(StructuredMimeTypesFromQuery.Split(',', StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);
else
StructuredMimeTypes = defaultConfiguration.StructuredMimeTypes;
await GetConfiguration(ComponentDetached);
var SearchTerm = string.IsNullOrEmpty(SearchTermFromQuery) ? string.Empty : SearchTermFromQuery;
var Version = string.IsNullOrEmpty(VersionFromQuery) ? string.Empty : VersionFromQuery;
if (!string.IsNullOrEmpty(SearchTerm) && !string.IsNullOrEmpty(Version) && string.IsNullOrEmpty(DescriptionUrl) && KiotaSearcher != null) {
var searchResults = await KiotaSearcher.SearchAsync(SearchTerm, Version, ComponentDetached);
if(searchResults.Any())
DescriptionUrl = searchResults.Values.First().DescriptionUrl?.ToString();
}
await base.OnParametersSetAsync();
}
[Inject] private KiotaSearcher? KiotaSearcher { get; set; }
private static readonly ThreadLocal<HashAlgorithm> HashAlgorithm = new(() => SHA256.Create());
[Inject] private IApplicationInsights? AppInsights { get; set; }
private Task GenerateClient() {
if (string.IsNullOrEmpty(DescriptionUrl)) {
return Task.CompletedTask;
} else {
DownloadUrl = string.Empty;
Dependencies = string.Empty;
Logs = string.Empty;
IsLoading = true;
return GenerateClientInternal();
}
}
private const string generateClientTelemetryKey = "generateclient";
private async Task GenerateClientInternal() {
if(AppInsights != null)
await AppInsights.StartTrackEvent(generateClientTelemetryKey).ConfigureAwait(false);
if(Language == null)
Language = GenerationLanguage.CSharp;
if (DescriptionUrl is null || HashAlgorithm.Value is null)
return;
var hashedUrl = BitConverter.ToString(HashAlgorithm.Value.ComputeHash(Encoding.UTF8.GetBytes(DescriptionUrl))).Replace("-", string.Empty);
OutputPath = Path.Combine(Path.GetTempPath(), "kiota", "generation", hashedUrl);
var defaultConfiguration = new GenerationConfiguration();
var generationConfiguration = new GenerationConfiguration{
OpenAPIFilePath = DescriptionUrl,
IncludePatterns = IncludePatterns?.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).Select(static x => x.Trim()).ToHashSet() ?? new(),
ExcludePatterns = ExcludePatterns?.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).Select(static x => x.Trim()).ToHashSet() ?? new(),
Language = Language.Value,
OutputPath = OutputPath,
ClientClassName = ClientClassName ?? defaultConfiguration.ClientClassName,
ClientNamespaceName = NamespaceName ?? defaultConfiguration.ClientNamespaceName,
IncludeAdditionalData = AdditionalData,
UsesBackingStore = BackingStore,
Serializers = Serializers,
Deserializers = Deserializers,
StructuredMimeTypes = StructuredMimeTypes,
};
var logBuilder = new StringBuilder();
var consoleLogger = LoggerFactory.CreateLogger<KiotaBuilder>();
using var fileLogger = new FileLogLogger<KiotaBuilder>(generationConfiguration.OutputPath, LogLevel.Warning);
var stringLogger = new StringBuilderLogger<KiotaBuilder>(logBuilder, LogLevel.Warning);
var aggregrateLogger = new AggregateLogger<KiotaBuilder>(consoleLogger, fileLogger, stringLogger);
var builder = new KiotaBuilder(aggregrateLogger, generationConfiguration, Http);
try {
await builder.GenerateClientAsync(ComponentDetached).ConfigureAwait(false);
var zipFilePath = Path.Combine(Path.GetTempPath(), "kiota", "clients", hashedUrl, "client.zip");
if (File.Exists(zipFilePath))
File.Delete(zipFilePath);
else
Directory.CreateDirectory(Path.GetDirectoryName(zipFilePath)!);
ZipFile.CreateFromDirectory(OutputPath, zipFilePath);
DownloadUrl = zipFilePath;
var informationSource = await builder.GetLanguagesInformationAsync(ComponentDetached).ConfigureAwait(false) ?? (await GetConfiguration(ComponentDetached).ConfigureAwait(false))?.Languages;
if (informationSource?.TryGetValue(generationConfiguration.Language.ToString(), out var languageInformation) ?? false) {
foreach(var dependency in languageInformation.Dependencies)
Dependencies += $"{string.Format(languageInformation.DependencyInstallCommand, dependency.Name, dependency.Version)}{Environment.NewLine}";
}
Logs = logBuilder.ToString();
} catch (Exception ex) {
if(string.IsNullOrEmpty(Logs)) Logs = logBuilder.ToString();
Logs += "ERROR : " + ex.Message;
} finally {
if(AppInsights != null)
await AppInsights.StopTrackEvent(generateClientTelemetryKey, new Dictionary<string, string?> {
{ "language", Language?.ToString() },
{ "includePatterns", IncludePatterns },
{ "excludePatterns", ExcludePatterns },
{ "additionalData", AdditionalData.ToString() },
{ "backingStore", BackingStore.ToString() }
}).ConfigureAwait(false);
IsLoading = false;
}
}
private const string downloadTelemetryKey = "download";
private async Task DownloadClient() {
if (!string.IsNullOrEmpty(DownloadUrl)) {
if(AppInsights != null)
await AppInsights.StartTrackEvent(downloadTelemetryKey).ConfigureAwait(false);
using var fileStream = File.OpenRead(DownloadUrl);
using var ms = new MemoryStream();
await fileStream.CopyToAsync(ms).ConfigureAwait(false);
await JSRuntime.InvokeVoidAsync("BlazorDownloadFile", "client.zip", "application/zip", ms.ToArray());
if(AppInsights != null)
await AppInsights.StopTrackEvent(downloadTelemetryKey, new Dictionary<string, string?> {
{ "language", Language?.ToString() },
{ "includePatterns", IncludePatterns },
{ "excludePatterns", ExcludePatterns },
{ "additionalData", AdditionalData.ToString() },
{ "backingStore", BackingStore.ToString() }
}).ConfigureAwait(false);
}
}
private static KiotaConfiguration? configuration;
private async Task<KiotaConfiguration?> GetConfiguration(CancellationToken cancellationToken) {
if(configuration == null)
configuration = await Http.GetFromJsonAsync<KiotaConfiguration>(
"appsettings.json",
new JsonSerializerOptions{
Converters ={
new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
},
},
cancellationToken);
return configuration;
}
}

Просмотреть файл

@ -1,7 +0,0 @@
.log-box {
white-space: pre-wrap;
overflow: auto;
}
.log-container {
max-width: fit-content;
}

Просмотреть файл

@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - generate an OpenAPI client</value>
</data>
<data name="Generate" xml:space="preserve">
<value>Generate a client</value>
</data>
<data name="DescriptionUrl" xml:space="preserve">
<value>OpenAPI Description Url</value>
</data>
<data name="NamespacePrefix" xml:space="preserve">
<value>Namespace prefix</value>
</data>
<data name="ClientClassName" xml:space="preserve">
<value>Client class name</value>
</data>
<data name="IncludePatterns" xml:space="preserve">
<value>Include Patterns</value>
</data>
<data name="ExcludePatterns" xml:space="preserve">
<value>Exclude Patterns</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="AdditionalData" xml:space="preserve">
<value>Generate additional data holder for models</value>
</data>
<data name="BackingStore" xml:space="preserve">
<value>Generate models with a backing store</value>
</data>
<data name="Download" xml:space="preserve">
<value>Download the generated client</value>
</data>
<data name="Dependencies" xml:space="preserve">
<value>Dependencies</value>
</data>
<data name="GenerateAction" xml:space="preserve">
<value>Generate</value>
</data>
<data name="Logs" xml:space="preserve">
<value>Generation logs</value>
</data>
</root>

Просмотреть файл

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - recherche d'une description OpenAPI</value>
</data>
<data name="Search" xml:space="preserve">
<value>Recherche d'une description OpenAPI</value>
</data>
<data name="SearchTermOrKey" xml:space="preserve">
<value>Termes de recherche</value>
</data>
<data name="SearchAction" xml:space="preserve">
<value>Rechercher</value>
</data>
<data name="MR_Key" xml:space="preserve">
<value>Clef</value>
</data>
<data name="MR_Description" xml:space="preserve">
<value>Description</value>
</data>
<data name="MR_Actions" xml:space="preserve">
<value>Actions</value>
</data>
<data name="GoToGenerate" xml:space="preserve">
<value>Générer un client</value>
</data>
<data name="GoToShow" xml:space="preserve">
<value>Afficher</value>
</data>
<data name="NoResults" xml:space="preserve">
<value>Aucun résulat.</value>
</data>
<data name="SelectVersion" xml:space="preserve">
<value>Sélectionez une version</value>
</data>
<data name="NoSearch" xml:space="preserve">
<value>Souhaitez-vous ajouter votre API aux résultats?</value>
</data>
</root>

Просмотреть файл

@ -1,154 +0,0 @@
@page "/"
@using Kiota.Builder
@using Kiota.Builder.SearchProviders
@using Kiota.Builder.Configuration
@using System.Web
@using System.Text.RegularExpressions
@using System.Linq
@inject ILoggerFactory LoggerFactory
@using System.Globalization
@using Microsoft.Extensions.Localization
@using Microsoft.Fast.Components.FluentUI
@using Markdig
@using Microsoft.Kiota.Abstractions.Authentication;
@inject IStringLocalizer<Index> Loc
@inject NavigationManager navManager
@inject HttpClient Http
<PageTitle>@Loc["PageTitle"]</PageTitle>
<h1>@Loc["Search"]</h1>
<div>
<FluentTextField Required="true" class="full-width-field" @bind-Value=@SearchTerm @onkeydown=@EnterSubmit>@Loc["SearchTermOrKey"]</FluentTextField>
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<FluentButton Appearance="Appearance.Accent" @onclick=@SearchDocuments Disabled=@IsLoading>@Loc["SearchAction"]</FluentButton>
@if(IsLoading) {
<FluentProgress></FluentProgress>
}
</div>
@if (SearchResults.Any()) {
<div id="results">
<FluentDataGrid TGridItem="KeyValuePair<string, SearchResult>" id="manualGrid" GenerateHeader=GenerateHeaderOption.Default GridTemplateColumns="1fr 4fr 1fr"
RowsData="@SearchResults.AsQueryable()" Pagination="@pagination">
<PropertyColumn Property="@(c => c.Key)" Sortable="true" Align="Align.Left" Title="@Loc["MR_Key"]" IsDefaultSort="SortDirection.Ascending" />
<PropertyColumn Property="@(c => SanitizeDescription(c.Value.Description))" Sortable="false" Align="Align.Left" Title="@Loc["MR_Description"]" />
<TemplateColumn Title="@Loc["MR_Actions"]" Align="Align.Left" Sortable="false">
<FluentButton Appearance="Appearance.Accent" @onclick="@(e => GoToGenerate(context.Key))">@Loc["GoToGenerate"]</FluentButton>
<FluentButton Appearance="Appearance.Neutral" @onclick="@(e => GoToShow(context.Key))">@Loc["GoToShow"]</FluentButton>
</TemplateColumn>
</FluentDataGrid>
<FluentPaginator Value="@pagination" State="@pagination" />
@if(ShowVersionSelector) {
<FluentDialog @ondialogdismiss=OnDialogDismiss>
<div class="dialog-content">
<h2>@Loc["SelectVersion"]</h2>
<FluentSelect Id="selectedversion" @bind-Value=@SelectedVersion Required=@true Items="@AvailableVersions" />
<FluentDivider Role=DividerRole.Presentation></FluentDivider>
<FluentButton Appearance="Appearance.Accent" @onclick=@GoToGenerateWithVersion>@Loc["GoToGenerate"]</FluentButton>
<FluentButton Appearance="Appearance.Neutral" @onclick=@GoToShowWithVersion>@Loc["GoToShow"]</FluentButton>
</div>
</FluentDialog>
}
</div>
} else if (Searched && !IsLoading) {
<div id="no-results" class="additional-information">
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<span>@Loc["NoResults"]</span>
</div>
} else {
<div id="no-search" class="additional-information">
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<span><a href="https://aka.ms/kiota/addapi" target="_blank">@Loc["NoSearch"]</a></span>
</div>
}
@code {
PaginationState pagination = new PaginationState { ItemsPerPage = 10 };
[Inject] private IApplicationInsights? AppInsights { get; set; }
[Inject] private KiotaSearcher? KiotaSearcher { get; set; }
private bool ShowVersionSelector { get; set; }
private bool IsLoading { get; set; }
private bool Searched { get; set; }
private string? SearchTerm { get; set; }
private IDictionary<string, SearchResult> SearchResults = new Dictionary<string, SearchResult>();
GridSort<KeyValuePair<string, SearchResult>> rankSort = GridSort<KeyValuePair<string, SearchResult>>.ByAscending(static x => x.Key);
private Task EnterSubmit(KeyboardEventArgs e) {
if(e.Key == "Enter") {
return EnterSubmitInternal(e);
}
return Task.CompletedTask;
}
private async Task EnterSubmitInternal(KeyboardEventArgs e) {
await Task.Delay(10, ComponentDetached).ConfigureAwait(false); // so the value is updated
await SearchDocuments();
}
private Task SearchDocuments() {
IsLoading = true;
Searched = true;
return SearchDocumentsInternal();
}
private const string searchTelemetryKey = "search";
private async Task SearchDocumentsInternal() {
if(AppInsights != null)
await AppInsights.StartTrackEvent(searchTelemetryKey).ConfigureAwait(false);
if(KiotaSearcher != null && !string.IsNullOrEmpty(SearchTerm))
SearchResults = await KiotaSearcher.SearchAsync(SearchTerm, string.Empty, ComponentDetached);
IsLoading = false;
if(AppInsights != null)
await AppInsights.StopTrackEvent(searchTelemetryKey, new Dictionary<string, string?> {
{ "searchterm", SearchTerm },
{ "results", SearchResults.Count.ToString() },
}).ConfigureAwait(false);
}
private void GoToShow(string key) {
if(SearchResults.TryGetValue(key, out var result) && result.VersionLabels.Count <= 1)
{
navManager.NavigateTo($"/show?d={result.DescriptionUrl}");
} else {
OpenVersionSelectionDialog(key);
}
}
private void GoToGenerateWithVersion() {
navManager.NavigateTo($"/generate?k={SelectedKey}&v={SelectedVersion}");
}
private void OnDialogDismiss() {
ShowVersionSelector = false;
SelectedKey = string.Empty;
SelectedVersion = string.Empty;
AvailableVersions.Clear();
}
private void GoToShowWithVersion() {
navManager.NavigateTo($"/show?k={SelectedKey}&v={SelectedVersion}");
}
private void GoToGenerate(string key) {
if(SearchResults.TryGetValue(key, out var result) && result.VersionLabels.Count <= 1)
{
navManager.NavigateTo($"/generate?d={result.DescriptionUrl}");
} else {
OpenVersionSelectionDialog(key);
}
}
private string SelectedKey { get; set; } = string.Empty;
private string SelectedVersion { get; set; } = string.Empty;
private List<string> AvailableVersions { get; set; } = new List<string>();
private void OpenVersionSelectionDialog(string key) {
if(SearchResults.TryGetValue(key, out var result) && result.VersionLabels.Count >= 1) {
ShowVersionSelector = true;
SelectedKey = key;
SelectedVersion = result.VersionLabels.First();
AvailableVersions = new(result.VersionLabels);
} else {
OnDialogDismiss();
}
}
private static readonly Regex _htmlTagRegex = new Regex("<.*?>", RegexOptions.Compiled);
private string SanitizeDescription(string original) {
if (string.IsNullOrEmpty(original))
return string.Empty;
return HttpUtility.HtmlDecode(_htmlTagRegex.Replace(Markdown.ToHtml(original), string.Empty));
}
}

Просмотреть файл

@ -1,8 +0,0 @@
.dialog-content {
margin-left: 10px;
margin-right: 10px;
}
.additional-information {
margin-top: 10px;
margin-bottom: 10px;
}

Просмотреть файл

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - search for an OpenAPI description</value>
</data>
<data name="Search" xml:space="preserve">
<value>Search for an OpenAPI description</value>
</data>
<data name="SearchTermOrKey" xml:space="preserve">
<value>Search terms</value>
</data>
<data name="SearchAction" xml:space="preserve">
<value>Search</value>
</data>
<data name="MR_Key" xml:space="preserve">
<value>Key</value>
</data>
<data name="MR_Description" xml:space="preserve">
<value>Description</value>
</data>
<data name="MR_Actions" xml:space="preserve">
<value>Actions</value>
</data>
<data name="GoToGenerate" xml:space="preserve">
<value>Generate client</value>
</data>
<data name="GoToShow" xml:space="preserve">
<value>Show</value>
</data>
<data name="NoResults" xml:space="preserve">
<value>No results found.</value>
</data>
<data name="SelectVersion" xml:space="preserve">
<value>Select a version</value>
</data>
<data name="NoSearch" xml:space="preserve">
<value>Want to add your API to the results?</value>
</data>
</root>

Просмотреть файл

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - afficher une description OpenAPI et configurer les filtres</value>
</data>
<data name="Show" xml:space="preserve">
<value>Afficher</value>
</data>
<data name="DescriptionUrl" xml:space="preserve">
<value>URL de la description OpenAPI</value>
</data>
<data name="IncludePatterns" xml:space="preserve">
<value>Filtres des segments à include</value>
</data>
<data name="ExcludePatterns" xml:space="preserve">
<value>Filtres des segments à exclure</value>
</data>
<data name="ShowButton" xml:space="preserve">
<value>Afficher</value>
</data>
<data name="GoToGenerate" xml:space="preserve">
<value>Générer</value>
</data>
<data name="ApiPaths" xml:space="preserve">
<value>Segments de l'API</value>
</data>
</root>

Просмотреть файл

@ -1,157 +0,0 @@
@page "/show"
@using Kiota.Builder
@using Kiota.Builder.SearchProviders
@using Kiota.Builder.Configuration
@using System.Linq
@using System.Text
@using System.Web
@using Microsoft.Fast.Components.FluentUI
@inject ILoggerFactory LoggerFactory
@inject NavigationManager navManager
@using System.Globalization
@using Microsoft.Extensions.Localization
@using Microsoft.Kiota.Abstractions.Authentication;
@inject IStringLocalizer<Show> Loc
@inject HttpClient Http
<PageTitle>@Loc["PageTitle"]</PageTitle>
<h1>@Loc["Show"]</h1>
<div>
<FluentTextField Required="true" class="full-width-field" @bind-Value=@DescriptionUrl>@Loc["DescriptionUrl"]</FluentTextField>
<FluentTextArea @bind-Value=@IncludePatterns class="full-width-field" Placeholder="**/messages/**" Rows="10" Resize="TextAreaResize.Vertical">
<span>@Loc["IncludePatterns"]</span>
</FluentTextArea>
<FluentTextArea @bind-Value=@ExcludePatterns class="full-width-field" Placeholder="**/users/**" Rows="10" Resize="TextAreaResize.Vertical">
<span>@Loc["ExcludePatterns"]</span>
</FluentTextArea>
<FluentDivider Role="DividerRole.Separator"></FluentDivider>
<FluentButton @onclick="ShowDescription" Appearance="Appearance.Accent">@Loc["ShowButton"]</FluentButton>
<FluentButton @onclick="GoToGenerate" Appearance="Appearance.Neutral" Disabled="@(string.IsNullOrEmpty(DescriptionUrl))">@Loc["GoToGenerate"]</FluentButton>
@if(IsLoading) {
<FluentProgress></FluentProgress>
}
</div>
@if(!string.IsNullOrEmpty(Tree)) {
<div>
<h2>@Loc["ApiPaths"]</h2>
<fluent-tree-view>@((MarkupString)Tree)</fluent-tree-view>
</div>
}
@code {
[Parameter]
[SupplyParameterFromQuery(Name = "k")]
public string? SearchTermFromQuery { get; set; }
public string? SearchTerm { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "v")]
public string? VersionFromQuery { get; set; }
public string? Version { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "d")]
public string? DescriptionUrlFromQuery { get; set; }
private string? DescriptionUrl { get; set; }
private IDictionary<string, SearchResult> SearchResults = new Dictionary<string, SearchResult>();
private string? IncludePatterns { get; set; }
private string? ExcludePatterns { get; set; }
private string? Tree { get; set; }
private bool IsLoading { get; set; }
[Inject] private IApplicationInsights? AppInsights { get; set; }
[Inject] private KiotaSearcher? KiotaSearcher { get; set; }
protected override async Task OnParametersSetAsync() {
if(!string.IsNullOrEmpty(SearchTermFromQuery))
SearchTerm = SearchTermFromQuery;
if(!string.IsNullOrEmpty(VersionFromQuery))
Version = VersionFromQuery;
if(!string.IsNullOrEmpty(DescriptionUrlFromQuery))
DescriptionUrl = DescriptionUrlFromQuery;
if (!string.IsNullOrEmpty(SearchTerm) && !string.IsNullOrEmpty(Version) && string.IsNullOrEmpty(DescriptionUrl) && KiotaSearcher != null) {
var searchResults = await KiotaSearcher.SearchAsync(SearchTerm, Version, ComponentDetached);
if(searchResults.Any())
DescriptionUrl = searchResults.Values.First().DescriptionUrl?.ToString();
}
await base.OnParametersSetAsync();
}
private const string goToGenerateTelemetryKey = "gotogenerate";
private async Task GoToGenerate() {
if(!string.IsNullOrEmpty(DescriptionUrl))
{
if(AppInsights != null)
await AppInsights.StartTrackEvent(goToGenerateTelemetryKey).ConfigureAwait(false);
var includeFilters = string.IsNullOrEmpty(IncludePatterns) ? string.Empty : string.Join(",", IncludePatterns
.Split(new [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(static x => x.Trim()));
var excludeFilters = string.IsNullOrEmpty(ExcludePatterns) ? string.Empty : string.Join(",", ExcludePatterns
.Split(new [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(static x => x.Trim()));
if(AppInsights != null)
await AppInsights.StopTrackEvent(goToGenerateTelemetryKey, new Dictionary<string, string?> {
{ "includePatterns", IncludePatterns },
{ "excludePatterns", ExcludePatterns },
}).ConfigureAwait(false);
navManager.NavigateTo($"/generate?d={DescriptionUrl}&i={includeFilters}&e={excludeFilters}");
}
}
private Task ShowDescription() {
IsLoading = true;
return ShowDescriptionInternal();
}
private KiotaBuilder? kiotaBuilder;
private GenerationConfiguration? generationConfiguration;
private const string showDescriptionTelemetryKey = "showdescription";
private async Task ShowDescriptionInternal() {
Tree = string.Empty;
if (string.IsNullOrEmpty(DescriptionUrl) && KiotaSearcher != null) {
SearchResults = await KiotaSearcher.SearchAsync(SearchTerm, Version, ComponentDetached);
DescriptionUrl = SearchResults.First().Value.DescriptionUrl?.ToString();
}
if(AppInsights != null)
await AppInsights.StartTrackEvent(showDescriptionTelemetryKey).ConfigureAwait(false);
if (kiotaBuilder == null || (!(generationConfiguration?.OpenAPIFilePath.Equals(DescriptionUrl, StringComparison.OrdinalIgnoreCase) ?? false))) {
generationConfiguration = new GenerationConfiguration();
if (!string.IsNullOrEmpty(DescriptionUrl))
generationConfiguration.OpenAPIFilePath = DescriptionUrl;
var builderLogger = LoggerFactory.CreateLogger<KiotaBuilder>();
kiotaBuilder = new KiotaBuilder(builderLogger, generationConfiguration, Http);
}
generationConfiguration.IncludePatterns = IncludePatterns?.Split('\n', StringSplitOptions.RemoveEmptyEntries).Select(static x => x.Trim()).ToHashSet(StringComparer.OrdinalIgnoreCase) ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
generationConfiguration.ExcludePatterns = ExcludePatterns?.Split('\n', StringSplitOptions.RemoveEmptyEntries).Select(static x => x.Trim()).ToHashSet(StringComparer.OrdinalIgnoreCase) ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var urlTreeNode = await kiotaBuilder.GetUrlTreeNodeAsync(ComponentDetached).ConfigureAwait(false);
var builder = new StringBuilder();
if (urlTreeNode != null)
RenderNode(urlTreeNode, 10, builder);
Tree = builder.ToString();
IsLoading = false;
if(AppInsights != null)
await AppInsights.StopTrackEvent(showDescriptionTelemetryKey, new Dictionary<string, string?> {
{ "includePatterns", IncludePatterns },
{ "excludePatterns", ExcludePatterns },
}).ConfigureAwait(false);
}
private static void RenderNode(Microsoft.OpenApi.Services.OpenApiUrlTreeNode node, uint maxDepth, StringBuilder builder, string indent = "", int nodeDepth = 0)
{
builder.AppendLine($"<fluent-tree-item{(nodeDepth < 2 ? " expanded" : string.Empty)}>");
builder.AppendLine(HttpUtility.HtmlEncode(node.Segment));
var children = node.Children;
var numberOfChildren = children.Count;
for (var i = 0; i < numberOfChildren; i++)
{
var child = children.ElementAt(i);
RenderChildNode(child.Value, maxDepth, builder, indent, nodeDepth);
}
builder.AppendLine("</fluent-tree-item>");
}
private static void RenderChildNode(Microsoft.OpenApi.Services.OpenApiUrlTreeNode node, uint maxDepth, StringBuilder builder, string indent, int nodeDepth = 0)
{
if (nodeDepth >= maxDepth && maxDepth != 0)
return;
RenderNode(node, maxDepth, builder, indent, nodeDepth + 1);
}
}

Просмотреть файл

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - show an OpenAPI description and fine tune your filters</value>
</data>
<data name="Show" xml:space="preserve">
<value>Show</value>
</data>
<data name="DescriptionUrl" xml:space="preserve">
<value>OpenAPI Description Url</value>
</data>
<data name="IncludePatterns" xml:space="preserve">
<value>Include Patterns</value>
</data>
<data name="ExcludePatterns" xml:space="preserve">
<value>Exclude Patterns</value>
</data>
<data name="ShowButton" xml:space="preserve">
<value>Show</value>
</data>
<data name="GoToGenerate" xml:space="preserve">
<value>Generate</value>
</data>
<data name="ApiPaths" xml:space="preserve">
<value>API Paths</value>
</data>
</root>

Просмотреть файл

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - mettre à jour un client OpenAPI</value>
</data>
<data name="Update" xml:space="preserve">
<value>Mettre à jour un client</value>
</data>
<data name="File" xml:space="preserve">
<value>Selectionez un fichier de sommaire kiota.</value>
</data>
<data name="InvalidLockFile" xml:space="preserve">
<value>Le fichier de sommaire n'a pas été reconnu.</value>
</data>
<data name="LockFileValid" xml:space="preserve">
<value>La description OpenAPI n'a pas été trouvée.</value>
</data>
</root>

Просмотреть файл

@ -1,59 +0,0 @@
@page "/update"
@using Microsoft.Extensions.Localization
@using Kiota.Builder.Lock
@inject IStringLocalizer<Update> Loc
@inject NavigationManager navManager
<PageTitle>@Loc["PageTitle"]</PageTitle>
<h1>@Loc["Update"]</h1>
<div>
<label for="file">@Loc["File"]</label>
<InputFile OnChange="@LoadFiles" id="file" accept=".json" />
@if(IsFileLoaded) {
@if(!IsLockFileValid) {
<p>@Loc["InvalidLockFile"]</p>
}
@if(!IsDocumentValid) {
<p>@Loc["LockFileValid"]</p>
}
}
</div>
@code {
private bool IsFileLoaded { get; set; }
private bool IsLockFileValid { get; set; } = true;
private bool IsDocumentValid { get; set; } = true;
[Inject] private IApplicationInsights? AppInsights { get; set; }
private const string updateClientTelemetryKey = "updateclient";
private async Task LoadFiles(InputFileChangeEventArgs e)
{
IsFileLoaded = true;
var lockService = new LockManagementService();
if(AppInsights != null)
await AppInsights.StartTrackEvent(updateClientTelemetryKey).ConfigureAwait(false);
await using var stream = e.File.OpenReadStream();
try {
var lockInfo = await lockService.GetLockFromStreamAsync(stream, ComponentDetached).ConfigureAwait(false);
IsLockFileValid = true;
if (lockInfo?.DescriptionLocation.StartsWith("http", StringComparison.OrdinalIgnoreCase) ?? false) {
var includeFilters = string.Join(",", lockInfo.IncludePatterns);
var excludeFilters = string.Join(",", lockInfo.ExcludePatterns);
var serializers = !(lockInfo.Serializers?.Any() ?? false) ? string.Empty : string.Join(",", lockInfo.Serializers);
var deserializers = !(lockInfo.Deserializers?.Any() ?? false) ? string.Empty : string.Join(",", lockInfo.Deserializers);
var structuredMimeTypes = !(lockInfo.StructuredMimeTypes?.Any() ?? false) ? string.Empty : string.Join(",", lockInfo.StructuredMimeTypes);
navManager.NavigateTo($"/generate?d={lockInfo.DescriptionLocation}&i={includeFilters}&e={excludeFilters}" +
$"&s={serializers}&ds={deserializers}&m={structuredMimeTypes}&l={lockInfo.Language}" +
$"&b={lockInfo.UsesBackingStore}&n={lockInfo.ClientNamespaceName}&c={lockInfo.ClientClassName}"+
$"&ad={lockInfo.IncludeAdditionalData}");
}
} catch (Exception) {
IsLockFileValid = false;
} finally {
if(AppInsights != null)
await AppInsights.StopTrackEvent(updateClientTelemetryKey).ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PageTitle" xml:space="preserve">
<value>Kiota - update an OpenAPI client</value>
</data>
<data name="Update" xml:space="preserve">
<value>Update a client</value>
</data>
<data name="File" xml:space="preserve">
<value>Select a kiota lock file</value>
</data>
<data name="InvalidLockFile" xml:space="preserve">
<value>The lock file couldn't be recognized.</value>
</data>
<data name="LockFileValid" xml:space="preserve">
<value>The OpenAPI description could not be found.</value>
</data>
</root>

Просмотреть файл

@ -1,47 +0,0 @@
using System.Globalization;
using BlazorApplicationInsights;
using Kiota.Builder.Configuration;
using Kiota.Web;
using Kiota.Web.Authentication.GitHub;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Fast.Components.FluentUI;
using Microsoft.Fast.Components.FluentUI.Infrastructure;
using Microsoft.JSInterop;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddLocalization();
LibraryConfiguration config = new(ConfigurationGenerator.GetIconConfiguration(), ConfigurationGenerator.GetEmojiConfiguration());
builder.Services.AddFluentUIComponents(config);
builder.Services.AddBlazorApplicationInsights();
var configObject = new KiotaConfiguration();
builder.Configuration.Bind(configObject);
builder.Services.AddSingleton(configObject);
builder.Services.AddPatAuthentication();
builder.Services.AddSearchService();
var host = builder.Build();
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();

Просмотреть файл

@ -1,30 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:35259",
"sslPort": 44313
}
},
"profiles": {
"Kiota.Web": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7230;http://localhost:5130",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
# Kiota Web
## Debug tips
```powershell
dotnet watch run
chrome --remote-debugging-port=9222 --user-data-dir="$Env:TEMP\blazor-chrome-debug" https://localhost:7230/
```
Once on the page:
alt + shift + D

Просмотреть файл

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="SignIn" xml:space="preserve">
<value>Se connecter à GitHub</value>
</data>
<data name="SignOut" xml:space="preserve">
<value>Se déconnecter de GitHub</value>
</data>
<data name="PersonalAccessTokenInstructionsStep1" xml:space="preserve">
<value>Ouvrez un nouvel onglet afin de créer un nouveau jeton d'accès.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep2" xml:space="preserve">
<value>Donnez un nom au nouveau jeton.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep3" xml:space="preserve">
<value>Sélectionnez le propriétaires du repository qui contient les définitions.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep4" xml:space="preserve">
<value>Optionel. Authentifiez vous auprès de la resource sélectionnée si demandé.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep5" xml:space="preserve">
<value>Sous "accès au repository", sélectionnez "Tous les repositories" ou "Uniquement les repositories sélectionnés".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep6" xml:space="preserve">
<value>Sous "permissions du repository" sélectionnez "contenu" puis "lecture simple".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep7" xml:space="preserve">
<value>Cliquez sur "Générer le jeton".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep8" xml:space="preserve">
<value>Copiez le jeton généré ci-dessous.</value>
</data>
<data name="PersonalAccessTokenDescription" xml:space="preserve">
<value>Le jeton est uniquement envoyé à l'API REST GitHub.</value>
</data>
<data name="PersonalAccessToken" xml:space="preserve">
<value>Jeton d'accès personnalisé</value>
</data>
<data name="PersonalAccessTokenHeader" xml:space="preserve">
<value>Connectez vous à GitHub à l'aide d'un jeton d'accès personnel</value>
</data>
<data name="PersonalAccessTokenInstructionsOpen" xml:space="preserve">
<value>Open</value>
</data>
<data name="PersonalAccessTokenInstructions" xml:space="preserve">
<value>Instructions to create the token</value>
</data>
<data name="PersonalAccessTokenAdd" xml:space="preserve">
<value>Add the personal access token</value>
</data>
<data name="SVGAltText" xml:space="preserve">
<value>Logo GitHub Octocat</value>
</data>
<data name="ToolTip" xml:space="preserve">
<value>Accédez à des description d'APIs privées.</value>
</data>
</root>

Просмотреть файл

@ -1,73 +0,0 @@
@using Kiota.Builder.Configuration
@using Kiota.Builder.SearchProviders.GitHub.Authentication
@using Microsoft.Fast.Components.FluentUI
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<GitHubSignIn> Loc
@inject ITokenStorageService TokenStorageService
@inject KiotaConfiguration KiotaConfiguration
<svg fill="black" role="img" viewBox="0 0 24 24" width="32px" height="32px" xmlns="http://www.w3.org/2000/svg">
<title>@Loc["SVGAltText"]</title>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
&nbsp;
<div class="ghsignin">
@if(IsSignedIn) {
<FluentButton @onclick="SignOut" Appearance="Appearance.Neutral">@Loc["SignOut"]</FluentButton>
} else {
<FluentButton id="signinbtn" @onclick="SignIn" Appearance="Appearance.Accent">@Loc["SignIn"]</FluentButton>
<FluentTooltip Anchor="signinbtn" Position=TooltipPosition.Bottom>@Loc["ToolTip"]</FluentTooltip>
}
</div>
<FluentDialog Modal="true" @ondialogdismiss=OnPatSetDialogDismiss @bind-Hidden=@PatSetDialogHidden>
<div class="gh-dialog-content">
<h2>@Loc["PersonalAccessTokenHeader"]</h2>
<h3>@Loc["PersonalAccessTokenInstructions"]</h3>
<ol>
<li>@Loc["PersonalAccessTokenInstructionsStep1"] <a href="https://github.com/settings/personal-access-tokens/new" target="_blank">@Loc["PersonalAccessTokenInstructionsOpen"]</a></li>
<li>@Loc["PersonalAccessTokenInstructionsStep2"]</li><!--Give a name-->
<li>@Loc["PersonalAccessTokenInstructionsStep3"]</li><!--Give a resource owner-->
<li>@Loc["PersonalAccessTokenInstructionsStep4"]</li><!--Optional. Authenticate with resource-->
<li>@Loc["PersonalAccessTokenInstructionsStep5"]</li><!--All repos or select repos-->
<li>@Loc["PersonalAccessTokenInstructionsStep6"]</li><!--Under "repository permissions-->
<li>@Loc["PersonalAccessTokenInstructionsStep7"]</li><!--Click generate token-->
<li>@Loc["PersonalAccessTokenInstructionsStep8"]</li><!--Copy the value here-->
</ol>
<span>@Loc["PersonalAccessTokenDescription"]</span>
<div class="gh-dialog-content-form">
<h3>@Loc["PersonalAccessTokenAdd"]</h3>
<FluentTextField TextFieldType="TextFieldType.Password" Required=true class="full-width-field" @bind-Value=@PersonalAccessToken>@Loc["PersonalAccessToken"]</FluentTextField>
<FluentDivider Role=DividerRole.Presentation></FluentDivider>
<FluentButton @onclick="Save" Appearance="Appearance.Accent">@Loc["Save"]</FluentButton>
<FluentButton @onclick="OnPatSetDialogDismiss" Appearance="Appearance.Neutral">@Loc["Close"]</FluentButton>
</div>
</div>
</FluentDialog>
@code {
private bool PatSetDialogHidden { get; set; } = true;
private bool IsSignedIn {get; set;}
private string? PersonalAccessToken {get; set;}
private void OnPatSetDialogDismiss() {
PatSetDialogHidden = true;
}
protected override async Task OnParametersSetAsync() {
IsSignedIn = await TokenStorageService.IsTokenPresentAsync(ComponentDetached);
await base.OnParametersSetAsync();
}
private void SignIn() {
PatSetDialogHidden = false;
}
private async Task Save() {
if(!String.IsNullOrEmpty(PersonalAccessToken)) {
IsSignedIn = true;
await TokenStorageService.SetTokenAsync(PersonalAccessToken, ComponentDetached);
PatSetDialogHidden = true;
PersonalAccessToken = string.Empty;
}
}
private async Task SignOut() {
await TokenStorageService.DeleteTokenAsync(ComponentDetached);
IsSignedIn = false;
}
}

Просмотреть файл

@ -1,7 +0,0 @@
.gh-dialog-content {
margin: 10px;
}
.gh-dialog-content-form {
margin-top:10px;
}

Просмотреть файл

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="SignIn" xml:space="preserve">
<value>Sign In with GitHub</value>
</data>
<data name="SignOut" xml:space="preserve">
<value>Sign Out from GitHub</value>
</data>
<data name="PersonalAccessTokenInstructionsStep1" xml:space="preserve">
<value>Open a new tab to create a personal access token.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep2" xml:space="preserve">
<value>Give a name to the new access token.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep3" xml:space="preserve">
<value>Select the resource owner for the repository containing the definitions.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep4" xml:space="preserve">
<value>Optional. Authenticate with the selected resource if requested.</value>
</data>
<data name="PersonalAccessTokenInstructionsStep5" xml:space="preserve">
<value>Under "repository access", select "All repositories" or "Only select repositories".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep6" xml:space="preserve">
<value>Under "repository permissions" select "contents" to "read-only".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep7" xml:space="preserve">
<value>Click on "Generate Token".</value>
</data>
<data name="PersonalAccessTokenInstructionsStep8" xml:space="preserve">
<value>Copy the generated token down below.</value>
</data>
<data name="PersonalAccessTokenDescription" xml:space="preserve">
<value>The personal access token is only ever sent to GitHub REST API.</value>
</data>
<data name="PersonalAccessToken" xml:space="preserve">
<value>Personal Access Token</value>
</data>
<data name="PersonalAccessTokenHeader" xml:space="preserve">
<value>Sign in to GitHub with a Personal Access Token</value>
</data>
<data name="PersonalAccessTokenInstructionsOpen" xml:space="preserve">
<value>Open</value>
</data>
<data name="PersonalAccessTokenInstructions" xml:space="preserve">
<value>Instructions to create the token</value>
</data>
<data name="PersonalAccessTokenAdd" xml:space="preserve">
<value>Add the personal access token</value>
</data>
<data name="SVGAltText" xml:space="preserve">
<value>GitHub Octocat logo</value>
</data>
<data name="ToolTip" xml:space="preserve">
<value>Access private API descriptions.</value>
</data>
</root>

Просмотреть файл

@ -1,16 +0,0 @@
@inherits LayoutComponentBase
<div class="page">
<div>
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<GitHubSignIn />
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>

Просмотреть файл

@ -1,75 +0,0 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
max-width: calc(100% - 100px);
}
.top-row {
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

Просмотреть файл

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Show" xml:space="preserve">
<value>Afficher</value>
</data>
<data name="Search" xml:space="preserve">
<value>Rechercher</value>
</data>
<data name="Generate" xml:space="preserve">
<value>Générer</value>
</data>
<data name="Update" xml:space="preserve">
<value>Mettre à jour</value>
</data>
<data name="About" xml:space="preserve">
<value>A propos</value>
</data>
</root>

Просмотреть файл

@ -1,88 +0,0 @@
@using System.Globalization
@using Microsoft.Extensions.Localization
@using Microsoft.Fast.Components.FluentUI
@inject IStringLocalizer<NavMenu> Loc
@inject NavigationManager navManager
<div class="ps-3 navbar navbar-dark burger-menu">
<div class="navbar-toggler">
<FluentButton title="Navigation menu" @onclick=@ToggleNavMenu>
<span slot="end">
<FluentIcon Name="@FluentIcons.List" Size="@IconSize.Size24" Filled=false UseAccentColor=true />
</span>
</FluentButton>
<FluentAnchor Href="#" Appearance="Appearance.Stealth">Kiota.dev</FluentAnchor>
</div>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<FluentMenu>
<FluentMenuItem @onclick=@GoHome>
@Loc["Search"]
<span slot="start">
<FluentIcon Name="@FluentIcons.Search" Size="@IconSize.Size24" Filled=false UseAccentColor=false />
</span>
</FluentMenuItem>
<FluentMenuItem @onclick="@GoToShow">
@Loc["Show"]
<span slot="start">
<FluentIcon Name="@FluentIcons.AppsList" Size="@IconSize.Size24" Filled=false UseAccentColor=false />
</span>
</FluentMenuItem>
<FluentMenuItem @onclick=@GoToGenerate>
@Loc["Generate"]
<span slot="start">
<FluentIcon Name="@FluentIcons.Code" Size="@IconSize.Size24" Filled=false UseAccentColor=false />
</span>
</FluentMenuItem>
<FluentMenuItem @onclick=@GoToUpdate>
@Loc["Update"]
<span slot="start">
<FluentIcon Name="@FluentIcons.ArrowSync" Size="@IconSize.Size24" Filled=false UseAccentColor=false />
</span>
</FluentMenuItem>
<FluentMenuItem @onclick=@GoToAbout>
@Loc["About"]
<span slot="start">
<FluentIcon Name="@FluentIcons.Info" Size="@IconSize.Size24" Filled=false UseAccentColor=false />
</span>
</FluentMenuItem>
</FluentMenu>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse main-nav-menu" : "main-nav-menu";
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
private void GoHome() {
GoTo("/");
}
private void GoToShow()
{
GoTo("show");
}
private void GoToGenerate()
{
GoTo("generate");
}
private void GoToUpdate()
{
GoTo("update");
}
private void GoTo(string target)
{
navManager.NavigateTo(target);
}
private void GoToAbout()
{
GoTo("https://learn.microsoft.com/openapi/kiota");
}
}

Просмотреть файл

@ -1,31 +0,0 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.collapse {
display: none;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.main-nav-menu {
margin-top: 40px;
min-width: 100px;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}

Просмотреть файл

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Show" xml:space="preserve">
<value>Show</value>
</data>
<data name="Search" xml:space="preserve">
<value>Search</value>
</data>
<data name="Generate" xml:space="preserve">
<value>Generate</value>
</data>
<data name="Update" xml:space="preserve">
<value>Update</value>
</data>
<data name="About" xml:space="preserve">
<value>About</value>
</data>
</root>

Просмотреть файл

@ -1,22 +0,0 @@
using System.Text;
namespace Kiota.Web;
public class StringBuilderLogger<T> : ILogger<T>
{
private readonly StringBuilder _stringBuilder;
private readonly LogLevel _logLevel;
public StringBuilderLogger(StringBuilder stringBuilder, LogLevel logLevel)
{
ArgumentNullException.ThrowIfNull(stringBuilder);
_stringBuilder = stringBuilder;
_logLevel = logLevel;
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None && logLevel >= _logLevel;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
return;
_stringBuilder.AppendLine(formatter(state, exception));
}
}

Просмотреть файл

@ -1,12 +0,0 @@
@inherits ComponentWithCancellationToken
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using Kiota.Web
@using Kiota.Web.Shared
@using BlazorApplicationInsights;

Просмотреть файл

@ -1,261 +0,0 @@
{
"Generation": {
"IgnoredRequestContentTypes": [
"multipart/form-data"
],
"MaxDegreeOfParallelism": -1
},
"Search": {
"APIsGuruListUrl": "https://raw.githubusercontent.com/APIs-guru/openapi-directory/gh-pages/v2/list.json",
"GitHub": {
"BlockListUrl": "https://raw.githubusercontent.com/microsoft/kiota/main/resources/index-block-list.yml",
"AppId": "Iv1.9ed2bcb878c90617",
"AppManagement": "https://aka.ms/kiota/install/github"
}
},
"Logging": {
"LogLevel": {
"Default": "Debug"
}
},
"Update": {
"OrgName": "microsoft",
"RepoName": "kiota",
"Disabled": false
},
"Languages": {
"CSharp": {
"MaturityLevel": "Stable",
"Dependencies": [
{
"Name": "Microsoft.Kiota.Abstractions",
"Version": "1.2.1"
},
{
"Name": "Microsoft.Kiota.Http.HttpClientLibrary",
"Version": "1.0.6"
},
{
"Name": "Microsoft.Kiota.Serialization.Form",
"Version": "1.0.1"
},
{
"Name": "Microsoft.Kiota.Serialization.Json",
"Version": "1.0.7"
},
{
"Name": "Microsoft.Kiota.Authentication.Azure",
"Version": "1.0.3"
},
{
"Name": "Microsoft.Kiota.Serialization.Text",
"Version": "1.0.1"
}
],
"DependencyInstallCommand": "dotnet add package {0} --version {1}"
},
"Java": {
"MaturityLevel": "Preview",
"Dependencies": [
{
"Name": "com.microsoft.kiota:microsoft-kiota-abstractions",
"Version": "0.4.5"
},
{
"Name": "com.microsoft.kiota:microsoft-kiota-http-okHttp",
"Version": "0.4.5"
},
{
"Name": "com.microsoft.kiota:microsoft-kiota-serialization-form",
"Version": "0.4.5"
},
{
"Name": "com.microsoft.kiota:microsoft-kiota-serialization-json",
"Version": "0.4.5"
},
{
"Name": "com.microsoft.kiota:microsoft-kiota-authentication-azure",
"Version": "0.4.5"
},
{
"Name": "com.microsoft.kiota:microsoft-kiota-serialization-text",
"Version": "0.4.5"
}
],
"DependencyInstallCommand": "{0}:{1}"
},
"Go": {
"MaturityLevel": "Stable",
"Dependencies": [
{
"Name": "github.com/microsoft/kiota-abstractions-go",
"Version": "v1.1.0"
},
{
"Name": "github.com/microsoft/kiota-http-go",
"Version": "v1.0.0"
},
{
"Name": "github.com/microsoft/kiota-serialization-form-go",
"Version": "v1.0.0"
},
{
"Name": "github.com/microsoft/kiota-serialization-json-go",
"Version": "v1.0.3"
},
{
"Name": "github.com/microsoft/kiota-authentication-azure-go",
"Version": "v1.0.0"
},
{
"Name": "github.com/microsoft/kiota-serialization-text-go",
"Version": "v1.0.0"
}
],
"DependencyInstallCommand": "go get {0}@{1}"
},
"TypeScript": {
"MaturityLevel": "Experimental",
"Dependencies": [
{
"Name": "@microsoft/kiota-abstractions",
"Version": "1.0.0-preview.22"
},
{
"Name": "@microsoft/kiota-http-fetchlibrary",
"Version": "1.0.0-preview.21"
},
{
"Name": "@microsoft/kiota-serialization-form",
"Version": "1.0.0-preview.11"
},
{
"Name": "@microsoft/kiota-serialization-json",
"Version": "1.0.0-preview.20"
},
{
"Name": "@microsoft/kiota-authentication-azure",
"Version": "1.0.0-preview.17"
},
{
"Name": "@microsoft/kiota-serialization-text",
"Version": "1.0.0-preview.19"
}
],
"DependencyInstallCommand": "npm install {0}@{1} -S"
},
"PHP": {
"MaturityLevel": "Preview",
"Dependencies": [
{
"Name": "microsoft/kiota-abstractions",
"Version": "0.8.0"
},
{
"Name": "microsoft/kiota-http-guzzle",
"Version": "0.8.1"
},
{
"Name": "microsoft/kiota-serialization-json",
"Version": "0.6.0"
},
{
"Name": "microsoft/kiota-authentication-phpleague",
"Version": "0.8.2"
},
{
"Name": "microsoft/kiota-serialization-text",
"Version": "0.7.0"
}
],
"DependencyInstallCommand": "composer require {0}:{1}"
},
"Python": {
"MaturityLevel": "Preview",
"Dependencies": [
{
"Name": "microsoft-kiota-abstractions",
"Version": "0.6.0"
},
{
"Name": "microsoft-kiota-http",
"Version": "0.4.4"
},
{
"Name": "microsoft-kiota-serialization-json",
"Version": "0.3.7"
},
{
"Name": "microsoft-kiota-authentication-azure",
"Version": "0.2.0"
},
{
"Name": "microsoft-kiota-serialization-text",
"Version": "0.2.1"
}
],
"DependencyInstallCommand": "pip install {0}=={1}"
},
"Ruby": {
"MaturityLevel": "Experimental",
"Dependencies": [
{
"Name": "microsoft_kiota_abstractions",
"Version": "0.14.0"
},
{
"Name": "microsoft_kiota_faraday",
"Version": "0.12.0"
},
{
"Name": "microsoft_kiota_serialization_json",
"Version": "0.9.0"
},
{
"Name": "microsoft_kiota_authentication_oauth",
"Version": "0.8.0"
}
],
"DependencyInstallCommand": "gem install \"{0}\" -v \"{1}\""
},
"Swift": {
"MaturityLevel": "Experimental",
"Dependencies": [],
"DependencyInstallCommand": ""
},
"Shell": {
"MaturityLevel": "Preview",
"Dependencies": [
{
"Name": "Microsoft.Kiota.Abstractions",
"Version": "1.2.1"
},
{
"Name": "Microsoft.Kiota.Http.HttpClientLibrary",
"Version": "1.0.6"
},
{
"Name": "Microsoft.Kiota.Serialization.Form",
"Version": "1.0.1"
},
{
"Name": "Microsoft.Kiota.Serialization.Json",
"Version": "1.0.7"
},
{
"Name": "Microsoft.Kiota.Authentication.Azure",
"Version": "1.0.3"
},
{
"Name": "Microsoft.Kiota.Serialization.Text",
"Version": "1.0.1"
},
{
"Name": "Microsoft.Kiota.Cli.Commons",
"Version": "0.3.1-preview.1"
}
],
"DependencyInstallCommand": "dotnet add package {0} --version {1}"
}
}
}

Просмотреть файл

@ -1,72 +0,0 @@
html, body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h1 {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h2 {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h3 {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h1:focus {
outline: none;
}
a, .btn-link {
color: #0071c1;
}
.full-width-field {
width: 100%;
}
.content {
padding-top: 1.1rem;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid red;
}
.validation-message {
color: red;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}

Двоичные данные
src/Kiota.Web/wwwroot/favicon.ico

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.3 KiB

Двоичные данные
src/Kiota.Web/wwwroot/icon-192.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Просмотреть файл

@ -1,64 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kiota.Web</title>
<base href="/" />
<link href="_content/Microsoft.Fast.Components.FluentUI/css/variables.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="Kiota.Web.styles.css" rel="stylesheet" />
<link rel="manifest" href="kiota.webmanifest" />
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script type="text/javascript">
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'] ?? navigator.language,
set: (value) => window.localStorage['BlazorCulture'] = value
};
function BlazorDownloadFile(filename, contentType, content) {
// Create the URL
const file = new File([content], filename, { type: contentType });
const exportUrl = URL.createObjectURL(file);
// Create the <a> element and click on it
const a = document.createElement("a");
document.body.appendChild(a);
a.href = exportUrl;
a.download = filename;
a.target = "_self";
a.click();
// We don't need to keep the object URL, let's release the memory
// On older versions of Safari, it seems you need to comment this line...
URL.revokeObjectURL(exportUrl);
}
</script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@fluentui/web-components@2.5.11/dist/web-components.min.js" integrity="sha384-o2bgGon5DZnA5NP2R2AxS4Rv2pmRBAATUaUXJRUZ6qjgh/jBGKehT9BpQoOQ/5HX" async crossorigin="anonymous"></script>
<script type="text/javascript">
!function(T,l,y){var S=T.location,k="script",D="instrumentationKey",C="ingestionendpoint",I="disableExceptionTracking",E="ai.device.",b="toLowerCase",w="crossOrigin",N="POST",e="appInsightsSDK",t=y.name||"appInsights";(y.name||T[e])&&(T[e]=t);var n=T[t]||function(d){var g=!1,f=!1,m={initialize:!0,queue:[],sv:"5",version:2,config:d};function v(e,t){var n={},a="Browser";return n[E+"id"]=a[b](),n[E+"type"]=a,n["ai.operation.name"]=S&&S.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(m.sv||m.version),{time:function(){var e=new Date;function t(e){var t=""+e;return 1===t.length&&(t="0"+t),t}return e.getUTCFullYear()+"-"+t(1+e.getUTCMonth())+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+((e.getUTCMilliseconds()/1e3).toFixed(3)+"").slice(2,5)+"Z"}(),iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}}}}var h=d.url||y.src;if(h){function a(e){var t,n,a,i,r,o,s,c,u,p,l;g=!0,m.queue=[],f||(f=!0,t=h,s=function(){var e={},t=d.connectionString;if(t)for(var n=t.split(";"),a=0;a<n.length;a++){var i=n[a].split("=");2===i.length&&(e[i[0][b]()]=i[1])}if(!e[C]){var r=e.endpointsuffix,o=r?e.location:null;e[C]="https://"+(o?o+".":"")+"dc."+(r||"services.visualstudio.com")}return e}(),c=s[D]||d[D]||"",u=s[C],p=u?u+"/v2/track":d.endpointUrl,(l=[]).push((n="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",a=t,i=p,(o=(r=v(c,"Exception")).data).baseType="ExceptionData",o.baseData.exceptions=[{typeName:"SDKLoadFailed",message:n.replace(/\./g,"-"),hasFullStack:!1,stack:n+"\nSnippet failed to load ["+a+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(S&&S.pathname||"_unknown_")+"\nEndpoint: "+i,parsedStack:[]}],r)),l.push(function(e,t,n,a){var i=v(c,"Message"),r=i.data;r.baseType="MessageData";var o=r.baseData;return o.message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+n+")").replace(/\"/g,"")+'"',o.properties={endpoint:a},i}(0,0,t,p)),function(e,t){if(JSON){var n=T.fetch;if(n&&!y.useXhr)n(t,{method:N,body:JSON.stringify(e),mode:"cors"});else if(XMLHttpRequest){var a=new XMLHttpRequest;a.open(N,t),a.setRequestHeader("Content-type","application/json"),a.send(JSON.stringify(e))}}}(l,p))}function i(e,t){f||setTimeout(function(){!t&&m.core||a()},500)}var e=function(){var n=l.createElement(k);n.src=h;var e=y[w];return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=i,n.onerror=a,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||i(0,t)},n}();y.ld<0?l.getElementsByTagName("head")[0].appendChild(e):setTimeout(function(){l.getElementsByTagName(k)[0].parentNode.appendChild(e)},y.ld||0)}try{m.cookie=l.cookie}catch(p){}function t(e){for(;e.length;)!function(t){m[t]=function(){var e=arguments;g||m.queue.push(function(){m[t].apply(m,e)})}}(e.pop())}var n="track",r="TrackPage",o="TrackEvent";t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+r,"stop"+r,"start"+o,"stop"+o,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),m.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4};var s=(d.extensionConfig||{}).ApplicationInsightsAnalytics||{};if(!0!==d[I]&&!0!==s[I]){var c="onerror";t(["_"+c]);var u=T[c];T[c]=function(e,t,n,a,i){var r=u&&u(e,t,n,a,i);return!0!==r&&m["_"+c]({message:e,url:t,lineNumber:n,columnNumber:a,error:i}),r},d.autoExceptionInstrumented=!0}return m}(y.cfg);function a(){y.onInit&&y.onInit(n)}(T[t]=n).queue&&0===n.queue.length?(n.queue.push(a),n.trackPageView({})):a()}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source
// name: "appInsights", // Global SDK Instance name defaults to "appInsights" when not supplied
// ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout,
// useXhr: 1, // Use XHR instead of fetch to report failures (if available),
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
// onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DO NOT ADD anything to the sdk.queue -- As they won't get called)
cfg: { // Application Insights Configuration
instrumentationKey: "553bd0f3-8e2a-4303-8a0a-7c5916dc2856"
}});
</script>
<script src="_content/BlazorApplicationInsights/JsInterop.js"></script>
<script>navigator.serviceWorker.register('service-worker.js');</script>
</body>
</html>

Просмотреть файл

@ -1,17 +0,0 @@
{
"name": "Kiota.dev",
"short_name": "kiota-dev",
"description": "Generate OpenAPI clients.",
"icons": [
{
"src": "icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "/",
"lang": "en-us",
"display": "fullscreen",
"theme_color": "#94C73D",
"background_color": "#4C5B31"
}

Просмотреть файл

@ -1,4 +0,0 @@
// In development, always fetch from the network and do not enable offline support.
// This is because caching would make development more difficult (changes would not
// be reflected on the first load after each change).
self.addEventListener('fetch', () => { });

Просмотреть файл

@ -1,48 +0,0 @@
// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations
self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
async function onInstall(event) {
console.info('Service worker: Install');
// Fetch and cache all matching items from the assets manifest
const assetsRequests = self.assetsManifest.assets
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
.map(asset => new Request(asset.url, { cache: 'no-cache' }));
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}
async function onActivate(event) {
console.info('Service worker: Activate');
// Delete unused caches
const cacheKeys = await caches.keys();
await Promise.all(cacheKeys
.filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName)
.map(key => caches.delete(key)));
}
async function onFetch(event) {
let cachedResponse = null;
if (event.request.method === 'GET') {
// For all navigation requests, try to serve index.html from cache
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
const shouldServeIndexHtml = event.request.mode === 'navigate';
const request = shouldServeIndexHtml ? 'index.html' : event.request;
const cache = await caches.open(cacheName);
cachedResponse = await cache.match(request);
}
return cachedResponse || fetch(event.request);
}

Просмотреть файл

@ -1,27 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Deque.AxeCore.Playwright" Version="4.4.0-alpha.c9651f2c2284967c64d2f28e460b5181d0af5c6d" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="Microsoft.Playwright" Version="1.36.0" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>

Просмотреть файл

@ -1,31 +0,0 @@
using Deque.AxeCore.Playwright;
namespace Kiota.Web.Tests;
[Collection(PlaywrightFixture.PlaywrightCollection)]
public class KiotaWebGeneralTests : IAsyncDisposable
{
private readonly PlaywrightFixture playwrightFixture;
public KiotaWebGeneralTests(PlaywrightFixture playwrightFixture)
{
this.playwrightFixture = playwrightFixture;
}
public async ValueTask DisposeAsync()
{
await playwrightFixture.DisposeAsync();
GC.SuppressFinalize(this);
}
[Fact]
public async Task PassesAxeAccessibilityReview()
{
// Open a page and run test logic.
await playwrightFixture.GotoPageAsync(
playwrightFixture.DotnetUrl!,
async (page) =>
{
var axeResults = await page.RunAxe();
Assert.Empty(axeResults.Violations);
},
Browser.Chromium);
}
}

Просмотреть файл

@ -1,258 +0,0 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
using FluentAssertions;
using Microsoft.Playwright;
namespace Kiota.Web.Tests;
/// <summary>
/// Playwright fixture implementing an asynchronous life cycle.
/// </summary>
public class PlaywrightFixture : IAsyncLifetime
{
/// <summary>
/// Playwright module.
/// </summary>
public IPlaywright? Playwright
{
get; private set;
}
/// <summary>
/// Chromium lazy initializer.
/// </summary>
public IBrowser? ChromiumBrowser
{
get; private set;
}
/// <summary>
/// Firefox lazy initializer.
/// </summary>
public IBrowser? FirefoxBrowser
{
get; private set;
}
/// <summary>
/// Webkit lazy initializer.
/// </summary>
public IBrowser? WebkitBrowser
{
get; private set;
}
/// <summary>
/// The process running the blazor app.
/// </summary>
public Process? DotnetRunProcess
{
get; private set;
}
/// <summary>
/// The URL the app is hosted at
/// </summary>
public string? DotnetUrl
{
get; private set;
}
private static readonly Regex urlRegex = new Regex(@"Now listening on: (?<url>.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
/// <summary>
/// Initialize the Playwright fixture.
/// </summary>
public async Task InitializeAsync()
{
var launchOptions = new BrowserTypeLaunchOptions
{
Headless = true,
};
// Install Playwright and its dependencies.
InstallPlaywright();
// Create Playwright module.
Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
// Setup Browser lazy initializers.
ChromiumBrowser = await Playwright.Chromium.LaunchAsync(launchOptions);
FirefoxBrowser = await Playwright.Firefox.LaunchAsync(launchOptions);
WebkitBrowser = await Playwright.Webkit.LaunchAsync(launchOptions);
// Start the blazor app.
DotnetRunProcess = new();
DotnetRunProcess.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
// Prepend line numbers to each line of the output.
if (!string.IsNullOrEmpty(e.Data) && urlRegex.IsMatch(e.Data))
{
var match = urlRegex.Match(e.Data);
DotnetUrl = match.Groups["url"].Value;
}
});
DotnetRunProcess.StartInfo = new()
{
FileName = "dotnet",
Arguments = "run",
WorkingDirectory = Path.GetFullPath("../../../../../src/Kiota.Web"),
RedirectStandardOutput = true,
};
DotnetRunProcess.Start();
DotnetRunProcess.BeginOutputReadLine();
var secondsToWaitForRunToStart = 300;
while (DotnetUrl == null && secondsToWaitForRunToStart > 0)
{
secondsToWaitForRunToStart--;
await Task.Delay(1000);
}
if (DotnetUrl == null)
{
DotnetRunProcess.Kill(true);
throw new Exception("Failed to start the blazor app.");
}
DotnetRunProcess.CancelOutputRead();
}
/// <summary>
/// Dispose all Playwright module resources.
/// </summary>
public async Task DisposeAsync()
{
await (ChromiumBrowser?.CloseAsync() ?? Task.CompletedTask);
await (FirefoxBrowser?.CloseAsync() ?? Task.CompletedTask);
await (WebkitBrowser?.CloseAsync() ?? Task.CompletedTask);
Playwright?.Dispose();
Playwright = null;
DotnetRunProcess?.Kill(true);
DotnetRunProcess?.Dispose();
}
/// <summary>
/// Install and deploy all binaries Playwright may need.
/// </summary>
private static void InstallPlaywright()
{
var exitCode = Microsoft.Playwright.Program.Main(
new[] { "install-deps" });
if (exitCode != 0)
{
throw new Exception(
$"Playwright exited with code {exitCode} on install-deps");
}
exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
if (exitCode != 0)
{
throw new Exception(
$"Playwright exited with code {exitCode} on install");
}
}
/// <summary>
/// PlaywrightCollection name that is used in the Collection
/// attribute on each test classes.
/// Like "[Collection(PlaywrightFixture.PlaywrightCollection)]"
/// </summary>
public const string PlaywrightCollection =
nameof(PlaywrightCollection);
[CollectionDefinition(PlaywrightCollection)]
public class PlaywrightCollectionDefinition
: ICollectionFixture<PlaywrightFixture>
{
// This class is just xUnit plumbing code to apply
// [CollectionDefinition] and the ICollectionFixture<>
// interfaces. Witch in our case is parametrized
// with the PlaywrightFixture.
}
/// <summary>
/// Open a Browser page and navigate to the given URL before
/// applying the given test handler.
/// </summary>
/// <param name="url">URL to navigate to.</param>
/// <param name="testHandler">Test handler to apply on the page.
/// </param>
/// <param name="browserType">The Browser to use to open the page.
/// </param>
/// <returns>The GotoPage task.</returns>
public async Task GotoPageAsync(
string url,
Func<IPage, Task> testHandler,
Browser browserType)
{
// select and launch the browser.
var browser = SelectBrowser(browserType);
// Open a new page with an option to ignore HTTPS errors
await using var context = await browser.NewContextAsync(
new BrowserNewContextOptions
{
IgnoreHTTPSErrors = true
}).ConfigureAwait(false);
// Start tracing before creating the page.
await context.Tracing.StartAsync(new TracingStartOptions()
{
Screenshots = true,
Snapshots = true,
Sources = true
});
var page = await context.NewPageAsync().ConfigureAwait(false);
page.Should().NotBeNull();
try
{
// Navigate to the given URL and wait until loading
// network activity is done.
var gotoResult = await page.GotoAsync(
url,
new PageGotoOptions
{
WaitUntil = WaitUntilState.NetworkIdle
});
if (gotoResult == null)
{
throw new Exception(
$"Failed to navigate to {url}.");
}
gotoResult.Should().NotBeNull();
await gotoResult.FinishedAsync();
gotoResult.Ok.Should().BeTrue();
// Run the actual test logic.
await testHandler(page);
}
finally
{
// Make sure the page is closed
await page.CloseAsync();
// Stop tracing and save data into a zip archive.
await context.Tracing.StopAsync(new TracingStopOptions()
{
Path = "trace.zip"
});
}
}
/// <summary>
/// Select the IBrowser instance depending on the given browser
/// enumeration value.
/// </summary>
/// <param name="browser">The browser to select.</param>
/// <returns>The selected IBrowser instance.</returns>
private IBrowser SelectBrowser(Browser browser)
{
return browser switch
{
Browser.Chromium => ChromiumBrowser ?? throw new Exception(
"Chromium browser is not initialized"),
Browser.Firefox => FirefoxBrowser ?? throw new Exception(
"Firefox browser is not initialized"),
Browser.Webkit => WebkitBrowser ?? throw new Exception(
"Webkit browser is not initialized"),
_ => throw new NotImplementedException(),
};
}
}
/// <summary>
/// Browser types we can use in the PlaywrightFixture.
/// </summary>
public enum Browser
{
Chromium,
Firefox,
Webkit,
}

Просмотреть файл

@ -1 +0,0 @@
global using Xunit;