Support GitBook blocks in OpenAPI operation description (#2868)

This commit is contained in:
Greg Bergé
2025-02-24 13:44:48 +01:00
committed by GitHub
parent dc2dbc5710
commit da55facf2c
8 changed files with 74 additions and 15 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@gitbook/openapi-parser': patch
'@gitbook/react-openapi': patch
'gitbook': patch
---
Render GitBook blocks in OpenAPI operation description
@@ -244,8 +244,8 @@ async function PDFPageDocument(props: {
{document ? (
<DocumentView
document={document}
style={'mt-6 space-y-6'}
blockStyle={['max-w-full']}
style="mt-6 space-y-6"
blockStyle="max-w-full"
context={{
mode: 'print',
content: {
@@ -1,4 +1,4 @@
import { DocumentBlockOpenAPI } from '@gitbook/api';
import { DocumentBlockOpenAPI, JSONDocument } from '@gitbook/api';
import { Icon } from '@gitbook/icons';
import { OpenAPIOperation } from '@gitbook/react-openapi';
import React from 'react';
@@ -8,6 +8,7 @@ import { tcls } from '@/lib/tailwind';
import { BlockProps } from '../Block';
import { PlainCodeBlock } from '../CodeBlock';
import { DocumentView } from '../DocumentView';
import { Heading } from '../Heading';
import './style.css';
@@ -57,7 +58,15 @@ async function OpenAPIBody(props: BlockProps<DocumentBlockOpenAPI>) {
chevronRight: <Icon icon="chevron-right" />,
plus: <Icon icon="plus" />,
},
CodeBlock: PlainCodeBlock,
renderCodeBlock: (codeProps) => <PlainCodeBlock {...codeProps} />,
renderDocument: (documentProps) => (
<DocumentView
document={documentProps.document as JSONDocument}
context={props.context}
style="space-y-6"
blockStyle="max-w-full"
/>
),
renderHeading: (headingProps) => (
<Heading
document={props.document}
+5
View File
@@ -42,6 +42,11 @@ export interface OpenAPICustomOperationProperties {
* Description in HTML format.
*/
'x-gitbook-description-html'?: string;
/**
* Description in Document format.
*/
'x-gitbook-description-document'?: object;
}
/**
@@ -72,7 +72,10 @@ export function OpenAPICodeSample(props: {
const autoCodeSamples = codeSampleGenerators.map((generator) => ({
key: `default-${generator.id}`,
label: generator.label,
body: <context.CodeBlock code={generator.generate(input)} syntax={generator.syntax} />,
body: context.renderCodeBlock({
code: generator.generate(input),
syntax: generator.syntax,
}),
}));
// Use custom samples if defined
@@ -95,7 +98,10 @@ export function OpenAPICodeSample(props: {
.map((sample) => ({
key: `redocly-${sample.lang}`,
label: sample.label,
body: <context.CodeBlock code={sample.source} syntax={sample.lang} />,
body: context.renderCodeBlock({
code: sample.source,
syntax: sample.lang,
}),
}));
}
});
@@ -7,6 +7,7 @@ import { OpenAPISpec } from './OpenAPISpec';
import type { OpenAPIClientContext, OpenAPIContextProps, OpenAPIOperationData } from './types';
import { OpenAPIPath } from './OpenAPIPath';
import { resolveDescription } from './utils';
import { OpenAPICustomOperationProperties, OpenAPIV3 } from '@gitbook/openapi-parser';
/**
* Display an interactive OpenAPI operation.
@@ -25,8 +26,6 @@ export function OpenAPIOperation(props: {
blockKey: context.blockKey,
};
const description = resolveDescription(operation);
return (
<div className={clsx('openapi-operation', className)}>
<div className="openapi-summary" id={operation.summary ? undefined : context.id}>
@@ -49,11 +48,7 @@ export function OpenAPIOperation(props: {
{`.`}
</div>
) : null}
{description ? (
<div className="openapi-intro">
<Markdown className="openapi-description" source={description} />
</div>
) : null}
<OpenAPIOperationDescription operation={operation} context={context} />
<OpenAPIPath data={data} context={context} />
<OpenAPISpec data={data} context={clientContext} />
</div>
@@ -67,3 +62,30 @@ export function OpenAPIOperation(props: {
</div>
);
}
function OpenAPIOperationDescription(props: {
operation: OpenAPIV3.OperationObject<OpenAPICustomOperationProperties>;
context: OpenAPIContextProps;
}) {
const { operation } = props;
if (operation['x-gitbook-description-document']) {
return (
<div className="openapi-intro">
{props.context.renderDocument({
document: operation['x-gitbook-description-document'],
})}
</div>
);
}
const description = resolveDescription(operation);
if (!description) {
return null;
}
return (
<div className="openapi-intro">
<Markdown className="openapi-description" source={description} />
</div>
);
}
@@ -209,7 +209,7 @@ function OpenAPIExample(props: {
return <OpenAPIEmptyResponseExample />;
}
return <context.CodeBlock code={code} syntax={syntax} />;
return context.renderCodeBlock({ code, syntax });
}
function stringifyExample(args: { example: OpenAPIV3.ExampleObject; xml: boolean }): string | null {
+11 -1
View File
@@ -5,8 +5,18 @@ import type {
} from '@gitbook/openapi-parser';
export interface OpenAPIContextProps extends OpenAPIClientContext {
CodeBlock: React.ComponentType<{ code: string; syntax: string }>;
/**
* Render a code block.
*/
renderCodeBlock: (props: { code: string; syntax: string }) => React.ReactNode;
/**
* Render the heading of the operation.
*/
renderHeading: (props: { deprecated: boolean; title: string }) => React.ReactNode;
/**
* Render the document of the operation.
*/
renderDocument: (props: { document: object }) => React.ReactNode;
/** Spec url for the Scalar Api Client */
specUrl: string;