Fix recursion in OpenAPISchemaAlternative (#2892)

This commit is contained in:
Nolann B.
2025-02-28 11:07:56 +01:00
committed by GitHub
parent 5bcea2fe3b
commit 722f02ea09
2 changed files with 69 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@gitbook/react-openapi': patch
---
Fix recursion in OpenAPISchemaAlternative
+64 -16
View File
@@ -49,20 +49,13 @@ export function OpenAPISchemaProperty(
if (alternatives?.[0]?.length) { if (alternatives?.[0]?.length) {
return ( return (
<InteractiveSection id={id} className={clsx('openapi-schema', className)}> <OpenAPISchemaAlternativesItem
<OpenAPISchemaPresentation {...props} /> {...props}
{alternatives[0].map((alternative, index) => ( circularRefs={circularRefs}
<OpenAPISchemaAlternative context={context}
key={`alternative-${index}`} alternatives={alternatives}
schema={alternative} parentCircularRef={parentCircularRef}
circularRefs={circularRefs} />
context={context}
/>
))}
{parentCircularRef ? (
<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
) : null}
</InteractiveSection>
); );
} }
@@ -173,6 +166,25 @@ function OpenAPISchemaAlternative(props: {
const id = useId(); const id = useId();
const subProperties = getSchemaProperties(schema); const subProperties = getSchemaProperties(schema);
const description = resolveDescription(schema); const description = resolveDescription(schema);
const alternatives = getSchemaAlternatives(schema, new Set(circularRefs?.keys()));
if (alternatives?.[0]?.length && !subProperties?.length) {
return (
<>
{description ? (
<Markdown source={description} className="openapi-schema-description" />
) : null}
<OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
<OpenAPISchemaAlternativesItem
schema={schema}
circularRefs={circularRefs}
context={context}
alternatives={alternatives}
/>
</OpenAPIDisclosure>
</>
);
}
return ( return (
<> <>
@@ -193,6 +205,35 @@ function OpenAPISchemaAlternative(props: {
); );
} }
function OpenAPISchemaAlternativesItem(
props: OpenAPISchemaPropertyEntry & {
circularRefs?: CircularRefsIds;
context: OpenAPIClientContext;
alternatives: OpenAPISchemaAlternatives;
parentCircularRef?: string;
}
) {
const id = useId();
const { schema, circularRefs, context, alternatives, parentCircularRef } = props;
return (
<InteractiveSection id={id} className={clsx('openapi-schema')}>
<OpenAPISchemaPresentation {...props} />
{alternatives[0].map((alternative, index) => (
<OpenAPISchemaAlternative
key={`alternative-${index}`}
schema={alternative}
circularRefs={circularRefs}
context={context}
/>
))}
{parentCircularRef ? (
<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
) : null}
</InteractiveSection>
);
}
/** /**
* Render a circular reference to a schema. * Render a circular reference to a schema.
*/ */
@@ -336,13 +377,18 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
return null; return null;
} }
type OpenAPISchemaAlternatives = [
OpenAPIV3.SchemaObject[],
OpenAPIV3.DiscriminatorObject | undefined,
];
/** /**
* Get the alternatives to display for a schema. * Get the alternatives to display for a schema.
*/ */
export function getSchemaAlternatives( export function getSchemaAlternatives(
schema: OpenAPIV3.SchemaObject, schema: OpenAPIV3.SchemaObject,
ancestors: Set<OpenAPIV3.SchemaObject> = new Set() ancestors: Set<OpenAPIV3.SchemaObject> = new Set()
): null | [OpenAPIV3.SchemaObject[], OpenAPIV3.DiscriminatorObject | undefined] { ): null | OpenAPISchemaAlternatives {
const downAncestors = new Set(ancestors).add(schema); const downAncestors = new Set(ancestors).add(schema);
if (schema.anyOf) { if (schema.anyOf) {
@@ -408,7 +454,9 @@ export function getSchemaTitle(
if (schema.format) { if (schema.format) {
type += ` · ${schema.format}`; type += ` · ${schema.format}`;
} }
} else if ('anyOf' in schema) { }
if ('anyOf' in schema) {
type = 'any of'; type = 'any of';
} else if ('oneOf' in schema) { } else if ('oneOf' in schema) {
type = 'one of'; type = 'one of';