docusaurus-theme-openapi-docs 4.1.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
- package/lib/theme/ApiExplorer/Authorization/index.js +3 -0
- package/lib/theme/ApiExplorer/Body/index.js +11 -2
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +2 -1
- package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +50 -0
- package/lib/theme/ApiItem/Layout/index.js +6 -2
- package/lib/theme/ApiItem/index.js +15 -4
- package/lib/theme/ApiTabs/_ApiTabs.scss +0 -1
- package/lib/theme/ArrayBrackets/index.d.ts +3 -0
- package/lib/theme/ArrayBrackets/index.js +50 -0
- package/lib/theme/Markdown/Details/_Details.scss +5 -2
- package/lib/theme/Markdown/index.js +160 -18
- package/lib/theme/ParamsDetails/index.d.ts +6 -0
- package/lib/theme/ParamsDetails/index.js +134 -0
- package/lib/theme/ParamsItem/index.d.ts +1 -0
- package/lib/theme/ParamsItem/index.js +11 -48
- package/lib/theme/RequestSchema/index.d.ts +15 -0
- package/lib/theme/RequestSchema/index.js +243 -0
- package/lib/theme/ResponseExamples/index.d.ts +18 -0
- package/lib/theme/ResponseExamples/index.js +194 -0
- package/lib/theme/ResponseHeaders/index.d.ts +13 -0
- package/lib/theme/ResponseHeaders/index.js +39 -0
- package/lib/theme/ResponseSchema/index.d.ts +15 -0
- package/lib/theme/ResponseSchema/index.js +208 -0
- package/lib/theme/Schema/index.d.ts +8 -0
- package/lib/theme/Schema/index.js +887 -0
- package/lib/theme/SchemaItem/index.d.ts +8 -8
- package/lib/theme/SchemaItem/index.js +11 -41
- package/lib/theme/SkeletonLoader/index.d.ts +6 -0
- package/lib/theme/SkeletonLoader/index.js +20 -0
- package/lib/theme/StatusCodes/index.d.ts +9 -0
- package/lib/theme/StatusCodes/index.js +81 -0
- package/lib/theme/styles.scss +56 -9
- package/package.json +13 -8
- package/src/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
- package/src/theme/ApiExplorer/Authorization/index.tsx +3 -0
- package/src/theme/ApiExplorer/Body/index.tsx +3 -2
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +2 -1
- package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +50 -0
- package/src/theme/ApiItem/Layout/index.tsx +5 -2
- package/src/theme/ApiItem/index.tsx +14 -2
- package/src/theme/ApiTabs/_ApiTabs.scss +0 -1
- package/src/theme/ArrayBrackets/index.tsx +37 -0
- package/src/theme/Markdown/Details/_Details.scss +5 -2
- package/src/theme/Markdown/index.js +160 -18
- package/src/theme/ParamsDetails/index.tsx +88 -0
- package/src/theme/ParamsItem/index.tsx +9 -36
- package/src/theme/RequestSchema/index.tsx +164 -0
- package/src/theme/ResponseExamples/index.tsx +192 -0
- package/src/theme/ResponseHeaders/index.tsx +49 -0
- package/src/theme/ResponseSchema/index.tsx +151 -0
- package/src/theme/Schema/index.tsx +935 -0
- package/src/theme/SchemaItem/index.tsx +21 -43
- package/src/theme/SkeletonLoader/index.tsx +18 -0
- package/src/theme/StatusCodes/index.tsx +72 -0
- package/src/theme/styles.scss +56 -9
|
@@ -23,10 +23,13 @@
|
|
|
23
23
|
|
|
24
24
|
/* Top-Level Details Caret Styling */
|
|
25
25
|
.openapi-left-panel__container > .openapi-markdown__details > summary::before,
|
|
26
|
-
.openapi-markdown__details.mime > summary::before
|
|
27
|
-
.openapi-markdown__details.response > summary::before {
|
|
26
|
+
.openapi-markdown__details.mime > summary::before {
|
|
28
27
|
top: 0.1rem;
|
|
29
28
|
}
|
|
29
|
+
|
|
30
|
+
.openapi-markdown__details.response > summary::before {
|
|
31
|
+
top: 0.25rem; /* TODO: figure out why this is necessary */
|
|
32
|
+
}
|
|
30
33
|
/* End of Top-Level Details Caret Styling */
|
|
31
34
|
|
|
32
35
|
.openapi-markdown__details {
|
|
@@ -7,30 +7,172 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
|
+
import Admonition from "@theme/Admonition";
|
|
10
11
|
import CodeBlock from "@theme/CodeBlock";
|
|
11
12
|
import ReactMarkdown from "react-markdown";
|
|
12
13
|
import rehypeRaw from "rehype-raw";
|
|
14
|
+
import remarkGfm from "remark-gfm";
|
|
15
|
+
|
|
16
|
+
function remarkAdmonition() {
|
|
17
|
+
return (tree) => {
|
|
18
|
+
const openingTagRegex = /^:::(\w+)(?:\[(.*?)\])?\s*$/;
|
|
19
|
+
const closingTagRegex = /^:::\s*$/;
|
|
20
|
+
const textOnlyAdmonition = /^:::(\w+)(?:\[(.*?)\])?\s*([\s\S]*?)\s*:::$/;
|
|
21
|
+
|
|
22
|
+
const nodes = [];
|
|
23
|
+
let bufferedChildren = [];
|
|
24
|
+
|
|
25
|
+
let insideAdmonition = false;
|
|
26
|
+
let type = null;
|
|
27
|
+
let title = null;
|
|
28
|
+
|
|
29
|
+
tree.children.forEach((node) => {
|
|
30
|
+
if (
|
|
31
|
+
node.type === "paragraph" &&
|
|
32
|
+
node.children.length === 1 &&
|
|
33
|
+
node.children[0].type === "text"
|
|
34
|
+
) {
|
|
35
|
+
const text = node.children[0].value.trim();
|
|
36
|
+
const openingMatch = text.match(openingTagRegex);
|
|
37
|
+
const closingMatch = text.match(closingTagRegex);
|
|
38
|
+
const textOnlyAdmonitionMatch = text.match(textOnlyAdmonition);
|
|
39
|
+
|
|
40
|
+
if (textOnlyAdmonitionMatch) {
|
|
41
|
+
const type = textOnlyAdmonitionMatch[1];
|
|
42
|
+
const title = textOnlyAdmonitionMatch[2]
|
|
43
|
+
? textOnlyAdmonitionMatch[2]?.trim()
|
|
44
|
+
: undefined;
|
|
45
|
+
const content = textOnlyAdmonitionMatch[3];
|
|
46
|
+
|
|
47
|
+
const admonitionNode = {
|
|
48
|
+
type: "admonition",
|
|
49
|
+
data: {
|
|
50
|
+
hName: "Admonition", // Tells ReactMarkdown to replace the node with Admonition component
|
|
51
|
+
hProperties: {
|
|
52
|
+
type, // Passed as a prop to the Admonition component
|
|
53
|
+
title,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
children: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
value: content?.trim(), // Trim leading/trailing whitespace
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
nodes.push(admonitionNode);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (openingMatch) {
|
|
68
|
+
type = openingMatch[1];
|
|
69
|
+
title = openingMatch[2] || type;
|
|
70
|
+
insideAdmonition = true;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (closingMatch && insideAdmonition) {
|
|
75
|
+
nodes.push({
|
|
76
|
+
type: "admonition",
|
|
77
|
+
data: {
|
|
78
|
+
hName: "Admonition",
|
|
79
|
+
hProperties: { type: type, title: title },
|
|
80
|
+
},
|
|
81
|
+
children: bufferedChildren,
|
|
82
|
+
});
|
|
83
|
+
bufferedChildren = [];
|
|
84
|
+
insideAdmonition = false;
|
|
85
|
+
type = null;
|
|
86
|
+
title = null;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (insideAdmonition) {
|
|
92
|
+
bufferedChildren.push(node);
|
|
93
|
+
} else {
|
|
94
|
+
nodes.push(node);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (bufferedChildren.length > 0 && type) {
|
|
99
|
+
nodes.push({
|
|
100
|
+
type: "admonition",
|
|
101
|
+
data: {
|
|
102
|
+
hName: "Admonition",
|
|
103
|
+
hProperties: { type: type, title: title },
|
|
104
|
+
},
|
|
105
|
+
children: bufferedChildren,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
tree.children = nodes;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function convertAstToHtmlStr(ast) {
|
|
113
|
+
if (!ast || !Array.isArray(ast)) {
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const convertNode = (node) => {
|
|
118
|
+
switch (node.type) {
|
|
119
|
+
case "text":
|
|
120
|
+
return node.value;
|
|
121
|
+
case "element":
|
|
122
|
+
const { tagName, properties, children } = node;
|
|
123
|
+
|
|
124
|
+
// Convert attributes to a string
|
|
125
|
+
const attrs = properties
|
|
126
|
+
? Object.entries(properties)
|
|
127
|
+
.map(([key, value]) => `${key}="${value}"`)
|
|
128
|
+
.join(" ")
|
|
129
|
+
: "";
|
|
130
|
+
|
|
131
|
+
// Convert children to HTML
|
|
132
|
+
const childrenHtml = children ? children.map(convertNode).join("") : "";
|
|
133
|
+
|
|
134
|
+
return `<${tagName} ${attrs}>${childrenHtml}</${tagName}>`;
|
|
135
|
+
default:
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return ast.map(convertNode).join("");
|
|
141
|
+
}
|
|
13
142
|
|
|
14
143
|
function Markdown({ children }) {
|
|
15
144
|
return (
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
145
|
+
<ReactMarkdown
|
|
146
|
+
rehypePlugins={[rehypeRaw]}
|
|
147
|
+
remarkPlugins={[remarkGfm, remarkAdmonition]}
|
|
148
|
+
components={{
|
|
149
|
+
pre: (props) => <div {...props} />,
|
|
150
|
+
code({ node, inline, className, children, ...props }) {
|
|
151
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
152
|
+
return match ? (
|
|
153
|
+
<CodeBlock className={className} language={match[1]} {...props}>
|
|
154
|
+
{children}
|
|
155
|
+
</CodeBlock>
|
|
156
|
+
) : (
|
|
157
|
+
<code className={className} {...props}>
|
|
158
|
+
{children}
|
|
159
|
+
</code>
|
|
160
|
+
);
|
|
161
|
+
},
|
|
162
|
+
admonition: ({ node, ...props }) => {
|
|
163
|
+
const type = node.data?.hProperties?.type || "note";
|
|
164
|
+
const title = node.data?.hProperties?.title || type;
|
|
165
|
+
const content = convertAstToHtmlStr(node.children);
|
|
166
|
+
return (
|
|
167
|
+
<Admonition type={type} title={title} {...props}>
|
|
168
|
+
<div dangerouslySetInnerHTML={{ __html: content }} />
|
|
169
|
+
</Admonition>
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
{children}
|
|
175
|
+
</ReactMarkdown>
|
|
34
176
|
);
|
|
35
177
|
}
|
|
36
178
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import React, { Suspense } from "react";
|
|
9
|
+
|
|
10
|
+
import BrowserOnly from "@docusaurus/BrowserOnly";
|
|
11
|
+
import Details from "@theme/Details";
|
|
12
|
+
import ParamsItem from "@theme/ParamsItem";
|
|
13
|
+
import SkeletonLoader from "@theme/SkeletonLoader";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
parameters: any[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ParamsDetailsComponent: React.FC<Props> = ({ parameters }) => {
|
|
20
|
+
const types = ["path", "query", "header", "cookie"];
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
{types.map((type) => {
|
|
25
|
+
const params = parameters?.filter((param: any) => param?.in === type);
|
|
26
|
+
|
|
27
|
+
if (!params || params.length === 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const summaryElement = (
|
|
32
|
+
<summary>
|
|
33
|
+
<h3 className="openapi-markdown__details-summary-header-params">
|
|
34
|
+
{`${type.charAt(0).toUpperCase() + type.slice(1)} Parameters`}
|
|
35
|
+
</h3>
|
|
36
|
+
</summary>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Details
|
|
41
|
+
key={type}
|
|
42
|
+
className="openapi-markdown__details"
|
|
43
|
+
style={{ marginBottom: "1rem" }}
|
|
44
|
+
data-collapsed={false}
|
|
45
|
+
open={true}
|
|
46
|
+
summary={summaryElement}
|
|
47
|
+
>
|
|
48
|
+
<ul>
|
|
49
|
+
{params.map((param: any, index: number) => (
|
|
50
|
+
<ParamsItem
|
|
51
|
+
key={index}
|
|
52
|
+
className="paramsItem"
|
|
53
|
+
param={{
|
|
54
|
+
...param,
|
|
55
|
+
enumDescriptions: Object.entries(
|
|
56
|
+
param?.schema?.["x-enumDescriptions"] ??
|
|
57
|
+
param?.schema?.items?.["x-enumDescriptions"] ??
|
|
58
|
+
{}
|
|
59
|
+
),
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
))}
|
|
63
|
+
</ul>
|
|
64
|
+
</Details>
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
</>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const ParamsDetails: React.FC<Props> = (props) => {
|
|
72
|
+
return (
|
|
73
|
+
<BrowserOnly fallback={<SkeletonLoader size="sm" />}>
|
|
74
|
+
{() => {
|
|
75
|
+
const LazyComponent = React.lazy(() =>
|
|
76
|
+
Promise.resolve({ default: ParamsDetailsComponent })
|
|
77
|
+
);
|
|
78
|
+
return (
|
|
79
|
+
<Suspense fallback={null}>
|
|
80
|
+
<LazyComponent {...props} />
|
|
81
|
+
</Suspense>
|
|
82
|
+
);
|
|
83
|
+
}}
|
|
84
|
+
</BrowserOnly>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default ParamsDetails;
|
|
@@ -7,16 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import Markdown from "@theme/Markdown";
|
|
11
11
|
import SchemaTabs from "@theme/SchemaTabs";
|
|
12
12
|
import TabItem from "@theme/TabItem";
|
|
13
13
|
/* eslint-disable import/no-extraneous-dependencies*/
|
|
14
14
|
import clsx from "clsx";
|
|
15
|
-
import ReactMarkdown from "react-markdown";
|
|
16
|
-
import rehypeRaw from "rehype-raw";
|
|
17
|
-
import remarkGfm from "remark-gfm";
|
|
18
15
|
|
|
19
|
-
import { createDescription } from "../../markdown/createDescription";
|
|
20
16
|
import { getQualifierMessage, getSchemaName } from "../../markdown/schema";
|
|
21
17
|
import { guard, toString } from "../../markdown/utils";
|
|
22
18
|
|
|
@@ -32,6 +28,7 @@ export interface ExampleObject {
|
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
export interface Props {
|
|
31
|
+
className: string;
|
|
35
32
|
param: {
|
|
36
33
|
description: string;
|
|
37
34
|
example: any;
|
|
@@ -96,45 +93,21 @@ function ParamsItem({ param, ...rest }: Props) {
|
|
|
96
93
|
<span className="openapi-schema__deprecated">deprecated</span>
|
|
97
94
|
));
|
|
98
95
|
|
|
99
|
-
const
|
|
100
|
-
<
|
|
101
|
-
<ReactMarkdown
|
|
102
|
-
children={createDescription(message)}
|
|
103
|
-
rehypePlugins={[rehypeRaw]}
|
|
104
|
-
/>
|
|
105
|
-
</div>
|
|
96
|
+
const renderQualifier = guard(getQualifierMessage(schema), (qualifier) => (
|
|
97
|
+
<Markdown>{qualifier}</Markdown>
|
|
106
98
|
));
|
|
107
99
|
|
|
108
100
|
const renderDescription = guard(description, (description) => (
|
|
109
|
-
<
|
|
110
|
-
<ReactMarkdown
|
|
111
|
-
children={createDescription(description)}
|
|
112
|
-
components={{
|
|
113
|
-
pre: "div",
|
|
114
|
-
code({ node, inline, className, children, ...props }) {
|
|
115
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
116
|
-
if (inline) return <code>{children}</code>;
|
|
117
|
-
return !inline && match ? (
|
|
118
|
-
<CodeBlock className={className}>{children}</CodeBlock>
|
|
119
|
-
) : (
|
|
120
|
-
<CodeBlock>{children}</CodeBlock>
|
|
121
|
-
);
|
|
122
|
-
},
|
|
123
|
-
}}
|
|
124
|
-
rehypePlugins={[rehypeRaw]}
|
|
125
|
-
/>
|
|
126
|
-
</div>
|
|
101
|
+
<Markdown>{description}</Markdown>
|
|
127
102
|
));
|
|
128
103
|
|
|
129
104
|
const renderEnumDescriptions = guard(
|
|
130
105
|
getEnumDescriptionMarkdown(enumDescriptions),
|
|
131
106
|
(value) => {
|
|
132
107
|
return (
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
children={value}
|
|
137
|
-
/>
|
|
108
|
+
<div style={{ marginTop: ".5rem" }}>
|
|
109
|
+
<Markdown>{value}</Markdown>
|
|
110
|
+
</div>
|
|
138
111
|
);
|
|
139
112
|
}
|
|
140
113
|
);
|
|
@@ -214,7 +187,7 @@ function ParamsItem({ param, ...rest }: Props) {
|
|
|
214
187
|
{renderSchemaRequired}
|
|
215
188
|
{renderDeprecated}
|
|
216
189
|
</span>
|
|
217
|
-
{
|
|
190
|
+
{renderQualifier}
|
|
218
191
|
{renderDescription}
|
|
219
192
|
{renderEnumDescriptions}
|
|
220
193
|
{renderDefaultValue()}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import React, { Suspense } from "react";
|
|
9
|
+
|
|
10
|
+
import BrowserOnly from "@docusaurus/BrowserOnly";
|
|
11
|
+
import Details from "@theme/Details";
|
|
12
|
+
import Markdown from "@theme/Markdown";
|
|
13
|
+
import MimeTabs from "@theme/MimeTabs"; // Assume these components exist
|
|
14
|
+
import SchemaNode from "@theme/Schema";
|
|
15
|
+
import SkeletonLoader from "@theme/SkeletonLoader";
|
|
16
|
+
import TabItem from "@theme/TabItem";
|
|
17
|
+
import { MediaTypeObject } from "docusaurus-plugin-openapi-docs/lib/openapi/types";
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
style?: React.CSSProperties;
|
|
21
|
+
title: string;
|
|
22
|
+
body: {
|
|
23
|
+
content?: {
|
|
24
|
+
[key: string]: MediaTypeObject;
|
|
25
|
+
};
|
|
26
|
+
description?: string;
|
|
27
|
+
required?: string[] | boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
|
|
32
|
+
if (
|
|
33
|
+
body === undefined ||
|
|
34
|
+
body.content === undefined ||
|
|
35
|
+
Object.keys(body).length === 0 ||
|
|
36
|
+
Object.keys(body.content).length === 0
|
|
37
|
+
) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const mimeTypes = Object.keys(body.content);
|
|
42
|
+
|
|
43
|
+
if (mimeTypes.length > 1) {
|
|
44
|
+
return (
|
|
45
|
+
<MimeTabs className="openapi-tabs__mime" schemaType="request">
|
|
46
|
+
{mimeTypes.map((mimeType) => {
|
|
47
|
+
const firstBody = body.content![mimeType].schema;
|
|
48
|
+
if (
|
|
49
|
+
firstBody === undefined ||
|
|
50
|
+
(firstBody.properties &&
|
|
51
|
+
Object.keys(firstBody.properties).length === 0)
|
|
52
|
+
) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return (
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
<TabItem key={mimeType} label={mimeType} value={mimeType}>
|
|
58
|
+
<Details
|
|
59
|
+
className="openapi-markdown__details mime"
|
|
60
|
+
data-collapsed={false}
|
|
61
|
+
open={true}
|
|
62
|
+
style={style}
|
|
63
|
+
summary={
|
|
64
|
+
<>
|
|
65
|
+
<summary>
|
|
66
|
+
<h3 className="openapi-markdown__details-summary-header-body">
|
|
67
|
+
{title}
|
|
68
|
+
{body.required === true && (
|
|
69
|
+
<span className="openapi-schema__required">
|
|
70
|
+
required
|
|
71
|
+
</span>
|
|
72
|
+
)}
|
|
73
|
+
</h3>
|
|
74
|
+
</summary>
|
|
75
|
+
</>
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
<div style={{ textAlign: "left", marginLeft: "1rem" }}>
|
|
79
|
+
{body.description && (
|
|
80
|
+
<div style={{ marginTop: "1rem", marginBottom: "1rem" }}>
|
|
81
|
+
<Markdown>{body.description}</Markdown>
|
|
82
|
+
</div>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
<ul style={{ marginLeft: "1rem" }}>
|
|
86
|
+
<SchemaNode schema={firstBody} schemaType="request" />
|
|
87
|
+
</ul>
|
|
88
|
+
</Details>
|
|
89
|
+
</TabItem>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</MimeTabs>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const randomFirstKey = mimeTypes[0];
|
|
97
|
+
const firstBody =
|
|
98
|
+
body.content[randomFirstKey].schema ?? body.content![randomFirstKey];
|
|
99
|
+
|
|
100
|
+
if (firstBody === undefined) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<MimeTabs className="openapi-tabs__mime" schemaType="request">
|
|
106
|
+
{/* @ts-ignore */}
|
|
107
|
+
<TabItem label={randomFirstKey} value={`${randomFirstKey}-schema`}>
|
|
108
|
+
<Details
|
|
109
|
+
className="openapi-markdown__details mime"
|
|
110
|
+
data-collapsed={false}
|
|
111
|
+
open={true}
|
|
112
|
+
style={style}
|
|
113
|
+
summary={
|
|
114
|
+
<>
|
|
115
|
+
<summary>
|
|
116
|
+
<h3 className="openapi-markdown__details-summary-header-body">
|
|
117
|
+
{title}
|
|
118
|
+
{firstBody.type === "array" && (
|
|
119
|
+
<span style={{ opacity: "0.6" }}> array</span>
|
|
120
|
+
)}
|
|
121
|
+
{body.required && (
|
|
122
|
+
<strong className="openapi-schema__required">
|
|
123
|
+
required
|
|
124
|
+
</strong>
|
|
125
|
+
)}
|
|
126
|
+
</h3>
|
|
127
|
+
</summary>
|
|
128
|
+
</>
|
|
129
|
+
}
|
|
130
|
+
>
|
|
131
|
+
<div style={{ textAlign: "left", marginLeft: "1rem" }}>
|
|
132
|
+
{body.description && (
|
|
133
|
+
<div style={{ marginTop: "1rem", marginBottom: "1rem" }}>
|
|
134
|
+
<Markdown>{body.description}</Markdown>
|
|
135
|
+
</div>
|
|
136
|
+
)}
|
|
137
|
+
</div>
|
|
138
|
+
<ul style={{ marginLeft: "1rem" }}>
|
|
139
|
+
<SchemaNode schema={firstBody} schemaType="request" />
|
|
140
|
+
</ul>
|
|
141
|
+
</Details>
|
|
142
|
+
</TabItem>
|
|
143
|
+
</MimeTabs>
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const RequestSchema: React.FC<Props> = (props) => {
|
|
148
|
+
return (
|
|
149
|
+
<BrowserOnly fallback={<SkeletonLoader size="sm" />}>
|
|
150
|
+
{() => {
|
|
151
|
+
const LazyComponent = React.lazy(() =>
|
|
152
|
+
Promise.resolve({ default: RequestSchemaComponent })
|
|
153
|
+
);
|
|
154
|
+
return (
|
|
155
|
+
<Suspense fallback={null}>
|
|
156
|
+
<LazyComponent {...props} />
|
|
157
|
+
</Suspense>
|
|
158
|
+
);
|
|
159
|
+
}}
|
|
160
|
+
</BrowserOnly>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export default RequestSchema;
|