Skip to content

Commit 6d3d2f5

Browse files
committed
fix: Preserve x-* on permissive object and multi-assertion AllOfSchema wrapper
When a schema map has only x-* keys (no type, no combinators, no shape keywords), the synthesized permissive ObjectSchema previously discarded them. Likewise, when parseMap collapsed multiple assertions into a wrapper AllOfSchema, the wrapper carried Map.of() instead of the top-level extensions. Both call sites now pass extractExtensions(raw).
1 parent 283a170 commit 6d3d2f5

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

src/main/java/com/retailsvc/http/spec/schema/SchemaParser.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ private static Schema parseMap(Map<String, Object> raw) {
6161
}
6262

6363
return switch (assertions.size()) {
64-
case 0 -> permissiveObject();
64+
case 0 -> permissiveObject(extractExtensions(raw));
6565
case 1 -> assertions.getFirst();
66-
default -> new AllOfSchema(List.copyOf(assertions), Map.of());
66+
default -> new AllOfSchema(List.copyOf(assertions), extractExtensions(raw));
6767
};
6868
}
6969

@@ -115,9 +115,9 @@ private static boolean hasArrayShapeKeywords(Map<String, Object> raw) {
115115
|| raw.containsKey("uniqueItems");
116116
}
117117

118-
private static Schema permissiveObject() {
118+
private static Schema permissiveObject(Map<String, Object> extensions) {
119119
return new ObjectSchema(
120-
Set.of(), Map.of(), List.of(), new AdditionalProperties.Allowed(), null, null, Map.of());
120+
Set.of(), Map.of(), List.of(), new AdditionalProperties.Allowed(), null, null, extensions);
121121
}
122122

123123
private static Set<TypeName> parseTypes(Map<String, Object> raw) {

src/test/java/com/retailsvc/http/spec/ExtensionsTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,52 @@ void oneOfSchemaExtensionsExposeXKeys() {
170170
assertThat(spec.componentSchemas().get("Either").extensions())
171171
.containsEntry("x-discriminator-hint", "kind");
172172
}
173+
174+
@Test
175+
void permissiveObjectPreservesXKeys() {
176+
Map<String, Object> raw =
177+
Map.of(
178+
"openapi",
179+
"3.1.0",
180+
"info",
181+
Map.of("title", "t", "version", "1"),
182+
"servers",
183+
List.of(Map.of("url", "https://example.com")),
184+
"paths",
185+
Map.of(),
186+
"components",
187+
Map.of("schemas", Map.of("FreeForm", Map.of("x-vendor", "acme"))));
188+
Spec spec = Spec.from(raw);
189+
assertThat(spec.componentSchemas().get("FreeForm").extensions())
190+
.containsEntry("x-vendor", "acme");
191+
}
192+
193+
@Test
194+
void multiAssertionWrapperPreservesXKeys() {
195+
Map<String, Object> raw =
196+
Map.of(
197+
"openapi",
198+
"3.1.0",
199+
"info",
200+
Map.of("title", "t", "version", "1"),
201+
"servers",
202+
List.of(Map.of("url", "https://example.com")),
203+
"paths",
204+
Map.of(),
205+
"components",
206+
Map.of(
207+
"schemas",
208+
Map.of(
209+
"Composite",
210+
Map.of(
211+
"type",
212+
"object",
213+
"anyOf",
214+
List.of(Map.of("type", "object"), Map.of("type", "object")),
215+
"x-tag",
216+
"composite"))));
217+
Spec spec = Spec.from(raw);
218+
assertThat(spec.componentSchemas().get("Composite").extensions())
219+
.containsEntry("x-tag", "composite");
220+
}
173221
}

0 commit comments

Comments
 (0)