mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-13 06:09:21 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33c30ba7a1 | |||
| 139a8050a5 | |||
| da7b369ffd | |||
| 432da64919 | |||
| 7d0b422200 | |||
| fb90eb0acc |
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@gitbook/react-openapi': patch
|
||||
'gitbook': patch
|
||||
---
|
||||
|
||||
Fix missing headers in OpenAPIResponses
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@gitbook/react-openapi': patch
|
||||
'gitbook': patch
|
||||
---
|
||||
|
||||
Fix OpenAPI enum display
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"packages/colors": {
|
||||
"name": "@gitbook/colors",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3",
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
},
|
||||
"packages/gitbook": {
|
||||
"name": "gitbook",
|
||||
"version": "0.8.2",
|
||||
"version": "0.9.1",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "*",
|
||||
"@gitbook/cache-do": "workspace:*",
|
||||
@@ -136,7 +136,7 @@
|
||||
},
|
||||
"packages/gitbook-v2": {
|
||||
"name": "gitbook-v2",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "*",
|
||||
"@gitbook/cache-tags": "workspace:*",
|
||||
@@ -162,7 +162,7 @@
|
||||
"name": "@gitbook/icons",
|
||||
"version": "0.2.0",
|
||||
"bin": {
|
||||
"gitbook-icons": "./bin/gitbook-icons.js",
|
||||
"gitbook-icons": "./bin/gitbook-icons.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
@@ -180,7 +180,7 @@
|
||||
},
|
||||
"packages/openapi-parser": {
|
||||
"name": "@gitbook/openapi-parser",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.2",
|
||||
"dependencies": {
|
||||
"@scalar/openapi-parser": "^0.10.10",
|
||||
"@scalar/openapi-types": "^0.1.9",
|
||||
@@ -219,7 +219,7 @@
|
||||
"name": "@gitbook/react-math",
|
||||
"version": "0.6.0",
|
||||
"bin": {
|
||||
"gitbook-math": "./bin/gitbook-math.js",
|
||||
"gitbook-math": "./bin/gitbook-math.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"object-hash": "^3.0.0",
|
||||
@@ -234,7 +234,7 @@
|
||||
},
|
||||
"packages/react-openapi": {
|
||||
"name": "@gitbook/react-openapi",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.8",
|
||||
"dependencies": {
|
||||
"@gitbook/openapi-parser": "workspace:*",
|
||||
"@scalar/api-client-react": "^1.2.5",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @gitbook/colors
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fb90eb0: Reduce chroma of first color scale step
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
|
||||
@@ -220,7 +220,7 @@ export function colorScale(
|
||||
continue;
|
||||
}
|
||||
|
||||
const chromaRatio = index < 8 ? (index + 1) * 0.05 : 1;
|
||||
const chromaRatio = index < 8 ? index * 0.05 : 1;
|
||||
|
||||
const shade = {
|
||||
L: targetL, // Blend lightness
|
||||
|
||||
@@ -179,4 +179,9 @@ export interface GitBookDataFetcher {
|
||||
integrationName: string;
|
||||
request: api.RenderIntegrationUI;
|
||||
}): Promise<DataFetcherResponse<api.ContentKitRenderOutput>>;
|
||||
|
||||
getAction(params: {
|
||||
url: string
|
||||
claims: any
|
||||
}): Promise<DataFetcherResponse<{ text: string; url: string; icon?: string }>>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# gitbook
|
||||
|
||||
## 0.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fb90eb0: Limit tinted background on bold theme to sites with filled sidebar
|
||||
- 7d0b422: Handle grouped OpenAPISchemas
|
||||
- Updated dependencies [7d0b422]
|
||||
- Updated dependencies [fb90eb0]
|
||||
- @gitbook/react-openapi@1.1.8
|
||||
- @gitbook/colors@0.3.1
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "env-cmd --silent -f ../../.env.local next dev",
|
||||
|
||||
@@ -25,10 +25,21 @@ export async function POST(req: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
const result = await revalidateTags(json.tags);
|
||||
try {
|
||||
const result = await revalidateTags(json.tags);
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
stats: result.stats,
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to revalidate tags',
|
||||
message: err instanceof Error ? err.message : 'Internal Server Error',
|
||||
stack: err instanceof Error ? err.stack : '',
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
stats: result.stats,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ const HINT_STYLES: {
|
||||
'[&_.can-override-text]:text-neutral-strong',
|
||||
],
|
||||
container:
|
||||
'bg-info border-info theme-muted-tint:bg-info-solid/2 theme-bold-tint:bg-info-solid/2',
|
||||
'bg-info border-info theme-muted-tint:bg-info-solid/2 [html.sidebar-filled.theme-bold.tint_&]:bg-info-solid/2',
|
||||
containerWithHeader: 'border-info-solid bg-info-subtle',
|
||||
},
|
||||
warning: {
|
||||
|
||||
@@ -13,6 +13,7 @@ import assertNever from 'assert-never';
|
||||
import { Annotation } from './Annotation/Annotation';
|
||||
import type { DocumentContextProps } from './DocumentView';
|
||||
import { Emoji } from './Emoji';
|
||||
import { InlineAction } from './InlineAction';
|
||||
import { InlineImage } from './InlineImage';
|
||||
import { InlineLink } from './InlineLink';
|
||||
import { InlineMath } from './Math';
|
||||
@@ -61,6 +62,8 @@ export function Inline<
|
||||
return <Mention {...contextProps} inline={inline} />;
|
||||
case 'inline-image':
|
||||
return <InlineImage {...contextProps} inline={inline} />;
|
||||
case 'action':
|
||||
return <InlineAction {...contextProps} inline={inline} />;
|
||||
default:
|
||||
assertNever(inline);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { getVisitorAuthClaims } from '@/lib/adaptive';
|
||||
import { getDataOrNull } from '@v2/lib/data';
|
||||
import { getSiteURLDataFromMiddleware } from '@v2/lib/middleware';
|
||||
import type { InlineProps } from './Inline';
|
||||
import { TrackEventButton } from './TrackEventButton';
|
||||
|
||||
export async function InlineAction(props: InlineProps<any>) {
|
||||
const { inline, context } = props;
|
||||
|
||||
if (!context.contentContext) {
|
||||
throw new Error('inline action requires a contentContext');
|
||||
}
|
||||
|
||||
const action = inline.data.action;
|
||||
|
||||
if (action.type === 'url') {
|
||||
return <TrackEventButton action={inline.data.action} resolved={{ url: action.url, text: action.text }} />
|
||||
}
|
||||
|
||||
// API action
|
||||
|
||||
const { dataFetcher } = context.contentContext;
|
||||
|
||||
const siteData = await getSiteURLDataFromMiddleware();
|
||||
const claims = getVisitorAuthClaims(siteData)
|
||||
const resolved = await getDataOrNull(dataFetcher.getAction({ url: inline.data.action.url, claims }));
|
||||
|
||||
if (!resolved) {
|
||||
throw new Error('inline action not found');
|
||||
}
|
||||
|
||||
return <TrackEventButton action={inline.data.action} resolved={resolved} />
|
||||
}
|
||||
@@ -50,6 +50,7 @@ async function OpenAPISchemasBody(props: BlockProps<OpenAPISchemasBlock>) {
|
||||
return (
|
||||
<BaseOpenAPISchemas
|
||||
data={data}
|
||||
grouped={block.data.grouped}
|
||||
context={{
|
||||
specUrl,
|
||||
icons: {
|
||||
|
||||
@@ -265,15 +265,11 @@
|
||||
|
||||
/* Schema Enum */
|
||||
.openapi-schema-enum {
|
||||
@apply flex flex-row text-sm leading-relaxed gap-2 flex-wrap text-tint;
|
||||
}
|
||||
|
||||
.openapi-schema-enum-list {
|
||||
@apply flex flex-row gap-1.5 items-center;
|
||||
@apply text-sm leading-relaxed max-w-full text-tint;
|
||||
}
|
||||
|
||||
.openapi-schema-enum-value {
|
||||
@apply text-sm;
|
||||
@apply text-sm mr-1.5;
|
||||
}
|
||||
|
||||
.openapi-schema-enum-value:first-child {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
'use client';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { useTrackEvent } from '../Insights';
|
||||
import { LoadingButton } from '../primitives';
|
||||
|
||||
export function TrackEventButton(props: {
|
||||
action: any;
|
||||
resolved: { url: string; text: string };
|
||||
}) {
|
||||
const { action, resolved } = props;
|
||||
const trackEvent = useTrackEvent();
|
||||
|
||||
return (
|
||||
<LoadingButton
|
||||
onClick={async () => {
|
||||
trackEvent({ type: 'action_click', action: action });
|
||||
window.open(resolved.url, '_blank', 'noopener noreferrer');
|
||||
}}
|
||||
href={resolved.url}
|
||||
variant="primary"
|
||||
size="medium"
|
||||
className={tcls(
|
||||
'theme-bold:bg-header-link theme-bold:text-header-background theme-bold:shadow-none theme-bold:hover:bg-header-link theme-bold:hover:text-header-background theme-bold:hover:shadow-none'
|
||||
)}
|
||||
// insights={{
|
||||
// type: 'link_click',
|
||||
// link: {
|
||||
// target: linkTarget,
|
||||
// position: SiteInsightsLinkPosition.Header,
|
||||
// },
|
||||
// }}
|
||||
>
|
||||
{resolved.text}
|
||||
</LoadingButton>
|
||||
);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ export function Header(props: { context: GitBookSiteContext; withTopHeader?: boo
|
||||
|
||||
'bg-tint-base/9',
|
||||
'theme-muted:bg-tint-subtle/9',
|
||||
'theme-bold-tint:bg-tint-subtle/9',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle/9',
|
||||
'theme-gradient:bg-gradient-primary',
|
||||
'theme-gradient-tint:bg-gradient-tint',
|
||||
'contrast-more:bg-tint-base',
|
||||
|
||||
@@ -93,6 +93,7 @@ export function InsightsProvider(props: InsightsProviderProps) {
|
||||
const flushEventsSync = useEventCallback(() => {
|
||||
const session = getSession();
|
||||
const visitorId = visitorIdRef.current;
|
||||
console.log('flushEventsSync');
|
||||
if (!visitorId) {
|
||||
throw new Error('Visitor ID should be set before flushing events');
|
||||
}
|
||||
@@ -126,6 +127,8 @@ export function InsightsProvider(props: InsightsProviderProps) {
|
||||
};
|
||||
}
|
||||
|
||||
console.log('allEvents', allEvents.length)
|
||||
|
||||
if (allEvents.length > 0) {
|
||||
if (enabled) {
|
||||
sendEvents({
|
||||
@@ -143,6 +146,7 @@ export function InsightsProvider(props: InsightsProviderProps) {
|
||||
const visitorId = visitorIdRef.current ?? (await getVisitorId(appURL));
|
||||
visitorIdRef.current = visitorId;
|
||||
|
||||
console.log('flushBatchedEvents');
|
||||
flushEventsSync();
|
||||
}, 1500);
|
||||
|
||||
@@ -167,6 +171,8 @@ export function InsightsProvider(props: InsightsProviderProps) {
|
||||
context,
|
||||
};
|
||||
|
||||
console.log('trackEvent', event, eventsRef.current[pathname].pageContext);
|
||||
|
||||
if (eventsRef.current[pathname].pageContext !== undefined) {
|
||||
// If the pageId is set, we know that the page_view event has been tracked
|
||||
// and we can flush the events
|
||||
|
||||
@@ -228,7 +228,7 @@ export function PageAside(props: {
|
||||
) : null}
|
||||
<div
|
||||
className={tcls(
|
||||
'sticky bottom-0 z-10 mt-auto flex flex-col bg-tint-base theme-bold-tint:bg-tint-subtle theme-gradient-tint:bg-gradient-tint theme-gradient:bg-gradient-primary theme-muted:bg-tint-subtle pb-4 page-api-block:xl:max-2xl:hidden page-api-block:xl:max-2xl:pb-0 page-api-block:xl:max-2xl:group-hover/aside:flex',
|
||||
'sticky bottom-0 z-10 mt-auto flex flex-col bg-tint-base theme-gradient-tint:bg-gradient-tint theme-gradient:bg-gradient-primary theme-muted:bg-tint-subtle pb-4 page-api-block:xl:max-2xl:hidden page-api-block:xl:max-2xl:pb-0 page-api-block:xl:max-2xl:group-hover/aside:flex [html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'page-api-block:xl:max-2xl:bg-transparent'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -111,7 +111,7 @@ export function ScrollSectionsList(props: { sections: DocumentSection[] }) {
|
||||
|
||||
'hover:bg-primary-hover',
|
||||
'theme-muted:hover:bg-primary-active',
|
||||
'theme-bold-tint:hover:bg-primary-active',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:hover:bg-primary-active',
|
||||
'theme-gradient:hover:bg-primary-active',
|
||||
|
||||
'tint:font-semibold',
|
||||
|
||||
@@ -153,9 +153,9 @@ export async function CustomizationRootLayout(props: {
|
||||
</head>
|
||||
<body
|
||||
className={tcls(
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'bg-tint-base',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
'theme-bold-tint:bg-tint-subtle',
|
||||
|
||||
'theme-gradient:bg-gradient-primary',
|
||||
'theme-gradient-tint:bg-gradient-tint'
|
||||
|
||||
@@ -32,7 +32,7 @@ export function SiteSectionList(props: { sections: ClientSiteSections; className
|
||||
<nav
|
||||
aria-label="Sections"
|
||||
className={tcls(
|
||||
'-mx-5 before:contents[] relative border-tint-subtle border-b from-transparent sidebar-filled:to-tint-subtle theme-bold-tint:to-tint-subtle theme-muted:to-tint-subtle to-tint-base text-sm text-tint before:pointer-events-none before:absolute before:right-2 before:bottom-0 before:left-0 before:h-12 before:bg-gradient-to-b [html.sidebar-filled.theme-bold.tint_&]:to-tint-base [html.sidebar-filled.theme-muted_&]:to-tint-base',
|
||||
'-mx-5 before:contents[] relative border-tint-subtle border-b from-transparent sidebar-filled:to-tint-subtle theme-muted:to-tint-subtle to-tint-base text-sm text-tint before:pointer-events-none before:absolute before:right-2 before:bottom-0 before:left-0 before:h-12 before:bg-gradient-to-b [html.sidebar-filled.theme-bold.tint_&]:to-tint-base [html.sidebar-filled.theme-bold.tint_&]:to-tint-subtle [html.sidebar-filled.theme-muted_&]:to-tint-base',
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -40,7 +40,7 @@ export function PageGroupItem(props: {
|
||||
'bg-tint-base',
|
||||
'sidebar-filled:bg-tint-subtle',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
'theme-bold-tint:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-muted_&]:bg-tint-base',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-base',
|
||||
'[html.sidebar-default.theme-gradient_&]:bg-gradient-primary',
|
||||
|
||||
@@ -75,7 +75,7 @@ export function TableOfContents(props: {
|
||||
|
||||
'sidebar-filled:bg-tint-subtle',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
'theme-bold-tint:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'[html.sidebar-filled.theme-muted_&]:bg-tint-base',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-base',
|
||||
'page-no-toc:!bg-transparent',
|
||||
|
||||
@@ -52,7 +52,7 @@ export function Trademark(props: {
|
||||
'before:to-tint-base',
|
||||
'sidebar-filled:before:to-tint-subtle',
|
||||
'theme-muted:before:to-tint-subtle',
|
||||
'theme-bold-tint:before:to-tint-subtle',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:before:to-tint-subtle',
|
||||
'[html.sidebar-filled.theme-muted_&]:before:to-tint-base',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:before:to-tint-base',
|
||||
'page-no-toc:before:!to-transparent'
|
||||
|
||||
@@ -79,7 +79,7 @@ function ThemeButton(props: {
|
||||
active && [
|
||||
'bg-primary',
|
||||
'theme-muted:bg-primary-hover',
|
||||
'theme-bold-tint:bg-primary-hover',
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-primary-hover',
|
||||
'hover:bg-primary',
|
||||
'text-primary-strong',
|
||||
'contrast-more:text-primary-strong',
|
||||
|
||||
@@ -6,7 +6,7 @@ import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
|
||||
import { Link, type LinkInsightsProps } from './Link';
|
||||
|
||||
type ButtonProps = {
|
||||
export type ButtonProps = {
|
||||
href?: string;
|
||||
variant?: 'primary' | 'secondary';
|
||||
size?: 'default' | 'medium' | 'small';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { useTransition } from 'react';
|
||||
import { Button, type ButtonProps } from './Button';
|
||||
|
||||
export function LoadingButton({ href, onClick, className, ...rest }: ButtonProps & { onClick: () => Promise<void> }) {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
startTransition(onClick);
|
||||
return false;
|
||||
}
|
||||
return <Button className={tcls(className, isPending ? 'animate-pulse' : '')} {...rest} onClick={handleClick} />
|
||||
}
|
||||
@@ -8,3 +8,4 @@ export * from './StyledLink';
|
||||
export * from './DateRelative';
|
||||
export * from './Emoji';
|
||||
export * from './LoadingPane';
|
||||
export * from './LoadingButton';
|
||||
@@ -6,6 +6,7 @@ import { headers } from 'next/headers';
|
||||
export async function shouldTrackEvents(): Promise<boolean> {
|
||||
const headersList = await headers();
|
||||
|
||||
return true;
|
||||
if (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
(process.env.GITBOOK_BLOCK_PAGE_VIEWS_TRACKING &&
|
||||
|
||||
@@ -270,6 +270,22 @@ async function getDataFetcherV1(): Promise<GitBookDataFetcher> {
|
||||
return result;
|
||||
});
|
||||
},
|
||||
|
||||
getAction(params) {
|
||||
return wrapDataFetcherError(async () => {
|
||||
console.log('fetching', params.url);
|
||||
const url = new URL(params.url);
|
||||
Object.keys(params.claims).forEach((key) => {
|
||||
url.searchParams.append(key, params.claims[key]);
|
||||
});
|
||||
const result = await fetch(url.toString());
|
||||
console.log('fetched', result.statusText)
|
||||
if (!result) {
|
||||
throw new DataFetcherError('Action not found', 404);
|
||||
}
|
||||
return await result.json();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return dataFetcher;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @gitbook/react-openapi
|
||||
|
||||
## 1.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7d0b422: Handle grouped OpenAPISchemas
|
||||
|
||||
## 1.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"version": "1.1.7",
|
||||
"version": "1.1.8",
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@gitbook/openapi-parser": "workspace:*",
|
||||
|
||||
@@ -36,13 +36,15 @@ export function OpenAPIResponse(props: {
|
||||
/>
|
||||
</OpenAPIDisclosure>
|
||||
) : null}
|
||||
<div className="openapi-responsebody">
|
||||
<OpenAPISchemaProperties
|
||||
id={`response-${context.blockKey}`}
|
||||
properties={mediaType.schema ? [{ schema: mediaType.schema }] : []}
|
||||
context={context}
|
||||
/>
|
||||
</div>
|
||||
{mediaType.schema && (
|
||||
<div className="openapi-responsebody">
|
||||
<OpenAPISchemaProperties
|
||||
id={`response-${context.blockKey}`}
|
||||
properties={[{ schema: mediaType.schema }]}
|
||||
context={context}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,42 @@ export function OpenAPIResponses(props: {
|
||||
icon={context.icons.chevronRight}
|
||||
groups={Object.entries(responses).map(
|
||||
([statusCode, response]: [string, OpenAPIV3.ResponseObject]) => {
|
||||
const content = Object.entries(response.content ?? {});
|
||||
const tabs = (() => {
|
||||
// If there is no content, but there are headers, we need to show the headers
|
||||
if (
|
||||
(!response.content || !Object.keys(response.content).length) &&
|
||||
response.headers &&
|
||||
Object.keys(response.headers).length
|
||||
) {
|
||||
return [
|
||||
{
|
||||
id: 'default',
|
||||
body: (
|
||||
<OpenAPIResponse
|
||||
response={response}
|
||||
mediaType={{}}
|
||||
context={context}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return Object.entries(response.content ?? {}).map(
|
||||
([contentType, mediaType]) => ({
|
||||
id: contentType,
|
||||
label: contentType,
|
||||
body: (
|
||||
<OpenAPIResponse
|
||||
response={response}
|
||||
mediaType={mediaType}
|
||||
context={context}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
})();
|
||||
|
||||
const description = response.description;
|
||||
|
||||
return {
|
||||
@@ -39,17 +74,7 @@ export function OpenAPIResponses(props: {
|
||||
) : null}
|
||||
</div>
|
||||
),
|
||||
tabs: content.map(([contentType, mediaType]) => ({
|
||||
id: contentType,
|
||||
label: contentType,
|
||||
body: (
|
||||
<OpenAPIResponse
|
||||
response={response}
|
||||
mediaType={mediaType}
|
||||
context={context}
|
||||
/>
|
||||
),
|
||||
})),
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
)}
|
||||
|
||||
@@ -275,22 +275,20 @@ function OpenAPISchemaEnum(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="openapi-schema-enum">
|
||||
<span>Available options:</span>
|
||||
<div className="openapi-schema-enum-list">
|
||||
{enumValues.map((item, index) => (
|
||||
<span key={index} className="openapi-schema-enum-value">
|
||||
<OpenAPICopyButton
|
||||
value={item.value}
|
||||
label={item.description}
|
||||
withTooltip={!!item.description}
|
||||
>
|
||||
<code>{`${item.value}`}</code>
|
||||
</OpenAPICopyButton>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<span className="openapi-schema-enum">
|
||||
Available options:{' '}
|
||||
{enumValues.map((item, index) => (
|
||||
<span key={index} className="openapi-schema-enum-value">
|
||||
<OpenAPICopyButton
|
||||
value={item.value}
|
||||
label={item.description}
|
||||
withTooltip={!!item.description}
|
||||
>
|
||||
<code>{`${item.value}`}</code>
|
||||
</OpenAPICopyButton>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,12 @@ export function OpenAPISchemas(props: {
|
||||
className?: string;
|
||||
data: OpenAPISchemasData;
|
||||
context: OpenAPISchemasContextProps;
|
||||
/**
|
||||
* Whether to show the schema directly if there is only one.
|
||||
*/
|
||||
grouped?: boolean;
|
||||
}) {
|
||||
const { className, data, context } = props;
|
||||
const { className, data, context, grouped } = props;
|
||||
const { schemas } = data;
|
||||
|
||||
const clientContext: OpenAPIClientContext = {
|
||||
@@ -32,7 +36,7 @@ export function OpenAPISchemas(props: {
|
||||
|
||||
return (
|
||||
<div className={clsx('openapi-schemas', className)}>
|
||||
<OpenAPIRootSchemasSchema schemas={schemas} context={clientContext} />
|
||||
<OpenAPIRootSchemasSchema grouped={grouped} schemas={schemas} context={clientContext} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -44,11 +48,12 @@ export function OpenAPISchemas(props: {
|
||||
function OpenAPIRootSchemasSchema(props: {
|
||||
schemas: OpenAPISchemasData['schemas'];
|
||||
context: OpenAPIClientContext;
|
||||
grouped?: boolean;
|
||||
}) {
|
||||
const { schemas, context } = props;
|
||||
const { schemas, context, grouped } = props;
|
||||
|
||||
// If there is only one model, we show it directly.
|
||||
if (schemas.length === 1) {
|
||||
// If there is only one model and we are not grouping, we show it directly.
|
||||
if (schemas.length === 1 && !grouped) {
|
||||
const schema = schemas?.[0]?.schema;
|
||||
|
||||
if (!schema) {
|
||||
|
||||
Reference in New Issue
Block a user