docusaurus-theme-openapi-docs 4.7.0 → 5.0.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/index.js +2 -0
- package/lib/markdown/schema.js +63 -9
- package/lib/theme/ApiExplorer/Accept/index.js +2 -1
- package/lib/theme/ApiExplorer/Authorization/index.js +12 -18
- package/lib/theme/ApiExplorer/Authorization/slice.d.ts +1 -1
- package/lib/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.js +0 -4
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.d.ts +6 -2
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.js +191 -38
- package/lib/theme/ApiExplorer/Body/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/Body/index.js +86 -15
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.d.ts +1 -1
- package/lib/theme/ApiExplorer/Body/slice.d.ts +136 -544
- package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +2 -1
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +4 -0
- package/lib/theme/ApiExplorer/CodeTabs/index.js +15 -16
- package/lib/theme/ApiExplorer/ContentType/index.js +7 -2
- 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/FormItem/_FormItem.scss +0 -5
- package/lib/theme/ApiExplorer/FormItem/index.d.ts +1 -4
- package/lib/theme/ApiExplorer/FormItem/index.js +2 -26
- package/lib/theme/ApiExplorer/FormLabel/_FormLabel.scss +4 -0
- package/lib/theme/ApiExplorer/FormLabel/index.d.ts +9 -0
- package/lib/theme/ApiExplorer/FormLabel/index.js +50 -0
- package/lib/theme/ApiExplorer/FormMultiSelect/index.d.ts +4 -1
- package/lib/theme/ApiExplorer/FormMultiSelect/index.js +97 -19
- package/lib/theme/ApiExplorer/FormSelect/index.d.ts +6 -1
- package/lib/theme/ApiExplorer/FormSelect/index.js +96 -15
- package/lib/theme/ApiExplorer/FormTextInput/index.d.ts +4 -1
- package/lib/theme/ApiExplorer/FormTextInput/index.js +71 -1
- package/lib/theme/ApiExplorer/MethodEndpoint/index.js +28 -0
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.d.ts +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.js +11 -3
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.d.ts +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.js +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.d.ts +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +6 -2
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.d.ts +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.js +6 -2
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.d.ts +4 -1
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.js +8 -3
- package/lib/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +0 -9
- package/lib/theme/ApiExplorer/ParamOptions/index.d.ts +10 -0
- package/lib/theme/ApiExplorer/ParamOptions/index.js +55 -5
- package/lib/theme/ApiExplorer/ParamOptions/slice.d.ts +1 -1
- package/lib/theme/ApiExplorer/Request/_Request.scss +11 -0
- package/lib/theme/ApiExplorer/Request/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/Request/index.js +19 -5
- package/lib/theme/ApiExplorer/Request/makeRequest.d.ts +3 -1
- package/lib/theme/ApiExplorer/Request/makeRequest.js +19 -3
- package/lib/theme/ApiExplorer/Response/_Response.scss +11 -0
- package/lib/theme/ApiExplorer/Response/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/Response/index.js +98 -12
- package/lib/theme/ApiExplorer/SecuritySchemes/index.js +2 -2
- package/lib/theme/ApiExplorer/Server/index.d.ts +4 -1
- package/lib/theme/ApiExplorer/Server/index.js +6 -3
- package/lib/theme/ApiExplorer/Server/slice.d.ts +1 -1
- package/lib/theme/ApiExplorer/buildPostmanRequest.d.ts +5 -2
- package/lib/theme/ApiExplorer/buildPostmanRequest.js +46 -5
- package/lib/theme/ApiExplorer/index.d.ts +1 -1
- 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 +2 -1
- package/lib/theme/ApiItem/store.d.ts +6 -0
- package/lib/theme/ApiItem/store.js +11 -7
- package/lib/theme/ApiTabs/index.js +10 -11
- package/lib/theme/DiscriminatorTabs/index.js +10 -11
- package/lib/theme/MimeTabs/index.js +10 -11
- package/lib/theme/OperationTabs/index.js +10 -11
- package/lib/theme/ParamsDetails/index.js +2 -2
- package/lib/theme/ParamsItem/index.js +27 -0
- package/lib/theme/RequestSchema/index.d.ts +1 -1
- package/lib/theme/RequestSchema/index.js +174 -111
- package/lib/theme/ResponseHeaders/index.js +0 -1
- package/lib/theme/ResponseSchema/index.d.ts +1 -1
- package/lib/theme/Schema/index.d.ts +1 -1
- package/lib/theme/Schema/index.js +91 -23
- package/lib/theme/SchemaItem/index.js +6 -1
- package/lib/theme/SchemaTabs/index.d.ts +1 -1
- package/lib/theme/SchemaTabs/index.js +31 -12
- package/lib/theme/StatusCodes/index.d.ts +1 -1
- package/lib/theme/styles.scss +1 -0
- package/lib/theme/translationIds.d.ts +3 -0
- package/lib/theme/translationIds.js +3 -0
- package/package.json +9 -8
- package/src/index.ts +2 -0
- package/src/markdown/schema.ts +69 -13
- package/src/theme/ApiExplorer/Accept/index.tsx +2 -1
- package/src/theme/ApiExplorer/Authorization/index.tsx +27 -33
- package/src/theme/ApiExplorer/Authorization/slice.ts +1 -1
- package/src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx +2 -5
- package/src/theme/ApiExplorer/Body/FormBodyItem/index.tsx +119 -39
- package/src/theme/ApiExplorer/Body/index.tsx +88 -21
- package/src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts +1 -1
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +9 -1
- package/src/theme/ApiExplorer/CodeTabs/index.tsx +19 -19
- package/src/theme/ApiExplorer/ContentType/index.tsx +7 -4
- package/src/theme/ApiExplorer/EncodingSelection/slice.ts +31 -0
- package/src/theme/ApiExplorer/EncodingSelection/useResolvedEncoding.ts +43 -0
- package/src/theme/ApiExplorer/FormItem/_FormItem.scss +0 -5
- package/src/theme/ApiExplorer/FormItem/index.tsx +2 -17
- package/src/theme/ApiExplorer/FormLabel/_FormLabel.scss +4 -0
- package/src/theme/ApiExplorer/FormLabel/index.tsx +43 -0
- package/src/theme/ApiExplorer/FormMultiSelect/index.tsx +40 -20
- package/src/theme/ApiExplorer/FormSelect/index.tsx +41 -15
- package/src/theme/ApiExplorer/FormTextInput/index.tsx +15 -1
- package/src/theme/ApiExplorer/MethodEndpoint/index.tsx +21 -0
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx +13 -2
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx +12 -1
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +14 -2
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx +14 -2
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx +16 -3
- package/src/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +0 -9
- package/src/theme/ApiExplorer/ParamOptions/index.tsx +97 -11
- package/src/theme/ApiExplorer/ParamOptions/slice.ts +1 -1
- package/src/theme/ApiExplorer/Request/_Request.scss +11 -0
- package/src/theme/ApiExplorer/Request/index.tsx +22 -10
- package/src/theme/ApiExplorer/Request/makeRequest.ts +19 -3
- package/src/theme/ApiExplorer/Response/_Response.scss +11 -0
- package/src/theme/ApiExplorer/Response/index.tsx +37 -17
- package/src/theme/ApiExplorer/SecuritySchemes/index.tsx +2 -3
- package/src/theme/ApiExplorer/Server/index.tsx +10 -3
- package/src/theme/ApiExplorer/Server/slice.ts +1 -1
- package/src/theme/ApiExplorer/buildPostmanRequest.ts +53 -6
- package/src/theme/ApiExplorer/index.tsx +2 -1
- package/src/theme/ApiItem/index.tsx +3 -2
- package/src/theme/ApiItem/store.ts +2 -0
- package/src/theme/ApiTabs/index.tsx +14 -19
- package/src/theme/DiscriminatorTabs/index.tsx +14 -19
- package/src/theme/MimeTabs/index.tsx +15 -19
- package/src/theme/OperationTabs/index.tsx +14 -19
- package/src/theme/ParamsDetails/index.tsx +2 -3
- package/src/theme/ParamsItem/index.tsx +25 -0
- package/src/theme/RequestSchema/index.tsx +144 -87
- package/src/theme/ResponseHeaders/index.tsx +1 -2
- package/src/theme/ResponseSchema/index.tsx +1 -1
- package/src/theme/Schema/index.tsx +112 -27
- package/src/theme/SchemaItem/index.tsx +6 -1
- package/src/theme/SchemaTabs/index.tsx +42 -21
- package/src/theme/StatusCodes/index.tsx +1 -1
- package/src/theme/styles.scss +1 -0
- package/src/theme/translationIds.ts +3 -0
- package/src/theme-classic.d.ts +25 -1
- package/src/types.d.ts +15 -52
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -34,13 +34,12 @@ function Authorization() {
|
|
|
34
34
|
return (
|
|
35
35
|
<div>
|
|
36
36
|
{optionKeys.length > 1 && (
|
|
37
|
-
<FormItem
|
|
38
|
-
label={translate({
|
|
39
|
-
id: OPENAPI_AUTH.SECURITY_SCHEME,
|
|
40
|
-
message: "Security Scheme",
|
|
41
|
-
})}
|
|
42
|
-
>
|
|
37
|
+
<FormItem>
|
|
43
38
|
<FormSelect
|
|
39
|
+
label={translate({
|
|
40
|
+
id: OPENAPI_AUTH.SECURITY_SCHEME,
|
|
41
|
+
message: "Security Scheme",
|
|
42
|
+
})}
|
|
44
43
|
options={optionKeys}
|
|
45
44
|
value={selected}
|
|
46
45
|
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
@@ -52,14 +51,12 @@ function Authorization() {
|
|
|
52
51
|
{selectedAuth.map((a: any) => {
|
|
53
52
|
if (a.type === "http" && a.scheme === "bearer") {
|
|
54
53
|
return (
|
|
55
|
-
<FormItem
|
|
56
|
-
label={translate({
|
|
57
|
-
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
58
|
-
message: "Bearer Token",
|
|
59
|
-
})}
|
|
60
|
-
key={a.key + "-bearer"}
|
|
61
|
-
>
|
|
54
|
+
<FormItem key={a.key + "-bearer"}>
|
|
62
55
|
<FormTextInput
|
|
56
|
+
label={translate({
|
|
57
|
+
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
58
|
+
message: "Bearer Token",
|
|
59
|
+
})}
|
|
63
60
|
placeholder={translate({
|
|
64
61
|
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
65
62
|
message: "Bearer Token",
|
|
@@ -83,14 +80,12 @@ function Authorization() {
|
|
|
83
80
|
|
|
84
81
|
if (a.type === "oauth2") {
|
|
85
82
|
return (
|
|
86
|
-
<FormItem
|
|
87
|
-
label={translate({
|
|
88
|
-
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
89
|
-
message: "Bearer Token",
|
|
90
|
-
})}
|
|
91
|
-
key={a.key + "-oauth2"}
|
|
92
|
-
>
|
|
83
|
+
<FormItem key={a.key + "-oauth2"}>
|
|
93
84
|
<FormTextInput
|
|
85
|
+
label={translate({
|
|
86
|
+
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
87
|
+
message: "Bearer Token",
|
|
88
|
+
})}
|
|
94
89
|
placeholder={translate({
|
|
95
90
|
id: OPENAPI_AUTH.BEARER_TOKEN,
|
|
96
91
|
message: "Bearer Token",
|
|
@@ -115,13 +110,12 @@ function Authorization() {
|
|
|
115
110
|
if (a.type === "http" && a.scheme === "basic") {
|
|
116
111
|
return (
|
|
117
112
|
<React.Fragment key={a.key + "-basic"}>
|
|
118
|
-
<FormItem
|
|
119
|
-
label={translate({
|
|
120
|
-
id: OPENAPI_AUTH.USERNAME,
|
|
121
|
-
message: "Username",
|
|
122
|
-
})}
|
|
123
|
-
>
|
|
113
|
+
<FormItem>
|
|
124
114
|
<FormTextInput
|
|
115
|
+
label={translate({
|
|
116
|
+
id: OPENAPI_AUTH.USERNAME,
|
|
117
|
+
message: "Username",
|
|
118
|
+
})}
|
|
125
119
|
placeholder={translate({
|
|
126
120
|
id: OPENAPI_AUTH.USERNAME,
|
|
127
121
|
message: "Username",
|
|
@@ -139,13 +133,12 @@ function Authorization() {
|
|
|
139
133
|
}}
|
|
140
134
|
/>
|
|
141
135
|
</FormItem>
|
|
142
|
-
<FormItem
|
|
143
|
-
label={translate({
|
|
144
|
-
id: OPENAPI_AUTH.PASSWORD,
|
|
145
|
-
message: "Password",
|
|
146
|
-
})}
|
|
147
|
-
>
|
|
136
|
+
<FormItem>
|
|
148
137
|
<FormTextInput
|
|
138
|
+
label={translate({
|
|
139
|
+
id: OPENAPI_AUTH.PASSWORD,
|
|
140
|
+
message: "Password",
|
|
141
|
+
})}
|
|
149
142
|
placeholder={translate({
|
|
150
143
|
id: OPENAPI_AUTH.PASSWORD,
|
|
151
144
|
message: "Password",
|
|
@@ -170,8 +163,9 @@ function Authorization() {
|
|
|
170
163
|
|
|
171
164
|
if (a.type === "apiKey") {
|
|
172
165
|
return (
|
|
173
|
-
<FormItem
|
|
166
|
+
<FormItem key={a.key + "-apikey"}>
|
|
174
167
|
<FormTextInput
|
|
168
|
+
label={`${a.key}`}
|
|
175
169
|
placeholder={`${a.key}`}
|
|
176
170
|
password
|
|
177
171
|
value={data[a.key].apiKey ?? ""}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
|
9
9
|
import { createStorage, hashArray } from "@theme/ApiExplorer/storage-utils";
|
|
10
|
-
import {
|
|
10
|
+
import type {
|
|
11
11
|
SecurityRequirementObject,
|
|
12
12
|
SecuritySchemeObject,
|
|
13
13
|
} from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
8
|
import React, { useState } from "react";
|
|
9
|
+
|
|
9
10
|
import FormFileUpload from "@theme/ApiExplorer/FormFileUpload";
|
|
10
11
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
12
|
+
|
|
11
13
|
import { FileContent, setFileArrayFormBody } from "../slice";
|
|
12
14
|
|
|
13
15
|
interface FileArrayFormItemProps {
|
|
@@ -41,11 +43,6 @@ export default function FileArrayFormBodyItem({
|
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
let maxIndex = 0;
|
|
45
|
-
|
|
46
|
-
newItems.keys().forEach((item) => {
|
|
47
|
-
maxIndex = item > maxIndex ? item : maxIndex;
|
|
48
|
-
});
|
|
49
46
|
newItems.set(index, {
|
|
50
47
|
src: `/path/to/${file.name}`,
|
|
51
48
|
content: file,
|
|
@@ -5,79 +5,151 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import React from "react";
|
|
8
|
+
import React, { useEffect, useState } from "react";
|
|
9
|
+
|
|
9
10
|
import FormFileUpload from "@theme/ApiExplorer/FormFileUpload";
|
|
11
|
+
import FormLabel from "@theme/ApiExplorer/FormLabel";
|
|
10
12
|
import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
11
13
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
12
14
|
import LiveApp from "@theme/ApiExplorer/LiveEditor";
|
|
13
15
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
14
|
-
import { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
15
|
-
|
|
16
|
+
import type { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
17
|
+
|
|
16
18
|
import FileArrayFormBodyItem from "../FileArrayFormBodyItem";
|
|
19
|
+
import { clearFormBodyKey, setFileFormBody, setStringFormBody } from "../slice";
|
|
20
|
+
import { setFieldEncoding } from "../../EncodingSelection/slice";
|
|
17
21
|
|
|
18
22
|
interface FormBodyItemProps {
|
|
19
23
|
schemaObject: SchemaObject;
|
|
20
24
|
id: string;
|
|
21
25
|
schema: SchemaObject;
|
|
26
|
+
label?: string;
|
|
27
|
+
required?: boolean;
|
|
28
|
+
exampleValue?: SchemaObject["example"];
|
|
29
|
+
fieldEncoding?: string;
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
export default function FormBodyItem({
|
|
25
33
|
schemaObject,
|
|
26
34
|
id,
|
|
27
35
|
schema,
|
|
36
|
+
label,
|
|
37
|
+
required,
|
|
38
|
+
exampleValue,
|
|
39
|
+
fieldEncoding,
|
|
28
40
|
}: FormBodyItemProps): React.JSX.Element {
|
|
29
41
|
const dispatch = useTypedDispatch();
|
|
30
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
|
+
}, []);
|
|
70
|
+
const [value, setValue] = useState(() => {
|
|
71
|
+
let initialValue = exampleValue ?? "";
|
|
72
|
+
|
|
73
|
+
if (schemaObject.type === "object" && exampleValue) {
|
|
74
|
+
initialValue = JSON.stringify(exampleValue, null, 2);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return initialValue;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (value) {
|
|
82
|
+
dispatch(setStringFormBody({ key: id, value }));
|
|
83
|
+
} else {
|
|
84
|
+
dispatch(clearFormBodyKey(id));
|
|
85
|
+
}
|
|
86
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
|
+
}, []);
|
|
88
|
+
|
|
31
89
|
if (
|
|
32
90
|
schemaObject.type === "array" &&
|
|
33
91
|
schemaObject.items?.format === "binary"
|
|
34
92
|
) {
|
|
35
93
|
return (
|
|
36
|
-
|
|
94
|
+
<>
|
|
95
|
+
{label && <FormLabel label={label} required={required} />}
|
|
96
|
+
<FileArrayFormBodyItem id={id} description={schemaObject.description} />
|
|
97
|
+
</>
|
|
37
98
|
);
|
|
38
99
|
}
|
|
39
100
|
|
|
40
101
|
if (schemaObject.format === "binary") {
|
|
41
102
|
return (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
103
|
+
<>
|
|
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
|
+
)}
|
|
119
|
+
<FormFileUpload
|
|
120
|
+
placeholder={schemaObject.description || id}
|
|
121
|
+
onChange={(file: any) => {
|
|
122
|
+
if (file === undefined) {
|
|
123
|
+
dispatch(clearFormBodyKey(id));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
dispatch(
|
|
127
|
+
setFileFormBody({
|
|
128
|
+
key: id,
|
|
129
|
+
value: {
|
|
130
|
+
src: `/path/to/${file.name}`,
|
|
131
|
+
content: file,
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
</>
|
|
60
138
|
);
|
|
61
139
|
}
|
|
62
140
|
|
|
63
|
-
if (
|
|
64
|
-
schemaObject.type === "object" &&
|
|
65
|
-
(schemaObject.example || schemaObject.examples)
|
|
66
|
-
) {
|
|
67
|
-
const objectExample = JSON.stringify(
|
|
68
|
-
schemaObject.example ?? schemaObject.examples[0],
|
|
69
|
-
null,
|
|
70
|
-
2
|
|
71
|
-
);
|
|
72
|
-
|
|
141
|
+
if (schemaObject.type === "object") {
|
|
73
142
|
return (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
+
</>
|
|
81
153
|
);
|
|
82
154
|
}
|
|
83
155
|
|
|
@@ -87,9 +159,13 @@ export default function FormBodyItem({
|
|
|
87
159
|
) {
|
|
88
160
|
return (
|
|
89
161
|
<FormSelect
|
|
162
|
+
label={label}
|
|
163
|
+
required={required}
|
|
164
|
+
value={value}
|
|
90
165
|
options={["---", ...schemaObject.enum]}
|
|
91
166
|
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
92
167
|
const val = e.target.value;
|
|
168
|
+
setValue(val);
|
|
93
169
|
if (val === "---") {
|
|
94
170
|
dispatch(clearFormBodyKey(id));
|
|
95
171
|
} else {
|
|
@@ -107,12 +183,16 @@ export default function FormBodyItem({
|
|
|
107
183
|
// TODO: support all the other types.
|
|
108
184
|
return (
|
|
109
185
|
<FormTextInput
|
|
186
|
+
label={label}
|
|
187
|
+
required={required}
|
|
188
|
+
value={value}
|
|
110
189
|
paramName={id}
|
|
111
190
|
isRequired={
|
|
112
191
|
Array.isArray(schema.required) && schema.required.includes(id)
|
|
113
192
|
}
|
|
114
193
|
placeholder={schemaObject.description || id}
|
|
115
194
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
195
|
+
setValue(e.target.value);
|
|
116
196
|
dispatch(setStringFormBody({ key: id, value: e.target.value }));
|
|
117
197
|
}}
|
|
118
198
|
/>
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import React, { useEffect, useMemo } from "react";
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
|
-
|
|
12
11
|
import json2xml from "@theme/ApiExplorer/Body/json2xml";
|
|
13
12
|
import FormFileUpload from "@theme/ApiExplorer/FormFileUpload";
|
|
14
13
|
import FormItem from "@theme/ApiExplorer/FormItem";
|
|
@@ -18,13 +17,13 @@ import Markdown from "@theme/Markdown";
|
|
|
18
17
|
import SchemaTabs from "@theme/SchemaTabs";
|
|
19
18
|
import TabItem from "@theme/TabItem";
|
|
20
19
|
import { OPENAPI_BODY, OPENAPI_REQUEST } from "@theme/translationIds";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
20
|
+
import { sampleFromSchema } from "docusaurus-plugin-openapi-docs/lib/openapi/createSchemaExample";
|
|
21
|
+
import type { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
23
22
|
import format from "xml-formatter";
|
|
24
23
|
|
|
25
|
-
import { clearRawBody, setFileRawBody, setStringRawBody } from "./slice";
|
|
26
24
|
import FormBodyItem from "./FormBodyItem";
|
|
27
25
|
import { resolveSchemaWithSelections } from "./resolveSchemaWithSelections";
|
|
26
|
+
import { clearRawBody, setFileRawBody, setStringRawBody } from "./slice";
|
|
28
27
|
|
|
29
28
|
export interface Props {
|
|
30
29
|
jsonRequestBodyExample: string;
|
|
@@ -94,6 +93,8 @@ function Body({
|
|
|
94
93
|
const rawSchema = requestBodyMetadata?.content?.[contentType]?.schema;
|
|
95
94
|
const example = requestBodyMetadata?.content?.[contentType]?.example;
|
|
96
95
|
const examples = requestBodyMetadata?.content?.[contentType]?.examples;
|
|
96
|
+
const encoding: Record<string, { contentType?: string }> | undefined =
|
|
97
|
+
requestBodyMetadata?.content?.[contentType]?.encoding;
|
|
97
98
|
|
|
98
99
|
// Resolve the schema based on user's anyOf/oneOf tab selections
|
|
99
100
|
const schema = useMemo(() => {
|
|
@@ -317,23 +318,89 @@ function Body({
|
|
|
317
318
|
) {
|
|
318
319
|
return (
|
|
319
320
|
<FormItem className="openapi-explorer__form-item-body-container">
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
321
|
+
<SchemaTabs className="openapi-tabs__schema" lazy>
|
|
322
|
+
{/* @ts-ignore */}
|
|
323
|
+
<TabItem
|
|
324
|
+
label={translate({
|
|
325
|
+
id: OPENAPI_BODY.EXAMPLE_FROM_SCHEMA,
|
|
326
|
+
message: "Example (from schema)",
|
|
327
|
+
})}
|
|
328
|
+
value="Example (from schema)"
|
|
329
|
+
default
|
|
330
|
+
>
|
|
331
|
+
{Object.entries(schema.properties ?? {}).map(([key, val]: any) => {
|
|
332
|
+
return (
|
|
333
|
+
<FormItem key={key}>
|
|
334
|
+
<FormBodyItem
|
|
335
|
+
schemaObject={val}
|
|
336
|
+
id={key}
|
|
337
|
+
schema={schema}
|
|
338
|
+
exampleValue={val.example}
|
|
339
|
+
label={key}
|
|
340
|
+
required={
|
|
341
|
+
Array.isArray(schema.required) &&
|
|
342
|
+
schema.required.includes(key)
|
|
343
|
+
}
|
|
344
|
+
fieldEncoding={encoding?.[key]?.contentType}
|
|
345
|
+
></FormBodyItem>
|
|
346
|
+
</FormItem>
|
|
347
|
+
);
|
|
348
|
+
})}
|
|
349
|
+
</TabItem>
|
|
350
|
+
{example && (
|
|
351
|
+
// @ts-ignore
|
|
352
|
+
<TabItem label="Example" value="example">
|
|
353
|
+
{Object.entries(schema.properties ?? {}).map(
|
|
354
|
+
([schemaKey, schemaVal]: any) => {
|
|
355
|
+
return (
|
|
356
|
+
<FormItem key={schemaKey}>
|
|
357
|
+
<FormBodyItem
|
|
358
|
+
schemaObject={schemaVal}
|
|
359
|
+
id={schemaKey}
|
|
360
|
+
schema={schema}
|
|
361
|
+
exampleValue={example[schemaKey]}
|
|
362
|
+
label={schemaKey}
|
|
363
|
+
required={
|
|
364
|
+
Array.isArray(schema.required) &&
|
|
365
|
+
schema.required.includes(schemaKey)
|
|
366
|
+
}
|
|
367
|
+
fieldEncoding={encoding?.[schemaKey]?.contentType}
|
|
368
|
+
></FormBodyItem>
|
|
369
|
+
</FormItem>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
)}
|
|
373
|
+
</TabItem>
|
|
374
|
+
)}
|
|
375
|
+
{examples &&
|
|
376
|
+
Object.entries(examples).map(([key, value]) => {
|
|
377
|
+
return (
|
|
378
|
+
// @ts-ignore
|
|
379
|
+
<TabItem label={key} value={key} key={key}>
|
|
380
|
+
{Object.entries(schema.properties ?? {}).map(
|
|
381
|
+
([schemaKey, schemaVal]: any) => {
|
|
382
|
+
return (
|
|
383
|
+
<FormItem key={schemaKey}>
|
|
384
|
+
<FormBodyItem
|
|
385
|
+
schemaObject={schemaVal}
|
|
386
|
+
id={schemaKey}
|
|
387
|
+
schema={schema}
|
|
388
|
+
exampleValue={value.value?.[schemaKey]}
|
|
389
|
+
label={schemaKey}
|
|
390
|
+
required={
|
|
391
|
+
Array.isArray(schema.required) &&
|
|
392
|
+
schema.required.includes(schemaKey)
|
|
393
|
+
}
|
|
394
|
+
fieldEncoding={encoding?.[schemaKey]?.contentType}
|
|
395
|
+
></FormBodyItem>
|
|
396
|
+
</FormItem>
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
)}
|
|
400
|
+
</TabItem>
|
|
401
|
+
);
|
|
402
|
+
})}
|
|
403
|
+
</SchemaTabs>
|
|
337
404
|
</FormItem>
|
|
338
405
|
);
|
|
339
406
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
8
|
+
import type { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
9
9
|
import merge from "lodash/merge";
|
|
10
10
|
|
|
11
11
|
export interface SchemaSelections {
|
|
@@ -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
|
|
@@ -9,11 +9,12 @@ import React, { cloneElement, ReactElement, useEffect, useRef } from "react";
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
sanitizeTabsChildren,
|
|
12
|
+
type TabItemProps,
|
|
12
13
|
type TabProps,
|
|
14
|
+
TabsProvider,
|
|
13
15
|
useScrollPositionBlocker,
|
|
14
|
-
|
|
16
|
+
useTabsContextValue,
|
|
15
17
|
} from "@docusaurus/theme-common/internal";
|
|
16
|
-
import { TabItemProps } from "@docusaurus/theme-common/lib/utils/tabsUtils";
|
|
17
18
|
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
18
19
|
import clsx from "clsx";
|
|
19
20
|
|
|
@@ -43,7 +44,7 @@ function TabList({
|
|
|
43
44
|
selectedValue,
|
|
44
45
|
selectValue,
|
|
45
46
|
tabValues,
|
|
46
|
-
}: CodeTabsProps & ReturnType<typeof
|
|
47
|
+
}: CodeTabsProps & ReturnType<typeof useTabsContextValue>) {
|
|
47
48
|
const tabRefs = useRef<(HTMLLIElement | null)[]>([]);
|
|
48
49
|
const tabsScrollContainerRef = useRef<any>(null);
|
|
49
50
|
const { blockElementScrollPositionUntilNextRender } =
|
|
@@ -192,7 +193,8 @@ function TabContent({
|
|
|
192
193
|
lazy,
|
|
193
194
|
children,
|
|
194
195
|
selectedValue,
|
|
195
|
-
}: CodeTabsProps &
|
|
196
|
+
}: CodeTabsProps &
|
|
197
|
+
ReturnType<typeof useTabsContextValue>): React.JSX.Element | null {
|
|
196
198
|
const childTabs = (Array.isArray(children) ? children : [children]).filter(
|
|
197
199
|
Boolean
|
|
198
200
|
) as ReactElement<TabItemProps>[];
|
|
@@ -207,28 +209,26 @@ function TabContent({
|
|
|
207
209
|
return cloneElement(selectedTabItem, { className: "margin-top--md" });
|
|
208
210
|
}
|
|
209
211
|
return (
|
|
210
|
-
<div className="margin-top--md openapi-tabs__code-content">
|
|
211
|
-
{childTabs.map((tabItem, i) =>
|
|
212
|
-
cloneElement(tabItem, {
|
|
213
|
-
key: i,
|
|
214
|
-
hidden: tabItem.props.value !== selectedValue,
|
|
215
|
-
})
|
|
216
|
-
)}
|
|
217
|
-
</div>
|
|
212
|
+
<div className="margin-top--md openapi-tabs__code-content">{childTabs}</div>
|
|
218
213
|
);
|
|
219
214
|
}
|
|
220
215
|
|
|
221
216
|
function TabsComponent(props: CodeTabsProps & Props): React.JSX.Element {
|
|
222
|
-
const tabs =
|
|
217
|
+
const tabs = useTabsContextValue(props);
|
|
223
218
|
const { className } = props;
|
|
224
219
|
|
|
225
220
|
return (
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
221
|
+
<TabsProvider value={tabs}>
|
|
222
|
+
<div
|
|
223
|
+
className={clsx(
|
|
224
|
+
"tabs-container openapi-tabs__code-container",
|
|
225
|
+
className
|
|
226
|
+
)}
|
|
227
|
+
>
|
|
228
|
+
<TabList {...props} {...tabs} />
|
|
229
|
+
<TabContent {...props} {...tabs} />
|
|
230
|
+
</div>
|
|
231
|
+
</TabsProvider>
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
234
|
|
|
@@ -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);
|
|
@@ -23,13 +24,15 @@ function ContentType() {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
return (
|
|
26
|
-
<FormItem
|
|
27
|
+
<FormItem>
|
|
27
28
|
<FormSelect
|
|
29
|
+
label="Content-Type"
|
|
28
30
|
value={value}
|
|
29
31
|
options={options}
|
|
30
|
-
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
|
|
31
|
-
dispatch(setContentType(e.target.value))
|
|
32
|
-
|
|
32
|
+
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
33
|
+
dispatch(setContentType(e.target.value));
|
|
34
|
+
dispatch(clearEncodingSelection());
|
|
35
|
+
}}
|
|
33
36
|
/>
|
|
34
37
|
</FormItem>
|
|
35
38
|
);
|