mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 18:13:29 +00:00
Improve OpenAPI circular references (#3821)
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'@gitbook/react-openapi': patch
|
||||||
|
'gitbook': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Improve OpenAPI circular references
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
|
|
||||||
/* Schema Presentation */
|
/* Schema Presentation */
|
||||||
.openapi-schema-presentation {
|
.openapi-schema-presentation {
|
||||||
@apply flex flex-col gap-1 font-normal;
|
@apply flex flex-col gap-1 font-normal scroll-mt-[calc(var(--toc-top-offset)+0.5rem)];
|
||||||
}
|
}
|
||||||
|
|
||||||
.openapi-schema-properties:last-child {
|
.openapi-schema-properties:last-child {
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.openapi-schema-circular {
|
.openapi-schema-circular {
|
||||||
@apply text-xs text-tint;
|
@apply text-sm text-tint;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openapi-schema-circular a {
|
.openapi-schema-circular a {
|
||||||
@@ -257,7 +257,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.openapi-schema-circular-glyph {
|
.openapi-schema-circular-glyph {
|
||||||
@apply text-base;
|
@apply text-base mr-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schema Enum */
|
/* Schema Enum */
|
||||||
|
|||||||
@@ -47,7 +47,13 @@ function OpenAPISchemaProperty(
|
|||||||
const circularRefId = parentCircularRefs.get(schema);
|
const circularRefId = parentCircularRefs.get(schema);
|
||||||
// Avoid recursing infinitely, and instead render a link to the parent schema
|
// Avoid recursing infinitely, and instead render a link to the parent schema
|
||||||
if (circularRefId) {
|
if (circularRefId) {
|
||||||
return <OpenAPISchemaCircularRef id={circularRefId} schema={schema} />;
|
return (
|
||||||
|
<OpenAPISchemaPresentation
|
||||||
|
context={context}
|
||||||
|
property={property}
|
||||||
|
circularRefId={circularRefId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const circularRefs = new Map(parentCircularRefs);
|
const circularRefs = new Map(parentCircularRefs);
|
||||||
@@ -58,7 +64,7 @@ function OpenAPISchemaProperty(
|
|||||||
const ancestors = new Set(circularRefs.keys());
|
const ancestors = new Set(circularRefs.keys());
|
||||||
const alternatives = getSchemaAlternatives(schema, ancestors);
|
const alternatives = getSchemaAlternatives(schema, ancestors);
|
||||||
|
|
||||||
const header = <OpenAPISchemaPresentation context={context} property={property} />;
|
const header = <OpenAPISchemaPresentation id={id} context={context} property={property} />;
|
||||||
const content = (() => {
|
const content = (() => {
|
||||||
if (alternatives?.schemas) {
|
if (alternatives?.schemas) {
|
||||||
const { schemas, discriminator } = alternatives;
|
const { schemas, discriminator } = alternatives;
|
||||||
@@ -101,10 +107,8 @@ function OpenAPISchemaProperty(
|
|||||||
return (
|
return (
|
||||||
<OpenAPIDisclosure
|
<OpenAPIDisclosure
|
||||||
icon={context.icons.plus}
|
icon={context.icons.plus}
|
||||||
className={clsx('openapi-schema', className)}
|
|
||||||
header={header}
|
header={header}
|
||||||
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
|
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
|
||||||
{...rest}
|
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</OpenAPIDisclosure>
|
</OpenAPIDisclosure>
|
||||||
@@ -289,8 +293,8 @@ function OpenAPISchemaCircularRef(props: { id: string; schema: OpenAPIV3.SchemaO
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="openapi-schema-circular">
|
<div className="openapi-schema-circular">
|
||||||
|
<span className="openapi-schema-circular-glyph">⤷</span>
|
||||||
Circular reference to <a href={`#${id}`}>{getSchemaTitle(schema)}</a>{' '}
|
Circular reference to <a href={`#${id}`}>{getSchemaTitle(schema)}</a>{' '}
|
||||||
<span className="openapi-schema-circular-glyph">↩</span>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -359,11 +363,15 @@ function OpenAPISchemaEnum(props: {
|
|||||||
* Render the top row of a schema. e.g: name, type, and required status.
|
* Render the top row of a schema. e.g: name, type, and required status.
|
||||||
*/
|
*/
|
||||||
export function OpenAPISchemaPresentation(props: {
|
export function OpenAPISchemaPresentation(props: {
|
||||||
|
id?: string;
|
||||||
property: OpenAPISchemaPropertyEntry;
|
property: OpenAPISchemaPropertyEntry;
|
||||||
context: OpenAPIClientContext;
|
context: OpenAPIClientContext;
|
||||||
|
circularRefId?: string;
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
|
id,
|
||||||
property: { schema, propertyName, required, isDiscriminatorProperty },
|
property: { schema, propertyName, required, isDiscriminatorProperty },
|
||||||
|
circularRefId,
|
||||||
context,
|
context,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@@ -371,7 +379,7 @@ export function OpenAPISchemaPresentation(props: {
|
|||||||
const example = resolveFirstExample(schema);
|
const example = resolveFirstExample(schema);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="openapi-schema-presentation">
|
<div id={id} className="openapi-schema-presentation">
|
||||||
<OpenAPISchemaName
|
<OpenAPISchemaName
|
||||||
schema={schema}
|
schema={schema}
|
||||||
type={getSchemaTitle(schema)}
|
type={getSchemaTitle(schema)}
|
||||||
@@ -380,38 +388,44 @@ export function OpenAPISchemaPresentation(props: {
|
|||||||
required={required}
|
required={required}
|
||||||
context={context}
|
context={context}
|
||||||
/>
|
/>
|
||||||
{typeof schema['x-deprecated-sunset'] === 'string' ? (
|
{circularRefId ? (
|
||||||
<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
|
<OpenAPISchemaCircularRef id={circularRefId} schema={schema} />
|
||||||
Sunset date:{' '}
|
) : (
|
||||||
<span className="openapi-deprecated-sunset-date">
|
<>
|
||||||
{schema['x-deprecated-sunset']}
|
{typeof schema['x-deprecated-sunset'] === 'string' ? (
|
||||||
</span>
|
<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
|
||||||
</div>
|
Sunset date:{' '}
|
||||||
) : null}
|
<span className="openapi-deprecated-sunset-date">
|
||||||
{description ? (
|
{schema['x-deprecated-sunset']}
|
||||||
<Markdown source={description} className="openapi-schema-description" />
|
</span>
|
||||||
) : null}
|
</div>
|
||||||
{schema.default !== undefined ? (
|
) : null}
|
||||||
<span className="openapi-schema-default">
|
{description ? (
|
||||||
Default:{' '}
|
<Markdown source={description} className="openapi-schema-description" />
|
||||||
<code>
|
) : null}
|
||||||
{typeof schema.default === 'string' && schema.default
|
{schema.default !== undefined ? (
|
||||||
? schema.default
|
<span className="openapi-schema-default">
|
||||||
: stringifyOpenAPI(schema.default)}
|
Default:{' '}
|
||||||
</code>
|
<code>
|
||||||
</span>
|
{typeof schema.default === 'string' && schema.default
|
||||||
) : null}
|
? schema.default
|
||||||
{typeof example === 'string' ? (
|
: stringifyOpenAPI(schema.default)}
|
||||||
<span className="openapi-schema-example">
|
</code>
|
||||||
Example: <code>{example}</code>
|
</span>
|
||||||
</span>
|
) : null}
|
||||||
) : null}
|
{typeof example === 'string' ? (
|
||||||
{schema.pattern ? (
|
<span className="openapi-schema-example">
|
||||||
<span className="openapi-schema-pattern">
|
Example: <code>{example}</code>
|
||||||
Pattern: <code>{schema.pattern}</code>
|
</span>
|
||||||
</span>
|
) : null}
|
||||||
) : null}
|
{schema.pattern ? (
|
||||||
<OpenAPISchemaEnum schema={schema} context={context} />
|
<span className="openapi-schema-pattern">
|
||||||
|
Pattern: <code>{schema.pattern}</code>
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
<OpenAPISchemaEnum schema={schema} context={context} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user