Skip to content

Commit b544206

Browse files
committed
add RequestExamples
1 parent a5b742a commit b544206

File tree

3 files changed

+286
-66
lines changed

3 files changed

+286
-66
lines changed

demo/examples/tests/examples.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ paths:
238238
description: "description of requestBody schema properties example"
239239
requestBody:
240240
description: "description of requestBody"
241+
required: true
241242
content:
242243
application/json:
243244
schema:
@@ -264,6 +265,7 @@ paths:
264265
description: "description of requestBody schema properties examples"
265266
requestBody:
266267
description: "description of requestBody"
268+
required: true
267269
content:
268270
application/json:
269271
schema:
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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 from "react";
9+
10+
import Markdown from "@theme/Markdown";
11+
import ResponseSamples from "@theme/ResponseSamples";
12+
import TabItem from "@theme/TabItem";
13+
import { sampleResponseFromSchema } from "docusaurus-plugin-openapi-docs/lib/openapi/createResponseExample";
14+
import format from "xml-formatter";
15+
16+
export function json2xml(o: Record<string, any>, tab: string): string {
17+
const toXml = (v: any, name: string, ind: string): string => {
18+
let xml = "";
19+
if (v instanceof Array) {
20+
for (let i = 0, n = v.length; i < n; i++) {
21+
xml += ind + toXml(v[i], name, ind + "\t") + "\n";
22+
}
23+
} else if (typeof v === "object") {
24+
let hasChild = false;
25+
xml += ind + "<" + name;
26+
for (const m in v) {
27+
if (m.charAt(0) === "@") {
28+
xml += " " + m.substr(1) + '="' + v[m].toString() + '"';
29+
} else {
30+
hasChild = true;
31+
}
32+
}
33+
xml += hasChild ? ">" : "/>";
34+
if (hasChild) {
35+
for (const m2 in v) {
36+
if (m2 === "#text") xml += v[m2];
37+
else if (m2 === "#cdata") xml += "<![CDATA[" + v[m2] + "]]>";
38+
else if (m2.charAt(0) !== "@") xml += toXml(v[m2], m2, ind + "\t");
39+
}
40+
xml +=
41+
(xml.charAt(xml.length - 1) === "\n" ? ind : "") + "</" + name + ">";
42+
}
43+
} else {
44+
xml += ind + "<" + name + ">" + v.toString() + "</" + name + ">";
45+
}
46+
return xml;
47+
};
48+
let xml = "";
49+
for (const m3 in o) xml += toXml(o[m3], m3, "");
50+
return tab ? xml.replace(/\t/g, tab) : xml.replace(/\t|\n/g, "");
51+
}
52+
53+
interface RequestExamplesProps {
54+
requestExamples: any;
55+
mimeType: string;
56+
}
57+
export const RequestExamples: React.FC<RequestExamplesProps> = ({
58+
requestExamples,
59+
mimeType,
60+
}): any => {
61+
let language = "shell";
62+
if (mimeType.endsWith("json")) language = "json";
63+
if (mimeType.endsWith("xml")) language = "xml";
64+
65+
// Map response examples to an array of TabItem elements
66+
const examplesArray = Object.entries(requestExamples).map(
67+
([exampleName, exampleValue]: any) => {
68+
const isObject = typeof exampleValue.value === "object";
69+
const responseExample = isObject
70+
? JSON.stringify(exampleValue.value, null, 2)
71+
: exampleValue.value;
72+
73+
return (
74+
// @ts-ignore
75+
<TabItem label={exampleName} value={exampleName} key={exampleName}>
76+
{exampleValue.summary && (
77+
<Markdown className="openapi-example__summary">
78+
{exampleValue.summary}
79+
</Markdown>
80+
)}
81+
<ResponseSamples
82+
responseExample={responseExample}
83+
language={language}
84+
/>
85+
</TabItem>
86+
);
87+
}
88+
);
89+
90+
return examplesArray;
91+
};
92+
93+
interface RequestExampleProps {
94+
requestExample: any;
95+
mimeType: string;
96+
}
97+
98+
export const RequestExample: React.FC<RequestExampleProps> = ({
99+
requestExample,
100+
mimeType,
101+
}) => {
102+
let language = "shell";
103+
if (mimeType.endsWith("json")) {
104+
language = "json";
105+
}
106+
if (mimeType.endsWith("xml")) {
107+
language = "xml";
108+
}
109+
110+
const isObject = typeof requestExample === "object";
111+
const exampleContent = isObject
112+
? JSON.stringify(requestExample, null, 2)
113+
: requestExample;
114+
115+
return (
116+
// @ts-ignore
117+
<TabItem label="Example" value="Example">
118+
{requestExample.summary && (
119+
<Markdown className="openapi-example__summary">
120+
{requestExample.summary}
121+
</Markdown>
122+
)}
123+
<ResponseSamples responseExample={exampleContent} language={language} />
124+
</TabItem>
125+
);
126+
};
127+
128+
interface ExampleFromSchemaProps {
129+
schema: any;
130+
mimeType: string;
131+
}
132+
133+
export const ExampleFromSchema: React.FC<ExampleFromSchemaProps> = ({
134+
schema,
135+
mimeType,
136+
}) => {
137+
const example = sampleResponseFromSchema(schema);
138+
139+
if (mimeType.endsWith("xml")) {
140+
let responseExampleObject;
141+
try {
142+
responseExampleObject = JSON.parse(JSON.stringify(example));
143+
} catch {
144+
return null;
145+
}
146+
147+
if (typeof responseExampleObject === "object") {
148+
let xmlExample;
149+
try {
150+
xmlExample = format(json2xml(responseExampleObject, ""), {
151+
indentation: " ",
152+
lineSeparator: "\n",
153+
collapseContent: true,
154+
});
155+
} catch {
156+
const xmlExampleWithRoot = { root: responseExampleObject };
157+
try {
158+
xmlExample = format(json2xml(xmlExampleWithRoot, ""), {
159+
indentation: " ",
160+
lineSeparator: "\n",
161+
collapseContent: true,
162+
});
163+
} catch {
164+
xmlExample = json2xml(responseExampleObject, "");
165+
}
166+
}
167+
return (
168+
// @ts-ignore
169+
<TabItem label="Example (auto)" value="Example (auto)">
170+
<ResponseSamples responseExample={xmlExample} language="xml" />
171+
</TabItem>
172+
);
173+
}
174+
}
175+
176+
if (typeof example === "object" || typeof example === "string") {
177+
return (
178+
// @ts-ignore
179+
<TabItem label="Example (auto)" value="Example (auto)">
180+
<ResponseSamples
181+
responseExample={JSON.stringify(example, null, 2)}
182+
language="json"
183+
/>
184+
</TabItem>
185+
);
186+
}
187+
188+
return null;
189+
};
190+
191+
export const RequestSchemaExample: React.FC<RequestExampleProps> = ({
192+
requestExample,
193+
mimeType,
194+
}) => {
195+
let language = "shell";
196+
if (mimeType.endsWith("json")) {
197+
language = "json";
198+
}
199+
if (mimeType.endsWith("xml")) {
200+
language = "xml";
201+
}
202+
203+
const isObject = typeof requestExample === "object";
204+
const exampleContent = isObject
205+
? JSON.stringify(requestExample, null, 2)
206+
: requestExample;
207+
208+
return (
209+
// @ts-ignore
210+
<TabItem label="Example" value="Example">
211+
{requestExample.summary && (
212+
<Markdown className="openapi-example__summary">
213+
{requestExample.summary}
214+
</Markdown>
215+
)}
216+
<ResponseSamples responseExample={exampleContent} language={language} />
217+
</TabItem>
218+
);
219+
};
220+
221+
export const RequestSchemaExamples: React.FC<RequestExamplesProps> = ({
222+
requestExamples,
223+
mimeType,
224+
}) => {
225+
let language = "shell";
226+
if (mimeType.endsWith("json")) language = "json";
227+
if (mimeType.endsWith("xml")) language = "xml";
228+
229+
// Map response examples to an array of TabItem elements
230+
const examplesArray = requestExamples.map((example: any, i: number) => {
231+
const exampleName = `Example ${i + 1}`;
232+
const isObject = typeof example === "object";
233+
const responseExample = isObject
234+
? JSON.stringify(example, null, 2)
235+
: example;
236+
237+
return (
238+
// @ts-ignore
239+
<TabItem label={exampleName} value={exampleName} key={exampleName}>
240+
<ResponseSamples
241+
responseExample={responseExample}
242+
language={language}
243+
/>
244+
</TabItem>
245+
);
246+
});
247+
248+
return examplesArray;
249+
};

0 commit comments

Comments
 (0)