mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 05:48:57 +00:00
Support expand-all options for OpenAPI (#4116)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gitbook/openapi-parser": patch
|
||||
"@gitbook/react-openapi": patch
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Support expand-all options for OpenAPI
|
||||
@@ -50,6 +50,10 @@ async function OpenAPIOperationBody(props: BlockProps<AnyOpenAPIOperationsBlock>
|
||||
props,
|
||||
specUrl: publicURL,
|
||||
context: context.contentContext,
|
||||
expandAllResponses:
|
||||
data.operation['x-expandAllResponses'] ?? data['x-expandAllResponses'],
|
||||
expandAllModelSections:
|
||||
data.operation['x-expandAllModelSections'] ?? data['x-expandAllModelSections'],
|
||||
})}
|
||||
className="openapi-block"
|
||||
/>
|
||||
|
||||
@@ -46,12 +46,13 @@ async function OpenAPISchemasBody(props: BlockProps<OpenAPISchemasBlock>) {
|
||||
|
||||
return (
|
||||
<BaseOpenAPISchemas
|
||||
schemas={data.schemas}
|
||||
data={data}
|
||||
grouped={block.data.grouped}
|
||||
context={getOpenAPIContext({
|
||||
props,
|
||||
specUrl: publicURL,
|
||||
context: context.contentContext,
|
||||
expandAllModelSections: data['x-expandAllModelSections'],
|
||||
})}
|
||||
className="openapi-block"
|
||||
/>
|
||||
|
||||
@@ -52,6 +52,10 @@ async function OpenAPIWebhookBody(props: BlockProps<OpenAPIWebhookBlock>) {
|
||||
props,
|
||||
specUrl: publicURL,
|
||||
context: context.contentContext,
|
||||
expandAllResponses:
|
||||
data.operation['x-expandAllResponses'] ?? data['x-expandAllResponses'],
|
||||
expandAllModelSections:
|
||||
data.operation['x-expandAllModelSections'] ?? data['x-expandAllModelSections'],
|
||||
})}
|
||||
className="openapi-block"
|
||||
/>
|
||||
|
||||
@@ -24,8 +24,10 @@ export function getOpenAPIContext(args: {
|
||||
props: BlockProps<AnyOpenAPIOperationsBlock | OpenAPISchemasBlock | OpenAPIWebhookBlock>;
|
||||
specUrl: string | null;
|
||||
context: GitBookAnyContext | undefined;
|
||||
expandAllResponses?: boolean;
|
||||
expandAllModelSections?: boolean;
|
||||
}): OpenAPIContextInput {
|
||||
const { props, specUrl, context } = args;
|
||||
const { props, specUrl, context, expandAllResponses, expandAllModelSections } = args;
|
||||
const { block } = props;
|
||||
|
||||
const customizationLocale = context ? getSpaceLocale(context) : DEFAULT_LOCALE;
|
||||
@@ -91,7 +93,8 @@ export function getOpenAPIContext(args: {
|
||||
}}
|
||||
/>
|
||||
),
|
||||
defaultInteractiveOpened: props.context.mode === 'print',
|
||||
expandAllResponses: expandAllResponses || props.context.mode === 'print',
|
||||
expandAllModelSections: expandAllModelSections || props.context.mode === 'print',
|
||||
id: block.meta?.id,
|
||||
blockKey: block.key,
|
||||
locale,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { OpenAPIParseError, type OpenAPISchema } from '@gitbook/openapi-parser';
|
||||
import { resolveOpenAPISchemas } from '@gitbook/react-openapi';
|
||||
import { OpenAPIParseError } from '@gitbook/openapi-parser';
|
||||
import { type OpenAPISchemasData, resolveOpenAPISchemas } from '@gitbook/react-openapi';
|
||||
import { fetchOpenAPIFilesystem } from './fetch';
|
||||
import type {
|
||||
OpenAPISchemasBlock,
|
||||
@@ -7,9 +7,7 @@ import type {
|
||||
ResolveOpenAPIBlockResult,
|
||||
} from './types';
|
||||
|
||||
type ResolveOpenAPISchemasBlockResult = ResolveOpenAPIBlockResult<{
|
||||
schemas: OpenAPISchema[];
|
||||
}>;
|
||||
type ResolveOpenAPISchemasBlockResult = ResolveOpenAPIBlockResult<OpenAPISchemasData>;
|
||||
|
||||
const weakmap = new WeakMap<OpenAPISchemasBlock, Promise<ResolveOpenAPISchemasBlockResult>>();
|
||||
|
||||
|
||||
@@ -23,6 +23,16 @@ export interface OpenAPICustomSpecProperties {
|
||||
*/
|
||||
'x-enable-proxy'?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, all response sections will be expanded by default.
|
||||
*/
|
||||
'x-expandAllResponses'?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, all model/schema sections will be expanded by default.
|
||||
*/
|
||||
'x-expandAllModelSections'?: boolean;
|
||||
|
||||
/**
|
||||
* Description in HTML format.
|
||||
*/
|
||||
@@ -75,6 +85,16 @@ export interface OpenAPICustomOperationProperties {
|
||||
*/
|
||||
'x-enable-proxy'?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, all response sections will be expanded by default.
|
||||
*/
|
||||
'x-expandAllResponses'?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, all model/schema sections will be expanded by default.
|
||||
*/
|
||||
'x-expandAllModelSections'?: boolean;
|
||||
|
||||
/**
|
||||
* Stability of the operation.
|
||||
* @enum 'experimental' | 'alpha' | 'beta'
|
||||
|
||||
@@ -43,6 +43,7 @@ export function OpenAPIResponse(props: {
|
||||
/>
|
||||
}
|
||||
icon={context.icons.plus}
|
||||
defaultExpanded={context.expandAllModelSections}
|
||||
label={(isExpanded) =>
|
||||
tString(
|
||||
context.translation,
|
||||
|
||||
@@ -107,11 +107,19 @@ export function OpenAPIResponses(props: {
|
||||
|
||||
const state = useResponseExamplesState(context.blockKey, groups[0]?.key);
|
||||
|
||||
const expandAll = context.expandAllResponses;
|
||||
const expandedKeys = expandAll
|
||||
? new Set(groups.map((g) => g.key))
|
||||
: state.key
|
||||
? new Set([state.key])
|
||||
: new Set<string>();
|
||||
|
||||
return (
|
||||
<StaticSection header={t(context.translation, 'responses')} className="openapi-responses">
|
||||
<OpenAPIDisclosureGroup
|
||||
icon={context.icons.chevronRight}
|
||||
expandedKeys={state.key ? new Set([state.key]) : new Set()}
|
||||
allowsMultipleExpanded={expandAll}
|
||||
expandedKeys={expandedKeys}
|
||||
onExpandedChange={(keys) => {
|
||||
const key = keys.values().next().value ?? null;
|
||||
state.setKey(key);
|
||||
|
||||
@@ -130,6 +130,7 @@ function OpenAPISchemaProperty(
|
||||
label={(isExpanded) =>
|
||||
getDisclosureLabel({ schema: effectiveSchema, isExpanded, context })
|
||||
}
|
||||
defaultExpanded={context.expandAllModelSections}
|
||||
>
|
||||
{content}
|
||||
</OpenAPIDisclosure>
|
||||
@@ -408,6 +409,7 @@ function OpenAPISchemaAlternative(props: {
|
||||
icon={context.icons.plus}
|
||||
header={<OpenAPISchemaPresentation property={{ schema }} context={context} />}
|
||||
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
|
||||
defaultExpanded={context.expandAllModelSections}
|
||||
>
|
||||
<OpenAPISchemaProperties
|
||||
properties={properties}
|
||||
|
||||
@@ -19,10 +19,16 @@ export interface OpenAPIClientContext {
|
||||
};
|
||||
|
||||
/**
|
||||
* Force all sections to be opened by default.
|
||||
* If `true`, all response sections will be expanded by default.
|
||||
* @default false
|
||||
*/
|
||||
defaultInteractiveOpened?: boolean;
|
||||
expandAllResponses?: boolean;
|
||||
|
||||
/**
|
||||
* If `true`, all model/schema sections will be expanded by default.
|
||||
* @default false
|
||||
*/
|
||||
expandAllModelSections?: boolean;
|
||||
|
||||
/**
|
||||
* The key of the block
|
||||
@@ -107,7 +113,8 @@ export function getOpenAPIClientContext(context: OpenAPIUniversalContext): OpenA
|
||||
return {
|
||||
translation: context.translation,
|
||||
icons: context.icons,
|
||||
defaultInteractiveOpened: context.defaultInteractiveOpened,
|
||||
expandAllResponses: context.expandAllResponses,
|
||||
expandAllModelSections: context.expandAllModelSections,
|
||||
blockKey: context.blockKey,
|
||||
id: context.id,
|
||||
proxyUrl: '$$isClientContext$$' in context ? context.proxyUrl : undefined,
|
||||
|
||||
@@ -83,6 +83,14 @@ export async function resolveOpenAPIOperation(
|
||||
: undefined,
|
||||
'x-enable-proxy':
|
||||
typeof schema['x-enable-proxy'] === 'boolean' ? schema['x-enable-proxy'] : undefined,
|
||||
'x-expandAllResponses':
|
||||
typeof schema['x-expandAllResponses'] === 'boolean'
|
||||
? schema['x-expandAllResponses']
|
||||
: undefined,
|
||||
'x-expandAllModelSections':
|
||||
typeof schema['x-expandAllModelSections'] === 'boolean'
|
||||
? schema['x-expandAllModelSections']
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,14 @@ export async function resolveOpenAPIWebhook(
|
||||
operation,
|
||||
method,
|
||||
name,
|
||||
'x-expandAllResponses':
|
||||
typeof schema['x-expandAllResponses'] === 'boolean'
|
||||
? schema['x-expandAllResponses']
|
||||
: undefined,
|
||||
'x-expandAllModelSections':
|
||||
typeof schema['x-expandAllModelSections'] === 'boolean'
|
||||
? schema['x-expandAllModelSections']
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ export function OpenAPISchemaItem(props: {
|
||||
icon={context.icons.plus}
|
||||
header={name}
|
||||
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
|
||||
defaultExpanded={context.expandAllModelSections}
|
||||
>
|
||||
<Section className="openapi-section-schemas">
|
||||
<SectionBody>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { OpenAPISchema } from '@gitbook/openapi-parser';
|
||||
import clsx from 'classnames';
|
||||
import { OpenAPIExample } from '../OpenAPIExample';
|
||||
import { OpenAPIRootSchema } from '../OpenAPISchemaServer';
|
||||
@@ -11,20 +10,22 @@ import {
|
||||
import { t } from '../translate';
|
||||
import { getExampleFromSchema } from '../util/example';
|
||||
import { OpenAPISchemaItem } from './OpenAPISchemaItem';
|
||||
import type { OpenAPISchemasData } from './resolveOpenAPISchemas';
|
||||
|
||||
/**
|
||||
* OpenAPI Schemas component.
|
||||
*/
|
||||
export function OpenAPISchemas(props: {
|
||||
className?: string;
|
||||
schemas: OpenAPISchema[];
|
||||
data: OpenAPISchemasData;
|
||||
context: OpenAPIContextInput;
|
||||
/**
|
||||
* Whether to show the schema directly if there is only one.
|
||||
*/
|
||||
grouped?: boolean;
|
||||
}) {
|
||||
const { schemas, context: contextInput, grouped, className } = props;
|
||||
const { data, context: contextInput, grouped, className } = props;
|
||||
const { schemas } = data;
|
||||
|
||||
const firstSchema = schemas[0];
|
||||
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import type { Filesystem, OpenAPISchema, OpenAPIV3xDocument } from '@gitbook/openapi-parser';
|
||||
import type {
|
||||
Filesystem,
|
||||
OpenAPICustomSpecProperties,
|
||||
OpenAPISchema,
|
||||
OpenAPIV3xDocument,
|
||||
} from '@gitbook/openapi-parser';
|
||||
import { filterSelectedOpenAPISchemas } from '@gitbook/openapi-parser';
|
||||
import { dereferenceFilesystem } from '../dereference';
|
||||
|
||||
export type OpenAPISchemasData = Pick<OpenAPICustomSpecProperties, 'x-expandAllModelSections'> & {
|
||||
schemas: OpenAPISchema[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve an OpenAPI schemas from a file and compile it to a more usable format.
|
||||
* Schemas are extracted from the OpenAPI components.schemas
|
||||
@@ -11,9 +20,7 @@ export async function resolveOpenAPISchemas(
|
||||
options: {
|
||||
schemas: string[];
|
||||
}
|
||||
): Promise<{
|
||||
schemas: OpenAPISchema[];
|
||||
} | null> {
|
||||
): Promise<OpenAPISchemasData | null> {
|
||||
const { schemas: selectedSchemas } = options;
|
||||
|
||||
const schema = await dereferenceFilesystem(filesystem);
|
||||
@@ -24,5 +31,11 @@ export async function resolveOpenAPISchemas(
|
||||
return null;
|
||||
}
|
||||
|
||||
return { schemas };
|
||||
return {
|
||||
schemas,
|
||||
'x-expandAllModelSections':
|
||||
typeof schema['x-expandAllModelSections'] === 'boolean'
|
||||
? schema['x-expandAllModelSections']
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user