Skip to content

Commit c554e17

Browse files
committed
feat: support allOf, anyOf, and oneOf schemas with properties in array items
1 parent 128d240 commit c554e17

File tree

6 files changed

+283
-77
lines changed

6 files changed

+283
-77
lines changed

demo/examples/tests/allOf.yaml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,76 @@ paths:
243243
items:
244244
$ref: "#/components/schemas/Book"
245245

246+
/allof-with-properties-in-array-item:
247+
get:
248+
tags:
249+
- allOf
250+
summary: allOf with Properties in Array Item
251+
description: |
252+
A list of books demonstrating allOf with properties in array item.
253+
254+
Schema:
255+
```yaml
256+
type: array
257+
items:
258+
$ref: '#/components/schemas/Book'
259+
```
260+
261+
Schema Components:
262+
```yaml
263+
BookBase:
264+
type: object
265+
required:
266+
- id
267+
- title
268+
- author
269+
properties:
270+
id:
271+
type: integer
272+
format: int64
273+
description: Unique identifier for the book
274+
title:
275+
type: string
276+
description: The title of the book
277+
author:
278+
type: string
279+
description: The author of the book
280+
281+
AdditionalBookInfo:
282+
type: object
283+
properties:
284+
publishedDate:
285+
type: string
286+
format: date
287+
description: The date the book was published
288+
genre:
289+
type: string
290+
description: The genre of the book
291+
tags:
292+
type: array
293+
items:
294+
type: string
295+
description: Tags associated with the book
296+
297+
CategorizedBook:
298+
allOf:
299+
- $ref: '#/components/schemas/BookBase'
300+
- $ref: '#/components/schemas/AdditionalBookInfo'
301+
properties:
302+
category:
303+
type: string
304+
description: The category of the book
305+
```
306+
responses:
307+
"200":
308+
description: A list of books
309+
content:
310+
application/json:
311+
schema:
312+
type: array
313+
items:
314+
$ref: "#/components/schemas/CategorizedBook"
315+
246316
/allof-nested:
247317
get:
248318
tags:
@@ -320,12 +390,15 @@ components:
320390
type: integer
321391
format: int64
322392
description: Unique identifier for the book
393+
example: 1234567890
323394
title:
324395
type: string
325396
description: The title of the book
397+
example: "The Great Gatsby"
326398
author:
327399
type: string
328400
description: The author of the book
401+
example: "F. Scott Fitzgerald"
329402

330403
AdditionalBookInfo:
331404
type: object
@@ -334,16 +407,29 @@ components:
334407
type: string
335408
format: date
336409
description: The date the book was published
410+
example: "2021-01-01"
337411
genre:
338412
type: string
339413
description: The genre of the book
414+
example: "Fiction"
340415
tags:
341416
type: array
342417
items:
343418
type: string
344419
description: Tags associated with the book
420+
example: ["Fiction", "Mystery"]
345421

346422
Book:
347423
allOf:
348424
- $ref: "#/components/schemas/BookBase"
349425
- $ref: "#/components/schemas/AdditionalBookInfo"
426+
427+
CategorizedBook:
428+
allOf:
429+
- $ref: "#/components/schemas/BookBase"
430+
- $ref: "#/components/schemas/AdditionalBookInfo"
431+
properties:
432+
category:
433+
type: string
434+
description: The category of the book
435+
example: "Fiction"

demo/examples/tests/anyOf.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,63 @@ paths:
6161
- type: boolean
6262
title: A boolean
6363
title: A string or integer, or a boolean
64+
65+
/anyof-with-properties-in-array-item:
66+
get:
67+
tags:
68+
- anyOf
69+
summary: anyOf with Properties in Array Item
70+
description: |
71+
Schema:
72+
```yaml
73+
type: array
74+
items:
75+
type: object
76+
anyOf:
77+
- type: object
78+
title: Item
79+
properties:
80+
orderNo:
81+
type: string
82+
example: "123456"
83+
- type: object
84+
title: Error
85+
properties:
86+
error:
87+
type: string
88+
example: "Invalid order number"
89+
properties:
90+
name:
91+
type: string
92+
example: pencil
93+
required:
94+
- orderNo
95+
```
96+
responses:
97+
"200":
98+
description: Successful response
99+
content:
100+
application/json:
101+
schema:
102+
type: array
103+
items:
104+
type: object
105+
anyOf:
106+
- type: object
107+
title: Item
108+
properties:
109+
orderNo:
110+
type: string
111+
example: "123456"
112+
- type: object
113+
title: Error
114+
properties:
115+
error:
116+
type: string
117+
example: "Invalid order number"
118+
properties:
119+
name:
120+
type: string
121+
example: pencil
122+
required:
123+
- orderNo

