docusaurus-theme-openapi-docs 0.0.0-1159 → 0.0.0-1161
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/Body/FormBodyItem/index.d.ts +2 -1
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.js +47 -0
- package/lib/theme/ApiExplorer/Body/index.js +4 -0
- package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +2 -1
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +4 -0
- package/lib/theme/ApiExplorer/ContentType/index.js +5 -1
- package/lib/theme/ApiExplorer/EncodingSelection/slice.d.ts +17 -0
- package/lib/theme/ApiExplorer/EncodingSelection/slice.js +29 -0
- package/lib/theme/ApiExplorer/EncodingSelection/useResolvedEncoding.d.ts +12 -0
- package/lib/theme/ApiExplorer/EncodingSelection/useResolvedEncoding.js +39 -0
- package/lib/theme/ApiExplorer/Request/index.js +7 -1
- package/lib/theme/ApiExplorer/Request/makeRequest.d.ts +3 -1
- package/lib/theme/ApiExplorer/Request/makeRequest.js +17 -3
- package/lib/theme/ApiExplorer/buildPostmanRequest.d.ts +4 -1
- package/lib/theme/ApiExplorer/buildPostmanRequest.js +46 -5
- package/lib/theme/ApiExplorer/index.js +1 -0
- package/lib/theme/ApiExplorer/persistenceMiddleware.d.ts +2 -0
- package/lib/theme/ApiItem/hooks.d.ts +1 -0
- package/lib/theme/ApiItem/index.js +1 -0
- package/lib/theme/ApiItem/store.d.ts +6 -0
- package/lib/theme/ApiItem/store.js +11 -7
- package/package.json +3 -3
- package/src/theme/ApiExplorer/Body/FormBodyItem/index.tsx +55 -10
- package/src/theme/ApiExplorer/Body/index.tsx +5 -0
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +9 -1
- package/src/theme/ApiExplorer/ContentType/index.tsx +5 -3
- package/src/theme/ApiExplorer/EncodingSelection/slice.ts +31 -0
- package/src/theme/ApiExplorer/EncodingSelection/useResolvedEncoding.ts +43 -0
- package/src/theme/ApiExplorer/Request/index.tsx +6 -1
- package/src/theme/ApiExplorer/Request/makeRequest.ts +17 -3
- package/src/theme/ApiExplorer/buildPostmanRequest.ts +52 -5
- package/src/theme/ApiExplorer/index.tsx +1 -0
- package/src/theme/ApiItem/index.tsx +1 -0
- package/src/theme/ApiItem/store.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -7,6 +7,7 @@ interface FormBodyItemProps {
|
|
|
7
7
|
label?: string;
|
|
8
8
|
required?: boolean;
|
|
9
9
|
exampleValue?: SchemaObject["example"];
|
|
10
|
+
fieldEncoding?: string;
|
|
10
11
|
}
|
|
11
|
-
export default function FormBodyItem({ schemaObject, id, schema, label, required, exampleValue, }: FormBodyItemProps): React.JSX.Element;
|
|
12
|
+
export default function FormBodyItem({ schemaObject, id, schema, label, required, exampleValue, fieldEncoding, }: FormBodyItemProps): React.JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -83,6 +83,7 @@ const FileArrayFormBodyItem_1 = __importDefault(
|
|
|
83
83
|
require("../FileArrayFormBodyItem")
|
|
84
84
|
);
|
|
85
85
|
const slice_1 = require("../slice");
|
|
86
|
+
const slice_2 = require("../../EncodingSelection/slice");
|
|
86
87
|
function FormBodyItem({
|
|
87
88
|
schemaObject,
|
|
88
89
|
id,
|
|
@@ -90,8 +91,37 @@ function FormBodyItem({
|
|
|
90
91
|
label,
|
|
91
92
|
required,
|
|
92
93
|
exampleValue,
|
|
94
|
+
fieldEncoding,
|
|
93
95
|
}) {
|
|
94
96
|
const dispatch = (0, hooks_1.useTypedDispatch)();
|
|
97
|
+
// Parse comma-separated encoding contentType into selectable options
|
|
98
|
+
const encodingOptions = fieldEncoding
|
|
99
|
+
? fieldEncoding
|
|
100
|
+
.split(",")
|
|
101
|
+
.map((t) => t.trim())
|
|
102
|
+
.filter(Boolean)
|
|
103
|
+
: [];
|
|
104
|
+
const hasMultipleEncodings = encodingOptions.length > 1;
|
|
105
|
+
// Initialize with the first declared content type
|
|
106
|
+
const [selectedEncoding, setSelectedEncoding] = (0, react_1.useState)(
|
|
107
|
+
encodingOptions[0] ?? ""
|
|
108
|
+
);
|
|
109
|
+
// Seed Redux with the first declared encoding on mount so the code snippet
|
|
110
|
+
// reflects a content type immediately, even before the user interacts.
|
|
111
|
+
// The empty dep array is intentional: `fieldEncoding` comes from a static
|
|
112
|
+
// spec value that never changes for the lifetime of this component instance,
|
|
113
|
+
// and re-seeding on every render would fight user selections.
|
|
114
|
+
(0, react_1.useEffect)(() => {
|
|
115
|
+
if (encodingOptions[0]) {
|
|
116
|
+
dispatch(
|
|
117
|
+
(0, slice_2.setFieldEncoding)({
|
|
118
|
+
field: id,
|
|
119
|
+
contentType: encodingOptions[0],
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
|
+
}, []);
|
|
95
125
|
const [value, setValue] = (0, react_1.useState)(() => {
|
|
96
126
|
let initialValue = exampleValue ?? "";
|
|
97
127
|
if (schemaObject.type === "object" && exampleValue) {
|
|
@@ -134,6 +164,23 @@ function FormBodyItem({
|
|
|
134
164
|
label: label,
|
|
135
165
|
required: required,
|
|
136
166
|
}),
|
|
167
|
+
hasMultipleEncodings &&
|
|
168
|
+
react_1.default.createElement(
|
|
169
|
+
"div",
|
|
170
|
+
{ style: { marginTop: "0.5rem" } },
|
|
171
|
+
react_1.default.createElement(FormSelect_1.default, {
|
|
172
|
+
label: "Content-Type",
|
|
173
|
+
options: encodingOptions,
|
|
174
|
+
value: selectedEncoding,
|
|
175
|
+
onChange: (e) => {
|
|
176
|
+
const ct = e.target.value;
|
|
177
|
+
setSelectedEncoding(ct);
|
|
178
|
+
dispatch(
|
|
179
|
+
(0, slice_2.setFieldEncoding)({ field: id, contentType: ct })
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
),
|
|
137
184
|
react_1.default.createElement(FormFileUpload_1.default, {
|
|
138
185
|
placeholder: schemaObject.description || id,
|
|
139
186
|
onChange: (file) => {
|
|
@@ -140,6 +140,7 @@ function Body({
|
|
|
140
140
|
const rawSchema = requestBodyMetadata?.content?.[contentType]?.schema;
|
|
141
141
|
const example = requestBodyMetadata?.content?.[contentType]?.example;
|
|
142
142
|
const examples = requestBodyMetadata?.content?.[contentType]?.examples;
|
|
143
|
+
const encoding = requestBodyMetadata?.content?.[contentType]?.encoding;
|
|
143
144
|
// Resolve the schema based on user's anyOf/oneOf tab selections
|
|
144
145
|
const schema = (0, react_1.useMemo)(() => {
|
|
145
146
|
if (!rawSchema) return rawSchema;
|
|
@@ -391,6 +392,7 @@ function Body({
|
|
|
391
392
|
required:
|
|
392
393
|
Array.isArray(schema.required) &&
|
|
393
394
|
schema.required.includes(key),
|
|
395
|
+
fieldEncoding: encoding?.[key]?.contentType,
|
|
394
396
|
})
|
|
395
397
|
);
|
|
396
398
|
})
|
|
@@ -414,6 +416,7 @@ function Body({
|
|
|
414
416
|
required:
|
|
415
417
|
Array.isArray(schema.required) &&
|
|
416
418
|
schema.required.includes(schemaKey),
|
|
419
|
+
fieldEncoding: encoding?.[schemaKey]?.contentType,
|
|
417
420
|
})
|
|
418
421
|
);
|
|
419
422
|
}
|
|
@@ -440,6 +443,7 @@ function Body({
|
|
|
440
443
|
required:
|
|
441
444
|
Array.isArray(schema.required) &&
|
|
442
445
|
schema.required.includes(schemaKey),
|
|
446
|
+
fieldEncoding: encoding?.[schemaKey]?.contentType,
|
|
443
447
|
})
|
|
444
448
|
);
|
|
445
449
|
}
|
|
@@ -6,6 +6,7 @@ export interface Props {
|
|
|
6
6
|
postman: sdk.Request;
|
|
7
7
|
codeSamples: CodeSample[];
|
|
8
8
|
maskCredentials?: boolean;
|
|
9
|
+
requestBody?: import("docusaurus-plugin-openapi-docs/src/openapi/types").RequestBodyObject;
|
|
9
10
|
}
|
|
10
|
-
declare function CodeSnippets({ postman, codeSamples, maskCredentials: propMaskCredentials, }: Props): React.JSX.Element | null;
|
|
11
|
+
declare function CodeSnippets({ postman, codeSamples, maskCredentials: propMaskCredentials, requestBody, }: Props): React.JSX.Element | null;
|
|
11
12
|
export default CodeSnippets;
|
|
@@ -79,6 +79,7 @@ const buildPostmanRequest_1 = __importDefault(
|
|
|
79
79
|
require("@theme/ApiExplorer/buildPostmanRequest")
|
|
80
80
|
);
|
|
81
81
|
const CodeTabs_1 = __importDefault(require("@theme/ApiExplorer/CodeTabs"));
|
|
82
|
+
const useResolvedEncoding_1 = require("@theme/ApiExplorer/EncodingSelection/useResolvedEncoding");
|
|
82
83
|
const hooks_1 = require("@theme/ApiItem/hooks");
|
|
83
84
|
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
84
85
|
const postman_code_generators_1 = __importDefault(
|
|
@@ -97,6 +98,7 @@ function CodeSnippets({
|
|
|
97
98
|
postman,
|
|
98
99
|
codeSamples,
|
|
99
100
|
maskCredentials: propMaskCredentials,
|
|
101
|
+
requestBody,
|
|
100
102
|
}) {
|
|
101
103
|
const { siteConfig } = (0, useDocusaurusContext_1.default)();
|
|
102
104
|
const contentType = (0, hooks_1.useTypedSelector)(
|
|
@@ -147,6 +149,7 @@ function CodeSnippets({
|
|
|
147
149
|
};
|
|
148
150
|
})()
|
|
149
151
|
: auth;
|
|
152
|
+
const encoding = (0, useResolvedEncoding_1.useResolvedEncoding)(requestBody);
|
|
150
153
|
// Create a Postman request object using cleanedAuth or original auth
|
|
151
154
|
const cleanedPostmanRequest = (0, buildPostmanRequest_1.default)(postman, {
|
|
152
155
|
queryParams,
|
|
@@ -158,6 +161,7 @@ function CodeSnippets({
|
|
|
158
161
|
body,
|
|
159
162
|
server,
|
|
160
163
|
auth: cleanedAuth,
|
|
164
|
+
encoding,
|
|
161
165
|
});
|
|
162
166
|
// User-defined languages array
|
|
163
167
|
// Can override languageSet, change order of langs, override options and variants
|
|
@@ -16,6 +16,7 @@ const FormItem_1 = __importDefault(require("@theme/ApiExplorer/FormItem"));
|
|
|
16
16
|
const FormSelect_1 = __importDefault(require("@theme/ApiExplorer/FormSelect"));
|
|
17
17
|
const hooks_1 = require("@theme/ApiItem/hooks");
|
|
18
18
|
const slice_1 = require("./slice");
|
|
19
|
+
const slice_2 = require("@theme/ApiExplorer/EncodingSelection/slice");
|
|
19
20
|
function ContentType() {
|
|
20
21
|
const value = (0, hooks_1.useTypedSelector)(
|
|
21
22
|
(state) => state.contentType.value
|
|
@@ -34,7 +35,10 @@ function ContentType() {
|
|
|
34
35
|
label: "Content-Type",
|
|
35
36
|
value: value,
|
|
36
37
|
options: options,
|
|
37
|
-
onChange: (e) =>
|
|
38
|
+
onChange: (e) => {
|
|
39
|
+
dispatch((0, slice_1.setContentType)(e.target.value));
|
|
40
|
+
dispatch((0, slice_2.clearEncodingSelection)());
|
|
41
|
+
},
|
|
38
42
|
})
|
|
39
43
|
);
|
|
40
44
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PayloadAction } from "@reduxjs/toolkit";
|
|
2
|
+
export type State = Record<string, string>;
|
|
3
|
+
export declare const slice: import("@reduxjs/toolkit").Slice<State, {
|
|
4
|
+
setFieldEncoding: (state: {
|
|
5
|
+
[x: string]: string;
|
|
6
|
+
}, action: PayloadAction<{
|
|
7
|
+
field: string;
|
|
8
|
+
contentType: string;
|
|
9
|
+
}>) => void;
|
|
10
|
+
clearEncodingSelection: () => State;
|
|
11
|
+
}, "encodingSelection", "encodingSelection", import("@reduxjs/toolkit").SliceSelectors<State>>;
|
|
12
|
+
export declare const setFieldEncoding: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
13
|
+
field: string;
|
|
14
|
+
contentType: string;
|
|
15
|
+
}, "encodingSelection/setFieldEncoding">, clearEncodingSelection: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"encodingSelection/clearEncodingSelection">;
|
|
16
|
+
declare const _default: import("redux").Reducer<State>;
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
var _a;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.clearEncodingSelection =
|
|
11
|
+
exports.setFieldEncoding =
|
|
12
|
+
exports.slice =
|
|
13
|
+
void 0;
|
|
14
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
15
|
+
const initialState = {};
|
|
16
|
+
exports.slice = (0, toolkit_1.createSlice)({
|
|
17
|
+
name: "encodingSelection",
|
|
18
|
+
initialState,
|
|
19
|
+
reducers: {
|
|
20
|
+
setFieldEncoding: (state, action) => {
|
|
21
|
+
state[action.payload.field] = action.payload.contentType;
|
|
22
|
+
},
|
|
23
|
+
clearEncodingSelection: () => initialState,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
((_a = exports.slice.actions),
|
|
27
|
+
(exports.setFieldEncoding = _a.setFieldEncoding),
|
|
28
|
+
(exports.clearEncodingSelection = _a.clearEncodingSelection));
|
|
29
|
+
exports.default = exports.slice.reducer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
2
|
+
/**
|
|
3
|
+
* Merges the spec-declared `encoding` for the active content type with any
|
|
4
|
+
* per-field content-type selections the user has made in the UI. User picks
|
|
5
|
+
* take precedence over the spec default.
|
|
6
|
+
*
|
|
7
|
+
* Returns `undefined` when no encoding is declared for the current content
|
|
8
|
+
* type so callers can skip the encoding path entirely.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useResolvedEncoding(requestBody: RequestBodyObject | undefined): Record<string, {
|
|
11
|
+
contentType?: string;
|
|
12
|
+
}> | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.useResolvedEncoding = useResolvedEncoding;
|
|
10
|
+
const hooks_1 = require("@theme/ApiItem/hooks");
|
|
11
|
+
/**
|
|
12
|
+
* Merges the spec-declared `encoding` for the active content type with any
|
|
13
|
+
* per-field content-type selections the user has made in the UI. User picks
|
|
14
|
+
* take precedence over the spec default.
|
|
15
|
+
*
|
|
16
|
+
* Returns `undefined` when no encoding is declared for the current content
|
|
17
|
+
* type so callers can skip the encoding path entirely.
|
|
18
|
+
*/
|
|
19
|
+
function useResolvedEncoding(requestBody) {
|
|
20
|
+
const contentType = (0, hooks_1.useTypedSelector)(
|
|
21
|
+
(state) => state.contentType.value
|
|
22
|
+
);
|
|
23
|
+
const encodingSelection = (0, hooks_1.useTypedSelector)(
|
|
24
|
+
(state) => state.encodingSelection
|
|
25
|
+
);
|
|
26
|
+
const specEncoding = requestBody?.content?.[contentType]?.encoding ?? {};
|
|
27
|
+
if (!Object.keys(specEncoding).length) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return Object.fromEntries(
|
|
31
|
+
Object.entries(specEncoding).map(([field, enc]) => [
|
|
32
|
+
field,
|
|
33
|
+
{
|
|
34
|
+
...enc,
|
|
35
|
+
contentType: encodingSelection[field] ?? enc.contentType,
|
|
36
|
+
},
|
|
37
|
+
])
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -90,6 +90,7 @@ const ParamOptions_1 = __importDefault(
|
|
|
90
90
|
);
|
|
91
91
|
const slice_1 = require("@theme/ApiExplorer/Response/slice");
|
|
92
92
|
const Server_1 = __importDefault(require("@theme/ApiExplorer/Server"));
|
|
93
|
+
const useResolvedEncoding_1 = require("@theme/ApiExplorer/EncodingSelection/useResolvedEncoding");
|
|
93
94
|
const hooks_1 = require("@theme/ApiItem/hooks");
|
|
94
95
|
const translationIds_1 = require("@theme/translationIds");
|
|
95
96
|
const sdk = __importStar(require("postman-collection"));
|
|
@@ -147,6 +148,9 @@ function Request({ item }) {
|
|
|
147
148
|
...cookieParams,
|
|
148
149
|
...headerParams,
|
|
149
150
|
];
|
|
151
|
+
const encoding = (0, useResolvedEncoding_1.useResolvedEncoding)(
|
|
152
|
+
item.requestBody
|
|
153
|
+
);
|
|
150
154
|
const postmanRequest = (0, buildPostmanRequest_1.default)(postman, {
|
|
151
155
|
queryParams,
|
|
152
156
|
pathParams,
|
|
@@ -157,6 +161,7 @@ function Request({ item }) {
|
|
|
157
161
|
body,
|
|
158
162
|
server,
|
|
159
163
|
auth,
|
|
164
|
+
encoding,
|
|
160
165
|
});
|
|
161
166
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
162
167
|
const paramsObject = {
|
|
@@ -236,7 +241,8 @@ function Request({ item }) {
|
|
|
236
241
|
proxy,
|
|
237
242
|
body,
|
|
238
243
|
requestTimeout,
|
|
239
|
-
requestCredentials
|
|
244
|
+
requestCredentials,
|
|
245
|
+
encoding
|
|
240
246
|
);
|
|
241
247
|
if (res.headers.get("content-type")?.includes("text/event-stream")) {
|
|
242
248
|
await handleEventStream(res);
|
|
@@ -6,5 +6,7 @@ export declare class RequestError extends Error {
|
|
|
6
6
|
originalError?: Error;
|
|
7
7
|
constructor(type: RequestErrorType, message: string, originalError?: Error);
|
|
8
8
|
}
|
|
9
|
-
declare function makeRequest(request: sdk.Request, proxy: string | undefined, _body: Body, timeout?: number, credentials?: RequestCredentials
|
|
9
|
+
declare function makeRequest(request: sdk.Request, proxy: string | undefined, _body: Body, timeout?: number, credentials?: RequestCredentials, encoding?: Record<string, {
|
|
10
|
+
contentType?: string;
|
|
11
|
+
}>): Promise<Response>;
|
|
10
12
|
export default makeRequest;
|
|
@@ -90,7 +90,8 @@ async function makeRequest(
|
|
|
90
90
|
proxy,
|
|
91
91
|
_body,
|
|
92
92
|
timeout = DEFAULT_REQUEST_TIMEOUT,
|
|
93
|
-
credentials
|
|
93
|
+
credentials,
|
|
94
|
+
encoding
|
|
94
95
|
) {
|
|
95
96
|
const headers = request.toJSON().header;
|
|
96
97
|
let myHeaders = new Headers();
|
|
@@ -197,12 +198,25 @@ async function makeRequest(
|
|
|
197
198
|
const members = request.body?.formdata?.members;
|
|
198
199
|
if (Array.isArray(members)) {
|
|
199
200
|
for (const data of members) {
|
|
201
|
+
const partContentType = encoding?.[data.key]?.contentType
|
|
202
|
+
?.split(",")[0]
|
|
203
|
+
.trim();
|
|
200
204
|
if (data.key && data.value.content) {
|
|
201
|
-
|
|
205
|
+
const blob = partContentType
|
|
206
|
+
? new Blob([data.value.content], { type: partContentType })
|
|
207
|
+
: data.value.content;
|
|
208
|
+
myBody.append(data.key, blob);
|
|
202
209
|
}
|
|
203
210
|
// handle generic key-value payload
|
|
204
211
|
if (data.key && typeof data.value === "string") {
|
|
205
|
-
|
|
212
|
+
if (partContentType) {
|
|
213
|
+
myBody.append(
|
|
214
|
+
data.key,
|
|
215
|
+
new Blob([data.value], { type: partContentType })
|
|
216
|
+
);
|
|
217
|
+
} else {
|
|
218
|
+
myBody.append(data.key, data.value);
|
|
219
|
+
}
|
|
206
220
|
}
|
|
207
221
|
}
|
|
208
222
|
}
|
|
@@ -15,6 +15,9 @@ interface Options {
|
|
|
15
15
|
accept: string;
|
|
16
16
|
body: Body;
|
|
17
17
|
auth: AuthState;
|
|
18
|
+
encoding?: Record<string, {
|
|
19
|
+
contentType?: string;
|
|
20
|
+
}>;
|
|
18
21
|
}
|
|
19
|
-
declare function buildPostmanRequest(postman: sdk.Request, { queryParams, pathParams, cookieParams, contentType, accept, headerParams, body, server, auth, }: Options): sdk.Request;
|
|
22
|
+
declare function buildPostmanRequest(postman: sdk.Request, { queryParams, pathParams, cookieParams, contentType, accept, headerParams, body, server, auth, encoding, }: Options): sdk.Request;
|
|
20
23
|
export default buildPostmanRequest;
|
|
@@ -314,11 +314,30 @@ function tryDecodeJsonParam(value) {
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
// TODO: this is all a bit hacky
|
|
317
|
-
function setBody(clonedPostman, body) {
|
|
317
|
+
function setBody(clonedPostman, body, encoding) {
|
|
318
318
|
if (clonedPostman.body === undefined) {
|
|
319
319
|
return;
|
|
320
320
|
}
|
|
321
321
|
if (body.type === "empty") {
|
|
322
|
+
// When the original request has formdata and encoding is declared, keep the
|
|
323
|
+
// placeholder params so the code snippet reflects the selected encoding even
|
|
324
|
+
// before the user has uploaded a file.
|
|
325
|
+
if (
|
|
326
|
+
clonedPostman.body?.mode === "formdata" &&
|
|
327
|
+
encoding &&
|
|
328
|
+
Object.keys(encoding).length > 0
|
|
329
|
+
) {
|
|
330
|
+
const members = clonedPostman.body.formdata?.members ?? [];
|
|
331
|
+
members.forEach((param) => {
|
|
332
|
+
const partContentType = encoding[param.key]?.contentType
|
|
333
|
+
?.split(",")[0]
|
|
334
|
+
.trim();
|
|
335
|
+
if (partContentType) {
|
|
336
|
+
param.contentType = partContentType;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
322
341
|
clonedPostman.body = undefined;
|
|
323
342
|
return;
|
|
324
343
|
}
|
|
@@ -354,14 +373,35 @@ function setBody(clonedPostman, body) {
|
|
|
354
373
|
Object.entries(body.content)
|
|
355
374
|
.filter((entry) => !!entry[1])
|
|
356
375
|
.forEach(([key, content]) => {
|
|
376
|
+
const partContentType = encoding?.[key]?.contentType
|
|
377
|
+
?.split(",")[0]
|
|
378
|
+
.trim();
|
|
357
379
|
if (content.type === "file") {
|
|
358
|
-
params.push(
|
|
380
|
+
params.push(
|
|
381
|
+
new sdk.FormParam({
|
|
382
|
+
key: key,
|
|
383
|
+
...content,
|
|
384
|
+
...(partContentType && { contentType: partContentType }),
|
|
385
|
+
})
|
|
386
|
+
);
|
|
359
387
|
} else if (content.type === "file[]") {
|
|
360
388
|
content.value.forEach((file) =>
|
|
361
|
-
params.push(
|
|
389
|
+
params.push(
|
|
390
|
+
new sdk.FormParam({
|
|
391
|
+
key,
|
|
392
|
+
value: file,
|
|
393
|
+
...(partContentType && { contentType: partContentType }),
|
|
394
|
+
})
|
|
395
|
+
)
|
|
362
396
|
);
|
|
363
397
|
} else {
|
|
364
|
-
params.push(
|
|
398
|
+
params.push(
|
|
399
|
+
new sdk.FormParam({
|
|
400
|
+
key: key,
|
|
401
|
+
value: content.value,
|
|
402
|
+
...(partContentType && { contentType: partContentType }),
|
|
403
|
+
})
|
|
404
|
+
);
|
|
365
405
|
}
|
|
366
406
|
});
|
|
367
407
|
params.forEach((param) => {
|
|
@@ -409,6 +449,7 @@ function buildPostmanRequest(
|
|
|
409
449
|
body,
|
|
410
450
|
server,
|
|
411
451
|
auth,
|
|
452
|
+
encoding,
|
|
412
453
|
}
|
|
413
454
|
) {
|
|
414
455
|
const clonedPostman = (0, cloneDeep_1.default)(postman);
|
|
@@ -521,7 +562,7 @@ function buildPostmanRequest(
|
|
|
521
562
|
headerParams,
|
|
522
563
|
otherHeaders
|
|
523
564
|
);
|
|
524
|
-
setBody(clonedPostman, body);
|
|
565
|
+
setBody(clonedPostman, body, encoding);
|
|
525
566
|
return clonedPostman;
|
|
526
567
|
}
|
|
527
568
|
exports.default = buildPostmanRequest;
|
|
@@ -99,6 +99,7 @@ function ApiExplorer({ item, infoPath }) {
|
|
|
99
99
|
postman: postman,
|
|
100
100
|
codeSamples: item["x-codeSamples"] ?? [],
|
|
101
101
|
maskCredentials: mask_credentials,
|
|
102
|
+
requestBody: item.requestBody,
|
|
102
103
|
}),
|
|
103
104
|
react_1.default.createElement(Request_1.default, { item: item }),
|
|
104
105
|
react_1.default.createElement(Response_1.default, { item: item })
|
|
@@ -3,6 +3,7 @@ import type { ThemeConfig } from "docusaurus-theme-openapi-docs/src/types";
|
|
|
3
3
|
export declare function createPersistenceMiddleware(options: ThemeConfig["api"]): Middleware<{}, {
|
|
4
4
|
accept: import("./Accept/slice").State;
|
|
5
5
|
contentType: import("./ContentType/slice").State;
|
|
6
|
+
encodingSelection: import("./EncodingSelection/slice").State;
|
|
6
7
|
response: import("./Response/slice").State;
|
|
7
8
|
server: import("./Server/slice").State;
|
|
8
9
|
body: import("./Body/slice").FormBody | import("./Body/slice").RawBody | import("./Body/slice").EmptyBody;
|
|
@@ -12,6 +13,7 @@ export declare function createPersistenceMiddleware(options: ThemeConfig["api"])
|
|
|
12
13
|
}, import("redux-thunk").ThunkDispatch<{
|
|
13
14
|
accept: import("./Accept/slice").State;
|
|
14
15
|
contentType: import("./ContentType/slice").State;
|
|
16
|
+
encodingSelection: import("./EncodingSelection/slice").State;
|
|
15
17
|
response: import("./Response/slice").State;
|
|
16
18
|
server: import("./Server/slice").State;
|
|
17
19
|
body: import("./Body/slice").FormBody | import("./Body/slice").RawBody | import("./Body/slice").EmptyBody;
|
|
@@ -3,6 +3,7 @@ import type { RootState } from "./store";
|
|
|
3
3
|
export declare const useTypedDispatch: () => import("redux-thunk").ThunkDispatch<{
|
|
4
4
|
accept: import("../ApiExplorer/Accept/slice").State;
|
|
5
5
|
contentType: import("../ApiExplorer/ContentType/slice").State;
|
|
6
|
+
encodingSelection: import("../ApiExplorer/EncodingSelection/slice").State;
|
|
6
7
|
response: import("../ApiExplorer/Response/slice").State;
|
|
7
8
|
server: import("../ApiExplorer/Server/slice").State;
|
|
8
9
|
body: import("../ApiExplorer/Body/slice").FormBody | import("../ApiExplorer/Body/slice").RawBody | import("../ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare const rootReducer: import("redux").Reducer<{
|
|
2
2
|
accept: import("@theme/ApiExplorer/Accept/slice").State;
|
|
3
3
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State;
|
|
4
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State;
|
|
4
5
|
response: import("@theme/ApiExplorer/Response/slice").State;
|
|
5
6
|
server: import("@theme/ApiExplorer/Server/slice").State;
|
|
6
7
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -10,6 +11,7 @@ declare const rootReducer: import("redux").Reducer<{
|
|
|
10
11
|
}, import("redux").UnknownAction, Partial<{
|
|
11
12
|
accept: import("@theme/ApiExplorer/Accept/slice").State | undefined;
|
|
12
13
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State | undefined;
|
|
14
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State | undefined;
|
|
13
15
|
response: import("@theme/ApiExplorer/Response/slice").State | undefined;
|
|
14
16
|
server: import("@theme/ApiExplorer/Server/slice").State | undefined;
|
|
15
17
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody | undefined;
|
|
@@ -21,6 +23,7 @@ export type RootState = ReturnType<typeof rootReducer>;
|
|
|
21
23
|
export declare const createStoreWithState: (preloadedState: RootState, middlewares: any[]) => import("@reduxjs/toolkit").EnhancedStore<{
|
|
22
24
|
accept: import("@theme/ApiExplorer/Accept/slice").State;
|
|
23
25
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State;
|
|
26
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State;
|
|
24
27
|
response: import("@theme/ApiExplorer/Response/slice").State;
|
|
25
28
|
server: import("@theme/ApiExplorer/Server/slice").State;
|
|
26
29
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -31,6 +34,7 @@ export declare const createStoreWithState: (preloadedState: RootState, middlewar
|
|
|
31
34
|
dispatch: import("redux-thunk").ThunkDispatch<{
|
|
32
35
|
accept: import("@theme/ApiExplorer/Accept/slice").State;
|
|
33
36
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State;
|
|
37
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State;
|
|
34
38
|
response: import("@theme/ApiExplorer/Response/slice").State;
|
|
35
39
|
server: import("@theme/ApiExplorer/Server/slice").State;
|
|
36
40
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -42,6 +46,7 @@ export declare const createStoreWithState: (preloadedState: RootState, middlewar
|
|
|
42
46
|
export declare const createStoreWithoutState: (preloadedState: {}, middlewares: any[]) => import("@reduxjs/toolkit").EnhancedStore<{
|
|
43
47
|
accept: import("@theme/ApiExplorer/Accept/slice").State;
|
|
44
48
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State;
|
|
49
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State;
|
|
45
50
|
response: import("@theme/ApiExplorer/Response/slice").State;
|
|
46
51
|
server: import("@theme/ApiExplorer/Server/slice").State;
|
|
47
52
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -52,6 +57,7 @@ export declare const createStoreWithoutState: (preloadedState: {}, middlewares:
|
|
|
52
57
|
dispatch: import("redux-thunk").ThunkDispatch<{
|
|
53
58
|
accept: import("@theme/ApiExplorer/Accept/slice").State;
|
|
54
59
|
contentType: import("@theme/ApiExplorer/ContentType/slice").State;
|
|
60
|
+
encodingSelection: import("@theme/ApiExplorer/EncodingSelection/slice").State;
|
|
55
61
|
response: import("@theme/ApiExplorer/Response/slice").State;
|
|
56
62
|
server: import("@theme/ApiExplorer/Server/slice").State;
|
|
57
63
|
body: import("@theme/ApiExplorer/Body/slice").FormBody | import("@theme/ApiExplorer/Body/slice").RawBody | import("@theme/ApiExplorer/Body/slice").EmptyBody;
|
|
@@ -22,22 +22,26 @@ const slice_4 = __importDefault(
|
|
|
22
22
|
require("@theme/ApiExplorer/ContentType/slice")
|
|
23
23
|
);
|
|
24
24
|
const slice_5 = __importDefault(
|
|
25
|
+
require("@theme/ApiExplorer/EncodingSelection/slice")
|
|
26
|
+
);
|
|
27
|
+
const slice_6 = __importDefault(
|
|
25
28
|
require("@theme/ApiExplorer/ParamOptions/slice")
|
|
26
29
|
);
|
|
27
|
-
const
|
|
28
|
-
const
|
|
30
|
+
const slice_7 = __importDefault(require("@theme/ApiExplorer/Response/slice"));
|
|
31
|
+
const slice_8 = __importDefault(
|
|
29
32
|
require("@theme/ApiExplorer/SchemaSelection/slice")
|
|
30
33
|
);
|
|
31
|
-
const
|
|
34
|
+
const slice_9 = __importDefault(require("@theme/ApiExplorer/Server/slice"));
|
|
32
35
|
const rootReducer = (0, toolkit_1.combineReducers)({
|
|
33
36
|
accept: slice_1.default,
|
|
34
37
|
contentType: slice_4.default,
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
encodingSelection: slice_5.default,
|
|
39
|
+
response: slice_7.default,
|
|
40
|
+
server: slice_9.default,
|
|
37
41
|
body: slice_3.default,
|
|
38
|
-
params:
|
|
42
|
+
params: slice_6.default,
|
|
39
43
|
auth: slice_2.default,
|
|
40
|
-
schemaSelection:
|
|
44
|
+
schemaSelection: slice_8.default,
|
|
41
45
|
});
|
|
42
46
|
const createStoreWithState = (preloadedState, middlewares) =>
|
|
43
47
|
(0, toolkit_1.configureStore)({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-theme-openapi-docs",
|
|
3
3
|
"description": "OpenAPI theme for Docusaurus.",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-1161",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@types/postman-collection": "^3.5.11",
|
|
39
39
|
"@types/react-modal": "^3.16.3",
|
|
40
40
|
"concurrently": "^9.2.0",
|
|
41
|
-
"docusaurus-plugin-openapi-docs": "0.0.0-
|
|
41
|
+
"docusaurus-plugin-openapi-docs": "0.0.0-1161",
|
|
42
42
|
"docusaurus-plugin-sass": "^0.2.6",
|
|
43
43
|
"eslint-plugin-prettier": "^5.5.1"
|
|
44
44
|
},
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"engines": {
|
|
83
83
|
"node": ">=14"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "43f0aa571d28347f05806d74d5d1af1e23ecc0e0"
|
|
86
86
|
}
|
|
@@ -17,6 +17,7 @@ import type { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/ty
|
|
|
17
17
|
|
|
18
18
|
import FileArrayFormBodyItem from "../FileArrayFormBodyItem";
|
|
19
19
|
import { clearFormBodyKey, setFileFormBody, setStringFormBody } from "../slice";
|
|
20
|
+
import { setFieldEncoding } from "../../EncodingSelection/slice";
|
|
20
21
|
|
|
21
22
|
interface FormBodyItemProps {
|
|
22
23
|
schemaObject: SchemaObject;
|
|
@@ -25,6 +26,7 @@ interface FormBodyItemProps {
|
|
|
25
26
|
label?: string;
|
|
26
27
|
required?: boolean;
|
|
27
28
|
exampleValue?: SchemaObject["example"];
|
|
29
|
+
fieldEncoding?: string;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export default function FormBodyItem({
|
|
@@ -34,8 +36,37 @@ export default function FormBodyItem({
|
|
|
34
36
|
label,
|
|
35
37
|
required,
|
|
36
38
|
exampleValue,
|
|
39
|
+
fieldEncoding,
|
|
37
40
|
}: FormBodyItemProps): React.JSX.Element {
|
|
38
41
|
const dispatch = useTypedDispatch();
|
|
42
|
+
|
|
43
|
+
// Parse comma-separated encoding contentType into selectable options
|
|
44
|
+
const encodingOptions = fieldEncoding
|
|
45
|
+
? fieldEncoding
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((t) => t.trim())
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
: [];
|
|
50
|
+
const hasMultipleEncodings = encodingOptions.length > 1;
|
|
51
|
+
|
|
52
|
+
// Initialize with the first declared content type
|
|
53
|
+
const [selectedEncoding, setSelectedEncoding] = useState<string>(
|
|
54
|
+
encodingOptions[0] ?? ""
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Seed Redux with the first declared encoding on mount so the code snippet
|
|
58
|
+
// reflects a content type immediately, even before the user interacts.
|
|
59
|
+
// The empty dep array is intentional: `fieldEncoding` comes from a static
|
|
60
|
+
// spec value that never changes for the lifetime of this component instance,
|
|
61
|
+
// and re-seeding on every render would fight user selections.
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (encodingOptions[0]) {
|
|
64
|
+
dispatch(
|
|
65
|
+
setFieldEncoding({ field: id, contentType: encodingOptions[0] })
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
|
+
}, []);
|
|
39
70
|
const [value, setValue] = useState(() => {
|
|
40
71
|
let initialValue = exampleValue ?? "";
|
|
41
72
|
|
|
@@ -71,6 +102,20 @@ export default function FormBodyItem({
|
|
|
71
102
|
return (
|
|
72
103
|
<>
|
|
73
104
|
{label && <FormLabel label={label} required={required} />}
|
|
105
|
+
{hasMultipleEncodings && (
|
|
106
|
+
<div style={{ marginTop: "0.5rem" }}>
|
|
107
|
+
<FormSelect
|
|
108
|
+
label="Content-Type"
|
|
109
|
+
options={encodingOptions}
|
|
110
|
+
value={selectedEncoding}
|
|
111
|
+
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
112
|
+
const ct = e.target.value;
|
|
113
|
+
setSelectedEncoding(ct);
|
|
114
|
+
dispatch(setFieldEncoding({ field: id, contentType: ct }));
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
74
119
|
<FormFileUpload
|
|
75
120
|
placeholder={schemaObject.description || id}
|
|
76
121
|
onChange={(file: any) => {
|
|
@@ -95,16 +140,16 @@ export default function FormBodyItem({
|
|
|
95
140
|
|
|
96
141
|
if (schemaObject.type === "object") {
|
|
97
142
|
return (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
143
|
+
<>
|
|
144
|
+
{label && <FormLabel label={label} required={required} />}
|
|
145
|
+
<LiveApp
|
|
146
|
+
action={(code: string) =>
|
|
147
|
+
dispatch(setStringFormBody({ key: id, value: code }))
|
|
148
|
+
}
|
|
149
|
+
>
|
|
150
|
+
{value}
|
|
151
|
+
</LiveApp>
|
|
152
|
+
</>
|
|
108
153
|
);
|
|
109
154
|
}
|
|
110
155
|
|
|
@@ -93,6 +93,8 @@ function Body({
|
|
|
93
93
|
const rawSchema = requestBodyMetadata?.content?.[contentType]?.schema;
|
|
94
94
|
const example = requestBodyMetadata?.content?.[contentType]?.example;
|
|
95
95
|
const examples = requestBodyMetadata?.content?.[contentType]?.examples;
|
|
96
|
+
const encoding: Record<string, { contentType?: string }> | undefined =
|
|
97
|
+
requestBodyMetadata?.content?.[contentType]?.encoding;
|
|
96
98
|
|
|
97
99
|
// Resolve the schema based on user's anyOf/oneOf tab selections
|
|
98
100
|
const schema = useMemo(() => {
|
|
@@ -339,6 +341,7 @@ function Body({
|
|
|
339
341
|
Array.isArray(schema.required) &&
|
|
340
342
|
schema.required.includes(key)
|
|
341
343
|
}
|
|
344
|
+
fieldEncoding={encoding?.[key]?.contentType}
|
|
342
345
|
></FormBodyItem>
|
|
343
346
|
</FormItem>
|
|
344
347
|
);
|
|
@@ -361,6 +364,7 @@ function Body({
|
|
|
361
364
|
Array.isArray(schema.required) &&
|
|
362
365
|
schema.required.includes(schemaKey)
|
|
363
366
|
}
|
|
367
|
+
fieldEncoding={encoding?.[schemaKey]?.contentType}
|
|
364
368
|
></FormBodyItem>
|
|
365
369
|
</FormItem>
|
|
366
370
|
);
|
|
@@ -387,6 +391,7 @@ function Body({
|
|
|
387
391
|
Array.isArray(schema.required) &&
|
|
388
392
|
schema.required.includes(schemaKey)
|
|
389
393
|
}
|
|
394
|
+
fieldEncoding={encoding?.[schemaKey]?.contentType}
|
|
390
395
|
></FormBodyItem>
|
|
391
396
|
</FormItem>
|
|
392
397
|
);
|
|
@@ -11,6 +11,7 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
|
11
11
|
import ApiCodeBlock from "@theme/ApiExplorer/ApiCodeBlock";
|
|
12
12
|
import buildPostmanRequest from "@theme/ApiExplorer/buildPostmanRequest";
|
|
13
13
|
import CodeTabs from "@theme/ApiExplorer/CodeTabs";
|
|
14
|
+
import { useResolvedEncoding } from "@theme/ApiExplorer/EncodingSelection/useResolvedEncoding";
|
|
14
15
|
import { useTypedSelector } from "@theme/ApiItem/hooks";
|
|
15
16
|
import cloneDeep from "lodash/cloneDeep";
|
|
16
17
|
import codegen from "postman-code-generators";
|
|
@@ -30,6 +31,7 @@ export interface Props {
|
|
|
30
31
|
postman: sdk.Request;
|
|
31
32
|
codeSamples: CodeSample[];
|
|
32
33
|
maskCredentials?: boolean;
|
|
34
|
+
requestBody?: import("docusaurus-plugin-openapi-docs/src/openapi/types").RequestBodyObject;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
function CodeTab({ children, hidden, className }: any): React.JSX.Element {
|
|
@@ -44,6 +46,7 @@ function CodeSnippets({
|
|
|
44
46
|
postman,
|
|
45
47
|
codeSamples,
|
|
46
48
|
maskCredentials: propMaskCredentials,
|
|
49
|
+
requestBody,
|
|
47
50
|
}: Props) {
|
|
48
51
|
const { siteConfig } = useDocusaurusContext();
|
|
49
52
|
|
|
@@ -76,7 +79,9 @@ function CodeSnippets({
|
|
|
76
79
|
const authOptions =
|
|
77
80
|
clonedAuth?.options?.[key] ??
|
|
78
81
|
clonedAuth?.options?.[comboAuthId];
|
|
79
|
-
placeholder = authOptions?.find(
|
|
82
|
+
placeholder = authOptions?.find(
|
|
83
|
+
(opt: any) => opt.key === key
|
|
84
|
+
)?.name;
|
|
80
85
|
obj[key] = cleanCredentials(obj[key]);
|
|
81
86
|
} else {
|
|
82
87
|
obj[key] = `<${placeholder ?? key}>`;
|
|
@@ -93,6 +98,8 @@ function CodeSnippets({
|
|
|
93
98
|
})()
|
|
94
99
|
: auth;
|
|
95
100
|
|
|
101
|
+
const encoding = useResolvedEncoding(requestBody);
|
|
102
|
+
|
|
96
103
|
// Create a Postman request object using cleanedAuth or original auth
|
|
97
104
|
const cleanedPostmanRequest = buildPostmanRequest(postman, {
|
|
98
105
|
queryParams,
|
|
@@ -104,6 +111,7 @@ function CodeSnippets({
|
|
|
104
111
|
body,
|
|
105
112
|
server,
|
|
106
113
|
auth: cleanedAuth,
|
|
114
|
+
encoding,
|
|
107
115
|
});
|
|
108
116
|
|
|
109
117
|
// User-defined languages array
|
|
@@ -12,6 +12,7 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
|
12
12
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
13
13
|
|
|
14
14
|
import { setContentType } from "./slice";
|
|
15
|
+
import { clearEncodingSelection } from "@theme/ApiExplorer/EncodingSelection/slice";
|
|
15
16
|
|
|
16
17
|
function ContentType() {
|
|
17
18
|
const value = useTypedSelector((state: any) => state.contentType.value);
|
|
@@ -28,9 +29,10 @@ function ContentType() {
|
|
|
28
29
|
label="Content-Type"
|
|
29
30
|
value={value}
|
|
30
31
|
options={options}
|
|
31
|
-
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
|
|
32
|
-
dispatch(setContentType(e.target.value))
|
|
33
|
-
|
|
32
|
+
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
33
|
+
dispatch(setContentType(e.target.value));
|
|
34
|
+
dispatch(clearEncodingSelection());
|
|
35
|
+
}}
|
|
34
36
|
/>
|
|
35
37
|
</FormItem>
|
|
36
38
|
);
|
|
@@ -0,0 +1,31 @@
|
|
|
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 { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
|
9
|
+
|
|
10
|
+
// Maps form field name → user-selected content type
|
|
11
|
+
export type State = Record<string, string>;
|
|
12
|
+
|
|
13
|
+
const initialState: State = {};
|
|
14
|
+
|
|
15
|
+
export const slice = createSlice({
|
|
16
|
+
name: "encodingSelection",
|
|
17
|
+
initialState,
|
|
18
|
+
reducers: {
|
|
19
|
+
setFieldEncoding: (
|
|
20
|
+
state,
|
|
21
|
+
action: PayloadAction<{ field: string; contentType: string }>
|
|
22
|
+
) => {
|
|
23
|
+
state[action.payload.field] = action.payload.contentType;
|
|
24
|
+
},
|
|
25
|
+
clearEncodingSelection: () => initialState,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const { setFieldEncoding, clearEncodingSelection } = slice.actions;
|
|
30
|
+
|
|
31
|
+
export default slice.reducer;
|
|
@@ -0,0 +1,43 @@
|
|
|
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 { useTypedSelector } from "@theme/ApiItem/hooks";
|
|
9
|
+
import type { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Merges the spec-declared `encoding` for the active content type with any
|
|
13
|
+
* per-field content-type selections the user has made in the UI. User picks
|
|
14
|
+
* take precedence over the spec default.
|
|
15
|
+
*
|
|
16
|
+
* Returns `undefined` when no encoding is declared for the current content
|
|
17
|
+
* type so callers can skip the encoding path entirely.
|
|
18
|
+
*/
|
|
19
|
+
export function useResolvedEncoding(
|
|
20
|
+
requestBody: RequestBodyObject | undefined
|
|
21
|
+
): Record<string, { contentType?: string }> | undefined {
|
|
22
|
+
const contentType = useTypedSelector((state: any) => state.contentType.value);
|
|
23
|
+
const encodingSelection = useTypedSelector(
|
|
24
|
+
(state: any) => state.encodingSelection
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const specEncoding: Record<string, { contentType?: string }> =
|
|
28
|
+
requestBody?.content?.[contentType]?.encoding ?? {};
|
|
29
|
+
|
|
30
|
+
if (!Object.keys(specEncoding).length) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return Object.fromEntries(
|
|
35
|
+
Object.entries(specEncoding).map(([field, enc]) => [
|
|
36
|
+
field,
|
|
37
|
+
{
|
|
38
|
+
...enc,
|
|
39
|
+
contentType: encodingSelection[field] ?? enc.contentType,
|
|
40
|
+
},
|
|
41
|
+
])
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
clearHeaders,
|
|
26
26
|
} from "@theme/ApiExplorer/Response/slice";
|
|
27
27
|
import Server from "@theme/ApiExplorer/Server";
|
|
28
|
+
import { useResolvedEncoding } from "@theme/ApiExplorer/EncodingSelection/useResolvedEncoding";
|
|
28
29
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
29
30
|
import { OPENAPI_REQUEST } from "@theme/translationIds";
|
|
30
31
|
import type { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
@@ -76,6 +77,8 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
76
77
|
...headerParams,
|
|
77
78
|
];
|
|
78
79
|
|
|
80
|
+
const encoding = useResolvedEncoding(item.requestBody);
|
|
81
|
+
|
|
79
82
|
const postmanRequest = buildPostmanRequest(postman, {
|
|
80
83
|
queryParams,
|
|
81
84
|
pathParams,
|
|
@@ -86,6 +89,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
86
89
|
body,
|
|
87
90
|
server,
|
|
88
91
|
auth,
|
|
92
|
+
encoding,
|
|
89
93
|
});
|
|
90
94
|
|
|
91
95
|
const delay = (ms: number) =>
|
|
@@ -175,7 +179,8 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
175
179
|
proxy,
|
|
176
180
|
body,
|
|
177
181
|
requestTimeout,
|
|
178
|
-
requestCredentials
|
|
182
|
+
requestCredentials,
|
|
183
|
+
encoding
|
|
179
184
|
);
|
|
180
185
|
if (res.headers.get("content-type")?.includes("text/event-stream")) {
|
|
181
186
|
await handleEventStream(res);
|
|
@@ -115,7 +115,8 @@ async function makeRequest(
|
|
|
115
115
|
proxy: string | undefined,
|
|
116
116
|
_body: Body,
|
|
117
117
|
timeout: number = DEFAULT_REQUEST_TIMEOUT,
|
|
118
|
-
credentials?: RequestCredentials
|
|
118
|
+
credentials?: RequestCredentials,
|
|
119
|
+
encoding?: Record<string, { contentType?: string }>
|
|
119
120
|
) {
|
|
120
121
|
const headers = request.toJSON().header;
|
|
121
122
|
|
|
@@ -227,12 +228,25 @@ async function makeRequest(
|
|
|
227
228
|
const members = (request.body as any)?.formdata?.members;
|
|
228
229
|
if (Array.isArray(members)) {
|
|
229
230
|
for (const data of members) {
|
|
231
|
+
const partContentType = encoding?.[data.key]?.contentType
|
|
232
|
+
?.split(",")[0]
|
|
233
|
+
.trim();
|
|
230
234
|
if (data.key && data.value.content) {
|
|
231
|
-
|
|
235
|
+
const blob = partContentType
|
|
236
|
+
? new Blob([data.value.content], { type: partContentType })
|
|
237
|
+
: data.value.content;
|
|
238
|
+
myBody.append(data.key, blob);
|
|
232
239
|
}
|
|
233
240
|
// handle generic key-value payload
|
|
234
241
|
if (data.key && typeof data.value === "string") {
|
|
235
|
-
|
|
242
|
+
if (partContentType) {
|
|
243
|
+
myBody.append(
|
|
244
|
+
data.key,
|
|
245
|
+
new Blob([data.value], { type: partContentType })
|
|
246
|
+
);
|
|
247
|
+
} else {
|
|
248
|
+
myBody.append(data.key, data.value);
|
|
249
|
+
}
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
252
|
}
|
|
@@ -293,12 +293,36 @@ function tryDecodeJsonParam(value: string): any {
|
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
// TODO: this is all a bit hacky
|
|
296
|
-
function setBody(
|
|
296
|
+
function setBody(
|
|
297
|
+
clonedPostman: sdk.Request,
|
|
298
|
+
body: Body,
|
|
299
|
+
encoding?: Record<string, { contentType?: string }>
|
|
300
|
+
) {
|
|
297
301
|
if (clonedPostman.body === undefined) {
|
|
298
302
|
return;
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
if (body.type === "empty") {
|
|
306
|
+
// When the original request has formdata and encoding is declared, keep the
|
|
307
|
+
// placeholder params so the code snippet reflects the selected encoding even
|
|
308
|
+
// before the user has uploaded a file.
|
|
309
|
+
if (
|
|
310
|
+
clonedPostman.body?.mode === "formdata" &&
|
|
311
|
+
encoding &&
|
|
312
|
+
Object.keys(encoding).length > 0
|
|
313
|
+
) {
|
|
314
|
+
const members: any[] =
|
|
315
|
+
(clonedPostman.body.formdata as any)?.members ?? [];
|
|
316
|
+
members.forEach((param: any) => {
|
|
317
|
+
const partContentType = encoding[param.key]?.contentType
|
|
318
|
+
?.split(",")[0]
|
|
319
|
+
.trim();
|
|
320
|
+
if (partContentType) {
|
|
321
|
+
param.contentType = partContentType;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
302
326
|
clonedPostman.body = undefined;
|
|
303
327
|
return;
|
|
304
328
|
}
|
|
@@ -336,14 +360,35 @@ function setBody(clonedPostman: sdk.Request, body: Body) {
|
|
|
336
360
|
Object.entries(body.content)
|
|
337
361
|
.filter((entry): entry is [string, NonNullable<Content>] => !!entry[1])
|
|
338
362
|
.forEach(([key, content]) => {
|
|
363
|
+
const partContentType = encoding?.[key]?.contentType
|
|
364
|
+
?.split(",")[0]
|
|
365
|
+
.trim();
|
|
339
366
|
if (content.type === "file") {
|
|
340
|
-
params.push(
|
|
367
|
+
params.push(
|
|
368
|
+
new sdk.FormParam({
|
|
369
|
+
key: key,
|
|
370
|
+
...content,
|
|
371
|
+
...(partContentType && { contentType: partContentType }),
|
|
372
|
+
})
|
|
373
|
+
);
|
|
341
374
|
} else if (content.type === "file[]") {
|
|
342
375
|
content.value.forEach((file) =>
|
|
343
|
-
params.push(
|
|
376
|
+
params.push(
|
|
377
|
+
new sdk.FormParam({
|
|
378
|
+
key,
|
|
379
|
+
value: file,
|
|
380
|
+
...(partContentType && { contentType: partContentType }),
|
|
381
|
+
})
|
|
382
|
+
)
|
|
344
383
|
);
|
|
345
384
|
} else {
|
|
346
|
-
params.push(
|
|
385
|
+
params.push(
|
|
386
|
+
new sdk.FormParam({
|
|
387
|
+
key: key,
|
|
388
|
+
value: content.value,
|
|
389
|
+
...(partContentType && { contentType: partContentType }),
|
|
390
|
+
})
|
|
391
|
+
);
|
|
347
392
|
}
|
|
348
393
|
});
|
|
349
394
|
params.forEach((param) => {
|
|
@@ -391,6 +436,7 @@ interface Options {
|
|
|
391
436
|
accept: string;
|
|
392
437
|
body: Body;
|
|
393
438
|
auth: AuthState;
|
|
439
|
+
encoding?: Record<string, { contentType?: string }>;
|
|
394
440
|
}
|
|
395
441
|
|
|
396
442
|
function buildPostmanRequest(
|
|
@@ -405,6 +451,7 @@ function buildPostmanRequest(
|
|
|
405
451
|
body,
|
|
406
452
|
server,
|
|
407
453
|
auth,
|
|
454
|
+
encoding,
|
|
408
455
|
}: Options
|
|
409
456
|
) {
|
|
410
457
|
const clonedPostman = cloneDeep(postman);
|
|
@@ -532,7 +579,7 @@ function buildPostmanRequest(
|
|
|
532
579
|
otherHeaders
|
|
533
580
|
);
|
|
534
581
|
|
|
535
|
-
setBody(clonedPostman, body);
|
|
582
|
+
setBody(clonedPostman, body, encoding);
|
|
536
583
|
|
|
537
584
|
return clonedPostman;
|
|
538
585
|
}
|
|
@@ -10,6 +10,7 @@ import accept from "@theme/ApiExplorer/Accept/slice";
|
|
|
10
10
|
import auth from "@theme/ApiExplorer/Authorization/slice";
|
|
11
11
|
import body from "@theme/ApiExplorer/Body/slice";
|
|
12
12
|
import contentType from "@theme/ApiExplorer/ContentType/slice";
|
|
13
|
+
import encodingSelection from "@theme/ApiExplorer/EncodingSelection/slice";
|
|
13
14
|
import params from "@theme/ApiExplorer/ParamOptions/slice";
|
|
14
15
|
import response from "@theme/ApiExplorer/Response/slice";
|
|
15
16
|
import schemaSelection from "@theme/ApiExplorer/SchemaSelection/slice";
|
|
@@ -18,6 +19,7 @@ import server from "@theme/ApiExplorer/Server/slice";
|
|
|
18
19
|
const rootReducer = combineReducers({
|
|
19
20
|
accept,
|
|
20
21
|
contentType,
|
|
22
|
+
encodingSelection,
|
|
21
23
|
response,
|
|
22
24
|
server,
|
|
23
25
|
body,
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/plugin-content-docs.d.ts","./src/postman-code-generators.d.ts","./src/react-magic-dropzone.d.ts","./src/theme-classic.d.ts","./src/theme-openapi.d.ts","./src/types.d.ts","./src/markdown/createDescription.ts","./src/markdown/schema.ts","./src/markdown/utils.test.ts","./src/markdown/utils.ts","./src/theme/translationIds.ts","./src/theme/ApiExplorer/buildPostmanRequest.ts","./src/theme/ApiExplorer/index.tsx","./src/theme/ApiExplorer/persistenceMiddleware.ts","./src/theme/ApiExplorer/storage-utils.ts","./src/theme/ApiExplorer/Accept/index.tsx","./src/theme/ApiExplorer/Accept/slice.ts","./src/theme/ApiExplorer/ApiCodeBlock/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Container/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/Element.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx","./src/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Line/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.tsx","./src/theme/ApiExplorer/Authorization/auth-types.ts","./src/theme/ApiExplorer/Authorization/index.tsx","./src/theme/ApiExplorer/Authorization/slice.ts","./src/theme/ApiExplorer/Body/index.tsx","./src/theme/ApiExplorer/Body/json2xml.d.ts","./src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts","./src/theme/ApiExplorer/Body/slice.ts","./src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx","./src/theme/ApiExplorer/Body/FormBodyItem/index.tsx","./src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts","./src/theme/ApiExplorer/CodeSnippets/index.tsx","./src/theme/ApiExplorer/CodeSnippets/languages.ts","./src/theme/ApiExplorer/CodeTabs/index.tsx","./src/theme/ApiExplorer/ContentType/index.tsx","./src/theme/ApiExplorer/ContentType/slice.ts","./src/theme/ApiExplorer/Export/index.tsx","./src/theme/ApiExplorer/FloatingButton/index.tsx","./src/theme/ApiExplorer/FormFileUpload/index.tsx","./src/theme/ApiExplorer/FormItem/index.tsx","./src/theme/ApiExplorer/FormLabel/index.tsx","./src/theme/ApiExplorer/FormMultiSelect/index.tsx","./src/theme/ApiExplorer/FormSelect/index.tsx","./src/theme/ApiExplorer/FormTextInput/index.tsx","./src/theme/ApiExplorer/LiveEditor/index.tsx","./src/theme/ApiExplorer/MethodEndpoint/index.tsx","./src/theme/ApiExplorer/ParamOptions/index.tsx","./src/theme/ApiExplorer/ParamOptions/slice.ts","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx","./src/theme/ApiExplorer/Request/index.tsx","./src/theme/ApiExplorer/Request/makeRequest.ts","./src/theme/ApiExplorer/Response/index.tsx","./src/theme/ApiExplorer/Response/slice.ts","./src/theme/ApiExplorer/SchemaSelection/index.ts","./src/theme/ApiExplorer/SchemaSelection/slice.ts","./src/theme/ApiExplorer/SecuritySchemes/index.tsx","./src/theme/ApiExplorer/Server/index.tsx","./src/theme/ApiExplorer/Server/slice.ts","./src/theme/ApiItem/hooks.ts","./src/theme/ApiItem/index.tsx","./src/theme/ApiItem/store.ts","./src/theme/ApiItem/Layout/index.tsx","./src/theme/ApiLogo/index.tsx","./src/theme/ApiTabs/index.tsx","./src/theme/ArrayBrackets/index.tsx","./src/theme/CodeSamples/index.tsx","./src/theme/DiscriminatorTabs/index.tsx","./src/theme/Example/index.tsx","./src/theme/Markdown/index.d.ts","./src/theme/MimeTabs/index.tsx","./src/theme/OperationTabs/index.tsx","./src/theme/ParamsDetails/index.tsx","./src/theme/ParamsItem/index.tsx","./src/theme/RequestSchema/index.tsx","./src/theme/ResponseExamples/index.tsx","./src/theme/ResponseHeaders/index.tsx","./src/theme/ResponseSchema/index.tsx","./src/theme/Schema/index.tsx","./src/theme/SchemaItem/index.tsx","./src/theme/SchemaTabs/index.tsx","./src/theme/SkeletonLoader/index.tsx","./src/theme/StatusCodes/index.tsx"],"version":"5.9.3"}
|
|
1
|
+
{"root":["./src/index.ts","./src/plugin-content-docs.d.ts","./src/postman-code-generators.d.ts","./src/react-magic-dropzone.d.ts","./src/theme-classic.d.ts","./src/theme-openapi.d.ts","./src/types.d.ts","./src/markdown/createDescription.ts","./src/markdown/schema.ts","./src/markdown/utils.test.ts","./src/markdown/utils.ts","./src/theme/translationIds.ts","./src/theme/ApiExplorer/buildPostmanRequest.ts","./src/theme/ApiExplorer/index.tsx","./src/theme/ApiExplorer/persistenceMiddleware.ts","./src/theme/ApiExplorer/storage-utils.ts","./src/theme/ApiExplorer/Accept/index.tsx","./src/theme/ApiExplorer/Accept/slice.ts","./src/theme/ApiExplorer/ApiCodeBlock/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Container/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/Element.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx","./src/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Line/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.tsx","./src/theme/ApiExplorer/Authorization/auth-types.ts","./src/theme/ApiExplorer/Authorization/index.tsx","./src/theme/ApiExplorer/Authorization/slice.ts","./src/theme/ApiExplorer/Body/index.tsx","./src/theme/ApiExplorer/Body/json2xml.d.ts","./src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts","./src/theme/ApiExplorer/Body/slice.ts","./src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx","./src/theme/ApiExplorer/Body/FormBodyItem/index.tsx","./src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts","./src/theme/ApiExplorer/CodeSnippets/index.tsx","./src/theme/ApiExplorer/CodeSnippets/languages.ts","./src/theme/ApiExplorer/CodeTabs/index.tsx","./src/theme/ApiExplorer/ContentType/index.tsx","./src/theme/ApiExplorer/ContentType/slice.ts","./src/theme/ApiExplorer/EncodingSelection/slice.ts","./src/theme/ApiExplorer/EncodingSelection/useResolvedEncoding.ts","./src/theme/ApiExplorer/Export/index.tsx","./src/theme/ApiExplorer/FloatingButton/index.tsx","./src/theme/ApiExplorer/FormFileUpload/index.tsx","./src/theme/ApiExplorer/FormItem/index.tsx","./src/theme/ApiExplorer/FormLabel/index.tsx","./src/theme/ApiExplorer/FormMultiSelect/index.tsx","./src/theme/ApiExplorer/FormSelect/index.tsx","./src/theme/ApiExplorer/FormTextInput/index.tsx","./src/theme/ApiExplorer/LiveEditor/index.tsx","./src/theme/ApiExplorer/MethodEndpoint/index.tsx","./src/theme/ApiExplorer/ParamOptions/index.tsx","./src/theme/ApiExplorer/ParamOptions/slice.ts","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx","./src/theme/ApiExplorer/Request/index.tsx","./src/theme/ApiExplorer/Request/makeRequest.ts","./src/theme/ApiExplorer/Response/index.tsx","./src/theme/ApiExplorer/Response/slice.ts","./src/theme/ApiExplorer/SchemaSelection/index.ts","./src/theme/ApiExplorer/SchemaSelection/slice.ts","./src/theme/ApiExplorer/SecuritySchemes/index.tsx","./src/theme/ApiExplorer/Server/index.tsx","./src/theme/ApiExplorer/Server/slice.ts","./src/theme/ApiItem/hooks.ts","./src/theme/ApiItem/index.tsx","./src/theme/ApiItem/store.ts","./src/theme/ApiItem/Layout/index.tsx","./src/theme/ApiLogo/index.tsx","./src/theme/ApiTabs/index.tsx","./src/theme/ArrayBrackets/index.tsx","./src/theme/CodeSamples/index.tsx","./src/theme/DiscriminatorTabs/index.tsx","./src/theme/Example/index.tsx","./src/theme/Markdown/index.d.ts","./src/theme/MimeTabs/index.tsx","./src/theme/OperationTabs/index.tsx","./src/theme/ParamsDetails/index.tsx","./src/theme/ParamsItem/index.tsx","./src/theme/RequestSchema/index.tsx","./src/theme/ResponseExamples/index.tsx","./src/theme/ResponseHeaders/index.tsx","./src/theme/ResponseSchema/index.tsx","./src/theme/Schema/index.tsx","./src/theme/SchemaItem/index.tsx","./src/theme/SchemaTabs/index.tsx","./src/theme/SkeletonLoader/index.tsx","./src/theme/StatusCodes/index.tsx"],"version":"5.9.3"}
|