Skip to content

Commit 1ce7273

Browse files
committed
Handle self-reference edge case in openapi schema
1 parent 9261a35 commit 1ce7273

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

src/components/OpenAPI/schema/SchemaObject.astro

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ const hasMany = schemaObjects !== undefined;
3333

3434
{
3535
hasMany ? (
36-
<SchemaObjects {parents} discriminator={schemaObject.discriminator} {nested} {schemaObjects} />
36+
<SchemaObjects
37+
{parents}
38+
{schemaObject}
39+
discriminator={schemaObject.discriminator}
40+
{nested}
41+
{schemaObjects}
42+
/>
3743
) : isSchemaObject(schemaObject.not) ? (
3844
<Astro.self negated schemaObject={schemaObject.not} />
3945
) : (

src/components/OpenAPI/schema/SchemaObjectAllOf.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const { nested, schemaObject, parents = [] } = Astro.props;
3030
return (
3131
<SchemaObjects
3232
parents={[...parents, schemaObject]}
33+
schemaObject={schemaObject}
3334
discriminator={schemaObject.discriminator}
3435
{nested}
3536
{schemaObjects}

src/components/OpenAPI/schema/SchemaObjects.astro

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
import { Tabs, TabItem } from "@astrojs/starlight/components";
33
44
import { getType } from "starlight-openapi/libs/items";
5-
import type {
6-
Discriminator,
7-
SchemaObjects,
8-
SchemaObject as SchemaObjectType,
5+
import {
6+
getSchemaObjects,
7+
type Discriminator,
8+
type SchemaObjects,
9+
type SchemaObject as SchemaObjectType,
910
} from "starlight-openapi/libs/schemaObject";
1011
import Tag from "../Tag.astro";
1112
@@ -15,6 +16,7 @@ interface Props {
1516
discriminator: Discriminator;
1617
nested: boolean;
1718
parents?: SchemaObjectType[];
19+
schemaObject: SchemaObjectType;
1820
schemaObjects: SchemaObjects;
1921
}
2022
@@ -36,6 +38,29 @@ const humanReadableType: Record<SchemaObjects["type"], string> = {
3638
anyOf: "Any of",
3739
oneOf: "One of",
3840
};
41+
42+
function isCircularArrayItem(item: SchemaObjectType, parents: SchemaObjectType[] = []): boolean {
43+
if (parents.some((parent) => parent === item)) {
44+
return true;
45+
}
46+
47+
if (
48+
item.type !== "array" ||
49+
!item.items ||
50+
"$ref" in item.items ||
51+
item.items.type !== "object"
52+
) {
53+
return false;
54+
}
55+
56+
const nestedSchemaObjects = getSchemaObjects(item.items);
57+
58+
return (
59+
nestedSchemaObjects?.schemaObjects.some((nestedSchemaObject) =>
60+
isCircularArrayItem(nestedSchemaObject, [...parents, item]),
61+
) ?? false
62+
);
63+
}
3964
---
4065

4166
<div>
@@ -46,7 +71,11 @@ const humanReadableType: Record<SchemaObjects["type"], string> = {
4671
{
4772
schemaObjects.map((schemaObject) => (
4873
<TabItem label={schemaObject.title ?? getType(schemaObject) ?? "unknown"}>
49-
<SchemaObject {parents} {nested} schemaObject={schemaObject} />
74+
{isCircularArrayItem(schemaObject) ? (
75+
"Self reference"
76+
) : (
77+
<SchemaObject {parents} {nested} schemaObject={schemaObject} />
78+
)}
5079
</TabItem>
5180
))
5281
}

0 commit comments

Comments
 (0)