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) {
return (
<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
<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>
<OpenAPISchemaAlternativesItem
{...props}
circularRefs={circularRefs}
context={context}
alternatives={alternatives}
parentCircularRef={parentCircularRef}
/>
);
}
@@ -173,6 +166,25 @@ function OpenAPISchemaAlternative(props: {
const id = useId();
const subProperties = getSchemaProperties(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 (
<>
@@ -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.
*/
@@ -336,13 +377,18 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
return null;
}
type OpenAPISchemaAlternatives = [
OpenAPIV3.SchemaObject[],
OpenAPIV3.DiscriminatorObject | undefined,
];
/**
* Get the alternatives to display for a schema.
*/
export function getSchemaAlternatives(
schema: OpenAPIV3.SchemaObject,
ancestors: Set<OpenAPIV3.SchemaObject> = new Set()
): null | [OpenAPIV3.SchemaObject[], OpenAPIV3.DiscriminatorObject | undefined] {
): null | OpenAPISchemaAlternatives {
const downAncestors = new Set(ancestors).add(schema);
if (schema.anyOf) {
@@ -408,7 +454,9 @@ export function getSchemaTitle(
if (schema.format) {
type += ` · ${schema.format}`;
}
} else if ('anyOf' in schema) {
}
if ('anyOf' in schema) {
type = 'any of';
} else if ('oneOf' in schema) {
type = 'one of';