demo/examples/tests/oneOf.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,63 @@ paths:
262262
requiredPropB:
263263
type: number
264264
required: ["requiredPropB"]
265+
266+
/oneof-with-properties-in-array-item:
267+
get:
268+
tags:
269+
- oneOf
270+
summary: oneOf with Properties in Array Item
271+
description: |
272+
Schema:
273+
```yaml
274+
type: array
275+
items:
276+
type: object
277+
oneOf:
278+
- type: object
279+
title: Item
280+
properties:
281+
orderNo:
282+
type: string
283+
example: "123456"
284+
- type: object
285+
title: Error
286+
properties:
287+
error:
288+
type: string
289+
example: "Invalid order number"
290+
properties:
291+
name:
292+
type: string
293+
example: pencil
294+
required:
295+
- orderNo
296+
```
297+
responses:
298+
"200":
299+
description: Successful response
300+
content:
301+
application/json:
302+
schema:
303+
type: array
304+
items:
305+
type: object
306+
oneOf:
307+
- type: object
308+
title: Item
309+
properties:
310+
orderNo:
311+
type: string
312+
example: "123456"
313+
- type: object
314+
title: Error
315+
properties:
316+
error:
317+
type: string
318+
example: "Invalid order number"
319+
properties:
320+
name:
321+
type: string
322+
example: pencil
323+
required:
324+
- orderNo

packages/docusaurus-plugin-openapi-docs/src/openapi/createRequestExample.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
174174

175175
if (type === "array") {
176176
if (Array.isArray(items?.anyOf)) {
177-
return items?.anyOf.map((item: any) => sampleRequestFromSchema(item));
177+
return processArrayItems(items, "anyOf");
178178
}
179179

180180
if (Array.isArray(items?.oneOf)) {
181-
return items?.oneOf.map((item: any) => sampleRequestFromSchema(item));
181+
return processArrayItems(items, "oneOf");
182182
}
183183

184184
return normalizeArray(sampleRequestFromSchema(items));
@@ -233,3 +233,26 @@ function normalizeArray(arr: any) {
233233
}
234234
return [arr];
235235
}
236+
237+
function processArrayItems(
238+
items: SchemaObject,
239+
schemaType: "anyOf" | "oneOf"
240+
): any[] {
241+
const itemsArray = items[schemaType] as SchemaObject[];
242+
return itemsArray.map((item: SchemaObject) => {
243+
// If items has properties, merge them with each item
244+
if (items.properties) {
245+
const combinedSchema = {
246+
...item,
247+
properties: {
248+
...items.properties, // Common properties from parent
249+
...item.properties, // Specific properties from this anyOf/oneOf item
250+
},
251+
};
252+
// Remove anyOf/oneOf to prevent infinite recursion when calling sampleRequestFromSchema
253+
delete combinedSchema[schemaType];
254+
return sampleRequestFromSchema(combinedSchema);
255+
}
256+
return sampleRequestFromSchema(item);
257+
});
258+
}

packages/docusaurus-plugin-openapi-docs/src/openapi/createResponseExample.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,11 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
177177

178178
if (type === "array") {
179179
if (Array.isArray(items?.anyOf)) {
180-
return items?.anyOf.map((item: any) => sampleResponseFromSchema(item));
180+
return processArrayItems(items, "anyOf");
181181
}
182182

183183
if (Array.isArray(items?.oneOf)) {
184-
return items?.oneOf.map((item: any) => sampleResponseFromSchema(item));
184+
return processArrayItems(items, "oneOf");
185185
}
186186

187187
return [sampleResponseFromSchema(items)];
@@ -236,3 +236,26 @@ function normalizeArray(arr: any) {
236236
}
237237
return [arr];
238238
}
239+
240+
function processArrayItems(
241+
items: SchemaObject,
242+
schemaType: "anyOf" | "oneOf"
243+
): any[] {
244+
const itemsArray = items[schemaType] as SchemaObject[];
245+
return itemsArray.map((item: SchemaObject) => {
246+
// If items has properties, merge them with each item
247+
if (items.properties) {
248+
const combinedSchema = {
249+
...item,
250+
properties: {
251+
...items.properties, // Common properties from parent
252+
...item.properties, // Specific properties from this anyOf/oneOf item
253+
},
254+
};
255+
// Remove anyOf/oneOf to prevent infinite recursion when calling sampleResponseFromSchema
256+
delete combinedSchema[schemaType];
257+
return sampleResponseFromSchema(combinedSchema);
258+
}
259+
return sampleResponseFromSchema(item);
260+
});
261+
}

0 commit comments

Comments
 (0)