Skip to content

Commit 9465b8a

Browse files
committed
Merge branch 'feature/3-0-4' into feature/3.1.1
2 parents ad1bdec + a4ac872 commit 9465b8a

File tree

72 files changed

+1242
-949
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1242
-949
lines changed

src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ private static IList<OpenApiParameter> ResolveFunctionParameters(IList<OpenApiPa
166166
parameter.Content = null;
167167
parameter.Schema = new()
168168
{
169-
Type = "array",
169+
Type = JsonSchemaType.Array,
170170
Items = new()
171171
{
172-
Type = "string"
172+
Type = JsonSchemaType.String
173173
}
174174
};
175175
}
@@ -178,9 +178,9 @@ private static IList<OpenApiParameter> ResolveFunctionParameters(IList<OpenApiPa
178178

179179
private void AddAdditionalPropertiesToSchema(OpenApiSchema schema)
180180
{
181-
if (schema != null && !_schemaLoop.Contains(schema) && "object".Equals((string)schema.Type, StringComparison.OrdinalIgnoreCase))
181+
if (schema != null && !_schemaLoop.Contains(schema) && schema.Type.Equals(JsonSchemaType.Object))
182182
{
183-
schema.AdditionalProperties = new() { Type = "object" };
183+
schema.AdditionalProperties = new() { Type = JsonSchemaType.Object };
184184

185185
/* Because 'additionalProperties' are now being walked,
186186
* we need a way to keep track of visited schemas to avoid

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<Nullable>enable</Nullable>
1010
<ToolCommandName>hidi</ToolCommandName>
1111
<PackageOutputPath>./../../artifacts</PackageOutputPath>
12-
<Version>1.4.13</Version>
12+
<Version>1.4.15</Version>
1313
<Description>OpenAPI.NET CLI tool for slicing OpenAPI documents</Description>
1414
<SignAssembly>true</SignAssembly>
1515
<!-- https://github.com/dotnet/sourcelink/blob/main/docs/README.md#embeduntrackedsources -->
@@ -38,8 +38,8 @@
3838
<PrivateAssets>all</PrivateAssets>
3939
</PackageReference>
4040
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
41-
<PackageReference Include="Microsoft.OData.Edm" Version="8.1.0" />
42-
<PackageReference Include="Microsoft.OpenApi.OData" Version="2.0.0-preview.6" />
41+
<PackageReference Include="Microsoft.OData.Edm" Version="8.2.0" />
42+
<PackageReference Include="Microsoft.OpenApi.OData" Version="2.0.0-preview.7" />
4343
<PackageReference Include="Microsoft.OpenApi.ApiManifest" Version="0.5.0-preview" />
4444
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
4545
<!--STJ

src/Microsoft.OpenApi.Hidi/OpenApiService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog
7777
throw new IOException($"The file {options.Output} already exists. Please input a new file path.");
7878
}
7979

80-
// Default to yaml and OpenApiVersion 3 during csdl to OpenApi conversion
80+
// Default to yaml and OpenApiVersion 3_1 during csdl to OpenApi conversion
8181
var openApiFormat = options.OpenApiFormat ?? (!string.IsNullOrEmpty(options.OpenApi) ? GetOpenApiFormat(options.OpenApi, logger) : OpenApiFormat.Yaml);
8282
var openApiVersion = options.Version != null ? TryParseOpenApiSpecVersion(options.Version) : OpenApiSpecVersion.OpenApi3_1;
8383

src/Microsoft.OpenApi.Workbench/MainModel.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.OpenApi.Extensions;
1212
using Microsoft.OpenApi.Models;
1313
using Microsoft.OpenApi.Reader;
14+
using Microsoft.OpenApi.Readers;
1415
using Microsoft.OpenApi.Services;
1516
using Microsoft.OpenApi.Validations;
1617

@@ -158,6 +159,7 @@ public OpenApiSpecVersion Version
158159
_version = value;
159160
OnPropertyChanged(nameof(IsV2_0));
160161
OnPropertyChanged(nameof(IsV3_0));
162+
OnPropertyChanged(nameof(IsV3_1));
161163
}
162164
}
163165

@@ -185,6 +187,12 @@ public bool IsV3_0
185187
set => Version = OpenApiSpecVersion.OpenApi3_0;
186188
}
187189

190+
public bool IsV3_1
191+
{
192+
get => Version == OpenApiSpecVersion.OpenApi3_1;
193+
set => Version = OpenApiSpecVersion.OpenApi3_1;
194+
}
195+
188196
/// <summary>
189197
/// Handling method when the property with given name has changed.
190198
/// </summary>
@@ -203,6 +211,9 @@ protected void OnPropertyChanged(string propertyName)
203211
/// </summary>
204212
internal async Task ParseDocumentAsync()
205213
{
214+
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader());
215+
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader());
216+
206217
Stream stream = null;
207218
try
208219
{

src/Microsoft.OpenApi.Workbench/MainWindow.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
</StackPanel>
4141
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
4242
<Label>Version:</Label>
43+
<RadioButton GroupName="Format" Content="V3.1.0" Padding="5" Height="24" VerticalAlignment="Top" IsChecked="{Binding IsV3_1}" />
4344
<RadioButton GroupName="Format" Content="V3.0.4" Padding="5" Height="24" VerticalAlignment="Top" IsChecked="{Binding IsV3_0}" />
4445
<RadioButton GroupName="Format" Content="V2.0" Padding="5" Height="24" VerticalAlignment="Top" IsChecked="{Binding IsV2_0}" />
4546
</StackPanel>

src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using Microsoft.OpenApi.Exceptions;
67
using Microsoft.OpenApi.Models;
78

89
namespace Microsoft.OpenApi.Extensions
@@ -12,40 +13,81 @@ namespace Microsoft.OpenApi.Extensions
1213
/// </summary>
1314
public static class OpenApiTypeMapper
1415
{
16+
/// <summary>
17+
/// Maps a JsonSchema data type to an identifier.
18+
/// </summary>
19+
/// <param name="schemaType"></param>
20+
/// <returns></returns>
21+
public static string ToIdentifier(this JsonSchemaType? schemaType)
22+
{
23+
return schemaType switch
24+
{
25+
JsonSchemaType.Null => "null",
26+
JsonSchemaType.Boolean => "boolean",
27+
JsonSchemaType.Integer => "integer",
28+
JsonSchemaType.Number => "number",
29+
JsonSchemaType.String => "string",
30+
JsonSchemaType.Array => "array",
31+
JsonSchemaType.Object => "object",
32+
_ => null,
33+
};
34+
}
35+
36+
/// <summary>
37+
/// Converts a schema type's identifier into the enum equivalent
38+
/// </summary>
39+
/// <param name="identifier"></param>
40+
/// <returns></returns>
41+
public static JsonSchemaType ToJsonSchemaType(this string identifier)
42+
{
43+
return identifier switch
44+
{
45+
"null" => JsonSchemaType.Null,
46+
"boolean" => JsonSchemaType.Boolean,
47+
"integer" or "int" => JsonSchemaType.Integer,
48+
"number" or "double" or "float" or "decimal"=> JsonSchemaType.Number,
49+
"string" => JsonSchemaType.String,
50+
"array" => JsonSchemaType.Array,
51+
"object" => JsonSchemaType.Object,
52+
"file" => JsonSchemaType.String, // File is treated as string
53+
_ => throw new OpenApiException(string.Format("Invalid schema type identifier: {0}", identifier))
54+
};
55+
}
56+
1557
private static readonly Dictionary<Type, Func<OpenApiSchema>> _simpleTypeToOpenApiSchema = new()
1658
{
17-
[typeof(bool)] = () => new() { Type = "boolean" },
18-
[typeof(byte)] = () => new() { Type = "string", Format = "byte" },
19-
[typeof(int)] = () => new() { Type = "number", Format = "int32" },
20-
[typeof(uint)] = () => new() { Type = "number", Format = "int32" },
21-
[typeof(long)] = () => new() { Type = "number", Format = "int64" },
22-
[typeof(ulong)] = () => new() { Type = "number", Format = "int64" },
23-
[typeof(float)] = () => new() { Type = "number", Format = "float" },
24-
[typeof(double)] = () => new() { Type = "number", Format = "double" },
25-
[typeof(decimal)] = () => new() { Type = "number", Format = "double" },
26-
[typeof(DateTime)] = () => new() { Type = "string", Format = "date-time" },
27-
[typeof(DateTimeOffset)] = () => new() { Type = "string", Format = "date-time" },
28-
[typeof(Guid)] = () => new() { Type = "string", Format = "uuid" },
29-
[typeof(char)] = () => new() { Type = "string" },
59+
[typeof(bool)] = () => new() { Type = JsonSchemaType.Boolean },
60+
[typeof(byte)] = () => new() { Type = JsonSchemaType.String, Format = "byte" },
61+
[typeof(int)] = () => new() { Type = JsonSchemaType.Integer, Format = "int32" },
62+
[typeof(uint)] = () => new() { Type = JsonSchemaType.Integer, Format = "int32" },
63+
[typeof(long)] = () => new() { Type = JsonSchemaType.Integer, Format = "int64" },
64+
[typeof(ulong)] = () => new() { Type = JsonSchemaType.Integer, Format = "int64" },
65+
[typeof(float)] = () => new() { Type = JsonSchemaType.Number, Format = "float" },
66+
[typeof(double)] = () => new() { Type = JsonSchemaType.Number, Format = "double" },
67+
[typeof(decimal)] = () => new() { Type = JsonSchemaType.Number, Format = "double" },
68+
[typeof(DateTime)] = () => new() { Type = JsonSchemaType.String, Format = "date-time" },
69+
[typeof(DateTimeOffset)] = () => new() { Type = JsonSchemaType.String, Format = "date-time" },
70+
[typeof(Guid)] = () => new() { Type = JsonSchemaType.String, Format = "uuid" },
71+
[typeof(char)] = () => new() { Type = JsonSchemaType.String },
3072

3173
// Nullable types
32-
[typeof(bool?)] = () => new() { Type = "boolean", Nullable = true },
33-
[typeof(byte?)] = () => new() { Type = "string", Format = "byte", Nullable = true },
34-
[typeof(int?)] = () => new() { Type = "number", Format = "int32", Nullable = true },
35-
[typeof(uint?)] = () => new() { Type = "number", Format = "int32", Nullable = true },
36-
[typeof(long?)] = () => new() { Type = "number", Format = "int64", Nullable = true },
37-
[typeof(ulong?)] = () => new() { Type = "number", Format = "int64", Nullable = true },
38-
[typeof(float?)] = () => new() { Type = "number", Format = "float", Nullable = true },
39-
[typeof(double?)] = () => new() { Type = "number", Format = "double", Nullable = true },
40-
[typeof(decimal?)] = () => new() { Type = "number", Format = "double", Nullable = true },
41-
[typeof(DateTime?)] = () => new() { Type = "string", Format = "date-time", Nullable = true },
42-
[typeof(DateTimeOffset?)] = () => new() { Type = "string", Format = "date-time", Nullable = true },
43-
[typeof(Guid?)] = () => new() { Type = "string", Format = "uuid", Nullable = true },
44-
[typeof(char?)] = () => new() { Type = "string", Nullable = true },
74+
[typeof(bool?)] = () => new() { Type = JsonSchemaType.Boolean, Nullable = true },
75+
[typeof(byte?)] = () => new() { Type = JsonSchemaType.String, Format = "byte", Nullable = true },
76+
[typeof(int?)] = () => new() { Type = JsonSchemaType.Integer, Format = "int32", Nullable = true },
77+
[typeof(uint?)] = () => new() { Type = JsonSchemaType.Integer, Format = "int32", Nullable = true },
78+
[typeof(long?)] = () => new() { Type = JsonSchemaType.Integer, Format = "int64", Nullable = true },
79+
[typeof(ulong?)] = () => new() { Type = JsonSchemaType.Integer, Format = "int64", Nullable = true },
80+
[typeof(float?)] = () => new() { Type = JsonSchemaType.Number, Format = "float", Nullable = true },
81+
[typeof(double?)] = () => new() { Type = JsonSchemaType.Number, Format = "double", Nullable = true },
82+
[typeof(decimal?)] = () => new() { Type = JsonSchemaType.Number, Format = "double", Nullable = true },
83+
[typeof(DateTime?)] = () => new() { Type = JsonSchemaType.String, Format = "date-time", Nullable = true },
84+
[typeof(DateTimeOffset?)] = () => new() { Type = JsonSchemaType.String, Format = "date-time", Nullable = true },
85+
[typeof(Guid?)] = () => new() { Type = JsonSchemaType.String, Format = "uuid", Nullable = true },
86+
[typeof(char?)] = () => new() { Type = JsonSchemaType.String, Nullable = true },
4587

46-
[typeof(Uri)] = () => new() { Type = "string", Format = "uri" }, // Uri is treated as simple string
47-
[typeof(string)] = () => new() { Type = "string" },
48-
[typeof(object)] = () => new() { Type = "object" }
88+
[typeof(Uri)] = () => new() { Type = JsonSchemaType.String, Format = "uri" }, // Uri is treated as simple string
89+
[typeof(string)] = () => new() { Type = JsonSchemaType.String },
90+
[typeof(object)] = () => new() { Type = JsonSchemaType.Object }
4991
};
5092

5193
/// <summary>
@@ -79,7 +121,7 @@ public static OpenApiSchema MapTypeToOpenApiPrimitiveType(this Type type)
79121

80122
return _simpleTypeToOpenApiSchema.TryGetValue(type, out var result)
81123
? result()
82-
: new() { Type = "string" };
124+
: new() { Type = JsonSchemaType.String };
83125
}
84126

85127
/// <summary>
@@ -95,7 +137,7 @@ public static Type MapOpenApiPrimitiveTypeToSimpleType(this OpenApiSchema schema
95137
throw new ArgumentNullException(nameof(schema));
96138
}
97139

98-
var type = (schema.Type?.ToString().ToLowerInvariant(), schema.Format?.ToLowerInvariant(), schema.Nullable) switch
140+
var type = (schema.Type.ToIdentifier(), schema.Format?.ToLowerInvariant(), schema.Nullable) switch
99141
{
100142
("boolean", null, false) => typeof(bool),
101143
// integer is technically not valid with format, but we must provide some compatibility
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
6+
namespace Microsoft.OpenApi.Models
7+
{
8+
/// <summary>
9+
/// Represents the type of a JSON schema.
10+
/// </summary>
11+
[Flags]
12+
public enum JsonSchemaType
13+
{
14+
/// <summary>
15+
/// Represents a null type.
16+
/// </summary>
17+
Null = 1,
18+
19+
/// <summary>
20+
/// Represents a boolean type.
21+
/// </summary>
22+
Boolean = 2,
23+
24+
/// <summary>
25+
/// Represents an integer type.
26+
/// </summary>
27+
Integer = 4,
28+
29+
/// <summary>
30+
/// Represents a number type.
31+
/// </summary>
32+
Number = 8,
33+
34+
/// <summary>
35+
/// Represents a string type.
36+
/// </summary>
37+
String = 16,
38+
39+
/// <summary>
40+
/// Represents an object type.
41+
/// </summary>
42+
Object = 32,
43+
44+
/// <summary>
45+
/// Represents an array type.
46+
/// </summary>
47+
Array = 64,
48+
}
49+
}

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;
@@ -292,7 +292,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
292292
}
293293
// In V2 parameter's type can't be a reference to a custom object schema or can't be of type object
294294
// So in that case map the type as string.
295-
else if (Schema?.UnresolvedReference == true || "object".Equals(Schema?.Type?.ToString(), StringComparison.OrdinalIgnoreCase))
295+
else if (Schema?.UnresolvedReference == true || Schema?.Type == JsonSchemaType.Object)
296296
{
297297
writer.WriteProperty(OpenApiConstants.Type, "string");
298298
}
@@ -333,7 +333,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
333333
// allowEmptyValue
334334
writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false);
335335

336-
if (this.In == ParameterLocation.Query && "array".Equals(Schema?.Type.ToString(), StringComparison.OrdinalIgnoreCase))
336+
if (this.In == ParameterLocation.Query && Schema?.Type == JsonSchemaType.Array)
337337
{
338338
if (this.Style == ParameterStyle.Form && this.Explode == true)
339339
{

src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using Microsoft.OpenApi.Any;
8+
using Microsoft.OpenApi.Extensions;
89
using Microsoft.OpenApi.Interfaces;
910
using Microsoft.OpenApi.Writers;
1011

@@ -141,11 +142,11 @@ internal IEnumerable<OpenApiFormDataParameter> ConvertToFormDataParameters()
141142
foreach (var property in Content.First().Value.Schema.Properties)
142143
{
143144
var paramSchema = property.Value;
144-
if ("string".Equals(paramSchema.Type.ToString(), StringComparison.OrdinalIgnoreCase)
145+
if ("string".Equals(paramSchema.Type.ToIdentifier(), StringComparison.OrdinalIgnoreCase)
145146
&& ("binary".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)
146147
|| "base64".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)))
147148
{
148-
paramSchema.Type = "file";
149+
paramSchema.Type = "file".ToJsonSchemaType();
149150
paramSchema.Format = null;
150151
}
151152
yield return new()

0 commit comments

Comments
 (0)