Skip to content

Commit acd7652

Browse files
authored
Merge pull request #1335 from microsoft/vnext
releases 1.6.8
2 parents 1a39857 + ab78dee commit acd7652

18 files changed

+995
-5
lines changed

src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<PackageId>Microsoft.OpenApi.Hidi</PackageId>
1616
<ToolCommandName>hidi</ToolCommandName>
1717
<PackageOutputPath>./../../artifacts</PackageOutputPath>
18-
<Version>1.2.8</Version>
18+
<Version>1.2.9</Version>
1919
<Description>OpenAPI.NET CLI tool for slicing OpenAPI documents</Description>
2020
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
2121
<PackageTags>OpenAPI .NET</PackageTags>
@@ -43,8 +43,8 @@
4343
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
4444
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
4545
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
46-
<PackageReference Include="Microsoft.OData.Edm" Version="7.17.0" />
47-
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.5.0-preview3" />
46+
<PackageReference Include="Microsoft.OData.Edm" Version="7.18.0" />
47+
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.5.0-preview4" />
4848
<PackageReference Include="Microsoft.OpenApi.ApiManifest" Version="0.5.0-preview" />
4949
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
5050
</ItemGroup>

src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<Company>Microsoft</Company>
1212
<Title>Microsoft.OpenApi.Readers</Title>
1313
<PackageId>Microsoft.OpenApi.Readers</PackageId>
14-
<Version>1.6.7</Version>
14+
<Version>1.6.8</Version>
1515
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
1616
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1717
<PackageTags>OpenAPI .NET</PackageTags>

src/Microsoft.OpenApi.Readers/OpenApiReaderSettings.cs

+27
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Microsoft.OpenApi.Any;
55
using Microsoft.OpenApi.Interfaces;
6+
using Microsoft.OpenApi.MicrosoftExtensions;
67
using Microsoft.OpenApi.Readers.Interface;
78
using Microsoft.OpenApi.Validations;
89
using System;
@@ -74,5 +75,31 @@ public class OpenApiReaderSettings
7475
/// from an <see cref="OpenApiStreamReader"/> object.
7576
/// </summary>
7677
public bool LeaveStreamOpen { get; set; }
78+
79+
/// <summary>
80+
/// Adds parsers for Microsoft OpenAPI extensions:
81+
/// - <see cref="OpenApiPagingExtension"/>
82+
/// - <see cref="OpenApiEnumValuesDescriptionExtension"/>
83+
/// - <see cref="OpenApiPrimaryErrorMessageExtension"/>
84+
/// - <see cref="OpenApiDeprecationExtension"/>
85+
/// - <see cref="OpenApiReservedParameterExtension"/>
86+
/// - <see cref="OpenApiEnumFlagsExtension"/>
87+
/// NOTE: The list of extensions is subject to change.
88+
/// </summary>
89+
public void AddMicrosoftExtensionParsers()
90+
{
91+
if (!ExtensionParsers.ContainsKey(OpenApiPagingExtension.Name))
92+
ExtensionParsers.Add(OpenApiPagingExtension.Name, static (i, _) => OpenApiPagingExtension.Parse(i));
93+
if (!ExtensionParsers.ContainsKey(OpenApiEnumValuesDescriptionExtension.Name))
94+
ExtensionParsers.Add(OpenApiEnumValuesDescriptionExtension.Name, static (i, _ ) => OpenApiEnumValuesDescriptionExtension.Parse(i));
95+
if (!ExtensionParsers.ContainsKey(OpenApiPrimaryErrorMessageExtension.Name))
96+
ExtensionParsers.Add(OpenApiPrimaryErrorMessageExtension.Name, static (i, _ ) => OpenApiPrimaryErrorMessageExtension.Parse(i));
97+
if (!ExtensionParsers.ContainsKey(OpenApiDeprecationExtension.Name))
98+
ExtensionParsers.Add(OpenApiDeprecationExtension.Name, static (i, _ ) => OpenApiDeprecationExtension.Parse(i));
99+
if (!ExtensionParsers.ContainsKey(OpenApiReservedParameterExtension.Name))
100+
ExtensionParsers.Add(OpenApiReservedParameterExtension.Name, static (i, _ ) => OpenApiReservedParameterExtension.Parse(i));
101+
if (!ExtensionParsers.ContainsKey(OpenApiEnumFlagsExtension.Name))
102+
ExtensionParsers.Add(OpenApiEnumFlagsExtension.Name, static (i, _ ) => OpenApiEnumFlagsExtension.Parse(i));
103+
}
77104
}
78105
}

