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

releases 1.6.8 #1335

Merged
merged 11 commits into from
Sep 7, 2023
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageId>Microsoft.OpenApi.Hidi</PackageId>
<ToolCommandName>hidi</ToolCommandName>
<PackageOutputPath>./../../artifacts</PackageOutputPath>
<Version>1.2.8</Version>
<Version>1.2.9</Version>
<Description>OpenAPI.NET CLI tool for slicing OpenAPI documents</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down Expand Up @@ -43,8 +43,8 @@
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Microsoft.OData.Edm" Version="7.17.0" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.5.0-preview3" />
<PackageReference Include="Microsoft.OData.Edm" Version="7.18.0" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.5.0-preview4" />
<PackageReference Include="Microsoft.OpenApi.ApiManifest" Version="0.5.0-preview" />
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Company>Microsoft</Company>
<Title>Microsoft.OpenApi.Readers</Title>
<PackageId>Microsoft.OpenApi.Readers</PackageId>
<Version>1.6.7</Version>
<Version>1.6.8</Version>
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down
27 changes: 27 additions & 0 deletions src/Microsoft.OpenApi.Readers/OpenApiReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.MicrosoftExtensions;
using Microsoft.OpenApi.Readers.Interface;
using Microsoft.OpenApi.Validations;
using System;
Expand Down Expand Up @@ -74,5 +75,31 @@ public class OpenApiReaderSettings
/// from an <see cref="OpenApiStreamReader"/> object.
/// </summary>
public bool LeaveStreamOpen { get; set; }

/// <summary>
/// Adds parsers for Microsoft OpenAPI extensions:
/// - <see cref="OpenApiPagingExtension"/>
/// - <see cref="OpenApiEnumValuesDescriptionExtension"/>
/// - <see cref="OpenApiPrimaryErrorMessageExtension"/>
/// - <see cref="OpenApiDeprecationExtension"/>
/// - <see cref="OpenApiReservedParameterExtension"/>
/// - <see cref="OpenApiEnumFlagsExtension"/>
/// NOTE: The list of extensions is subject to change.
/// </summary>
public void AddMicrosoftExtensionParsers()
{
if (!ExtensionParsers.ContainsKey(OpenApiPagingExtension.Name))
ExtensionParsers.Add(OpenApiPagingExtension.Name, static (i, _) => OpenApiPagingExtension.Parse(i));
if (!ExtensionParsers.ContainsKey(OpenApiEnumValuesDescriptionExtension.Name))
ExtensionParsers.Add(OpenApiEnumValuesDescriptionExtension.Name, static (i, _ ) => OpenApiEnumValuesDescriptionExtension.Parse(i));
if (!ExtensionParsers.ContainsKey(OpenApiPrimaryErrorMessageExtension.Name))
ExtensionParsers.Add(OpenApiPrimaryErrorMessageExtension.Name, static (i, _ ) => OpenApiPrimaryErrorMessageExtension.Parse(i));
if (!ExtensionParsers.ContainsKey(OpenApiDeprecationExtension.Name))
ExtensionParsers.Add(OpenApiDeprecationExtension.Name, static (i, _ ) => OpenApiDeprecationExtension.Parse(i));
if (!ExtensionParsers.ContainsKey(OpenApiReservedParameterExtension.Name))
ExtensionParsers.Add(OpenApiReservedParameterExtension.Name, static (i, _ ) => OpenApiReservedParameterExtension.Parse(i));
if (!ExtensionParsers.ContainsKey(OpenApiEnumFlagsExtension.Name))
ExtensionParsers.Add(OpenApiEnumFlagsExtension.Name, static (i, _ ) => OpenApiEnumFlagsExtension.Parse(i));
}
}
}
2 changes: 2 additions & 0 deletions src/Microsoft.OpenApi/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ public static T GetEnumFromDisplayName<T>(this string displayName)

return default;
}
internal static string ToFirstCharacterLowerCase(this string input)
=> string.IsNullOrEmpty(input) ? string.Empty : char.ToLowerInvariant(input[0]) + input.Substring(1);
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Company>Microsoft</Company>
<Title>Microsoft.OpenApi</Title>
<PackageId>Microsoft.OpenApi</PackageId>
<Version>1.6.7</Version>
<Version>1.6.8</Version>
<Description>.NET models with JSON and YAML writers for OpenAPI specification</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------

