docusaurus-theme-openapi-docs 4.2.0 → 4.3.1

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.
Files changed (33) hide show
  1. package/lib/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
  2. package/lib/theme/ApiExplorer/Authorization/index.js +3 -0
  3. package/lib/theme/ApiExplorer/Body/index.js +11 -2
  4. package/lib/theme/ApiExplorer/CodeSnippets/index.js +41 -45
  5. package/lib/theme/ApiExplorer/buildPostmanRequest.js +1 -1
  6. package/lib/theme/Markdown/Details/_Details.scss +5 -2
  7. package/lib/theme/Markdown/index.js +160 -18
  8. package/lib/theme/ParamsItem/index.js +7 -48
  9. package/lib/theme/RequestSchema/index.js +11 -3
  10. package/lib/theme/ResponseExamples/index.d.ts +9 -39
  11. package/lib/theme/ResponseExamples/index.js +3 -99
  12. package/lib/theme/ResponseHeaders/index.d.ts +13 -0
  13. package/lib/theme/ResponseHeaders/index.js +39 -0
  14. package/lib/theme/ResponseSchema/index.js +4 -2
  15. package/lib/theme/Schema/index.js +29 -21
  16. package/lib/theme/SchemaItem/index.js +7 -41
  17. package/lib/theme/StatusCodes/index.js +10 -7
  18. package/package.json +10 -6
  19. package/src/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
  20. package/src/theme/ApiExplorer/Authorization/index.tsx +3 -0
  21. package/src/theme/ApiExplorer/Body/index.tsx +3 -2
  22. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +45 -47
  23. package/src/theme/ApiExplorer/buildPostmanRequest.ts +1 -1
  24. package/src/theme/Markdown/Details/_Details.scss +5 -2
  25. package/src/theme/Markdown/index.js +160 -18
  26. package/src/theme/ParamsItem/index.tsx +6 -36
  27. package/src/theme/RequestSchema/index.tsx +3 -3
  28. package/src/theme/ResponseExamples/index.tsx +24 -122
  29. package/src/theme/ResponseHeaders/index.tsx +49 -0
  30. package/src/theme/ResponseSchema/index.tsx +2 -2
  31. package/src/theme/Schema/index.tsx +29 -22
  32. package/src/theme/SchemaItem/index.tsx +11 -35
  33. package/src/theme/StatusCodes/index.tsx +3 -3
@@ -5,13 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- /* ============================================================================
9
- * Copyright (c) Palo Alto Networks
10
- *
11
- * This source code is licensed under the MIT license found in the
12
- * LICENSE file in the root directory of this source tree.
13
- * ========================================================================== */
14
-
15
8
  import React, { useState, useEffect } from "react";
16
9
 
17
10
  import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
@@ -19,6 +12,7 @@ import ApiCodeBlock from "@theme/ApiExplorer/ApiCodeBlock";
19
12
  import buildPostmanRequest from "@theme/ApiExplorer/buildPostmanRequest";
20
13
  import CodeTabs from "@theme/ApiExplorer/CodeTabs";
21
14
  import { useTypedSelector } from "@theme/ApiItem/hooks";
15
+ import cloneDeep from "lodash/cloneDeep";
22
16
  import codegen from "postman-code-generators";
23
17
  import sdk from "postman-collection";
24
18
 
