docusaurus-theme-openapi-docs 4.3.7 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.js +3 -3
- package/lib/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.d.ts +5 -1
- package/lib/theme/ApiExplorer/Authorization/slice.js +2 -2
- package/lib/theme/ApiExplorer/Body/slice.js +2 -2
- package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +3 -3
- package/lib/theme/ApiExplorer/FormFileUpload/_FormFileUpload.scss +4 -2
- package/lib/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +4 -4
- package/lib/theme/ApiExplorer/Request/index.js +27 -6
- package/lib/theme/ApiExplorer/Request/makeRequest.d.ts +1 -1
- package/lib/theme/ApiExplorer/Request/makeRequest.js +3 -2
- package/lib/theme/ApiExplorer/Response/slice.js +2 -2
- package/lib/theme/ApiExplorer/Server/slice.js +2 -2
- package/lib/theme/ApiExplorer/buildPostmanRequest.d.ts +1 -1
- package/lib/theme/ApiExplorer/buildPostmanRequest.js +119 -46
- package/lib/theme/ApiExplorer/index.js +58 -2
- package/lib/theme/CodeSamples/_CodeSamples.scss +3 -0
- package/lib/theme/CodeSamples/index.d.ts +8 -0
- package/lib/theme/{ResponseSamples → CodeSamples}/index.js +4 -4
- package/lib/theme/ParamsItem/index.d.ts +1 -4
- package/lib/theme/ParamsItem/index.js +4 -1
- package/lib/theme/ResponseExamples/index.js +9 -9
- package/lib/theme/Schema/index.js +73 -133
- package/lib/theme/SchemaItem/index.js +34 -0
- package/lib/theme/styles.scss +1 -1
- package/lib/types.d.ts +5 -116
- package/package.json +5 -3
- package/src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx +3 -3
- package/src/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.tsx +5 -1
- package/src/theme/ApiExplorer/Body/index.tsx +1 -2
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +3 -3
- package/src/theme/ApiExplorer/FormFileUpload/_FormFileUpload.scss +4 -2
- package/src/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +4 -4
- package/src/theme/ApiExplorer/Request/index.tsx +28 -5
- package/src/theme/ApiExplorer/Request/makeRequest.ts +4 -3
- package/src/theme/ApiExplorer/buildPostmanRequest.ts +48 -18
- package/src/theme/ApiExplorer/index.tsx +4 -2
- package/src/theme/CodeSamples/_CodeSamples.scss +3 -0
- package/src/theme/{ResponseSamples → CodeSamples}/index.tsx +5 -10
- package/src/theme/ParamsItem/index.tsx +7 -6
- package/src/theme/ResponseExamples/index.tsx +6 -9
- package/src/theme/Schema/index.tsx +69 -96
- package/src/theme/SchemaItem/index.tsx +27 -0
- package/src/theme/styles.scss +1 -1
- package/src/types.ts +5 -115
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/theme/ResponseSamples/_ResponseSamples.scss +0 -3
- package/lib/theme/ResponseSamples/index.d.ts +0 -8
- package/src/theme/ApiExplorer/postman-collection.d.ts +0 -10
- package/src/theme/ApiExplorer/react-modal.d.ts +0 -8
- package/src/theme/ResponseSamples/_ResponseSamples.scss +0 -3
- package/src/theme-translations.d.ts +0 -9
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
&:hover {
|
|
15
15
|
border: 2px dashed var(--ifm-color-primary);
|
|
16
|
-
background:
|
|
16
|
+
background:
|
|
17
|
+
linear-gradient(
|
|
17
18
|
var(--openapi-dropzone-hover-shim),
|
|
18
19
|
var(--openapi-dropzone-hover-shim)
|
|
19
20
|
),
|
|
@@ -38,7 +39,8 @@
|
|
|
38
39
|
font-size: var(--ifm-code-font-size);
|
|
39
40
|
border: 2px dashed var(--ifm-color-primary);
|
|
40
41
|
|
|
41
|
-
background:
|
|
42
|
+
background:
|
|
43
|
+
linear-gradient(
|
|
42
44
|
var(--openapi-dropzone-hover-shim),
|
|
43
45
|
var(--openapi-dropzone-hover-shim)
|
|
44
46
|
),
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
line-height: 1.5;
|
|
46
46
|
|
|
47
47
|
transition-property: color, background, border-color, box-shadow;
|
|
48
|
-
transition-duration:
|
|
49
|
-
var(--ifm-button-transition-duration);
|
|
48
|
+
transition-duration:
|
|
49
|
+
100ms, 100ms, 100ms, var(--ifm-button-transition-duration);
|
|
50
50
|
transition-timing-function: cubic-bezier(0.08, 0.52, 0.52, 1);
|
|
51
51
|
|
|
52
52
|
-webkit-user-select: none;
|
|
@@ -85,8 +85,8 @@
|
|
|
85
85
|
padding: 0.5rem 1rem;
|
|
86
86
|
font-size: 12px;
|
|
87
87
|
transition-property: color, background, border-color, box-shadow;
|
|
88
|
-
transition-duration:
|
|
89
|
-
var(--ifm-button-transition-duration);
|
|
88
|
+
transition-duration:
|
|
89
|
+
100ms, 100ms, 100ms, var(--ifm-button-transition-duration);
|
|
90
90
|
transition-timing-function: cubic-bezier(0.08, 0.52, 0.52, 1);
|
|
91
91
|
user-select: none;
|
|
92
92
|
white-space: nowrap;
|
|
@@ -26,7 +26,7 @@ import Server from "@theme/ApiExplorer/Server";
|
|
|
26
26
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
27
27
|
import { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
28
28
|
import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types";
|
|
29
|
-
import sdk from "postman-collection";
|
|
29
|
+
import * as sdk from "postman-collection";
|
|
30
30
|
import { FormProvider, useForm } from "react-hook-form";
|
|
31
31
|
|
|
32
32
|
import makeRequest from "./makeRequest";
|
|
@@ -95,15 +95,38 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
95
95
|
|
|
96
96
|
const methods = useForm({ shouldFocusError: false });
|
|
97
97
|
|
|
98
|
+
const handleEventStream = async (res) => {
|
|
99
|
+
res.headers && dispatch(setHeaders(Object.fromEntries(res.headers)));
|
|
100
|
+
dispatch(setCode(res.status));
|
|
101
|
+
|
|
102
|
+
const reader = res.body.getReader();
|
|
103
|
+
const decoder = new TextDecoder();
|
|
104
|
+
let result = "";
|
|
105
|
+
while (true) {
|
|
106
|
+
const { done, value } = await reader.read();
|
|
107
|
+
if (done) break;
|
|
108
|
+
result += decoder.decode(value, { stream: true });
|
|
109
|
+
dispatch(setResponse(result));
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handleResponse = async (res) => {
|
|
114
|
+
dispatch(setResponse(await res.text()));
|
|
115
|
+
dispatch(setCode(res.status));
|
|
116
|
+
res.headers && dispatch(setHeaders(Object.fromEntries(res.headers)));
|
|
117
|
+
};
|
|
118
|
+
|
|
98
119
|
const onSubmit = async (data) => {
|
|
99
120
|
dispatch(setResponse("Fetching..."));
|
|
100
121
|
try {
|
|
101
122
|
await delay(1200);
|
|
102
123
|
const res = await makeRequest(postmanRequest, proxy, body);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
if (res.headers.get("content-type")?.includes("text/event-stream")) {
|
|
125
|
+
await handleEventStream(res);
|
|
126
|
+
} else {
|
|
127
|
+
await handleResponse(res);
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
107
130
|
console.log(e);
|
|
108
131
|
dispatch(setResponse("Connection failed"));
|
|
109
132
|
dispatch(clearCode());
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
8
|
import { Body } from "@theme/ApiExplorer/Body/slice";
|
|
9
|
-
import sdk from "postman-collection";
|
|
9
|
+
import * as sdk from "postman-collection";
|
|
10
10
|
|
|
11
11
|
function fetchWithtimeout(
|
|
12
12
|
url: string,
|
|
@@ -156,8 +156,9 @@ async function makeRequest(
|
|
|
156
156
|
myHeaders.delete("Content-Type");
|
|
157
157
|
|
|
158
158
|
myBody = new FormData();
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
const members = (request.body as any)?.formdata?.members;
|
|
160
|
+
if (Array.isArray(members)) {
|
|
161
|
+
for (const data of members) {
|
|
161
162
|
if (data.key && data.value.content) {
|
|
162
163
|
myBody.append(data.key, data.value.content);
|
|
163
164
|
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ServerObject,
|
|
13
13
|
} from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
14
14
|
import cloneDeep from "lodash/cloneDeep";
|
|
15
|
-
import sdk from "postman-collection";
|
|
15
|
+
import * as sdk from "postman-collection";
|
|
16
16
|
|
|
17
17
|
type Param = {
|
|
18
18
|
value?: string | string[];
|
|
@@ -73,7 +73,7 @@ function setQueryParams(postman: sdk.Request, queryParams: Param[]) {
|
|
|
73
73
|
([key, val]) =>
|
|
74
74
|
new sdk.QueryParam({
|
|
75
75
|
key: `${param.name}[${key}]`,
|
|
76
|
-
value: val,
|
|
76
|
+
value: String(val),
|
|
77
77
|
})
|
|
78
78
|
);
|
|
79
79
|
} else if (param.explode) {
|
|
@@ -81,7 +81,7 @@ function setQueryParams(postman: sdk.Request, queryParams: Param[]) {
|
|
|
81
81
|
([key, val]) =>
|
|
82
82
|
new sdk.QueryParam({
|
|
83
83
|
key: key,
|
|
84
|
-
value: val,
|
|
84
|
+
value: String(val),
|
|
85
85
|
})
|
|
86
86
|
);
|
|
87
87
|
} else {
|
|
@@ -181,7 +181,10 @@ function setPathParams(postman: sdk.Request, pathParams: Param[]) {
|
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
postman.url.variables.assimilate(
|
|
184
|
+
postman.url.variables.assimilate(
|
|
185
|
+
source.filter((v): v is sdk.Variable => v !== undefined),
|
|
186
|
+
false
|
|
187
|
+
);
|
|
185
188
|
}
|
|
186
189
|
|
|
187
190
|
function buildCookie(cookieParams: Param[]) {
|
|
@@ -207,7 +210,9 @@ function buildCookie(cookieParams: Param[]) {
|
|
|
207
210
|
([key, val]) =>
|
|
208
211
|
new sdk.Cookie({
|
|
209
212
|
key: key,
|
|
210
|
-
value: val,
|
|
213
|
+
value: String(val),
|
|
214
|
+
domain: "",
|
|
215
|
+
path: "",
|
|
211
216
|
})
|
|
212
217
|
);
|
|
213
218
|
} else {
|
|
@@ -217,6 +222,8 @@ function buildCookie(cookieParams: Param[]) {
|
|
|
217
222
|
value: Object.entries(jsonResult)
|
|
218
223
|
.map(([key, val]) => `${key},${val}`)
|
|
219
224
|
.join(","),
|
|
225
|
+
domain: "",
|
|
226
|
+
path: "",
|
|
220
227
|
});
|
|
221
228
|
}
|
|
222
229
|
}
|
|
@@ -224,7 +231,9 @@ function buildCookie(cookieParams: Param[]) {
|
|
|
224
231
|
// Handle scalar values
|
|
225
232
|
return new sdk.Cookie({
|
|
226
233
|
key: param.name,
|
|
227
|
-
value: param.value,
|
|
234
|
+
value: String(param.value),
|
|
235
|
+
domain: "",
|
|
236
|
+
path: "",
|
|
228
237
|
});
|
|
229
238
|
}
|
|
230
239
|
}
|
|
@@ -430,10 +439,9 @@ function buildPostmanRequest(
|
|
|
430
439
|
clonedPostman.url.host = [url];
|
|
431
440
|
}
|
|
432
441
|
|
|
433
|
-
|
|
434
|
-
|
|
442
|
+
const enhancedQueryParams = [...queryParams];
|
|
443
|
+
const enhancedCookieParams = [...cookieParams];
|
|
435
444
|
|
|
436
|
-
const cookie = buildCookie(cookieParams);
|
|
437
445
|
let otherHeaders = [];
|
|
438
446
|
|
|
439
447
|
let selectedAuth: Scheme[] = [];
|
|
@@ -491,24 +499,46 @@ function buildPostmanRequest(
|
|
|
491
499
|
continue;
|
|
492
500
|
}
|
|
493
501
|
|
|
494
|
-
// API Key
|
|
502
|
+
// API Key in header
|
|
495
503
|
if (a.type === "apiKey" && a.in === "header") {
|
|
496
504
|
const { apiKey } = auth.data[a.key];
|
|
497
|
-
if (apiKey === undefined) {
|
|
498
|
-
otherHeaders.push({
|
|
499
|
-
key: a.name,
|
|
500
|
-
value: `<${a.name ?? a.type}>`,
|
|
501
|
-
});
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
505
|
otherHeaders.push({
|
|
505
506
|
key: a.name,
|
|
506
|
-
value: apiKey
|
|
507
|
+
value: apiKey || `<${a.name ?? a.type}>`,
|
|
508
|
+
});
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// API Key in query
|
|
513
|
+
if (a.type === "apiKey" && a.in === "query") {
|
|
514
|
+
const { apiKey } = auth.data[a.key];
|
|
515
|
+
enhancedQueryParams.push({
|
|
516
|
+
name: a.name,
|
|
517
|
+
in: "query",
|
|
518
|
+
value: apiKey || `<${a.name ?? a.type}>`,
|
|
519
|
+
});
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// API Key in cookie
|
|
524
|
+
if (a.type === "apiKey" && a.in === "cookie") {
|
|
525
|
+
const { apiKey } = auth.data[a.key];
|
|
526
|
+
enhancedCookieParams.push({
|
|
527
|
+
name: a.name,
|
|
528
|
+
in: "cookie",
|
|
529
|
+
value: apiKey || `<${a.name ?? a.type}>`,
|
|
507
530
|
});
|
|
508
531
|
continue;
|
|
509
532
|
}
|
|
510
533
|
}
|
|
511
534
|
|
|
535
|
+
// Use the enhanced params that might include API keys
|
|
536
|
+
setQueryParams(clonedPostman, enhancedQueryParams);
|
|
537
|
+
setPathParams(clonedPostman, pathParams);
|
|
538
|
+
|
|
539
|
+
// Use enhanced cookie params that might include API keys
|
|
540
|
+
const cookie = buildCookie(enhancedCookieParams);
|
|
541
|
+
|
|
512
542
|
setHeaders(
|
|
513
543
|
clonedPostman,
|
|
514
544
|
contentType,
|
|
@@ -12,7 +12,7 @@ import Request from "@theme/ApiExplorer/Request";
|
|
|
12
12
|
import Response from "@theme/ApiExplorer/Response";
|
|
13
13
|
import SecuritySchemes from "@theme/ApiExplorer/SecuritySchemes";
|
|
14
14
|
import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types";
|
|
15
|
-
import sdk from "postman-collection";
|
|
15
|
+
import * as sdk from "postman-collection";
|
|
16
16
|
|
|
17
17
|
function ApiExplorer({
|
|
18
18
|
item,
|
|
@@ -21,7 +21,9 @@ function ApiExplorer({
|
|
|
21
21
|
item: NonNullable<ApiItem>;
|
|
22
22
|
infoPath: string;
|
|
23
23
|
}) {
|
|
24
|
-
const postman = new sdk.Request(
|
|
24
|
+
const postman = new sdk.Request(
|
|
25
|
+
item.postman ? (item.postman as any).toJSON() : {}
|
|
26
|
+
);
|
|
25
27
|
|
|
26
28
|
return (
|
|
27
29
|
<>
|
|
@@ -11,21 +11,16 @@ import CodeBlock from "@theme/CodeBlock";
|
|
|
11
11
|
import { Language } from "prism-react-renderer";
|
|
12
12
|
|
|
13
13
|
export interface Props {
|
|
14
|
-
readonly
|
|
14
|
+
readonly example: string;
|
|
15
15
|
readonly language: Language;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function
|
|
19
|
-
responseExample,
|
|
20
|
-
language,
|
|
21
|
-
}: Props): React.JSX.Element {
|
|
18
|
+
function CodeSamples({ example, language }: Props): React.JSX.Element {
|
|
22
19
|
return (
|
|
23
|
-
<div className="openapi-
|
|
24
|
-
<CodeBlock language={language ? language : "json"}>
|
|
25
|
-
{responseExample}
|
|
26
|
-
</CodeBlock>
|
|
20
|
+
<div className="openapi-code__code-samples-container">
|
|
21
|
+
<CodeBlock language={language ? language : "json"}>{example}</CodeBlock>
|
|
27
22
|
</div>
|
|
28
23
|
);
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
export default
|
|
26
|
+
export default CodeSamples;
|
|
@@ -16,10 +16,6 @@ import clsx from "clsx";
|
|
|
16
16
|
import { getQualifierMessage, getSchemaName } from "../../markdown/schema";
|
|
17
17
|
import { guard, toString } from "../../markdown/utils";
|
|
18
18
|
|
|
19
|
-
interface Map<T> {
|
|
20
|
-
[key: string]: T;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
19
|
export interface ExampleObject {
|
|
24
20
|
summary?: string;
|
|
25
21
|
description?: string;
|
|
@@ -32,7 +28,7 @@ export interface Props {
|
|
|
32
28
|
param: {
|
|
33
29
|
description: string;
|
|
34
30
|
example: any;
|
|
35
|
-
examples:
|
|
31
|
+
examples: Record<string, ExampleObject>;
|
|
36
32
|
name: string;
|
|
37
33
|
required: boolean;
|
|
38
34
|
deprecated: boolean;
|
|
@@ -70,9 +66,14 @@ function ParamsItem({ param, ...rest }: Props) {
|
|
|
70
66
|
let schema = param.schema;
|
|
71
67
|
let defaultValue: string | undefined;
|
|
72
68
|
|
|
73
|
-
if (!schema
|
|
69
|
+
if (!schema) {
|
|
74
70
|
schema = { type: "any" };
|
|
75
71
|
}
|
|
72
|
+
|
|
73
|
+
if (!schema.type) {
|
|
74
|
+
schema.type = "any";
|
|
75
|
+
}
|
|
76
|
+
|
|
76
77
|
if (schema) {
|
|
77
78
|
if (schema.items) {
|
|
78
79
|
defaultValue = schema.items.default;
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
|
+
import CodeSamples from "@theme/CodeSamples";
|
|
10
11
|
import Markdown from "@theme/Markdown";
|
|
11
|
-
import ResponseSamples from "@theme/ResponseSamples";
|
|
12
12
|
import TabItem from "@theme/TabItem";
|
|
13
13
|
import { sampleResponseFromSchema } from "docusaurus-plugin-openapi-docs/lib/openapi/createResponseExample";
|
|
14
14
|
import format from "xml-formatter";
|
|
@@ -78,10 +78,7 @@ export const ResponseExamples: React.FC<ResponseExamplesProps> = ({
|
|
|
78
78
|
{exampleValue.summary}
|
|
79
79
|
</Markdown>
|
|
80
80
|
)}
|
|
81
|
-
<
|
|
82
|
-
responseExample={responseExample}
|
|
83
|
-
language={language}
|
|
84
|
-
/>
|
|
81
|
+
<CodeSamples example={responseExample} language={language} />
|
|
85
82
|
</TabItem>
|
|
86
83
|
);
|
|
87
84
|
}
|
|
@@ -120,7 +117,7 @@ export const ResponseExample: React.FC<ResponseExampleProps> = ({
|
|
|
120
117
|
{responseExample.summary}
|
|
121
118
|
</Markdown>
|
|
122
119
|
)}
|
|
123
|
-
<
|
|
120
|
+
<CodeSamples example={exampleContent} language={language} />
|
|
124
121
|
</TabItem>
|
|
125
122
|
);
|
|
126
123
|
};
|
|
@@ -167,7 +164,7 @@ export const ExampleFromSchema: React.FC<ExampleFromSchemaProps> = ({
|
|
|
167
164
|
return (
|
|
168
165
|
// @ts-ignore
|
|
169
166
|
<TabItem label="Example (auto)" value="Example (auto)">
|
|
170
|
-
<
|
|
167
|
+
<CodeSamples example={xmlExample} language="xml" />
|
|
171
168
|
</TabItem>
|
|
172
169
|
);
|
|
173
170
|
}
|
|
@@ -180,8 +177,8 @@ export const ExampleFromSchema: React.FC<ExampleFromSchemaProps> = ({
|
|
|
180
177
|
return (
|
|
181
178
|
// @ts-ignore
|
|
182
179
|
<TabItem label="Example (auto)" value="Example (auto)">
|
|
183
|
-
<
|
|
184
|
-
|
|
180
|
+
<CodeSamples
|
|
181
|
+
example={JSON.stringify(responseExample, null, 2)}
|
|
185
182
|
language="json"
|
|
186
183
|
/>
|
|
187
184
|
</TabItem>
|
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
getQualifierMessage,
|
|
22
22
|
getSchemaName,
|
|
23
23
|
} from "docusaurus-plugin-openapi-docs/lib/markdown/schema";
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
SchemaObject,
|
|
26
|
+
SchemaType,
|
|
27
|
+
} from "docusaurus-plugin-openapi-docs/lib/openapi/types";
|
|
25
28
|
import isEmpty from "lodash/isEmpty";
|
|
26
29
|
|
|
27
30
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
@@ -113,7 +116,7 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
113
116
|
</span>
|
|
114
117
|
<SchemaTabs>
|
|
115
118
|
{schema[type]?.map((anyOneSchema: any, index: number) => {
|
|
116
|
-
const label = anyOneSchema.title ||
|
|
119
|
+
const label = anyOneSchema.title || anyOneSchema.type;
|
|
117
120
|
return (
|
|
118
121
|
// @ts-ignore
|
|
119
122
|
<TabItem
|
|
@@ -122,9 +125,7 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
122
125
|
value={`${index}-item-properties`}
|
|
123
126
|
>
|
|
124
127
|
{/* Handle primitive types directly */}
|
|
125
|
-
{
|
|
126
|
-
anyOneSchema.type
|
|
127
|
-
) && (
|
|
128
|
+
{(isPrimitive(anyOneSchema) || anyOneSchema.const) && (
|
|
128
129
|
<SchemaItem
|
|
129
130
|
collapsible={false}
|
|
130
131
|
name={undefined}
|
|
@@ -352,7 +353,8 @@ const DiscriminatorNode: React.FC<DiscriminatorNodeProps> = ({
|
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
const subProperties = subSchema.properties || mergedSubSchema.properties;
|
|
355
|
-
|
|
356
|
+
// Add a safeguard check to avoid referencing subProperties if it's undefined
|
|
357
|
+
if (subProperties && subProperties[discriminator.propertyName]) {
|
|
356
358
|
if (schema.properties) {
|
|
357
359
|
schema.properties![discriminator.propertyName] = {
|
|
358
360
|
...schema.properties![discriminator.propertyName],
|
|
@@ -502,88 +504,42 @@ const Items: React.FC<{
|
|
|
502
504
|
schema: any;
|
|
503
505
|
schemaType: "request" | "response";
|
|
504
506
|
}> = ({ schema, schemaType }) => {
|
|
505
|
-
//
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
<OpeningArrayBracket />
|
|
510
|
-
<Properties schema={schema.items} schemaType={schemaType} />
|
|
511
|
-
<ClosingArrayBracket />
|
|
512
|
-
</>
|
|
513
|
-
);
|
|
507
|
+
// Process schema.items to handle allOf merging
|
|
508
|
+
let itemsSchema = schema.items;
|
|
509
|
+
if (schema.items?.allOf) {
|
|
510
|
+
itemsSchema = mergeAllOf(schema.items) as SchemaObject;
|
|
514
511
|
}
|
|
515
512
|
|
|
516
|
-
//
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
<OpeningArrayBracket />
|
|
521
|
-
<AdditionalProperties schema={schema.items} schemaType={schemaType} />
|
|
522
|
-
<ClosingArrayBracket />
|
|
523
|
-
</>
|
|
524
|
-
);
|
|
525
|
-
}
|
|
513
|
+
// Handle complex schemas with multiple schema types
|
|
514
|
+
const hasOneOfAnyOf = itemsSchema?.oneOf || itemsSchema?.anyOf;
|
|
515
|
+
const hasProperties = itemsSchema?.properties;
|
|
516
|
+
const hasAdditionalProperties = itemsSchema?.additionalProperties;
|
|
526
517
|
|
|
527
|
-
|
|
528
|
-
if (schema.items?.oneOf || schema.items?.anyOf) {
|
|
518
|
+
if (hasOneOfAnyOf || hasProperties || hasAdditionalProperties) {
|
|
529
519
|
return (
|
|
530
520
|
<>
|
|
531
521
|
<OpeningArrayBracket />
|
|
532
|
-
|
|
522
|
+
{hasOneOfAnyOf && (
|
|
523
|
+
<AnyOneOf schema={itemsSchema} schemaType={schemaType} />
|
|
524
|
+
)}
|
|
525
|
+
{hasProperties && (
|
|
526
|
+
<Properties schema={itemsSchema} schemaType={schemaType} />
|
|
527
|
+
)}
|
|
528
|
+
{hasAdditionalProperties && (
|
|
529
|
+
<AdditionalProperties schema={itemsSchema} schemaType={schemaType} />
|
|
530
|
+
)}
|
|
533
531
|
<ClosingArrayBracket />
|
|
534
532
|
</>
|
|
535
533
|
);
|
|
536
534
|
}
|
|
537
535
|
|
|
538
|
-
// Handles case when schema.items has allOf
|
|
539
|
-
if (schema.items?.allOf) {
|
|
540
|
-
const mergedSchemas = mergeAllOf(schema.items) as SchemaObject;
|
|
541
|
-
|
|
542
|
-
// Handles combo anyOf/oneOf + properties
|
|
543
|
-
if (
|
|
544
|
-
(mergedSchemas.oneOf || mergedSchemas.anyOf) &&
|
|
545
|
-
mergedSchemas.properties
|
|
546
|
-
) {
|
|
547
|
-
return (
|
|
548
|
-
<>
|
|
549
|
-
<OpeningArrayBracket />
|
|
550
|
-
<AnyOneOf schema={mergedSchemas} schemaType={schemaType} />
|
|
551
|
-
<Properties schema={mergedSchemas} schemaType={schemaType} />
|
|
552
|
-
<ClosingArrayBracket />
|
|
553
|
-
</>
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// Handles only anyOf/oneOf
|
|
558
|
-
if (mergedSchemas.oneOf || mergedSchemas.anyOf) {
|
|
559
|
-
return (
|
|
560
|
-
<>
|
|
561
|
-
<OpeningArrayBracket />
|
|
562
|
-
<AnyOneOf schema={mergedSchemas} schemaType={schemaType} />
|
|
563
|
-
<ClosingArrayBracket />
|
|
564
|
-
</>
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// Handles properties
|
|
569
|
-
if (mergedSchemas.properties) {
|
|
570
|
-
return (
|
|
571
|
-
<>
|
|
572
|
-
<OpeningArrayBracket />
|
|
573
|
-
<Properties schema={mergedSchemas} schemaType={schemaType} />
|
|
574
|
-
<ClosingArrayBracket />
|
|
575
|
-
</>
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
536
|
// Handles basic types (string, number, integer, boolean, object)
|
|
581
537
|
if (
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
538
|
+
itemsSchema?.type === "string" ||
|
|
539
|
+
itemsSchema?.type === "number" ||
|
|
540
|
+
itemsSchema?.type === "integer" ||
|
|
541
|
+
itemsSchema?.type === "boolean" ||
|
|
542
|
+
itemsSchema?.type === "object"
|
|
587
543
|
) {
|
|
588
544
|
return (
|
|
589
545
|
<div style={{ marginLeft: ".5rem" }}>
|
|
@@ -591,9 +547,9 @@ const Items: React.FC<{
|
|
|
591
547
|
<SchemaItem
|
|
592
548
|
collapsible={false}
|
|
593
549
|
name="" // No name for array items
|
|
594
|
-
schemaName={getSchemaName(
|
|
595
|
-
qualifierMessage={getQualifierMessage(
|
|
596
|
-
schema={
|
|
550
|
+
schemaName={getSchemaName(itemsSchema)}
|
|
551
|
+
qualifierMessage={getQualifierMessage(itemsSchema)}
|
|
552
|
+
schema={itemsSchema}
|
|
597
553
|
discriminator={false}
|
|
598
554
|
children={null}
|
|
599
555
|
/>
|
|
@@ -606,7 +562,7 @@ const Items: React.FC<{
|
|
|
606
562
|
return (
|
|
607
563
|
<>
|
|
608
564
|
<OpeningArrayBracket />
|
|
609
|
-
{Object.entries(
|
|
565
|
+
{Object.entries(itemsSchema || {}).map(([key, val]: [string, any]) => (
|
|
610
566
|
<SchemaEdge
|
|
611
567
|
key={key}
|
|
612
568
|
name={key}
|
|
@@ -840,6 +796,25 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
840
796
|
);
|
|
841
797
|
};
|
|
842
798
|
|
|
799
|
+
function renderChildren(
|
|
800
|
+
schema: SchemaObject,
|
|
801
|
+
schemaType: "request" | "response"
|
|
802
|
+
) {
|
|
803
|
+
return (
|
|
804
|
+
<>
|
|
805
|
+
{schema.oneOf && <AnyOneOf schema={schema} schemaType={schemaType} />}
|
|
806
|
+
{schema.anyOf && <AnyOneOf schema={schema} schemaType={schemaType} />}
|
|
807
|
+
{schema.properties && (
|
|
808
|
+
<Properties schema={schema} schemaType={schemaType} />
|
|
809
|
+
)}
|
|
810
|
+
{schema.additionalProperties && (
|
|
811
|
+
<AdditionalProperties schema={schema} schemaType={schemaType} />
|
|
812
|
+
)}
|
|
813
|
+
{schema.items && <Items schema={schema} schemaType={schemaType} />}
|
|
814
|
+
</>
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
|
|
843
818
|
const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
844
819
|
if (
|
|
845
820
|
(schemaType === "request" && schema.readOnly) ||
|
|
@@ -888,10 +863,6 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
888
863
|
);
|
|
889
864
|
}
|
|
890
865
|
|
|
891
|
-
if (schema.oneOf || schema.anyOf) {
|
|
892
|
-
return <AnyOneOf schema={schema} schemaType={schemaType} />;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
866
|
// Handle primitives
|
|
896
867
|
if (
|
|
897
868
|
schema.type &&
|
|
@@ -917,19 +888,21 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
917
888
|
);
|
|
918
889
|
}
|
|
919
890
|
|
|
920
|
-
return (
|
|
921
|
-
<div>
|
|
922
|
-
{schema.oneOf && <AnyOneOf schema={schema} schemaType={schemaType} />}
|
|
923
|
-
{schema.anyOf && <AnyOneOf schema={schema} schemaType={schemaType} />}
|
|
924
|
-
{schema.properties && (
|
|
925
|
-
<Properties schema={schema} schemaType={schemaType} />
|
|
926
|
-
)}
|
|
927
|
-
{schema.additionalProperties && (
|
|
928
|
-
<AdditionalProperties schema={schema} schemaType={schemaType} />
|
|
929
|
-
)}
|
|
930
|
-
{schema.items && <Items schema={schema} schemaType={schemaType} />}
|
|
931
|
-
</div>
|
|
932
|
-
);
|
|
891
|
+
return renderChildren(schema, schemaType);
|
|
933
892
|
};
|
|
934
893
|
|
|
935
894
|
export default SchemaNode;
|
|
895
|
+
|
|
896
|
+
type PrimitiveSchemaType = Exclude<SchemaType, "object" | "array">;
|
|
897
|
+
|
|
898
|
+
const PRIMITIVE_TYPES: Record<PrimitiveSchemaType, true> = {
|
|
899
|
+
string: true,
|
|
900
|
+
number: true,
|
|
901
|
+
integer: true,
|
|
902
|
+
boolean: true,
|
|
903
|
+
null: true,
|
|
904
|
+
} as const;
|
|
905
|
+
|
|
906
|
+
const isPrimitive = (schema: SchemaObject) => {
|
|
907
|
+
return PRIMITIVE_TYPES[schema.type as PrimitiveSchemaType];
|
|
908
|
+
};
|