Skip to content

Commit fd15b0a

Browse files
Merge branch 'main' into feat/enable-NRT
2 parents fa012ac + db10afa commit fd15b0a

19 files changed

+263
-242
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "2.0.0-preview9"
2+
".": "2.0.0-preview10"
33
}

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# Changelog
22

3+
## [2.0.0-preview10](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview9...v2.0.0-preview10) (2025-02-27)
4+
5+
6+
### Features
7+
8+
* deduplicates tags at the document level ([93c468e](https://github.com/microsoft/OpenAPI.NET/commit/93c468ebd9ee30b0cb32a583821d8abe3d017b18))
9+
* tags references are now deduplicated as well ([763c0c1](https://github.com/microsoft/OpenAPI.NET/commit/763c0c1c5856a0ed56128b0ab8ce4b3a29ed193a))
10+
11+
12+
### Bug Fixes
13+
14+
* add logic for serializing date time objects ([23395c5](https://github.com/microsoft/OpenAPI.NET/commit/23395c5776a781f64a7dc7bfd2867ca83eaa0bb7))
15+
* adds missing cancellation parameter to async method ([243a111](https://github.com/microsoft/OpenAPI.NET/commit/243a111c19f2939b0a5d27c21db302f8349049eb))
16+
* avoid creating new http clients to load additional documents of the workspace ([0f23798](https://github.com/microsoft/OpenAPI.NET/commit/0f23798f61ac964f9e71ef7402213392ebe91151))
17+
* deduplicates exclusive min/max properties in the object model ([08414a1](https://github.com/microsoft/OpenAPI.NET/commit/08414a16db5e0a627c953f107aa34501c18996bb))
18+
* deduplicates exclusive min/max properties in the object model ([0d5b471](https://github.com/microsoft/OpenAPI.NET/commit/0d5b4716d8cf0215257680d6cbaddaa84438eac5))
19+
* moves the http client for the reader to settings so it can be passed by client application ([9b910f3](https://github.com/microsoft/OpenAPI.NET/commit/9b910f3928ebcb24560ff004a58e5d397ed3d836))
20+
* OpenAPIDocument JsonSchemaDialect property is now a URI ([45977b5](https://github.com/microsoft/OpenAPI.NET/commit/45977b50188a0065fde02a3ac44a1fe718a85b30))
21+
* openapischema schema property is now a Uri ([452a6b9](https://github.com/microsoft/OpenAPI.NET/commit/452a6b9730a2fa310aee64d0b9d2a0c7ea6d131f))
22+
* primitive parsing for strings as DateTimes is too greedy ([4ee1d8b](https://github.com/microsoft/OpenAPI.NET/commit/4ee1d8bf44b5fcdf0fd22deca1d36ee4faf421d1))
23+
* removes static readers registry ([fe7a2fd](https://github.com/microsoft/OpenAPI.NET/commit/fe7a2fd654e93ce99dd0ebd628042f816c787104))
24+
* use a single http client in hidi ([9386fae](https://github.com/microsoft/OpenAPI.NET/commit/9386faec70655279ec3a031fd2afcd9cab09af40))
25+
326
## [2.0.0-preview9](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview8...v2.0.0-preview9) (2025-02-21)
427

528

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<PackageProjectUrl>https://github.com/Microsoft/OpenAPI.NET</PackageProjectUrl>
1313
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1414
<PackageTags>OpenAPI .NET</PackageTags>
15-
<Version>2.0.0-preview9</Version>
15+
<Version>2.0.0-preview10</Version>
1616
</PropertyGroup>
1717
<!-- https://github.com/clairernovotny/DeterministicBuilds#deterministic-builds -->
1818
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Text.Json.Nodes;
34
using Microsoft.OpenApi.Interfaces;
45

@@ -19,7 +20,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiSerializable
1920
/// <summary>
2021
/// $schema, a JSON Schema dialect identifier. Value must be a URI
2122
/// </summary>
22-
public string? Schema { get; }
23+
public Uri Schema { get; }
2324

2425
/// <summary>
2526
/// $id - Identifies a schema resource with its canonical URI.
@@ -55,12 +56,12 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiSerializable
5556
/// <summary>
5657
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
5758
/// </summary>
58-
public decimal? V31ExclusiveMaximum { get; }
59+
public decimal? ExclusiveMaximum { get; }
5960

6061
/// <summary>
6162
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
6263
/// </summary>
63-
public decimal? V31ExclusiveMinimum { get; }
64+
public decimal? ExclusiveMinimum { get; }
6465

6566
/// <summary>
6667
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
@@ -90,21 +91,11 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiSerializable
9091
/// </summary>
9192
public decimal? Maximum { get; }
9293

93-
/// <summary>
94-
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
95-
/// </summary>
96-
public bool? ExclusiveMaximum { get; }
97-
9894
/// <summary>
9995
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
10096
/// </summary>
10197
public decimal? Minimum { get; }
10298

103-
/// <summary>
104-
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
105-
/// </summary>
106-
public bool? ExclusiveMinimum { get; }
107-
10899
/// <summary>
109100
/// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
110101
/// </summary>

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void RegisterComponents()
4646
/// <summary>
4747
/// The default value for the $schema keyword within Schema Objects contained within this OAS document. This MUST be in the form of a URI.
4848
/// </summary>
49-
public string? JsonSchemaDialect { get; set; }
49+
public Uri? JsonSchemaDialect { get; set; }
5050

5151
/// <summary>
5252
/// An array of Server Objects, which provide connectivity information to a target server.
@@ -161,7 +161,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
161161
writer.WriteProperty(OpenApiConstants.OpenApi, "3.1.1");
162162

163163
// jsonSchemaDialect
164-
writer.WriteProperty(OpenApiConstants.JsonSchemaDialect, JsonSchemaDialect);
164+
writer.WriteProperty(OpenApiConstants.JsonSchemaDialect, JsonSchemaDialect?.ToString());
165165

166166
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (w, element) => element.SerializeAsV31(w));
167167

src/Microsoft.OpenApi/Models/OpenApiSchema.cs

Lines changed: 139 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class OpenApiSchema : IOpenApiReferenceable, IOpenApiExtensible, IOpenApi
2424
public string? Title { get; set; }
2525

2626
/// <inheritdoc />
27-
public string? Schema { get; set; }
27+
public Uri Schema { get; set; }
2828

2929
/// <inheritdoc />
3030
public string? Id { get; set; }
@@ -44,11 +44,63 @@ public class OpenApiSchema : IOpenApiReferenceable, IOpenApiExtensible, IOpenApi
4444
/// <inheritdoc />
4545
public IDictionary<string, IOpenApiSchema>? Definitions { get; set; }
4646

47+
private decimal? _exclusiveMaximum;
4748
/// <inheritdoc />
48-
public decimal? V31ExclusiveMaximum { get; set; }
49+
public decimal? ExclusiveMaximum
50+
{
51+
get
52+
{
53+
if (_exclusiveMaximum.HasValue)
54+
{
55+
return _exclusiveMaximum;
56+
}
57+
if (IsExclusiveMaximum == true && _maximum.HasValue)
58+
{
59+
return _maximum;
60+
}
61+
return null;
62+
}
63+
set
64+
{
65+
_exclusiveMaximum = value;
66+
IsExclusiveMaximum = value != null;
67+
}
68+
}
4969

70+
/// <summary>
71+
/// Compatibility property for OpenAPI 3.0 or earlier serialization of the exclusive maximum value.
72+
/// </summary>
73+
/// DO NOT CHANGE THE VISIBILITY OF THIS PROPERTY TO PUBLIC
74+
internal bool? IsExclusiveMaximum { get; set; }
75+
76+
private decimal? _exclusiveMinimum;
5077
/// <inheritdoc />
51-
public decimal? V31ExclusiveMinimum { get; set; }
78+
public decimal? ExclusiveMinimum
79+
{
80+
get
81+
{
82+
if (_exclusiveMinimum.HasValue)
83+
{
84+
return _exclusiveMinimum;
85+
}
86+
if (IsExclusiveMinimum == true && _minimum.HasValue)
87+
{
88+
return _minimum;
89+
}
90+
return null;
91+
}
92+
set
93+
{
94+
_exclusiveMinimum = value;
95+
IsExclusiveMinimum = value != null;
96+
}
97+
}
98+
99+
/// <summary>
100+
/// Compatibility property for OpenAPI 3.0 or earlier serialization of the exclusive minimum value.
101+
/// </summary>
102+
/// DO NOT CHANGE THE VISIBILITY OF THIS PROPERTY TO PUBLIC
103+
internal bool? IsExclusiveMinimum { get; set; }
52104

53105
/// <inheritdoc />
54106
public bool UnEvaluatedProperties { get; set; }
@@ -65,17 +117,42 @@ public class OpenApiSchema : IOpenApiReferenceable, IOpenApiExtensible, IOpenApi
65117
/// <inheritdoc />
66118
public string? Description { get; set; }
67119

120+
private decimal? _maximum;
68121
/// <inheritdoc />
69-
public decimal? Maximum { get; set; }
70-
71-
/// <inheritdoc />
72-
public bool? ExclusiveMaximum { get; set; }
122+
public decimal? Maximum
123+
{
124+
get
125+
{
126+
if (IsExclusiveMaximum == true)
127+
{
128+
return null;
129+
}
130+
return _maximum;
131+
}
132+
set
133+
{
134+
_maximum = value;
135+
}
136+
}
73137

74-
/// <inheritdoc />
75-
public decimal? Minimum { get; set; }
138+
private decimal? _minimum;
76139

77140
/// <inheritdoc />
78-
public bool? ExclusiveMinimum { get; set; }
141+
public decimal? Minimum
142+
{
143+
get
144+
{
145+
if (IsExclusiveMinimum == true)
146+
{
147+
return null;
148+
}
149+
return _minimum;
150+
}
151+
set
152+
{
153+
_minimum = value;
154+
}
155+
}
79156

80157
/// <inheritdoc />
81158
public int? MaxLength { get; set; }
@@ -201,15 +278,18 @@ internal OpenApiSchema(IOpenApiSchema schema)
201278
DynamicRef = schema.DynamicRef ?? DynamicRef;
202279
Definitions = schema.Definitions != null ? new Dictionary<string, IOpenApiSchema>(schema.Definitions) : null;
203280
UnevaluatedProperties = schema.UnevaluatedProperties;
204-
V31ExclusiveMaximum = schema.V31ExclusiveMaximum ?? V31ExclusiveMaximum;
205-
V31ExclusiveMinimum = schema.V31ExclusiveMinimum ?? V31ExclusiveMinimum;
281+
ExclusiveMaximum = schema.ExclusiveMaximum ?? ExclusiveMaximum;
282+
ExclusiveMinimum = schema.ExclusiveMinimum ?? ExclusiveMinimum;
283+
if (schema is OpenApiSchema eMSchema)
284+
{
285+
IsExclusiveMaximum = eMSchema.IsExclusiveMaximum;
286+
IsExclusiveMinimum = eMSchema.IsExclusiveMinimum;
287+
}
206288
Type = schema.Type ?? Type;
207289
Format = schema.Format ?? Format;
208290
Description = schema.Description ?? Description;
209291
Maximum = schema.Maximum ?? Maximum;
210-
ExclusiveMaximum = schema.ExclusiveMaximum ?? ExclusiveMaximum;
211292
Minimum = schema.Minimum ?? Minimum;
212-
ExclusiveMinimum = schema.ExclusiveMinimum ?? ExclusiveMinimum;
213293
MaxLength = schema.MaxLength ?? MaxLength;
214294
MinLength = schema.MinLength ?? MinLength;
215295
Pattern = schema.Pattern ?? Pattern;
@@ -257,6 +337,44 @@ public void SerializeAsV3(IOpenApiWriter writer)
257337
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
258338
}
259339

340+
private static void SerializeBounds(IOpenApiWriter writer, OpenApiSpecVersion version, string propertyName, string exclusivePropertyName, string isExclusivePropertyName, decimal? value, decimal? exclusiveValue, bool? isExclusiveValue)
341+
{
342+
if (version >= OpenApiSpecVersion.OpenApi3_1)
343+
{
344+
if (exclusiveValue.HasValue)
345+
{
346+
// was explicitly set in the document or object model
347+
writer.WriteProperty(exclusivePropertyName, exclusiveValue.Value);
348+
}
349+
else if (isExclusiveValue == true && value.HasValue)
350+
{
351+
// came from parsing an old document
352+
writer.WriteProperty(exclusivePropertyName, value);
353+
}
354+
else if (value.HasValue)
355+
{
356+
// was explicitly set in the document or object model
357+
writer.WriteProperty(propertyName, value);
358+
}
359+
}
360+
else
361+
{
362+
if (exclusiveValue.HasValue)
363+
{
364+
// was explicitly set in a new document being downcast or object model
365+
writer.WriteProperty(propertyName, exclusiveValue.Value);
366+
writer.WriteProperty(isExclusivePropertyName, true);
367+
}
368+
else if (value.HasValue)
369+
{
370+
// came from parsing an old document, we're just mirroring the information
371+
writer.WriteProperty(propertyName, value);
372+
if (isExclusiveValue.HasValue)
373+
writer.WriteProperty(isExclusivePropertyName, isExclusiveValue.Value);
374+
}
375+
}
376+
}
377+
260378
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
261379
Action<IOpenApiWriter, IOpenApiSerializable> callback)
262380
{
@@ -274,16 +392,12 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
274392
writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf);
275393

276394
// maximum
277-
writer.WriteProperty(OpenApiConstants.Maximum, Maximum);
278-
279395
// exclusiveMaximum
280-
writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);
396+
SerializeBounds(writer, version, OpenApiConstants.Maximum, OpenApiConstants.ExclusiveMaximum, OpenApiConstants.V31ExclusiveMaximum, Maximum, ExclusiveMaximum, IsExclusiveMaximum);
281397

282398
// minimum
283-
writer.WriteProperty(OpenApiConstants.Minimum, Minimum);
284-
285399
// exclusiveMinimum
286-
writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);
400+
SerializeBounds(writer, version, OpenApiConstants.Minimum, OpenApiConstants.ExclusiveMinimum, OpenApiConstants.V31ExclusiveMinimum, Minimum, ExclusiveMinimum, IsExclusiveMinimum);
287401

288402
// maxLength
289403
writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);
@@ -400,15 +514,13 @@ public void SerializeAsV2(IOpenApiWriter writer)
400514
internal void WriteJsonSchemaKeywords(IOpenApiWriter writer)
401515
{
402516
writer.WriteProperty(OpenApiConstants.Id, Id);
403-
writer.WriteProperty(OpenApiConstants.DollarSchema, Schema);
517+
writer.WriteProperty(OpenApiConstants.DollarSchema, Schema?.ToString());
404518
writer.WriteProperty(OpenApiConstants.Comment, Comment);
405519
writer.WriteProperty(OpenApiConstants.Const, Const);
406520
writer.WriteOptionalMap(OpenApiConstants.Vocabulary, Vocabulary, (w, s) => w.WriteValue(s));
407521
writer.WriteOptionalMap(OpenApiConstants.Defs, Definitions, (w, s) => s.SerializeAsV31(w));
408522
writer.WriteProperty(OpenApiConstants.DynamicRef, DynamicRef);
409523
writer.WriteProperty(OpenApiConstants.DynamicAnchor, DynamicAnchor);
410-
writer.WriteProperty(OpenApiConstants.V31ExclusiveMaximum, V31ExclusiveMaximum);
411-
writer.WriteProperty(OpenApiConstants.V31ExclusiveMinimum, V31ExclusiveMinimum);
412524
writer.WriteProperty(OpenApiConstants.UnevaluatedProperties, UnevaluatedProperties, false);
413525
writer.WriteOptionalCollection(OpenApiConstants.Examples, Examples, (nodeWriter, s) => nodeWriter.WriteAny(s));
414526
writer.WriteOptionalMap(OpenApiConstants.PatternProperties, PatternProperties, (w, s) => s.SerializeAsV31(w));
@@ -438,16 +550,12 @@ internal void WriteAsItemsProperties(IOpenApiWriter writer)
438550
writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d));
439551

440552
// maximum
441-
writer.WriteProperty(OpenApiConstants.Maximum, Maximum);
442-
443553
// exclusiveMaximum
444-
writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);
554+
SerializeBounds(writer, OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Maximum, OpenApiConstants.ExclusiveMaximum, OpenApiConstants.V31ExclusiveMaximum, Maximum, ExclusiveMaximum, IsExclusiveMaximum);
445555

446556
// minimum
447-
writer.WriteProperty(OpenApiConstants.Minimum, Minimum);
448-
449557
// exclusiveMinimum
450-
writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);
558+
SerializeBounds(writer, OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Minimum, OpenApiConstants.ExclusiveMinimum, OpenApiConstants.V31ExclusiveMinimum, Minimum, ExclusiveMinimum, IsExclusiveMinimum);
451559

452560
// maxLength
453561
writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);
@@ -522,16 +630,12 @@ private void SerializeAsV2(
522630
writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf);
523631

524632
// maximum
525-
writer.WriteProperty(OpenApiConstants.Maximum, Maximum);
526-
527633
// exclusiveMaximum
528-
writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum);
634+
SerializeBounds(writer, OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Maximum, OpenApiConstants.ExclusiveMaximum, OpenApiConstants.V31ExclusiveMaximum, Maximum, ExclusiveMaximum, IsExclusiveMaximum);
529635

530636
// minimum
531-
writer.WriteProperty(OpenApiConstants.Minimum, Minimum);
532-
533637
// exclusiveMinimum
534-
writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum);
638+
SerializeBounds(writer, OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Minimum, OpenApiConstants.ExclusiveMinimum, OpenApiConstants.V31ExclusiveMinimum, Minimum, ExclusiveMinimum, IsExclusiveMinimum);
535639

536640
// maxLength
537641
writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength);

0 commit comments

Comments
 (0)