@@ -59,6 +53,44 @@ function CodeSnippets({ postman, codeSamples }: Props) {
59
53
  const headerParams = useTypedSelector((state: any) => state.params.header);
60
54
 
61
55
  const auth = useTypedSelector((state: any) => state.auth);
56
+ const clonedAuth = cloneDeep(auth);
57
+ let placeholder: string;
58
+
59
+ function cleanCredentials(obj: any) {
60
+ for (const key in obj) {
61
+ if (typeof obj[key] === "object" && obj[key] !== null) {
62
+ // use name as placeholder if exists
63
+ const comboAuthId = Object.keys(obj).join(" and ");
64
+ const authOptions =
65
+ clonedAuth?.options?.[key] ?? clonedAuth?.options?.[comboAuthId];
66
+ placeholder = authOptions?.[0]?.name;
67
+ obj[key] = cleanCredentials(obj[key]);
68
+ } else {
69
+ obj[key] = `<${placeholder ?? key}>`;
70
+ }
71
+ }
72
+
73
+ return obj;
74
+ }
75
+
76
+ // scrub credentials from code snippets
77
+ const cleanedAuth = {
78
+ ...clonedAuth,
79
+ data: cleanCredentials(clonedAuth.data),
80
+ };
81
+
82
+ // Create a Postman request object using cleanedAuth
83
+ const cleanedPostmanRequest = buildPostmanRequest(postman, {
84
+ queryParams,
85
+ pathParams,
86
+ cookieParams,
87
+ contentType,
88
+ accept,
89
+ headerParams,
90
+ body,
91
+ server,
92
+ auth: cleanedAuth,
93
+ });
62
94
 
63
95
  // User-defined languages array
64
96
  // Can override languageSet, change order of langs, override options and variants
@@ -105,21 +137,10 @@ function CodeSnippets({ postman, codeSamples }: Props) {
105
137
  }
106
138
 
107
139
  if (language && !!language.options) {
108
- const postmanRequest = buildPostmanRequest(postman, {
109
- queryParams,
110
- pathParams,
111
- cookieParams,
112
- contentType,
113
- accept,
114
- headerParams,
115
- body,
116
- server,
117
- auth,
118
- });
119
140
  codegen.convert(
120
141
  language.language,
121
142
  language.variant,
122
- postmanRequest,
143
+ cleanedPostmanRequest,
123
144
  language.options,
124
145
  (error: any, snippet: string) => {
125
146
  if (error) {
@@ -137,22 +158,10 @@ function CodeSnippets({ postman, codeSamples }: Props) {
137
158
  // This allows users to define only the minimal properties necessary in languageTabs
138
159
  // User-defined properties should override languageSet properties
139
160
  const mergedLanguage = { ...langSource[0], ...language };
140
- const postmanRequest = buildPostmanRequest(postman, {
141
- queryParams,
142
- pathParams,
143
- cookieParams,
144
- contentType,
145
- accept,
146
- headerParams,
147
- body,
148
- server,
149
- auth,
150
- });
151
-
152
161
  codegen.convert(
153
162
  mergedLanguage.language,
154
163
  mergedLanguage.variant,
155
- postmanRequest,
164
+ cleanedPostmanRequest,
156
165
  mergedLanguage.options,
157
166
  (error: any, snippet: string) => {
158
167
  if (error) {
@@ -175,27 +184,16 @@ function CodeSnippets({ postman, codeSamples }: Props) {
175
184
  postman,
176
185
  queryParams,
177
186
  server,
178
- auth,
187
+ cleanedPostmanRequest,
179
188
  mergedLangs,
180
189
  ]);
181
- // no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
190
+ // no dependencies was intentionally set for this particular hook. it's safe as long as if conditions are set
182
191
  useEffect(function onSelectedVariantUpdate() {
183
192
  if (selectedVariant && selectedVariant !== language?.variant) {
184
- const postmanRequest = buildPostmanRequest(postman, {
185
- queryParams,
186
- pathParams,
187
- cookieParams,
188
- contentType,
189
- accept,
190
- headerParams,
191
- body,
192
- server,
193
- auth,
194
- });
195
193
  codegen.convert(
196
194
  language.language,
197
195
  selectedVariant,
198
- postmanRequest,
196
+ cleanedPostmanRequest,
199
197
  language.options,
200
198
  (error: any, snippet: string) => {
201
199
  if (error) {
@@ -207,7 +205,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
207
205
  }
208
206
  });
209
207
 
210
- // no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
208
+ // no dependencies was intentionally set for this particular hook. it's safe as long as if conditions are set
211
209
  // eslint-disable-next-line react-hooks/exhaustive-deps
212
210
  useEffect(function onSelectedSampleUpdate() {
213
211
  if (
@@ -298,7 +298,7 @@ function buildPostmanRequest(
298
298
  if (apiKey === undefined) {
299
299
  otherHeaders.push({
300
300
  key: a.name,
301
- value: "<API_KEY_VALUE>",
301
+ value: `<${a.name ?? a.type}>`,
302
302
  });
303
303
  continue;
304
304
  }
@@ -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
- <div>
17
- <ReactMarkdown
18
- children={children}
19
- rehypePlugins={[rehypeRaw]}
20
- components={{
21
- pre: "div",
22
- code({ node, inline, className, children, ...props }) {
23
- const match = /language-(\w+)/.exec(className || "");
24
- if (inline) return <code>{children}</code>;
25
- return !inline && match ? (
26
- <CodeBlock className={className}>{children}</CodeBlock>
27
- ) : (
28
- <CodeBlock>{children}</CodeBlock>
29
- );
30
- },
31
- }}
32
- />
33
- </div>
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
 
@@ -7,16 +7,12 @@
7
7
 
8
8
  import React from "react";
9
9
 
10
- import CodeBlock from "@theme/CodeBlock";
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
 
@@ -97,34 +93,12 @@ function ParamsItem({ param, ...rest }: Props) {
97
93
  <span className="openapi-schema__deprecated">deprecated</span>
98
94
  ));
99
95
 
100
- const renderSchema = guard(getQualifierMessage(schema), (message) => (
101
- <div>
102
- <ReactMarkdown
103
- children={createDescription(message)}
104
- rehypePlugins={[rehypeRaw]}
105
- />
106
- </div>
96
+ const renderQualifier = guard(getQualifierMessage(schema), (qualifier) => (
97
+ <Markdown>{qualifier}</Markdown>
107
98
  ));
108
99
 
109
100
  const renderDescription = guard(description, (description) => (
110
- <>
111
- <ReactMarkdown
112
- children={createDescription(description)}
113
- components={{
114
- pre: "div",
115
- code({ node, inline, className, children, ...props }) {
116
- const match = /language-(\w+)/.exec(className || "");
117
- if (inline) return <code>{children}</code>;
118
- return !inline && match ? (
119
- <CodeBlock className={className}>{children}</CodeBlock>
120
- ) : (
121
- <CodeBlock>{children}</CodeBlock>
122
- );
123
- },
124
- }}
125
- rehypePlugins={[rehypeRaw]}
126
- />
127
- </>
101
+ <Markdown>{description}</Markdown>
128
102
  ));
129
103
 
130
104
  const renderEnumDescriptions = guard(
@@ -132,11 +106,7 @@ function ParamsItem({ param, ...rest }: Props) {
132
106
  (value) => {
133
107
  return (
134
108
  <div style={{ marginTop: ".5rem" }}>
135
- <ReactMarkdown
136
- rehypePlugins={[rehypeRaw]}
137
- remarkPlugins={[remarkGfm]}
138
- children={value}
139
- />
109
+ <Markdown>{value}</Markdown>
140
110
  </div>
141
111
  );
142
112
  }
@@ -217,7 +187,7 @@ function ParamsItem({ param, ...rest }: Props) {
217
187
  {renderSchemaRequired}
218
188
  {renderDeprecated}
219
189
  </span>
220
- {renderSchema}
190
+ {renderQualifier}
221
191
  {renderDescription}
222
192
  {renderEnumDescriptions}
223
193
  {renderDefaultValue()}
@@ -9,11 +9,11 @@ import React, { Suspense } from "react";
9
9
 
10
10
  import BrowserOnly from "@docusaurus/BrowserOnly";
11
11
  import Details from "@theme/Details";
12
+ import Markdown from "@theme/Markdown";
12
13
  import MimeTabs from "@theme/MimeTabs"; // Assume these components exist
13
14
  import SchemaNode from "@theme/Schema";
14
15
  import SkeletonLoader from "@theme/SkeletonLoader";
15
16
  import TabItem from "@theme/TabItem";
16
- import { createDescription } from "docusaurus-plugin-openapi-docs/lib/markdown/createDescription";
17
17
  import { MediaTypeObject } from "docusaurus-plugin-openapi-docs/lib/openapi/types";
18
18
 
19
19
  interface Props {
@@ -78,7 +78,7 @@ const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
78
78
  <div style={{ textAlign: "left", marginLeft: "1rem" }}>
79
79
  {body.description && (
80
80
  <div style={{ marginTop: "1rem", marginBottom: "1rem" }}>
81
- {createDescription(body.description)}
81
+ <Markdown>{body.description}</Markdown>
82
82
  </div>
83
83
  )}
84
84
  </div>
@@ -131,7 +131,7 @@ const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
131
131
  <div style={{ textAlign: "left", marginLeft: "1rem" }}>
132
132
  {body.description && (
133
133
  <div style={{ marginTop: "1rem", marginBottom: "1rem" }}>
134
- {createDescription(body.description)}
134
+ <Markdown>{body.description}</Markdown>
135
135
  </div>
136
136
  )}
137
137
  </div>
@@ -7,14 +7,12 @@
7
7
 
8
8
  import React from "react";
9
9
 
10
- import ParamsItem from "@theme/ParamsItem";
10
+ import Markdown from "@theme/Markdown";
11
11
  import ResponseSamples from "@theme/ResponseSamples";
12
12
  import TabItem from "@theme/TabItem";
13
- import { createDescription } from "docusaurus-plugin-openapi-docs/lib/markdown/createDescription";
14
13
  import { sampleResponseFromSchema } from "docusaurus-plugin-openapi-docs/lib/openapi/createResponseExample";
15
14
  import format from "xml-formatter";
16
15
 
17
- // Utility function
18
16
  export function json2xml(o: Record<string, any>, tab: string): string {
19
17
  const toXml = (v: any, name: string, ind: string): string => {
20
18
  let xml = "";
@@ -52,120 +50,14 @@ export function json2xml(o: Record<string, any>, tab: string): string {
52
50
  return tab ? xml.replace(/\t/g, tab) : xml.replace(/\t|\n/g, "");
53
51
  }
54
52
 
55
- interface ParameterProps {
56
- in: string;
57
- name: string;
58
- schema?: {
59
- type?: string;
60
- items?: Record<string, any>;
61
- };
62
- enumDescriptions?: [string, string][];
63
- }
64
-
65
- interface ResponseHeaderProps {
66
- description?: string;
67
- example?: string;
68
- schema?: {
69
- type?: string;
70
- };
71
- }
72
-
73
- interface ResponseExampleProps {
74
- value: any;
75
- summary?: string;
76
- }
77
-
78
- interface Props {
79
- parameters?: ParameterProps[];
80
- type: string;
81
- responseHeaders?: Record<string, ResponseHeaderProps>;
82
- responseExamples?: Record<string, ResponseExampleProps>;
83
- responseExample?: any;
84
- schema?: any;
85
- mimeType: string;
86
- }
87
-
88
- // React components
89
- export const ParamsDetails: React.FC<Props> = ({ parameters, type }) => {
90
- const params = parameters?.filter((param) => param?.in === type);
91
-
92
- if (!params || params.length === 0) {
93
- return null;
94
- }
95
-
96
- return (
97
- <details
98
- className="openapi-markdown__details"
99
- data-collapsed={false}
100
- open={true}
101
- style={{ marginBottom: "1rem" }}
102
- >
103
- <summary>
104
- <h3 className="openapi-markdown__details-summary-header-params">
105
- {`${type.charAt(0).toUpperCase() + type.slice(1)} Parameters`}
106
- </h3>
107
- </summary>
108
- <div>
109
- <ul>
110
- {params.map((param, index) => (
111
- <ParamsItem
112
- key={index}
113
- className="paramsItem"
114
- // @ts-ignore
115
- param={{
116
- ...param,
117
- enumDescriptions: Object.entries(
118
- param?.schema?.items?.["x-enumDescriptions"] ?? {}
119
- ),
120
- }}
121
- />
122
- ))}
123
- </ul>
124
- </div>
125
- </details>
126
- );
127
- };
128
-
129
- export const ResponseHeaders: React.FC<{
130
- responseHeaders?: Record<string, ResponseHeaderProps>;
131
- }> = ({ responseHeaders }) => {
132
- if (!responseHeaders) {
133
- return null;
134
- }
135
-
136
- return (
137
- <ul style={{ marginLeft: "1rem" }}>
138
- {Object.entries(responseHeaders).map(([headerName, headerObj]) => {
139
- const { description, example, schema } = headerObj;
140
- const type = schema?.type ?? "any";
141
-
142
- return (
143
- <li className="schemaItem" key={headerName}>
144
- <details>
145
- <summary>
146
- <strong>{headerName}</strong>
147
- {type && <span style={{ opacity: "0.6" }}> {type}</span>}
148
- </summary>
149
- <div>
150
- {description && (
151
- <div style={{ marginTop: ".5rem", marginBottom: ".5rem" }}>
152
- {example && `Example: ${example}`}
153
- {createDescription(description)}
154
- </div>
155
- )}
156
- </div>
157
- </details>
158
- </li>
159
- );
160
- })}
161
- </ul>
162
- );
163
- };
164
-
165
- export const ResponseExamples: React.FC<{
53
+ interface ResponseExamplesProps {
166
54
  responseExamples: any;
167
55
  mimeType: string;
168
- }> = ({ responseExamples, mimeType }): any => {
56
+ }
57
+ export const ResponseExamples: React.FC<ResponseExamplesProps> = ({
58
+ responseExamples,
59
+ mimeType,
60
+ }): any => {
169
61
  let language = "shell";
170
62
  if (mimeType.endsWith("json")) language = "json";
171
63
  if (mimeType.endsWith("xml")) language = "xml";
@@ -182,9 +74,9 @@ export const ResponseExamples: React.FC<{
182
74
  // @ts-ignore
183
75
  <TabItem label={exampleName} value={exampleName} key={exampleName}>
184
76
  {exampleValue.summary && (
185
- <div className="openapi-example__summary">
77
+ <Markdown className="openapi-example__summary">
186
78
  {exampleValue.summary}
187
- </div>
79
+ </Markdown>
188
80
  )}
189
81
  <ResponseSamples
190
82
  responseExample={responseExample}
@@ -198,10 +90,15 @@ export const ResponseExamples: React.FC<{
198
90
  return examplesArray;
199
91
  };
200
92
 
201
- export const ResponseExample: React.FC<{
93
+ interface ResponseExampleProps {
202
94
  responseExample: any;
203
95
  mimeType: string;
204
- }> = ({ responseExample, mimeType }) => {
96
+ }
97
+
98
+ export const ResponseExample: React.FC<ResponseExampleProps> = ({
99
+ responseExample,
100
+ mimeType,
101
+ }) => {
205
102
  let language = "shell";
206
103
  if (mimeType.endsWith("json")) {
207
104
  language = "json";
@@ -219,16 +116,21 @@ export const ResponseExample: React.FC<{
219
116
  // @ts-ignore
220
117
  <TabItem label="Example" value="Example">
221
118
  {responseExample.summary && (
222
- <div className="openapi-example__summary">
119
+ <Markdown className="openapi-example__summary">
223
120
  {responseExample.summary}
224
- </div>
121
+ </Markdown>
225
122
  )}
226
123
  <ResponseSamples responseExample={exampleContent} language={language} />
227
124
  </TabItem>
228
125
  );
229
126
  };
230
127
 
231
- export const ExampleFromSchema: React.FC<{ schema: any; mimeType: string }> = ({
128
+ interface ExampleFromSchemaProps {
129
+ schema: any;
130
+ mimeType: string;
131
+ }
132
+
133
+ export const ExampleFromSchema: React.FC<ExampleFromSchemaProps> = ({
232
134
  schema,
233
135
  mimeType,
234
136
  }) => {