using System;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.MicrosoftExtensions;

/// <summary>
/// Extension element for OpenAPI to add deprecation information. x-ms-deprecation
/// </summary>
public class OpenApiDeprecationExtension : IOpenApiExtension
{
/// <summary>
/// Name of the extension as used in the description.
/// </summary>
public static string Name => "x-ms-deprecation";
/// <summary>
/// The date at which the element has been/will be removed entirely from the service.
/// </summary>
public DateTimeOffset? RemovalDate
{
get; set;
}
/// <summary>
/// The date at which the element has been/will be deprecated.
/// </summary>
public DateTimeOffset? Date
{
get; set;
}
/// <summary>
/// The version this revision was introduced.
/// </summary>
public string Version
{
get; set;
} = string.Empty;
/// <summary>
/// The description of the revision.
/// </summary>
public string Description
{
get; set;
} = string.Empty;
/// <inheritdoc />
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
{
if (writer == null)
throw new ArgumentNullException(nameof(writer));

if (RemovalDate.HasValue || Date.HasValue || !string.IsNullOrEmpty(Version) || !string.IsNullOrEmpty(Description))
{
writer.WriteStartObject();

if (RemovalDate.HasValue)
writer.WriteProperty(nameof(RemovalDate).ToFirstCharacterLowerCase(), RemovalDate.Value);
if (Date.HasValue)
writer.WriteProperty(nameof(Date).ToFirstCharacterLowerCase(), Date.Value);
if (!string.IsNullOrEmpty(Version))
writer.WriteProperty(nameof(Version).ToFirstCharacterLowerCase(), Version);
if (!string.IsNullOrEmpty(Description))
writer.WriteProperty(nameof(Description).ToFirstCharacterLowerCase(), Description);

writer.WriteEndObject();
}
}
/// <summary>
/// Parses the <see cref="IOpenApiAny"/> to <see cref="OpenApiDeprecationExtension"/>.
/// </summary>
/// <param name="source">The source object.</param>
/// <returns>The <see cref="OpenApiDeprecationExtension"/>.</returns>
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
public static OpenApiDeprecationExtension Parse(IOpenApiAny source)
{
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
var extension = new OpenApiDeprecationExtension();
if (rawObject.TryGetValue(nameof(RemovalDate).ToFirstCharacterLowerCase(), out var removalDate) && removalDate is OpenApiDateTime removalDateValue)
extension.RemovalDate = removalDateValue.Value;
if (rawObject.TryGetValue(nameof(Date).ToFirstCharacterLowerCase(), out var date) && date is OpenApiDateTime dateValue)
extension.Date = dateValue.Value;
if (rawObject.TryGetValue(nameof(Version).ToFirstCharacterLowerCase(), out var version) && version is OpenApiString versionValue)
extension.Version = versionValue.Value;
if (rawObject.TryGetValue(nameof(Description).ToFirstCharacterLowerCase(), out var description) && description is OpenApiString descriptionValue)
extension.Description = descriptionValue.Value;
return extension;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------

using System;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.MicrosoftExtensions;

/// <summary>
/// Extension element for OpenAPI to add deprecation information. x-ms-enum-flags
/// </summary>
public class OpenApiEnumFlagsExtension : IOpenApiExtension
{
/// <summary>
/// Name of the extension as used in the description.
/// </summary>
public static string Name => "x-ms-enum-flags";
/// <summary>
/// Whether the enum is a flagged enum.
/// </summary>
public bool IsFlags
{
get; set;
}
/// <inheritdoc />
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
{
if (writer == null)
throw new ArgumentNullException(nameof(writer));

writer.WriteStartObject();
writer.WriteProperty(nameof(IsFlags).ToFirstCharacterLowerCase(), IsFlags);
writer.WriteEndObject();
}
/// <summary>
/// Parse the extension from the raw IOpenApiAny object.
/// </summary>
/// <param name="source">The source element to parse.</param>
/// <returns>The <see cref="OpenApiEnumFlagsExtension"/>.</returns>
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
public static OpenApiEnumFlagsExtension Parse(IOpenApiAny source)
{
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
var extension = new OpenApiEnumFlagsExtension();
if (rawObject.TryGetValue(nameof(IsFlags).ToFirstCharacterLowerCase(), out var flagsValue) && flagsValue is OpenApiBoolean isFlags)
{
extension.IsFlags = isFlags.Value;
}
return extension;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.MicrosoftExtensions;

/// <summary>
/// Extension element for OpenAPI to add enum values descriptions.
/// Based of the AutoRest specification https://github.com/Azure/autorest/blob/main/docs/extensions/readme.md#x-ms-enum
/// </summary>
public class OpenApiEnumValuesDescriptionExtension : IOpenApiExtension
{
/// <summary>
/// Name of the extension as used in the description.
/// </summary>
public static string Name => "x-ms-enum";

/// <summary>
/// The of the enum.
/// </summary>
public string EnumName { get; set; } = string.Empty;

/// <summary>
/// Descriptions for the enum symbols, where the value MUST match the enum symbols in the main description
/// </summary>
public List<EnumDescription> ValuesDescriptions { get; set; } = new();

/// <inheritdoc />
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
{
if (writer is null) throw new ArgumentNullException(nameof(writer));
if ((specVersion == OpenApiSpecVersion.OpenApi2_0 || specVersion == OpenApiSpecVersion.OpenApi3_0) &&
!string.IsNullOrEmpty(EnumName) &&
ValuesDescriptions.Any())
{ // when we upgrade to 3.1, we don't need to write this extension as JSON schema will support writing enum values
writer.WriteStartObject();
writer.WriteProperty(nameof(Name).ToFirstCharacterLowerCase(), EnumName);
writer.WriteProperty("modelAsString", false);
writer.WriteRequiredCollection("values", ValuesDescriptions, (w, x) =>
{
w.WriteStartObject();
w.WriteProperty(nameof(x.Value).ToFirstCharacterLowerCase(), x.Value);
w.WriteProperty(nameof(x.Description).ToFirstCharacterLowerCase(), x.Description);
w.WriteProperty(nameof(x.Name).ToFirstCharacterLowerCase(), x.Name);
w.WriteEndObject();
});
writer.WriteEndObject();
}
}
/// <summary>
/// Parse the extension from the raw IOpenApiAny object.
/// </summary>
/// <param name="source">The source element to parse.</param>
/// <returns>The <see cref="OpenApiEnumValuesDescriptionExtension"/>.</returns>
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
public static OpenApiEnumValuesDescriptionExtension Parse(IOpenApiAny source)
{
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
var extension = new OpenApiEnumValuesDescriptionExtension();
if (rawObject.TryGetValue("values", out var values) && values is OpenApiArray valuesArray)
{
extension.ValuesDescriptions.AddRange(valuesArray
.OfType<OpenApiObject>()
.Select(x => new EnumDescription(x)));
}
return extension;
}
}

/// <summary>
/// Description of an enum symbol
/// </summary>
public class EnumDescription : IOpenApiElement
{
/// <summary>
/// Default constructor
/// </summary>
public EnumDescription()
{

}
/// <summary>
/// Constructor from a raw OpenApiObject
/// </summary>
/// <param name="source">The source object</param>
public EnumDescription(OpenApiObject source)
{
if (source is null) throw new ArgumentNullException(nameof(source));
if (source.TryGetValue(nameof(Value).ToFirstCharacterLowerCase(), out var rawValue) && rawValue is OpenApiString value)
Value = value.Value;
if (source.TryGetValue(nameof(Description).ToFirstCharacterLowerCase(), out var rawDescription) && rawDescription is OpenApiString description)
Description = description.Value;
if (source.TryGetValue(nameof(Name).ToFirstCharacterLowerCase(), out var rawName) && rawName is OpenApiString name)
Name = name.Value;
}
/// <summary>
/// The description for the enum symbol
/// </summary>
public string Description { get; set; } = string.Empty;
/// <summary>
/// The symbol for the enum symbol to use for code-generation
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// The symbol as described in the main enum schema.
/// </summary>
public string Value { get; set; } = string.Empty;
}
Loading