docusaurus-theme-openapi-docs 1.1.12 → 1.2.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/ApiDemoPanel/Authorization/auth-types.js +4 -0
- package/lib/theme/ApiDemoPanel/Authorization/index.js +125 -0
- package/lib/theme/ApiDemoPanel/Authorization/slice.js +1 -1
- package/lib/theme/ApiDemoPanel/Body/index.js +7 -6
- package/lib/theme/ApiDemoPanel/Execute/index.js +168 -0
- package/lib/theme/ApiDemoPanel/Execute/makeRequest.js +204 -0
- package/lib/theme/ApiDemoPanel/FormItem/index.js +7 -0
- package/lib/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
- package/lib/theme/ApiDemoPanel/ParamOptions/index.js +1 -1
- package/lib/theme/ApiDemoPanel/Request/index.js +78 -0
- package/lib/theme/ApiDemoPanel/Request/styles.module.css +17 -0
- package/lib/theme/ApiDemoPanel/Response/index.js +16 -12
- package/lib/theme/ApiDemoPanel/SecuritySchemes/index.js +24 -19
- package/lib/theme/ApiDemoPanel/Server/index.js +1 -0
- package/lib/theme/ApiDemoPanel/buildPostmanRequest.js +25 -3
- package/lib/theme/ApiDemoPanel/index.js +5 -13
- package/lib/theme/ApiDemoPanel/persistanceMiddleware.js +1 -1
- package/lib/theme/ApiDemoPanel/react-modal.d.ts +8 -0
- package/lib/theme/ApiItem/Layout/styles.module.css +56 -0
- package/lib/theme/ParamsItem/index.js +5 -1
- package/lib-next/theme/ApiDemoPanel/Authorization/auth-types.js +4 -0
- package/lib-next/theme/ApiDemoPanel/Authorization/index.js +149 -0
- package/lib-next/theme/ApiDemoPanel/Authorization/slice.js +1 -1
- package/lib-next/theme/ApiDemoPanel/Body/index.js +28 -6
- package/lib-next/theme/ApiDemoPanel/Execute/index.js +170 -0
- package/lib-next/theme/ApiDemoPanel/Execute/makeRequest.js +190 -0
- package/lib-next/theme/ApiDemoPanel/FormItem/index.js +9 -1
- package/lib-next/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
- package/lib-next/theme/ApiDemoPanel/ParamOptions/index.js +1 -1
- package/lib-next/theme/ApiDemoPanel/Request/index.js +60 -0
- package/lib-next/theme/ApiDemoPanel/Request/styles.module.css +17 -0
- package/lib-next/theme/ApiDemoPanel/Response/index.js +18 -13
- package/lib-next/theme/ApiDemoPanel/SecuritySchemes/index.js +22 -20
- package/lib-next/theme/ApiDemoPanel/Server/index.js +1 -0
- package/lib-next/theme/ApiDemoPanel/buildPostmanRequest.js +25 -3
- package/lib-next/theme/ApiDemoPanel/index.js +4 -13
- package/lib-next/theme/ApiDemoPanel/persistanceMiddleware.js +1 -1
- package/lib-next/theme/ApiDemoPanel/react-modal.d.ts +8 -0
- package/lib-next/theme/ApiItem/Layout/styles.module.css +56 -0
- package/lib-next/theme/ParamsItem/index.js +5 -1
- package/package.json +5 -4
- package/src/theme/ApiDemoPanel/Authorization/auth-types.ts +4 -0
- package/src/theme/ApiDemoPanel/Authorization/index.tsx +154 -0
- package/src/theme/ApiDemoPanel/Authorization/slice.ts +1 -1
- package/src/theme/ApiDemoPanel/Body/index.tsx +28 -6
- package/src/theme/ApiDemoPanel/Execute/index.tsx +188 -0
- package/src/theme/ApiDemoPanel/Execute/makeRequest.ts +197 -0
- package/src/theme/ApiDemoPanel/FormItem/index.tsx +11 -2
- package/src/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
- package/src/theme/ApiDemoPanel/ParamOptions/index.tsx +1 -1
- package/src/theme/ApiDemoPanel/Request/index.tsx +71 -0
- package/src/theme/ApiDemoPanel/Request/styles.module.css +17 -0
- package/src/theme/ApiDemoPanel/Response/index.tsx +19 -13
- package/src/theme/ApiDemoPanel/SecuritySchemes/index.tsx +22 -17
- package/src/theme/ApiDemoPanel/Server/index.tsx +1 -0
- package/src/theme/ApiDemoPanel/buildPostmanRequest.ts +22 -3
- package/src/theme/ApiDemoPanel/index.tsx +4 -13
- package/src/theme/ApiDemoPanel/persistanceMiddleware.ts +1 -1
- package/src/theme/ApiDemoPanel/react-modal.d.ts +8 -0
- package/src/theme/ApiItem/Layout/styles.module.css +56 -0
- package/src/theme/ParamsItem/index.js +5 -1
|
@@ -0,0 +1,170 @@
|
|
|
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
|
+
import React from "react";
|
|
8
|
+
import Modal from "react-modal";
|
|
9
|
+
import { useTypedDispatch, useTypedSelector } from "../hooks";
|
|
10
|
+
import { setResponse } from "../Response/slice";
|
|
11
|
+
import buildPostmanRequest from "./../buildPostmanRequest";
|
|
12
|
+
import makeRequest from "./makeRequest";
|
|
13
|
+
|
|
14
|
+
function validateRequest(params) {
|
|
15
|
+
for (let paramList of Object.values(params)) {
|
|
16
|
+
for (let param of paramList) {
|
|
17
|
+
if (param.required && !param.value) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Execute({ postman, proxy }) {
|
|
27
|
+
const pathParams = useTypedSelector((state) => state.params.path);
|
|
28
|
+
const queryParams = useTypedSelector((state) => state.params.query);
|
|
29
|
+
const cookieParams = useTypedSelector((state) => state.params.cookie);
|
|
30
|
+
const headerParams = useTypedSelector((state) => state.params.header);
|
|
31
|
+
const contentType = useTypedSelector((state) => state.contentType.value);
|
|
32
|
+
const body = useTypedSelector((state) => state.body);
|
|
33
|
+
const accept = useTypedSelector((state) => state.accept.value);
|
|
34
|
+
const server = useTypedSelector((state) => state.server.value);
|
|
35
|
+
const params = useTypedSelector((state) => state.params);
|
|
36
|
+
const auth = useTypedSelector((state) => state.auth);
|
|
37
|
+
const isValidRequest = validateRequest(params);
|
|
38
|
+
const dispatch = useTypedDispatch();
|
|
39
|
+
const postmanRequest = buildPostmanRequest(postman, {
|
|
40
|
+
queryParams,
|
|
41
|
+
pathParams,
|
|
42
|
+
cookieParams,
|
|
43
|
+
contentType,
|
|
44
|
+
accept,
|
|
45
|
+
headerParams,
|
|
46
|
+
body,
|
|
47
|
+
server,
|
|
48
|
+
auth,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
52
|
+
|
|
53
|
+
function openModal() {
|
|
54
|
+
setIsOpen(true);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function closeModal() {
|
|
58
|
+
setIsOpen(false);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function acceptAgreement() {
|
|
62
|
+
setIsOpen(false);
|
|
63
|
+
setAgreementAccepted(true);
|
|
64
|
+
sessionStorage.setItem("agreement-ack", "true");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const [modalIsOpen, setIsOpen] = React.useState(false); // Set the following as default value to persist to session and enable modal
|
|
68
|
+
// sessionStorage.getItem("agreement-ack") === "true"
|
|
69
|
+
|
|
70
|
+
const [agreementAccepted, setAgreementAccepted] = React.useState(true);
|
|
71
|
+
const customStyles = {
|
|
72
|
+
overlay: {
|
|
73
|
+
backdropFilter: "blur(10px)",
|
|
74
|
+
backgroundColor: "transparent",
|
|
75
|
+
},
|
|
76
|
+
content: {
|
|
77
|
+
top: "50%",
|
|
78
|
+
left: "50%",
|
|
79
|
+
right: "auto",
|
|
80
|
+
bottom: "auto",
|
|
81
|
+
marginRight: "-50%",
|
|
82
|
+
border: "none",
|
|
83
|
+
padding: "none",
|
|
84
|
+
borderRadius: "var(--openapi-card-border-radius)",
|
|
85
|
+
background: "var(--ifm-card-background-color)",
|
|
86
|
+
transform: "translate(-50%, -50%)",
|
|
87
|
+
maxWidth: "550px",
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
if (agreementAccepted) {
|
|
92
|
+
return (
|
|
93
|
+
<button
|
|
94
|
+
className="button button--sm button--secondary"
|
|
95
|
+
disabled={!isValidRequest}
|
|
96
|
+
onClick={async () => {
|
|
97
|
+
dispatch(setResponse("Fetching..."));
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
await delay(1200);
|
|
101
|
+
const res = await makeRequest(postmanRequest, proxy, body);
|
|
102
|
+
dispatch(setResponse(res));
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.log(e);
|
|
105
|
+
dispatch(setResponse("Connection failed"));
|
|
106
|
+
}
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
Send API Request
|
|
110
|
+
</button>
|
|
111
|
+
);
|
|
112
|
+
} else {
|
|
113
|
+
return (
|
|
114
|
+
<React.Fragment>
|
|
115
|
+
<button
|
|
116
|
+
className="button button--sm button--secondary"
|
|
117
|
+
onClick={openModal}
|
|
118
|
+
>
|
|
119
|
+
Send API Request
|
|
120
|
+
</button>
|
|
121
|
+
<Modal
|
|
122
|
+
isOpen={modalIsOpen}
|
|
123
|
+
onRequestClose={closeModal}
|
|
124
|
+
style={customStyles}
|
|
125
|
+
contentLabel="Terms of Use"
|
|
126
|
+
>
|
|
127
|
+
<form>
|
|
128
|
+
<div className="card">
|
|
129
|
+
<div className="card__header">
|
|
130
|
+
<h2>Terms of Use</h2>
|
|
131
|
+
<hr></hr>
|
|
132
|
+
</div>
|
|
133
|
+
<div className="card__body">
|
|
134
|
+
<p>
|
|
135
|
+
By accepting this agreement the end user acknowledges the
|
|
136
|
+
risks of performing authenticated and non-authenticated API
|
|
137
|
+
requests from the browser.
|
|
138
|
+
</p>
|
|
139
|
+
<p>
|
|
140
|
+
The end user also accepts the responsibility of safeguarding
|
|
141
|
+
API credentials and any potentially sensitive data returned by
|
|
142
|
+
the API.
|
|
143
|
+
</p>
|
|
144
|
+
<br></br>
|
|
145
|
+
</div>
|
|
146
|
+
<div className="card__footer">
|
|
147
|
+
<div className="button-group button-group--block">
|
|
148
|
+
<button
|
|
149
|
+
className="button button--sm button--outline button--success"
|
|
150
|
+
onClick={acceptAgreement}
|
|
151
|
+
>
|
|
152
|
+
AGREE
|
|
153
|
+
</button>
|
|
154
|
+
<button
|
|
155
|
+
className="button button--sm button--outline button--danger"
|
|
156
|
+
onClick={closeModal}
|
|
157
|
+
>
|
|
158
|
+
DISAGREE
|
|
159
|
+
</button>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</form>
|
|
164
|
+
</Modal>
|
|
165
|
+
</React.Fragment>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default Execute;
|
|
@@ -0,0 +1,190 @@
|
|
|
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
|
+
function fetchWithtimeout(url, options, timeout = 5000) {
|
|
8
|
+
return Promise.race([
|
|
9
|
+
fetch(url, options),
|
|
10
|
+
new Promise((_, reject) =>
|
|
11
|
+
setTimeout(() => reject(new Error("Request timed out")), timeout)
|
|
12
|
+
),
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function loadImage(content) {
|
|
17
|
+
return new Promise((accept, reject) => {
|
|
18
|
+
const reader = new FileReader();
|
|
19
|
+
|
|
20
|
+
reader.onabort = () => {
|
|
21
|
+
console.log("file reading was aborted");
|
|
22
|
+
reject();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
reader.onerror = () => {
|
|
26
|
+
console.log("file reading has failed");
|
|
27
|
+
reject();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
reader.onload = () => {
|
|
31
|
+
// Do whatever you want with the file contents
|
|
32
|
+
const binaryStr = reader.result;
|
|
33
|
+
accept(binaryStr);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
reader.readAsArrayBuffer(content);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function makeRequest(request, proxy, _body) {
|
|
41
|
+
const headers = request.toJSON().header;
|
|
42
|
+
let myHeaders = new Headers();
|
|
43
|
+
|
|
44
|
+
if (headers) {
|
|
45
|
+
headers.forEach((header) => {
|
|
46
|
+
if (header.key && header.value) {
|
|
47
|
+
myHeaders.append(header.key, header.value);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
} // The following code handles multiple files in the same formdata param.
|
|
51
|
+
// It removes the form data params where the src property is an array of filepath strings
|
|
52
|
+
// Splits that array into different form data params with src set as a single filepath string
|
|
53
|
+
// TODO:
|
|
54
|
+
// if (request.body && request.body.mode === 'formdata') {
|
|
55
|
+
// let formdata = request.body.formdata,
|
|
56
|
+
// formdataArray = [];
|
|
57
|
+
// formdata.members.forEach((param) => {
|
|
58
|
+
// let key = param.key,
|
|
59
|
+
// type = param.type,
|
|
60
|
+
// disabled = param.disabled,
|
|
61
|
+
// contentType = param.contentType;
|
|
62
|
+
// // check if type is file or text
|
|
63
|
+
// if (type === 'file') {
|
|
64
|
+
// // if src is not of type string we check for array(multiple files)
|
|
65
|
+
// if (typeof param.src !== 'string') {
|
|
66
|
+
// // if src is an array(not empty), iterate over it and add files as separate form fields
|
|
67
|
+
// if (Array.isArray(param.src) && param.src.length) {
|
|
68
|
+
// param.src.forEach((filePath) => {
|
|
69
|
+
// addFormParam(
|
|
70
|
+
// formdataArray,
|
|
71
|
+
// key,
|
|
72
|
+
// param.type,
|
|
73
|
+
// filePath,
|
|
74
|
+
// disabled,
|
|
75
|
+
// contentType
|
|
76
|
+
// );
|
|
77
|
+
// });
|
|
78
|
+
// }
|
|
79
|
+
// // if src is not an array or string, or is an empty array, add a placeholder for file path(no files case)
|
|
80
|
+
// else {
|
|
81
|
+
// addFormParam(
|
|
82
|
+
// formdataArray,
|
|
83
|
+
// key,
|
|
84
|
+
// param.type,
|
|
85
|
+
// '/path/to/file',
|
|
86
|
+
// disabled,
|
|
87
|
+
// contentType
|
|
88
|
+
// );
|
|
89
|
+
// }
|
|
90
|
+
// }
|
|
91
|
+
// // if src is string, directly add the param with src as filepath
|
|
92
|
+
// else {
|
|
93
|
+
// addFormParam(
|
|
94
|
+
// formdataArray,
|
|
95
|
+
// key,
|
|
96
|
+
// param.type,
|
|
97
|
+
// param.src,
|
|
98
|
+
// disabled,
|
|
99
|
+
// contentType
|
|
100
|
+
// );
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
// // if type is text, directly add it to formdata array
|
|
104
|
+
// else {
|
|
105
|
+
// addFormParam(
|
|
106
|
+
// formdataArray,
|
|
107
|
+
// key,
|
|
108
|
+
// param.type,
|
|
109
|
+
// param.value,
|
|
110
|
+
// disabled,
|
|
111
|
+
// contentType
|
|
112
|
+
// );
|
|
113
|
+
// }
|
|
114
|
+
// });
|
|
115
|
+
// request.body.update({
|
|
116
|
+
// mode: 'formdata',
|
|
117
|
+
// formdata: formdataArray,
|
|
118
|
+
// });
|
|
119
|
+
// }
|
|
120
|
+
|
|
121
|
+
const body = request.body?.toJSON();
|
|
122
|
+
let myBody = undefined;
|
|
123
|
+
|
|
124
|
+
if (body !== undefined && Object.keys(body).length > 0) {
|
|
125
|
+
switch (body.mode) {
|
|
126
|
+
case "urlencoded": {
|
|
127
|
+
myBody = new URLSearchParams();
|
|
128
|
+
|
|
129
|
+
if (Array.isArray(body.urlencoded)) {
|
|
130
|
+
for (const data of body.urlencoded) {
|
|
131
|
+
if (data.key && data.value) {
|
|
132
|
+
myBody.append(data.key, data.value);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case "raw": {
|
|
141
|
+
myBody = (body.raw ?? "").toString();
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
case "formdata": {
|
|
146
|
+
myBody = new FormData();
|
|
147
|
+
|
|
148
|
+
if (Array.isArray(body.formdata)) {
|
|
149
|
+
for (const data of body.formdata) {
|
|
150
|
+
if (data.key && data.value) {
|
|
151
|
+
myBody.append(data.key, data.value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
case "file": {
|
|
160
|
+
if (_body.type === "raw" && _body.content?.type === "file") {
|
|
161
|
+
myBody = await loadImage(_body.content.value.content);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
default:
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const requestOptions = {
|
|
173
|
+
method: request.method,
|
|
174
|
+
headers: myHeaders,
|
|
175
|
+
body: myBody,
|
|
176
|
+
};
|
|
177
|
+
let finalUrl = request.url.toString();
|
|
178
|
+
|
|
179
|
+
if (proxy) {
|
|
180
|
+
// Ensure the proxy ends with a slash.
|
|
181
|
+
let normalizedProxy = proxy.replace(/\/$/, "") + "/";
|
|
182
|
+
finalUrl = normalizedProxy + request.url.toString();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return await fetchWithtimeout(finalUrl, requestOptions).then((response) => {
|
|
186
|
+
return response.text();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export default makeRequest;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import React from "react";
|
|
8
8
|
import styles from "./styles.module.css";
|
|
9
9
|
|
|
10
|
-
function FormItem({ label, type, children }) {
|
|
10
|
+
function FormItem({ label, type, required, children }) {
|
|
11
11
|
return (
|
|
12
12
|
<div className={styles.formItem}>
|
|
13
13
|
<code>{label}</code>
|
|
@@ -21,6 +21,14 @@ function FormItem({ label, type, children }) {
|
|
|
21
21
|
— {type}
|
|
22
22
|
</span>
|
|
23
23
|
)}
|
|
24
|
+
{required && (
|
|
25
|
+
<span>
|
|
26
|
+
{" "}
|
|
27
|
+
<small>
|
|
28
|
+
<strong className={styles.required}> required</strong>
|
|
29
|
+
</small>
|
|
30
|
+
</span>
|
|
31
|
+
)}
|
|
24
32
|
<div>{children}</div>
|
|
25
33
|
</div>
|
|
26
34
|
);
|
|
@@ -37,7 +37,7 @@ function ParamOption({ param }) {
|
|
|
37
37
|
|
|
38
38
|
function ParamOptionWrapper({ param }) {
|
|
39
39
|
return (
|
|
40
|
-
<FormItem label={param.name} type={param.in}>
|
|
40
|
+
<FormItem label={param.name} type={param.in} required={param.required}>
|
|
41
41
|
<ParamOption param={param} />
|
|
42
42
|
</FormItem>
|
|
43
43
|
);
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
import React from "react";
|
|
8
|
+
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
9
|
+
import sdk from "@paloaltonetworks/postman-collection";
|
|
10
|
+
import Accept from "../Accept";
|
|
11
|
+
import Authorization from "../Authorization";
|
|
12
|
+
import Body from "../Body";
|
|
13
|
+
import Execute from "../Execute";
|
|
14
|
+
import { useTypedSelector } from "../hooks";
|
|
15
|
+
import ParamOptions from "../ParamOptions";
|
|
16
|
+
import styles from "./styles.module.css";
|
|
17
|
+
|
|
18
|
+
function Request({ item }) {
|
|
19
|
+
const response = useTypedSelector((state) => state.response.value);
|
|
20
|
+
const { siteConfig } = useDocusaurusContext();
|
|
21
|
+
const themeConfig = siteConfig.themeConfig;
|
|
22
|
+
const options = themeConfig.api;
|
|
23
|
+
const postman = new sdk.Request(item.postman);
|
|
24
|
+
const params = {
|
|
25
|
+
path: [],
|
|
26
|
+
query: [],
|
|
27
|
+
header: [],
|
|
28
|
+
cookie: [],
|
|
29
|
+
};
|
|
30
|
+
item.parameters?.forEach((param) => {
|
|
31
|
+
const paramType = param.in;
|
|
32
|
+
const paramsArray = params[paramType];
|
|
33
|
+
paramsArray.push(param);
|
|
34
|
+
});
|
|
35
|
+
return (
|
|
36
|
+
<div>
|
|
37
|
+
<details className={`details__demo-panel`} open={response ? false : true}>
|
|
38
|
+
<summary>
|
|
39
|
+
<div className={`details__request-summary`}>
|
|
40
|
+
<h4>Request</h4>
|
|
41
|
+
{item.servers && (
|
|
42
|
+
<Execute postman={postman} proxy={options?.proxy} />
|
|
43
|
+
)}
|
|
44
|
+
</div>
|
|
45
|
+
</summary>
|
|
46
|
+
<div className={styles.optionsPanel}>
|
|
47
|
+
<Authorization />
|
|
48
|
+
<ParamOptions />
|
|
49
|
+
<Body
|
|
50
|
+
jsonRequestBodyExample={item.jsonRequestBodyExample}
|
|
51
|
+
requestBodyMetadata={item.requestBody}
|
|
52
|
+
/>
|
|
53
|
+
<Accept />
|
|
54
|
+
</div>
|
|
55
|
+
</details>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default Request;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.optionsPanel:empty {
|
|
2
|
+
display: none;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.optionsPanel {
|
|
6
|
+
background: var(--openapi-card-background-color);
|
|
7
|
+
border-radius: var(--openapi-card-border-radius);
|
|
8
|
+
color: var(--ifm-pre-color);
|
|
9
|
+
line-height: var(--ifm-pre-line-height);
|
|
10
|
+
margin-bottom: var(--ifm-spacing-vertical);
|
|
11
|
+
margin-top: 0;
|
|
12
|
+
overflow: auto;
|
|
13
|
+
padding: var(--ifm-pre-padding);
|
|
14
|
+
|
|
15
|
+
/* hack for view calculation when monaco is hidden */
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
import React from "react";
|
|
8
|
+
import CodeBlock from "@theme/CodeBlock";
|
|
8
9
|
import { useTypedDispatch, useTypedSelector } from "../hooks";
|
|
9
|
-
import FloatingButton from "./../FloatingButton";
|
|
10
10
|
import { clearResponse } from "./slice"; // TODO: We probably shouldn't attempt to format XML...
|
|
11
11
|
|
|
12
12
|
function formatXml(xml) {
|
|
@@ -42,23 +42,28 @@ function Response() {
|
|
|
42
42
|
try {
|
|
43
43
|
prettyResponse = JSON.stringify(JSON.parse(response), null, 2);
|
|
44
44
|
} catch {
|
|
45
|
-
if (response.startsWith("
|
|
45
|
+
if (response.startsWith("<")) {
|
|
46
46
|
prettyResponse = formatXml(response);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
<details className={`details__demo-panel`} open={true}>
|
|
52
|
+
<summary>
|
|
53
|
+
<div className={`details__response-summary`}>
|
|
54
|
+
<h4>Response</h4>
|
|
55
|
+
<button
|
|
56
|
+
className="button button--sm button--secondary"
|
|
57
|
+
onClick={() => dispatch(clearResponse())}
|
|
58
|
+
>
|
|
59
|
+
Clear
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
</summary>
|
|
63
|
+
<CodeBlock language={response.startsWith("<") ? `xml` : `json`}>
|
|
64
|
+
{prettyResponse || "No Response"}
|
|
65
|
+
</CodeBlock>
|
|
66
|
+
</details>
|
|
62
67
|
);
|
|
63
68
|
}
|
|
64
69
|
|
|
@@ -15,60 +15,62 @@ function SecuritySchemes(props) {
|
|
|
15
15
|
if (selected === undefined) return null;
|
|
16
16
|
const selectedAuth = options[selected];
|
|
17
17
|
return (
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
>
|
|
18
|
+
<details className={`details__demo-panel`} open={false}>
|
|
19
|
+
<summary className={`details__request-summary`}>
|
|
20
|
+
<h4>Authorization</h4>
|
|
21
|
+
</summary>
|
|
23
22
|
{selectedAuth.map((auth) => {
|
|
24
23
|
const isApiKey = auth.type === "apiKey";
|
|
25
24
|
const isBearer = auth.type === "http" && auth.key === "Bearer";
|
|
26
|
-
const
|
|
27
|
-
auth.type === "oauth2" && auth.key === "ClientCredentials";
|
|
25
|
+
const isOauth2 = auth.type === "oauth2";
|
|
28
26
|
|
|
29
27
|
if (isApiKey || isBearer) {
|
|
30
28
|
return (
|
|
31
|
-
<React.Fragment key={
|
|
32
|
-
<b>
|
|
33
|
-
Authorization: <Link to={infoAuthPath}>{auth.key}</Link>
|
|
34
|
-
</b>
|
|
29
|
+
<React.Fragment key={auth.key}>
|
|
35
30
|
<pre
|
|
36
31
|
style={{
|
|
37
32
|
display: "flex",
|
|
38
33
|
flexDirection: "column",
|
|
39
34
|
background: "var(--openapi-card-background-color)",
|
|
40
|
-
borderRadius: "var(--openapi-card-border-radius)",
|
|
41
35
|
}}
|
|
42
36
|
>
|
|
43
|
-
<span>name: {auth.name}</span>
|
|
44
|
-
<span>in: {auth.in}</span>
|
|
45
37
|
<span>type: {auth.type}</span>
|
|
38
|
+
<span>
|
|
39
|
+
name: <Link to={infoAuthPath}>{auth.name}</Link>
|
|
40
|
+
</span>
|
|
41
|
+
<span>in: {auth.in}</span>
|
|
46
42
|
</pre>
|
|
47
43
|
</React.Fragment>
|
|
48
44
|
);
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
if (
|
|
47
|
+
if (isOauth2) {
|
|
52
48
|
return (
|
|
53
49
|
<React.Fragment key={selected}>
|
|
54
|
-
<b>Authorization: {auth.key}</b>
|
|
55
50
|
<pre
|
|
56
51
|
style={{
|
|
57
52
|
display: "flex",
|
|
58
53
|
flexDirection: "column",
|
|
59
54
|
background: "var(--openapi-card-background-color)",
|
|
60
|
-
borderRadius: "var(--openapi-card-border-radius)",
|
|
61
55
|
}}
|
|
62
56
|
>
|
|
63
|
-
<span>
|
|
57
|
+
<span>
|
|
58
|
+
type: <Link to={infoAuthPath}>{auth.type}</Link>
|
|
59
|
+
</span>
|
|
60
|
+
{Object.keys(auth.flows).map((flow) => {
|
|
61
|
+
return <span key={flow}>flow: {flow}</span>;
|
|
62
|
+
})}
|
|
63
|
+
<span>
|
|
64
|
+
scopes: <code>{auth.scopes.toString()}</code>
|
|
65
|
+
</span>
|
|
64
66
|
</pre>
|
|
65
67
|
</React.Fragment>
|
|
66
68
|
);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
return
|
|
71
|
+
return undefined;
|
|
70
72
|
})}
|
|
71
|
-
</
|
|
73
|
+
</details>
|
|
72
74
|
);
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -258,6 +258,28 @@ function buildPostmanRequest(
|
|
|
258
258
|
continue;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
otherHeaders.push({
|
|
262
|
+
key: "Authorization",
|
|
263
|
+
value: `Bearer ${token}`,
|
|
264
|
+
});
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (a.type === "oauth2") {
|
|
269
|
+
let token;
|
|
270
|
+
|
|
271
|
+
if (auth.data[a.key]) {
|
|
272
|
+
token = auth.data[a.key].token;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (token === undefined) {
|
|
276
|
+
otherHeaders.push({
|
|
277
|
+
key: "Authorization",
|
|
278
|
+
value: "Bearer <TOKEN>",
|
|
279
|
+
});
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
|
|
261
283
|
otherHeaders.push({
|
|
262
284
|
key: "Authorization",
|
|
263
285
|
value: `Bearer ${token}`,
|
|
@@ -280,9 +302,9 @@ function buildPostmanRequest(
|
|
|
280
302
|
} // API Key
|
|
281
303
|
|
|
282
304
|
if (a.type === "apiKey" && a.in === "header") {
|
|
283
|
-
const {
|
|
305
|
+
const { apiKey } = auth.data[a.key];
|
|
284
306
|
|
|
285
|
-
if (
|
|
307
|
+
if (apiKey === undefined) {
|
|
286
308
|
otherHeaders.push({
|
|
287
309
|
key: a.name,
|
|
288
310
|
value: "<API_KEY_VALUE>",
|
|
@@ -292,7 +314,7 @@ function buildPostmanRequest(
|
|
|
292
314
|
|
|
293
315
|
otherHeaders.push({
|
|
294
316
|
key: a.name,
|
|
295
|
-
value:
|
|
317
|
+
value: apiKey,
|
|
296
318
|
});
|
|
297
319
|
continue;
|
|
298
320
|
}
|