mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 05:48:57 +00:00
Support GitBook blocks in OpenAPI operation description (#2868)
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user