src/Microsoft.OpenApi/Extensions/StringExtensions.cs

+2
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,7 @@ public static T GetEnumFromDisplayName<T>(this string displayName)
3737

3838
return default;
3939
}
40+
internal static string ToFirstCharacterLowerCase(this string input)
41+
=> string.IsNullOrEmpty(input) ? string.Empty : char.ToLowerInvariant(input[0]) + input.Substring(1);
4042
}
4143
}

src/Microsoft.OpenApi/Microsoft.OpenApi.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<Company>Microsoft</Company>
1212
<Title>Microsoft.OpenApi</Title>
1313
<PackageId>Microsoft.OpenApi</PackageId>
14-
<Version>1.6.7</Version>
14+
<Version>1.6.8</Version>
1515
<Description>.NET models with JSON and YAML writers for OpenAPI specification</Description>
1616
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1717
<PackageTags>OpenAPI .NET</PackageTags>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System;
7+
using Microsoft.OpenApi.Extensions;
8+
using Microsoft.OpenApi.Any;
9+
using Microsoft.OpenApi.Interfaces;
10+
using Microsoft.OpenApi.Writers;
11+
12+
namespace Microsoft.OpenApi.MicrosoftExtensions;
13+
14+
/// <summary>
15+
/// Extension element for OpenAPI to add deprecation information. x-ms-deprecation
16+
/// </summary>
17+
public class OpenApiDeprecationExtension : IOpenApiExtension
18+
{
19+
/// <summary>
20+
/// Name of the extension as used in the description.
21+
/// </summary>
22+
public static string Name => "x-ms-deprecation";
23+
/// <summary>
24+
/// The date at which the element has been/will be removed entirely from the service.
25+
/// </summary>
26+
public DateTimeOffset? RemovalDate
27+
{
28+
get; set;
29+
}
30+
/// <summary>
31+
/// The date at which the element has been/will be deprecated.
32+
/// </summary>
33+
public DateTimeOffset? Date
34+
{
35+
get; set;
36+
}
37+
/// <summary>
38+
/// The version this revision was introduced.
39+
/// </summary>
40+
public string Version
41+
{
42+
get; set;
43+
} = string.Empty;
44+
/// <summary>
45+
/// The description of the revision.
46+
/// </summary>
47+
public string Description
48+
{
49+
get; set;
50+
} = string.Empty;
51+
/// <inheritdoc />
52+
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
53+
{
54+
if (writer == null)
55+
throw new ArgumentNullException(nameof(writer));
56+
57+
if (RemovalDate.HasValue || Date.HasValue || !string.IsNullOrEmpty(Version) || !string.IsNullOrEmpty(Description))
58+
{
59+
writer.WriteStartObject();
60+
61+
if (RemovalDate.HasValue)
62+
writer.WriteProperty(nameof(RemovalDate).ToFirstCharacterLowerCase(), RemovalDate.Value);
63+
if (Date.HasValue)
64+
writer.WriteProperty(nameof(Date).ToFirstCharacterLowerCase(), Date.Value);
65+
if (!string.IsNullOrEmpty(Version))
66+
writer.WriteProperty(nameof(Version).ToFirstCharacterLowerCase(), Version);
67+
if (!string.IsNullOrEmpty(Description))
68+
writer.WriteProperty(nameof(Description).ToFirstCharacterLowerCase(), Description);
69+
70+
writer.WriteEndObject();
71+
}
72+
}
73+
/// <summary>
74+
/// Parses the <see cref="IOpenApiAny"/> to <see cref="OpenApiDeprecationExtension"/>.
75+
/// </summary>
76+
/// <param name="source">The source object.</param>
77+
/// <returns>The <see cref="OpenApiDeprecationExtension"/>.</returns>
78+
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
79+
public static OpenApiDeprecationExtension Parse(IOpenApiAny source)
80+
{
81+
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
82+
var extension = new OpenApiDeprecationExtension();
83+
if (rawObject.TryGetValue(nameof(RemovalDate).ToFirstCharacterLowerCase(), out var removalDate) && removalDate is OpenApiDateTime removalDateValue)
84+
extension.RemovalDate = removalDateValue.Value;
85+
if (rawObject.TryGetValue(nameof(Date).ToFirstCharacterLowerCase(), out var date) && date is OpenApiDateTime dateValue)
86+
extension.Date = dateValue.Value;
87+
if (rawObject.TryGetValue(nameof(Version).ToFirstCharacterLowerCase(), out var version) && version is OpenApiString versionValue)
88+
extension.Version = versionValue.Value;
89+
if (rawObject.TryGetValue(nameof(Description).ToFirstCharacterLowerCase(), out var description) && description is OpenApiString descriptionValue)
90+
extension.Description = descriptionValue.Value;
91+
return extension;
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System;
7+
using Microsoft.OpenApi.Extensions;
8+
using Microsoft.OpenApi.Any;
9+
using Microsoft.OpenApi.Interfaces;
10+
using Microsoft.OpenApi.Writers;
11+
12+
namespace Microsoft.OpenApi.MicrosoftExtensions;
13+
14+
/// <summary>
15+
/// Extension element for OpenAPI to add deprecation information. x-ms-enum-flags
16+
/// </summary>
17+
public class OpenApiEnumFlagsExtension : IOpenApiExtension
18+
{
19+
/// <summary>
20+
/// Name of the extension as used in the description.
21+
/// </summary>
22+
public static string Name => "x-ms-enum-flags";
23+
/// <summary>
24+
/// Whether the enum is a flagged enum.
25+
/// </summary>
26+
public bool IsFlags
27+
{
28+
get; set;
29+
}
30+
/// <inheritdoc />
31+
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
32+
{
33+
if (writer == null)
34+
throw new ArgumentNullException(nameof(writer));
35+
36+
writer.WriteStartObject();
37+
writer.WriteProperty(nameof(IsFlags).ToFirstCharacterLowerCase(), IsFlags);
38+
writer.WriteEndObject();
39+
}
40+
/// <summary>
41+
/// Parse the extension from the raw IOpenApiAny object.
42+
/// </summary>
43+
/// <param name="source">The source element to parse.</param>
44+
/// <returns>The <see cref="OpenApiEnumFlagsExtension"/>.</returns>
45+
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
46+
public static OpenApiEnumFlagsExtension Parse(IOpenApiAny source)
47+
{
48+
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
49+
var extension = new OpenApiEnumFlagsExtension();
50+
if (rawObject.TryGetValue(nameof(IsFlags).ToFirstCharacterLowerCase(), out var flagsValue) && flagsValue is OpenApiBoolean isFlags)
51+
{
52+
extension.IsFlags = isFlags.Value;
53+
}
54+
return extension;
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using Microsoft.OpenApi.Extensions;
10+
using Microsoft.OpenApi.Any;
11+
using Microsoft.OpenApi.Interfaces;
12+
using Microsoft.OpenApi.Writers;
13+
14+
namespace Microsoft.OpenApi.MicrosoftExtensions;
15+
16+
/// <summary>
17+
/// Extension element for OpenAPI to add enum values descriptions.
18+
/// Based of the AutoRest specification https://github.com/Azure/autorest/blob/main/docs/extensions/readme.md#x-ms-enum
19+
/// </summary>
20+
public class OpenApiEnumValuesDescriptionExtension : IOpenApiExtension
21+
{
22+
/// <summary>
23+
/// Name of the extension as used in the description.
24+
/// </summary>
25+
public static string Name => "x-ms-enum";
26+
27+
/// <summary>
28+
/// The of the enum.
29+
/// </summary>
30+
public string EnumName { get; set; } = string.Empty;
31+
32+
/// <summary>
33+
/// Descriptions for the enum symbols, where the value MUST match the enum symbols in the main description
34+
/// </summary>
35+
public List<EnumDescription> ValuesDescriptions { get; set; } = new();
36+
37+
/// <inheritdoc />
38+
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
39+
{
40+
if (writer is null) throw new ArgumentNullException(nameof(writer));
41+
if ((specVersion == OpenApiSpecVersion.OpenApi2_0 || specVersion == OpenApiSpecVersion.OpenApi3_0) &&
42+
!string.IsNullOrEmpty(EnumName) &&
43+
ValuesDescriptions.Any())
44+
{ // when we upgrade to 3.1, we don't need to write this extension as JSON schema will support writing enum values
45+
writer.WriteStartObject();
46+
writer.WriteProperty(nameof(Name).ToFirstCharacterLowerCase(), EnumName);
47+
writer.WriteProperty("modelAsString", false);
48+
writer.WriteRequiredCollection("values", ValuesDescriptions, (w, x) =>
49+
{
50+
w.WriteStartObject();
51+
w.WriteProperty(nameof(x.Value).ToFirstCharacterLowerCase(), x.Value);
52+
w.WriteProperty(nameof(x.Description).ToFirstCharacterLowerCase(), x.Description);
53+
w.WriteProperty(nameof(x.Name).ToFirstCharacterLowerCase(), x.Name);
54+
w.WriteEndObject();
55+
});
56+
writer.WriteEndObject();
57+
}
58+
}
59+
/// <summary>
60+
/// Parse the extension from the raw IOpenApiAny object.
61+
/// </summary>
62+
/// <param name="source">The source element to parse.</param>
63+
/// <returns>The <see cref="OpenApiEnumValuesDescriptionExtension"/>.</returns>
64+
/// <exception cref="ArgumentOutOfRangeException">When the source element is not an object</exception>
65+
public static OpenApiEnumValuesDescriptionExtension Parse(IOpenApiAny source)
66+
{
67+
if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
68+
var extension = new OpenApiEnumValuesDescriptionExtension();
69+
if (rawObject.TryGetValue("values", out var values) && values is OpenApiArray valuesArray)
70+
{
71+
extension.ValuesDescriptions.AddRange(valuesArray
72+
.OfType<OpenApiObject>()
73+
.Select(x => new EnumDescription(x)));
74+
}
75+
return extension;
76+
}
77+
}
78+
79+
/// <summary>
80+
/// Description of an enum symbol
81+
/// </summary>
82+
public class EnumDescription : IOpenApiElement
83+
{
84+
/// <summary>
85+
/// Default constructor
86+
/// </summary>
87+
public EnumDescription()
88+
{
89+
90+
}
91+
/// <summary>
92+
/// Constructor from a raw OpenApiObject
93+
/// </summary>
94+
/// <param name="source">The source object</param>
95+
public EnumDescription(OpenApiObject source)
96+
{
97+
if (source is null) throw new ArgumentNullException(nameof(source));
98+
if (source.TryGetValue(nameof(Value).ToFirstCharacterLowerCase(), out var rawValue) && rawValue is OpenApiString value)
99+
Value = value.Value;
100+
if (source.TryGetValue(nameof(Description).ToFirstCharacterLowerCase(), out var rawDescription) && rawDescription is OpenApiString description)
101+
Description = description.Value;
102+
if (source.TryGetValue(nameof(Name).ToFirstCharacterLowerCase(), out var rawName) && rawName is OpenApiString name)
103+
Name = name.Value;
104+
}
105+
/// <summary>
106+
/// The description for the enum symbol
107+
/// </summary>
108+
public string Description { get; set; } = string.Empty;
109+
/// <summary>
110+
/// The symbol for the enum symbol to use for code-generation
111+
/// </summary>
112+
public string Name { get; set; } = string.Empty;
113+
/// <summary>
114+
/// The symbol as described in the main enum schema.
115+
/// </summary>
116+
public string Value { get; set; } = string.Empty;
117+
}

0 commit comments

Comments
 (0)