Skip to content

Commit 722f02e

Browse files
authored
Fix recursion in OpenAPISchemaAlternative (#2892)
1 parent 5bcea2f commit 722f02e

File tree

2 files changed

+69
-16
lines changed

2 files changed

+69
-16
lines changed

.changeset/pretty-lies-marry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@gitbook/react-openapi': patch
3+
---
4+
5+
Fix recursion in OpenAPISchemaAlternative

packages/react-openapi/src/OpenAPISchema.tsx

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,13 @@ export function OpenAPISchemaProperty(
4949

5050
if (alternatives?.[0]?.length) {
5151
return (
52-
<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
53-
<OpenAPISchemaPresentation {...props} />
54-
{alternatives[0].map((alternative, index) => (
55-
<OpenAPISchemaAlternative
56-
key={`alternative-${index}`}
57-
schema={alternative}
58-
circularRefs={circularRefs}
59-
context={context}
60-
/>
61-
))}
62-
{parentCircularRef ? (
63-
<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
64-
) : null}
65-
</InteractiveSection>
52+
<OpenAPISchemaAlternativesItem
53+
{...props}
54+
circularRefs={circularRefs}
55+
context={context}
56+
alternatives={alternatives}
57+
parentCircularRef={parentCircularRef}
58+
/>
6659
);
6760
}
6861

@@ -173,6 +166,25 @@ function OpenAPISchemaAlternative(props: {
173166
const id = useId();
174167
const subProperties = getSchemaProperties(schema);
175168
const description = resolveDescription(schema);
169+
const alternatives = getSchemaAlternatives(schema, new Set(circularRefs?.keys()));
170+
171+
if (alternatives?.[0]?.length && !subProperties?.length) {
172+
return (
173+
<>
174+
{description ? (
175+
<Markdown source={description} className="openapi-schema-description" />
176+
) : null}
177+
<OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
178+
<OpenAPISchemaAlternativesItem
179+
schema={schema}
180+
circularRefs={circularRefs}
181+
context={context}
182+
alternatives={alternatives}
183+
/>
184+
</OpenAPIDisclosure>
185+
</>
186+
);
187+
}
176188

177189
return (
178190
<>
@@ -193,6 +205,35 @@ function OpenAPISchemaAlternative(props: {
193205
);
194206
}
195207

208+
function OpenAPISchemaAlternativesItem(
209+
props: OpenAPISchemaPropertyEntry & {
210+
circularRefs?: CircularRefsIds;
211+
context: OpenAPIClientContext;
212+
alternatives: OpenAPISchemaAlternatives;
213+
parentCircularRef?: string;
214+
}
215+
) {
216+
const id = useId();
217+
const { schema, circularRefs, context, alternatives, parentCircularRef } = props;
218+
219+
return (
220+
<InteractiveSection id={id} className={clsx('openapi-schema')}>
221+
<OpenAPISchemaPresentation {...props} />
222+
{alternatives[0].map((alternative, index) => (
223+
<OpenAPISchemaAlternative
224+
key={`alternative-${index}`}
225+
schema={alternative}
226+
circularRefs={circularRefs}
227+
context={context}
228+
/>
229+
))}
230+
{parentCircularRef ? (
231+
<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
232+
) : null}
233+
</InteractiveSection>
234+
);
235+
}
236+
196237
/**
197238
* Render a circular reference to a schema.
198239
*/
@@ -336,13 +377,18 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
336377
return null;
337378
}
338379

380+
type OpenAPISchemaAlternatives = [
381+
OpenAPIV3.SchemaObject[],
382+
OpenAPIV3.DiscriminatorObject | undefined,
383+
];
384+
339385
/**
340386
* Get the alternatives to display for a schema.
341387
*/
342388
export function getSchemaAlternatives(
343389
schema: OpenAPIV3.SchemaObject,
344390
ancestors: Set<OpenAPIV3.SchemaObject> = new Set()
345-
): null | [OpenAPIV3.SchemaObject[], OpenAPIV3.DiscriminatorObject | undefined] {
391+
): null | OpenAPISchemaAlternatives {
346392
const downAncestors = new Set(ancestors).add(schema);
347393

348394
if (schema.anyOf) {
@@ -408,7 +454,9 @@ export function getSchemaTitle(
408454
if (schema.format) {
409455
type += ` · ${schema.format}`;
410456
}
411-
} else if ('anyOf' in schema) {
457+
}
458+
459+
if ('anyOf' in schema) {
412460
type = 'any of';
413461
} else if ('oneOf' in schema) {
414462
type = 'one of';

0 commit comments

Comments
 (0)