Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set lib target framework to netstandard2.0 #55

Merged
merged 9 commits into from
Dec 6, 2023
Merged
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.4] - 2023-12-06

### Added

- Added support for netStandard2.0.

## [0.5.3] - 2023-11-16

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/lib/AccessRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static AccessRequest Load(JsonElement content)
}
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
if (!String.IsNullOrWhiteSpace(Type)) writer.WriteString(TypeProperty, Type);
if (Content != null)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ApiDependency.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public string? ApiDeploymentBaseUrl
// Write method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();

if (!string.IsNullOrWhiteSpace(ApiDescriptionUrl)) writer.WriteString(ApiDescriptionUrlProperty, ApiDescriptionUrl);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ApiManifestDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ApiManifestDocument(JsonElement value)
// Write method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
Validate();
writer.WriteStartObject();
writer.WriteString(ApplicationNameProperty, ApplicationName);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/AuthorizationRequirements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private static void LoadAccessProperty(AuthorizationRequirements o, JsonElement
// Write Method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();

if (!string.IsNullOrWhiteSpace(ClientIdentifier)) writer.WriteString(ClientIdentifierProperty, ClientIdentifier);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.Helpers;
using System.Text.Json;
using System.Text.Json.Nodes;

Expand All @@ -26,7 +27,7 @@ public static Extensions Load(JsonElement value)

public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
foreach (var extension in this)
{
Expand Down
19 changes: 8 additions & 11 deletions src/lib/Helpers/ParsingHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@

using Microsoft.OpenApi.Readers;
using System.Diagnostics;
using System.Net;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.Helpers;

internal static class ParsingHelpers
{
// The HttpClient will default to SslProtocol of none. This lets the OS pick an appropriate SSL protocol.
private static readonly Lazy<HttpClient> s_httpClient = new(() => new HttpClient())
{
Value = { DefaultRequestVersion = HttpVersion.Version20 }
};
private static readonly Lazy<HttpClient> s_httpClient = new(() => new HttpClient());


internal static void ParseMap<T>(JsonElement node, T permissionsDocument, FixedFieldMap<T> handlers)
{
Expand Down Expand Up @@ -68,7 +65,7 @@ internal static Dictionary<string, string> GetMapOfString(JsonElement v)
foreach (var item in v.EnumerateObject())
{
var value = item.Value.GetString();
map.Add(item.Name, string.IsNullOrWhiteSpace(value) ? string.Empty : value);
map.Add(item.Name, string.IsNullOrWhiteSpace(value) ? string.Empty : value!);
}
return map;
}
Expand Down Expand Up @@ -136,18 +133,18 @@ internal static IEnumerable<KeyValuePair<string, string>> ParseKey(string key)
if (string.IsNullOrEmpty(pair))
continue;

var index = pair.IndexOf('=', StringComparison.OrdinalIgnoreCase);
var index = pair.IndexOf("=", StringComparison.OrdinalIgnoreCase);
if (index == -1)
throw new InvalidOperationException($"Unable to parse: {key}. Format is name1=value1;name2=value2;...");

var keyValue = new KeyValuePair<string, string>(pair[..index], pair[(index + 1)..]);
var keyValue = new KeyValuePair<string, string>(pair.Substring(0, index), pair.Substring(index + 1));
yield return keyValue;
}
}

internal static async Task<ReadResult> ParseOpenApiAsync(Uri openApiFileUri, bool inlineExternal, CancellationToken cancellationToken)
{
using var stream = await GetStreamAsync(openApiFileUri, cancellationToken: cancellationToken).ConfigureAwait(false);
using var stream = await GetStreamAsync(openApiFileUri).ConfigureAwait(false);
return await ParseOpenApiAsync(stream, openApiFileUri, inlineExternal, cancellationToken).ConfigureAwait(false);
}

Expand All @@ -163,13 +160,13 @@ internal static async Task<ReadResult> ParseOpenApiAsync(Stream stream, Uri open
return result;
}

internal static async Task<Stream> GetStreamAsync(Uri uri, CancellationToken cancellationToken = default)
internal static async Task<Stream> GetStreamAsync(Uri uri)
{
if (!uri.Scheme.StartsWith("http", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException($"The input {uri} is not a valid url", nameof(uri));
try
{
return await s_httpClient.Value.GetStreamAsync(uri, cancellationToken).ConfigureAwait(false);
return await s_httpClient.Value.GetStreamAsync(uri).ConfigureAwait(false);
}
catch (HttpRequestException ex)
{
Expand Down
10 changes: 8 additions & 2 deletions src/lib/Helpers/ValidationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,22 @@ internal static void ValidateEmail(string parameterName, string? value, string p
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException(parameterName, string.Format(CultureInfo.InvariantCulture, ErrorMessage.FieldIsRequired, parameterName, parentName));
else
ValidateEmail(parameterName, value);
ValidateEmail(parameterName, value!);
}

internal static void ValidateBaseUrl(string parameterName, string? baseUrl)
{
// Check if the baseUrl is a valid URL and ends in a slash.
if (string.IsNullOrWhiteSpace(baseUrl) || !baseUrl.EndsWith("/", StringComparison.Ordinal) || !Uri.TryCreate(baseUrl, UriKind.Absolute, out _))
if (string.IsNullOrWhiteSpace(baseUrl) || !baseUrl!.EndsWith("/", StringComparison.Ordinal) || !Uri.TryCreate(baseUrl, UriKind.Absolute, out _))
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessage.BaseUrlIsNotValid, nameof(baseUrl)), parameterName);
}

internal static void ThrowIfNull(object? obj, string? paramName = null)
{
if (obj == null)
throw new ArgumentNullException(paramName);
}

private static readonly Regex s_emailRegex = new(@"^[^@\s]+@[^@\s]+$", RegexOptions.Compiled, Constants.DefaultRegexTimeout);
private static void ValidateEmail(string parameterName, string value)
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenAI/Api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static Api Load(JsonElement value)

public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
Validate(this);
writer.WriteStartObject();
writer.WriteString(TypeProperty, Type);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenAI/Authentication/BaseManifestAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected void LoadProperties(JsonElement value)
/// <param name="writer">The <see cref="Utf8JsonWriter"/> to use.</param>
protected void WriteProperties(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteString(TypeProperty, Type);
if (!string.IsNullOrWhiteSpace(Instructions)) writer.WriteString(InstructionsProperty, Instructions);
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/OpenAI/Authentication/ManifestNoAuth.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.Helpers;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI.Authentication;
Expand All @@ -21,7 +22,7 @@ public static ManifestNoAuth Load(JsonElement value)

public override void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
WriteProperties(writer);
writer.WriteEndObject();
Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenAI/Authentication/ManifestOAuthAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static ManifestOAuthAuth Load(JsonElement value)

public override void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
WriteProperties(writer);
if (!string.IsNullOrWhiteSpace(ClientUrl)) writer.WriteString(ClientUrlPropertyName, ClientUrl);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenAI/Authentication/ManifestServiceHttpAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static ManifestServiceHttpAuth Load(JsonElement value)

public override void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
WriteProperties(writer);
writer.WriteString(AuthorizationTypeProperty, AuthorizationType);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/OpenAI/Authentication/ManifestUserHttpAuth.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.ApiManifest.Helpers;
using System.Text.Json;

namespace Microsoft.OpenApi.ApiManifest.OpenAI.Authentication;
Expand Down Expand Up @@ -30,7 +31,7 @@ public static ManifestUserHttpAuth Load(JsonElement value)

public override void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
WriteProperties(writer);
writer.WriteString(AuthorizationTypeProperty, AuthorizationType);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenAI/Authentication/VerificationTokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static VerificationTokens Load(JsonElement value)

public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();
foreach (var verificationToken in this)
{
Expand Down
6 changes: 3 additions & 3 deletions src/lib/OpenAI/OpenAIPluginManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static OpenAIPluginManifest Load(JsonElement value)
//Write method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
Validate(this);
writer.WriteStartObject();
writer.WriteString(SchemaVersionProperty, SchemaVersion);
Expand Down Expand Up @@ -138,8 +138,8 @@ private void Validate(OpenAIPluginManifest openAIPluginManifest)
ValidationHelpers.ValidateLength(nameof(DescriptionForModel), openAIPluginManifest.DescriptionForModel, 8000);

ValidationHelpers.ValidateNullOrWhitespace(nameof(SchemaVersion), openAIPluginManifest.SchemaVersion, nameof(OpenAIPluginManifest));
ArgumentNullException.ThrowIfNull(openAIPluginManifest.Auth);
ArgumentNullException.ThrowIfNull(openAIPluginManifest.Api);
ValidationHelpers.ThrowIfNull(openAIPluginManifest.Auth, "Auth");
ValidationHelpers.ThrowIfNull(openAIPluginManifest.Api, "Api");
ValidationHelpers.ValidateNullOrWhitespace(nameof(LogoUrl), openAIPluginManifest.LogoUrl, nameof(OpenAIPluginManifest));
ValidationHelpers.ValidateEmail(nameof(ContactEmail), openAIPluginManifest.ContactEmail, nameof(OpenAIPluginManifest));
ValidationHelpers.ValidateNullOrWhitespace(nameof(LegalInfoUrl), openAIPluginManifest.LegalInfoUrl, nameof(OpenAIPluginManifest));
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Publisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private Publisher(JsonElement value)
// Write method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
Validate();
writer.WriteStartObject();
writer.WriteString(NameProperty, Name);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/RequestInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class RequestInfo
// Write method
public void Write(Utf8JsonWriter writer)
{
ArgumentNullException.ThrowIfNull(writer);
ValidationHelpers.ThrowIfNull(writer, nameof(writer));
writer.WriteStartObject();

if (!String.IsNullOrWhiteSpace(Method)) writer.WriteString(MethodProperty, Method);
Expand Down
14 changes: 8 additions & 6 deletions src/lib/TypeExtensions/ApiManifestDocumentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static class ApiManifestDocumentExtensions
/// <returns>A <see cref="Task{OpenAIPluginManifest}"/></returns>
public static async Task<OpenAIPluginManifest> ToOpenAIPluginManifestAsync(this ApiManifestDocument apiManifestDocument, string logoUrl, string legalInfoUrl, string? apiDependencyName = default, string? openApiPath = default, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(apiManifestDocument);
ValidationHelpers.ThrowIfNull(apiManifestDocument, nameof(apiManifestDocument));
if (!TryGetApiDependency(apiManifestDocument.ApiDependencies, apiDependencyName, out ApiDependency? apiDependency))
{
throw new ApiManifestException(string.Format(CultureInfo.InvariantCulture, ErrorMessage.ApiDependencyNotFound, nameof(OpenAIPluginManifest)));
Expand All @@ -32,8 +32,10 @@ public static async Task<OpenAIPluginManifest> ToOpenAIPluginManifestAsync(this
}
else
{
var result = await ParsingHelpers.ParseOpenApiAsync(new Uri(apiDependency.ApiDescriptionUrl), false, cancellationToken).ConfigureAwait(false);
return apiManifestDocument.ToOpenAIPluginManifest(result.OpenApiDocument, logoUrl, legalInfoUrl, openApiPath ?? apiDependency.ApiDescriptionUrl);
var result = await ParsingHelpers.ParseOpenApiAsync(new Uri(apiDependency!.ApiDescriptionUrl), false, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(openApiPath))
openApiPath = apiDependency.ApiDescriptionUrl;
return apiManifestDocument.ToOpenAIPluginManifest(result.OpenApiDocument, logoUrl, legalInfoUrl, openApiPath!);
}
}

Expand All @@ -48,8 +50,8 @@ public static async Task<OpenAIPluginManifest> ToOpenAIPluginManifestAsync(this
/// <returns>A <see cref="OpenAIPluginManifest"/></returns>
public static OpenAIPluginManifest ToOpenAIPluginManifest(this ApiManifestDocument apiManifestDocument, OpenApiDocument openApiDocument, string logoUrl, string legalInfoUrl, string openApiPath)
{
ArgumentNullException.ThrowIfNull(apiManifestDocument);
ArgumentNullException.ThrowIfNull(openApiDocument);
ValidationHelpers.ThrowIfNull(apiManifestDocument, nameof(apiManifestDocument));
ValidationHelpers.ThrowIfNull(openApiDocument, nameof(openApiDocument));
// Validates the ApiManifestDocument before generating the OpenAI manifest. This includes the publisher object.
apiManifestDocument.Validate();
string contactEmail = apiManifestDocument.Publisher?.ContactEmail!;
Expand All @@ -75,7 +77,7 @@ private static bool TryGetApiDependency(ApiDependencies apiDependencies, string?
if (string.IsNullOrEmpty(apiDependencyName))
apiDependency = apiDependencies.FirstOrDefault().Value;
else
_ = apiDependencies.TryGetValue(apiDependencyName, out apiDependency);
_ = apiDependencies.TryGetValue(apiDependencyName!, out apiDependency);
return apiDependency != null;
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/lib/TypeExtensions/OpenApiDocumentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace Microsoft.OpenApi.ApiManifest.TypeExtensions
{
public static partial class OpenApiDocumentExtensions
{
[GeneratedRegex("[^a-zA-Z0-9]", RegexOptions.Compiled, 5000)]
private static partial Regex SpecialCharactersInApiNameRegex();
private static readonly Regex s_specialCharactersInApiNameRegex = new("[^a-zA-Z0-9]", RegexOptions.Compiled, TimeSpan.FromSeconds(5));
internal const string DefaultPublisherName = "publisher-name";
internal const string DefaultPublisherEmail = "[email protected]";

Expand All @@ -34,7 +33,7 @@ public static partial class OpenApiDocumentExtensions
/// <returns>An <see cref="ApiManifestDocument"/>.</returns>
public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, string? apiDescriptionUrl, string applicationName, string? apiDependencyName = default, string? publisherName = default, string? publisherEmail = default)
{
ArgumentNullException.ThrowIfNull(document);
ValidationHelpers.ThrowIfNull(document, nameof(document));
ValidationHelpers.ValidateNullOrWhitespace(nameof(apiDescriptionUrl), apiDescriptionUrl, nameof(ApiManifestDocument));
ValidationHelpers.ValidateNullOrWhitespace(nameof(applicationName), applicationName, nameof(ApiManifestDocument));

Expand All @@ -44,18 +43,18 @@ public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, s
if (string.IsNullOrEmpty(publisherEmail))
publisherEmail = document.Info.Contact?.Email is string cEmail && !string.IsNullOrEmpty(cEmail) ? cEmail : DefaultPublisherEmail;

apiDependencyName = NormalizeApiName(string.IsNullOrEmpty(apiDependencyName) ? document.Info.Title : apiDependencyName);
apiDependencyName = NormalizeApiName(string.IsNullOrEmpty(apiDependencyName) ? document.Info.Title : apiDependencyName!);
string? apiDeploymentBaseUrl = GetApiDeploymentBaseUrl(document.Servers.FirstOrDefault());

var apiManifest = new ApiManifestDocument(applicationName)
{
Publisher = new(publisherName, publisherEmail),
Publisher = new(publisherName!, publisherEmail!),
ApiDependencies = new() {
{
apiDependencyName, new() {
ApiDescriptionUrl = apiDescriptionUrl,
ApiDescriptionVersion = document.Info.Version,
ApiDeploymentBaseUrl = apiDeploymentBaseUrl,
ApiDeploymentBaseUrl = apiDeploymentBaseUrl
}
}
}
Expand All @@ -79,7 +78,7 @@ public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, s
private static string NormalizeApiName(string apiName)
{
// Normalize OpenAPI document title to API dependency name by removing all special characters from the provided api name.
return SpecialCharactersInApiNameRegex().Replace(apiName, string.Empty);
return s_specialCharactersInApiNameRegex.Replace(apiName, string.Empty);
}

private static string? GetApiDeploymentBaseUrl(OpenApiServer? server)
Expand Down
6 changes: 4 additions & 2 deletions src/lib/apimanifest.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Microsoft.OpenApi.ApiManifest</PackageId>
<VersionPrefix>0.5.3</VersionPrefix>
<VersionPrefix>0.5.4</VersionPrefix>
<VersionSuffix>preview</VersionSuffix>
<PackageIconUrl>http://go.microsoft.com/fwlink/?LinkID=288890</PackageIconUrl>
<PackageProjectUrl>https://github.com/Microsoft/OpenApi.ApiManifest</PackageProjectUrl>
Expand All @@ -13,6 +13,7 @@
<Company>Microsoft</Company>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageOutputPath>./../../artifacts</PackageOutputPath>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<SignAssembly>True</SignAssembly>
Expand All @@ -30,6 +31,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.11" />
<PackageReference Include="System.Text.Json" Version="8.0.0" />
peombwa marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

</Project>