Skip to content

Commit fe5ecbb

Browse files
baywetCopilot
andcommitted
chore(library): serialize contains keywords as v3 extensions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8990afa commit fe5ecbb

4 files changed

Lines changed: 36 additions & 3 deletions

File tree

src/Microsoft.OpenApi/Models/OpenApiConstants.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,21 @@ public static class OpenApiConstants
895895
/// </summary>
896896
public const string ContentSchemaExtension = "x-jsonschema-contentSchema";
897897

898+
/// <summary>
899+
/// Extension: x-jsonschema-contains
900+
/// </summary>
901+
public const string ContainsExtension = "x-jsonschema-contains";
902+
903+
/// <summary>
904+
/// Extension: x-jsonschema-maxContains
905+
/// </summary>
906+
public const string MaxContainsExtension = "x-jsonschema-maxContains";
907+
908+
/// <summary>
909+
/// Extension: x-jsonschema-minContains
910+
/// </summary>
911+
public const string MinContainsExtension = "x-jsonschema-minContains";
912+
898913
#region V2.0
899914

900915
/// <summary>

src/Microsoft.OpenApi/Models/OpenApiSchema.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,9 @@ private void WriteV3CompatibilityKeywords(IOpenApiWriter writer, Action<IOpenApi
713713
writer.WriteProperty(OpenApiConstants.ContentEncodingExtension, ContentEncoding);
714714
writer.WriteProperty(OpenApiConstants.ContentMediaTypeExtension, ContentMediaType);
715715
writer.WriteOptionalObject(OpenApiConstants.ContentSchemaExtension, ContentSchema, callback);
716+
writer.WriteOptionalObject(OpenApiConstants.ContainsExtension, Contains, callback);
717+
writer.WriteProperty(OpenApiConstants.MaxContainsExtension, MaxContains);
718+
writer.WriteProperty(OpenApiConstants.MinContainsExtension, MinContains);
716719
writer.WriteOptionalObject(OpenApiConstants.PropertyNamesExtension, PropertyNames, callback);
717720
writer.WriteOptionalMap(OpenApiConstants.DependentSchemasExtension, DependentSchemas, callback);
718721
writer.WriteOptionalObject(OpenApiConstants.IfExtension, If, callback);

src/Microsoft.OpenApi/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ const Microsoft.OpenApi.OpenApiConstants.ContentMediaType = "contentMediaType" -
1010
const Microsoft.OpenApi.OpenApiConstants.ContentMediaTypeExtension = "x-jsonschema-contentMediaType" -> string!
1111
const Microsoft.OpenApi.OpenApiConstants.ContentSchema = "contentSchema" -> string!
1212
const Microsoft.OpenApi.OpenApiConstants.ContentSchemaExtension = "x-jsonschema-contentSchema" -> string!
13+
const Microsoft.OpenApi.OpenApiConstants.ContainsExtension = "x-jsonschema-contains" -> string!
1314
const Microsoft.OpenApi.OpenApiConstants.DependentSchemas = "dependentSchemas" -> string!
1415
const Microsoft.OpenApi.OpenApiConstants.DependentSchemasExtension = "x-jsonschema-dependentSchemas" -> string!
1516
const Microsoft.OpenApi.OpenApiConstants.Else = "else" -> string!
1617
const Microsoft.OpenApi.OpenApiConstants.ElseExtension = "x-jsonschema-else" -> string!
1718
const Microsoft.OpenApi.OpenApiConstants.If = "if" -> string!
1819
const Microsoft.OpenApi.OpenApiConstants.IfExtension = "x-jsonschema-if" -> string!
20+
const Microsoft.OpenApi.OpenApiConstants.MaxContainsExtension = "x-jsonschema-maxContains" -> string!
21+
const Microsoft.OpenApi.OpenApiConstants.MinContainsExtension = "x-jsonschema-minContains" -> string!
1922
const Microsoft.OpenApi.OpenApiConstants.PropertyNames = "propertyNames" -> string!
2023
const Microsoft.OpenApi.OpenApiConstants.PropertyNamesExtension = "x-jsonschema-propertyNames" -> string!
2124
const Microsoft.OpenApi.OpenApiConstants.Then = "then" -> string!

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,9 +1279,8 @@ public async Task SerializeContainsKeywordsAsV31Works()
12791279
}
12801280

12811281
[Fact]
1282-
public async Task SerializeContainsKeywordsAsV3DoesNotEmit()
1282+
public async Task SerializeContainsKeywordsAsV3EmitsCompatibilityExtensions()
12831283
{
1284-
// Arrange - contains/minContains/maxContains are JSON Schema 2020-12 keywords and have no equivalent in OpenAPI 3.0
12851284
var schema = new OpenApiSchema
12861285
{
12871286
Type = JsonSchemaType.Array,
@@ -1302,7 +1301,12 @@ public async Task SerializeContainsKeywordsAsV3DoesNotEmit()
13021301
var expectedV3Schema =
13031302
"""
13041303
{
1305-
"type": "array"
1304+
"type": "array",
1305+
"x-jsonschema-contains": {
1306+
"type": "string"
1307+
},
1308+
"x-jsonschema-maxContains": 5,
1309+
"x-jsonschema-minContains": 1
13061310
}
13071311
""";
13081312

@@ -1521,6 +1525,11 @@ public async Task SerializeMissingPropertiesEmitsOaiExtensionsInV3()
15211525
"x-jsonschema-contentSchema": {
15221526
"type": "array"
15231527
},
1528+
"x-jsonschema-contains": {
1529+
"type": "string"
1530+
},
1531+
"x-jsonschema-maxContains": 3,
1532+
"x-jsonschema-minContains": 1,
15241533
"x-jsonschema-propertyNames": {
15251534
"pattern": "^[a-z]+$"
15261535
},
@@ -1549,6 +1558,9 @@ public async Task SerializeMissingPropertiesEmitsOaiExtensionsInV3()
15491558
ContentEncoding = "base64",
15501559
ContentMediaType = "application/jwt",
15511560
ContentSchema = new OpenApiSchema { Type = JsonSchemaType.Array },
1561+
Contains = new OpenApiSchema { Type = JsonSchemaType.String },
1562+
MaxContains = 3,
1563+
MinContains = 1,
15521564
PropertyNames = new OpenApiSchema { Pattern = "^[a-z]+$" },
15531565
DependentSchemas = new Dictionary<string, IOpenApiSchema>
15541566
{

0 commit comments

Comments
 (0)