docusaurus-theme-openapi-docs 4.7.1 → 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/Body/FileArrayFormBodyItem/index.js +0 -4
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.d.ts +5 -1
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.js +190 -37
- package/lib/theme/ApiExplorer/Body/index.js +84 -13
- 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/Request/_Request.scss +11 -0
- 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.js +98 -12
- package/lib/theme/ApiExplorer/Server/index.d.ts +4 -1
- package/lib/theme/ApiExplorer/Server/index.js +6 -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 +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/ParamsItem/index.js +27 -0
- package/lib/theme/RequestSchema/index.js +172 -109
- package/lib/theme/ResponseHeaders/index.js +0 -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/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/Body/FileArrayFormBodyItem/index.tsx +0 -5
- package/src/theme/ApiExplorer/Body/FormBodyItem/index.tsx +115 -37
- package/src/theme/ApiExplorer/Body/index.tsx +85 -17
- 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 -16
- 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/Request/_Request.scss +11 -0
- package/src/theme/ApiExplorer/Request/index.tsx +20 -8
- 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 +35 -14
- package/src/theme/ApiExplorer/Server/index.tsx +10 -3
- package/src/theme/ApiExplorer/buildPostmanRequest.ts +52 -5
- package/src/theme/ApiExplorer/index.tsx +1 -0
- package/src/theme/ApiItem/index.tsx +2 -1
- 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/ParamsItem/index.tsx +25 -0
- package/src/theme/RequestSchema/index.tsx +141 -83
- package/src/theme/ResponseHeaders/index.tsx +1 -2
- 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/styles.scss +1 -0
- package/src/theme/translationIds.ts +3 -0
- package/src/theme-classic.d.ts +25 -1
- package/src/types.d.ts +7 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -233,25 +233,44 @@ function TabContent({ lazy, children, selectedValue }) {
|
|
|
233
233
|
return react_1.default.createElement(
|
|
234
234
|
"div",
|
|
235
235
|
{ className: "margin-top--md" },
|
|
236
|
-
childTabs
|
|
237
|
-
(0, react_1.cloneElement)(tabItem, {
|
|
238
|
-
key: i,
|
|
239
|
-
hidden: tabItem.props.value !== selectedValue,
|
|
240
|
-
})
|
|
241
|
-
)
|
|
236
|
+
childTabs
|
|
242
237
|
);
|
|
243
238
|
}
|
|
244
239
|
function TabsComponent(props) {
|
|
245
|
-
const tabs = (0, internal_1.
|
|
240
|
+
const tabs = (0, internal_1.useTabsContextValue)(props);
|
|
246
241
|
return react_1.default.createElement(
|
|
247
|
-
|
|
248
|
-
{
|
|
249
|
-
react_1.default.createElement(
|
|
250
|
-
|
|
242
|
+
internal_1.TabsProvider,
|
|
243
|
+
{ value: tabs },
|
|
244
|
+
react_1.default.createElement(
|
|
245
|
+
"div",
|
|
246
|
+
{ className: "openapi-tabs__schema-container" },
|
|
247
|
+
react_1.default.createElement(TabList, { ...props, ...tabs }),
|
|
248
|
+
react_1.default.createElement(TabContent, { ...props, ...tabs })
|
|
249
|
+
)
|
|
251
250
|
);
|
|
252
251
|
}
|
|
253
252
|
function SchemaTabs(props) {
|
|
254
253
|
const isBrowser = (0, useIsBrowser_1.default)();
|
|
254
|
+
const children = Array.isArray(props.children)
|
|
255
|
+
? props.children.filter(Boolean)
|
|
256
|
+
: props.children
|
|
257
|
+
? [props.children]
|
|
258
|
+
: [];
|
|
259
|
+
if (children.length === 0) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
let sanitizedChildren;
|
|
263
|
+
try {
|
|
264
|
+
sanitizedChildren = (0, internal_1.sanitizeTabsChildren)(children);
|
|
265
|
+
} catch {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
if (
|
|
269
|
+
!sanitizedChildren ||
|
|
270
|
+
(Array.isArray(sanitizedChildren) && sanitizedChildren.length === 0)
|
|
271
|
+
) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
255
274
|
return react_1.default.createElement(
|
|
256
275
|
TabsComponent,
|
|
257
276
|
// Remount tabs after hydration
|
|
@@ -262,6 +281,6 @@ function SchemaTabs(props) {
|
|
|
262
281
|
key: String(isBrowser),
|
|
263
282
|
...props,
|
|
264
283
|
},
|
|
265
|
-
|
|
284
|
+
sanitizedChildren
|
|
266
285
|
);
|
|
267
286
|
}
|
package/lib/theme/styles.scss
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
@use "./ApiExplorer/FloatingButton/FloatingButton";
|
|
10
10
|
@use "./ApiExplorer/FormFileUpload/FormFileUpload";
|
|
11
11
|
@use "./ApiExplorer/FormItem/FormItem";
|
|
12
|
+
@use "./ApiExplorer/FormLabel/FormLabel";
|
|
12
13
|
@use "./ApiExplorer/FormMultiSelect/FormMultiSelect";
|
|
13
14
|
@use "./ApiExplorer/FormSelect/FormSelect";
|
|
14
15
|
@use "./ApiExplorer/FormTextInput/FormTextInput";
|
|
@@ -60,6 +60,8 @@ export declare const OPENAPI_SCHEMA: {
|
|
|
60
60
|
NO_SCHEMA: string;
|
|
61
61
|
};
|
|
62
62
|
export declare const OPENAPI_SCHEMA_ITEM: {
|
|
63
|
+
CHARACTERS: string;
|
|
64
|
+
NON_EMPTY: string;
|
|
63
65
|
REQUIRED: string;
|
|
64
66
|
DEPRECATED: string;
|
|
65
67
|
NULLABLE: string;
|
|
@@ -71,6 +73,7 @@ export declare const OPENAPI_SCHEMA_ITEM: {
|
|
|
71
73
|
ENUM_VALUE: string;
|
|
72
74
|
ENUM_DESCRIPTION: string;
|
|
73
75
|
POSSIBLE_VALUES: string;
|
|
76
|
+
EXPRESSION: string;
|
|
74
77
|
ONE_OF: string;
|
|
75
78
|
ANY_OF: string;
|
|
76
79
|
};
|
|
@@ -84,6 +84,8 @@ exports.OPENAPI_SCHEMA = {
|
|
|
84
84
|
NO_SCHEMA: "theme.openapi.schema.noSchema",
|
|
85
85
|
};
|
|
86
86
|
exports.OPENAPI_SCHEMA_ITEM = {
|
|
87
|
+
CHARACTERS: "theme.openapi.schemaItem.characters",
|
|
88
|
+
NON_EMPTY: "theme.openapi.schemaItem.nonEmpty",
|
|
87
89
|
REQUIRED: "theme.openapi.schemaItem.required",
|
|
88
90
|
DEPRECATED: "theme.openapi.schemaItem.deprecated",
|
|
89
91
|
NULLABLE: "theme.openapi.schemaItem.nullable",
|
|
@@ -95,6 +97,7 @@ exports.OPENAPI_SCHEMA_ITEM = {
|
|
|
95
97
|
ENUM_VALUE: "theme.openapi.schemaItem.enumValue",
|
|
96
98
|
ENUM_DESCRIPTION: "theme.openapi.schemaItem.enumDescription",
|
|
97
99
|
POSSIBLE_VALUES: "theme.openapi.schemaItem.possibleValues",
|
|
100
|
+
EXPRESSION: "theme.openapi.schemaItem.expression",
|
|
98
101
|
ONE_OF: "theme.openapi.schemaItem.oneOf",
|
|
99
102
|
ANY_OF: "theme.openapi.schemaItem.anyOf",
|
|
100
103
|
};
|
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": "
|
|
4
|
+
"version": "5.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"watch": "concurrently --names \"lib,lib-next,tsc\" --kill-others \"yarn babel:lib --watch\" \"yarn babel:lib-next --watch\" \"yarn tsc --watch\""
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@docusaurus/theme-classic": "^3.
|
|
32
|
-
"@docusaurus/theme-common": "^3.
|
|
33
|
-
"@docusaurus/types": "^3.
|
|
31
|
+
"@docusaurus/theme-classic": "^3.10.0",
|
|
32
|
+
"@docusaurus/theme-common": "^3.10.0",
|
|
33
|
+
"@docusaurus/types": "^3.10.0",
|
|
34
34
|
"@types/crypto-js": "^4.2.2",
|
|
35
35
|
"@types/file-saver": "^2.0.7",
|
|
36
36
|
"@types/lodash": "^4.17.20",
|
|
@@ -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": "^
|
|
41
|
+
"docusaurus-plugin-openapi-docs": "^5.0.0",
|
|
42
42
|
"docusaurus-plugin-sass": "^0.2.6",
|
|
43
43
|
"eslint-plugin-prettier": "^5.5.1"
|
|
44
44
|
},
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"file-saver": "^2.0.5",
|
|
54
54
|
"lodash": "^4.17.21",
|
|
55
55
|
"pako": "^2.1.0",
|
|
56
|
+
"path-browserify": "^1.0.1",
|
|
56
57
|
"postman-code-generators": "^2.0.0",
|
|
57
58
|
"postman-collection": "^5.0.2",
|
|
58
59
|
"prism-react-renderer": "^2.4.1",
|
|
@@ -72,8 +73,8 @@
|
|
|
72
73
|
"xml-formatter": "^3.6.6"
|
|
73
74
|
},
|
|
74
75
|
"peerDependencies": {
|
|
75
|
-
"@docusaurus/theme-common": "^3.
|
|
76
|
-
"docusaurus-plugin-openapi-docs": "^
|
|
76
|
+
"@docusaurus/theme-common": "^3.10.0",
|
|
77
|
+
"docusaurus-plugin-openapi-docs": "^5.0.0",
|
|
77
78
|
"docusaurus-plugin-sass": "^0.2.3",
|
|
78
79
|
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
79
80
|
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
@@ -81,5 +82,5 @@
|
|
|
81
82
|
"engines": {
|
|
82
83
|
"node": ">=14"
|
|
83
84
|
},
|
|
84
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "516bd48c628fb16b7fe90d8f996168ab75ce5562"
|
|
85
86
|
}
|
package/src/index.ts
CHANGED
|
@@ -42,6 +42,7 @@ export default function docusaurusThemeOpenAPI(): Plugin<void> {
|
|
|
42
42
|
resolve: {
|
|
43
43
|
fallback: {
|
|
44
44
|
buffer: require.resolve("buffer/"),
|
|
45
|
+
path: require.resolve("path-browserify"),
|
|
45
46
|
},
|
|
46
47
|
},
|
|
47
48
|
plugins: [
|
|
@@ -71,6 +72,7 @@ export default function docusaurusThemeOpenAPI(): Plugin<void> {
|
|
|
71
72
|
resolve: {
|
|
72
73
|
fallback: {
|
|
73
74
|
buffer: require.resolve("buffer/"),
|
|
75
|
+
path: require.resolve("path-browserify"),
|
|
74
76
|
},
|
|
75
77
|
},
|
|
76
78
|
plugins: [
|
package/src/markdown/schema.ts
CHANGED
|
@@ -10,6 +10,44 @@ import { translate } from "@docusaurus/Translate";
|
|
|
10
10
|
import { OPENAPI_SCHEMA_ITEM } from "../theme/translationIds";
|
|
11
11
|
import { SchemaObject } from "../types";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Extracts enum values from a schema, including when wrapped in allOf.
|
|
15
|
+
*/
|
|
16
|
+
function getEnumFromSchema(schema: SchemaObject): any[] | undefined {
|
|
17
|
+
if (schema.enum) {
|
|
18
|
+
return schema.enum;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
22
|
+
for (const item of schema.allOf) {
|
|
23
|
+
if (item.enum) {
|
|
24
|
+
return item.enum;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Extracts the type from a schema, including when wrapped in allOf.
|
|
34
|
+
*/
|
|
35
|
+
function getTypeFromSchema(schema: SchemaObject): string | undefined {
|
|
36
|
+
if (schema.type) {
|
|
37
|
+
return schema.type as string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
41
|
+
for (const item of schema.allOf) {
|
|
42
|
+
if (item.type) {
|
|
43
|
+
return item.type as string;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
13
51
|
function prettyName(schema: SchemaObject, circular?: boolean) {
|
|
14
52
|
// Handle enum-only schemas (valid in JSON Schema)
|
|
15
53
|
// When enum is present without explicit type, treat as string
|
|
@@ -28,6 +66,12 @@ function prettyName(schema: SchemaObject, circular?: boolean) {
|
|
|
28
66
|
return schema.allOf[0];
|
|
29
67
|
}
|
|
30
68
|
}
|
|
69
|
+
// Check if allOf contains an enum - if so, return the type from allOf
|
|
70
|
+
const enumFromAllOf = getEnumFromSchema(schema);
|
|
71
|
+
if (enumFromAllOf) {
|
|
72
|
+
const typeFromAllOf = getTypeFromSchema(schema);
|
|
73
|
+
return typeFromAllOf ?? "string";
|
|
74
|
+
}
|
|
31
75
|
return "object";
|
|
32
76
|
}
|
|
33
77
|
|
|
@@ -92,11 +136,11 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
92
136
|
|
|
93
137
|
let qualifierGroups = [];
|
|
94
138
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
);
|
|
139
|
+
// Check for enum in array items (directly or inside allOf)
|
|
140
|
+
if (schema.items) {
|
|
141
|
+
const itemsEnum = getEnumFromSchema(schema.items as SchemaObject);
|
|
142
|
+
if (itemsEnum) {
|
|
143
|
+
qualifierGroups.push(`[${itemsEnum.map((e) => `\`${e}\``).join(", ")}]`);
|
|
100
144
|
}
|
|
101
145
|
}
|
|
102
146
|
|
|
@@ -104,14 +148,22 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
104
148
|
let lengthQualifier = "";
|
|
105
149
|
let minLength;
|
|
106
150
|
let maxLength;
|
|
151
|
+
const charactersMessage = translate({
|
|
152
|
+
id: OPENAPI_SCHEMA_ITEM.CHARACTERS,
|
|
153
|
+
message: "characters",
|
|
154
|
+
});
|
|
155
|
+
const nonEmptyMessage = translate({
|
|
156
|
+
id: OPENAPI_SCHEMA_ITEM.NON_EMPTY,
|
|
157
|
+
message: "non-empty",
|
|
158
|
+
});
|
|
107
159
|
if (schema.minLength && schema.minLength > 1) {
|
|
108
|
-
minLength = `\`>= ${schema.minLength}
|
|
160
|
+
minLength = `\`>= ${schema.minLength} ${charactersMessage}\``;
|
|
109
161
|
}
|
|
110
162
|
if (schema.minLength && schema.minLength === 1) {
|
|
111
|
-
minLength =
|
|
163
|
+
minLength = `\`${nonEmptyMessage}\``;
|
|
112
164
|
}
|
|
113
165
|
if (schema.maxLength) {
|
|
114
|
-
maxLength = `\`<= ${schema.maxLength}
|
|
166
|
+
maxLength = `\`<= ${schema.maxLength} ${charactersMessage}\``;
|
|
115
167
|
}
|
|
116
168
|
|
|
117
169
|
if (minLength && !maxLength) {
|
|
@@ -165,9 +217,11 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
165
217
|
}
|
|
166
218
|
|
|
167
219
|
if (schema.pattern) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
220
|
+
const expressionMessage = translate({
|
|
221
|
+
id: OPENAPI_SCHEMA_ITEM.EXPRESSION,
|
|
222
|
+
message: "Value must match regular expression",
|
|
223
|
+
});
|
|
224
|
+
qualifierGroups.push(`${expressionMessage} \`${schema.pattern}\``);
|
|
171
225
|
}
|
|
172
226
|
|
|
173
227
|
// Check if discriminator mapping
|
|
@@ -177,8 +231,10 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
177
231
|
qualifierGroups.push(`[${values.map((e) => `\`${e}\``).join(", ")}]`);
|
|
178
232
|
}
|
|
179
233
|
|
|
180
|
-
|
|
181
|
-
|
|
234
|
+
// Check for enum directly on schema or inside allOf
|
|
235
|
+
const schemaEnum = getEnumFromSchema(schema);
|
|
236
|
+
if (schemaEnum) {
|
|
237
|
+
qualifierGroups.push(`[${schemaEnum.map((e) => `\`${e}\``).join(", ")}]`);
|
|
182
238
|
}
|
|
183
239
|
|
|
184
240
|
if (schema.minItems) {
|
|
@@ -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 ?? ""}
|
|
@@ -43,11 +43,6 @@ export default function FileArrayFormBodyItem({
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
let maxIndex = 0;
|
|
47
|
-
|
|
48
|
-
newItems.keys().forEach((item) => {
|
|
49
|
-
maxIndex = item > maxIndex ? item : maxIndex;
|
|
50
|
-
});
|
|
51
46
|
newItems.set(index, {
|
|
52
47
|
src: `/path/to/${file.name}`,
|
|
53
48
|
content: file,
|
|
@@ -5,9 +5,10 @@
|
|
|
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
10
|
import FormFileUpload from "@theme/ApiExplorer/FormFileUpload";
|
|
11
|
+
import FormLabel from "@theme/ApiExplorer/FormLabel";
|
|
11
12
|
import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
12
13
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
13
14
|
import LiveApp from "@theme/ApiExplorer/LiveEditor";
|
|
@@ -16,70 +17,139 @@ import type { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/ty
|
|
|
16
17
|
|
|
17
18
|
import FileArrayFormBodyItem from "../FileArrayFormBodyItem";
|
|
18
19
|
import { clearFormBodyKey, setFileFormBody, setStringFormBody } from "../slice";
|
|
20
|
+
import { setFieldEncoding } from "../../EncodingSelection/slice";
|
|
19
21
|
|
|
20
22
|
interface FormBodyItemProps {
|
|
21
23
|
schemaObject: SchemaObject;
|
|
22
24
|
id: string;
|
|
23
25
|
schema: SchemaObject;
|
|
26
|
+
label?: string;
|
|
27
|
+
required?: boolean;
|
|
28
|
+
exampleValue?: SchemaObject["example"];
|
|
29
|
+
fieldEncoding?: string;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
export default function FormBodyItem({
|
|
27
33
|
schemaObject,
|
|
28
34
|
id,
|
|
29
35
|
schema,
|
|
36
|
+
label,
|
|
37
|
+
required,
|
|
38
|
+
exampleValue,
|
|
39
|
+
fieldEncoding,
|
|
30
40
|
}: FormBodyItemProps): React.JSX.Element {
|
|
31
41
|
const dispatch = useTypedDispatch();
|
|
32
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
|
+
|
|
33
89
|
if (
|
|
34
90
|
schemaObject.type === "array" &&
|
|
35
91
|
schemaObject.items?.format === "binary"
|
|
36
92
|
) {
|
|
37
93
|
return (
|
|
38
|
-
|
|
94
|
+
<>
|
|
95
|
+
{label && <FormLabel label={label} required={required} />}
|
|
96
|
+
<FileArrayFormBodyItem id={id} description={schemaObject.description} />
|
|
97
|
+
</>
|
|
39
98
|
);
|
|
40
99
|
}
|
|
41
100
|
|
|
42
101
|
if (schemaObject.format === "binary") {
|
|
43
102
|
return (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
+
</>
|
|
62
138
|
);
|
|
63
139
|
}
|
|
64
140
|
|
|
65
|
-
if (
|
|
66
|
-
schemaObject.type === "object" &&
|
|
67
|
-
(schemaObject.example || schemaObject.examples)
|
|
68
|
-
) {
|
|
69
|
-
const objectExample = JSON.stringify(
|
|
70
|
-
schemaObject.example ?? schemaObject.examples[0],
|
|
71
|
-
null,
|
|
72
|
-
2
|
|
73
|
-
);
|
|
74
|
-
|
|
141
|
+
if (schemaObject.type === "object") {
|
|
75
142
|
return (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
+
</>
|
|
83
153
|
);
|
|
84
154
|
}
|
|
85
155
|
|
|
@@ -89,9 +159,13 @@ export default function FormBodyItem({
|
|
|
89
159
|
) {
|
|
90
160
|
return (
|
|
91
161
|
<FormSelect
|
|
162
|
+
label={label}
|
|
163
|
+
required={required}
|
|
164
|
+
value={value}
|
|
92
165
|
options={["---", ...schemaObject.enum]}
|
|
93
166
|
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
94
167
|
const val = e.target.value;
|
|
168
|
+
setValue(val);
|
|
95
169
|
if (val === "---") {
|
|
96
170
|
dispatch(clearFormBodyKey(id));
|
|
97
171
|
} else {
|
|
@@ -109,12 +183,16 @@ export default function FormBodyItem({
|
|
|
109
183
|
// TODO: support all the other types.
|
|
110
184
|
return (
|
|
111
185
|
<FormTextInput
|
|
186
|
+
label={label}
|
|
187
|
+
required={required}
|
|
188
|
+
value={value}
|
|
112
189
|
paramName={id}
|
|
113
190
|
isRequired={
|
|
114
191
|
Array.isArray(schema.required) && schema.required.includes(id)
|
|
115
192
|
}
|
|
116
193
|
placeholder={schemaObject.description || id}
|
|
117
194
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
195
|
+
setValue(e.target.value);
|
|
118
196
|
dispatch(setStringFormBody({ key: id, value: e.target.value }));
|
|
119
197
|
}}
|
|
120
198
|
/>
|