docusaurus-theme-openapi-docs 4.5.1 → 4.7.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/markdown/schema.js +14 -1
- package/lib/theme/ApiExplorer/Accept/slice.d.ts +5 -2
- package/lib/theme/ApiExplorer/Authorization/index.js +50 -9
- package/lib/theme/ApiExplorer/Authorization/slice.d.ts +145 -3
- package/lib/theme/ApiExplorer/Authorization/slice.js +3 -1
- package/lib/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.d.ts +7 -0
- package/lib/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.js +126 -0
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.d.ts +9 -0
- package/lib/theme/ApiExplorer/Body/FormBodyItem/index.js +110 -0
- package/lib/theme/ApiExplorer/Body/index.js +322 -193
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.d.ts +13 -0
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.js +133 -0
- package/lib/theme/ApiExplorer/Body/slice.d.ts +1056 -11
- package/lib/theme/ApiExplorer/Body/slice.js +22 -2
- package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +2 -1
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +37 -26
- package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +5 -1
- package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +3 -3
- package/lib/theme/ApiExplorer/CodeTabs/index.js +2 -2
- package/lib/theme/ApiExplorer/ContentType/slice.d.ts +5 -2
- package/lib/theme/ApiExplorer/FormFileUpload/index.js +6 -1
- package/lib/theme/ApiExplorer/FormItem/index.js +6 -1
- package/lib/theme/ApiExplorer/FormTextInput/index.d.ts +2 -0
- package/lib/theme/ApiExplorer/FormTextInput/index.js +8 -1
- package/lib/theme/ApiExplorer/LiveEditor/index.js +11 -4
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.js +15 -5
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.js +11 -3
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +12 -4
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.js +11 -2
- package/lib/theme/ApiExplorer/ParamOptions/index.js +11 -1
- package/lib/theme/ApiExplorer/ParamOptions/slice.d.ts +0 -4
- package/lib/theme/ApiExplorer/ParamOptions/slice.js +4 -4
- package/lib/theme/ApiExplorer/Request/index.js +110 -17
- package/lib/theme/ApiExplorer/Request/makeRequest.d.ts +7 -1
- package/lib/theme/ApiExplorer/Request/makeRequest.js +94 -24
- package/lib/theme/ApiExplorer/Response/index.js +34 -14
- package/lib/theme/ApiExplorer/Response/slice.d.ts +31 -7
- package/lib/theme/ApiExplorer/SchemaSelection/index.d.ts +2 -0
- package/lib/theme/ApiExplorer/SchemaSelection/index.js +36 -0
- package/lib/theme/ApiExplorer/SchemaSelection/slice.d.ts +37 -0
- package/lib/theme/ApiExplorer/SchemaSelection/slice.js +39 -0
- package/lib/theme/ApiExplorer/SecuritySchemes/index.js +208 -69
- package/lib/theme/ApiExplorer/Server/index.js +16 -2
- package/lib/theme/ApiExplorer/Server/slice.d.ts +49 -3
- package/lib/theme/ApiExplorer/buildPostmanRequest.js +46 -57
- package/lib/theme/ApiExplorer/index.js +4 -0
- package/lib/theme/ApiExplorer/persistenceMiddleware.d.ts +21 -0
- package/lib/theme/ApiExplorer/{persistanceMiddleware.js → persistenceMiddleware.js} +16 -9
- package/lib/theme/ApiExplorer/storage-utils.d.ts +2 -2
- package/lib/theme/ApiExplorer/storage-utils.js +3 -3
- package/lib/theme/ApiItem/Layout/index.d.ts +1 -1
- package/lib/theme/ApiItem/hooks.d.ts +10 -9
- package/lib/theme/ApiItem/index.js +13 -8
- package/lib/theme/ApiItem/store.d.ts +61 -43
- package/lib/theme/ApiItem/store.js +6 -2
- package/lib/theme/ApiTabs/index.js +6 -1
- package/lib/theme/Example/_Example.scss +11 -0
- package/lib/theme/Example/index.d.ts +24 -0
- package/lib/theme/Example/index.js +170 -0
- package/lib/theme/ParamsDetails/index.js +9 -1
- package/lib/theme/ParamsItem/index.d.ts +1 -1
- package/lib/theme/ParamsItem/index.js +43 -74
- package/lib/theme/RequestSchema/index.js +68 -48
- package/lib/theme/ResponseExamples/index.js +23 -3
- package/lib/theme/ResponseSchema/index.js +97 -82
- package/lib/theme/Schema/index.d.ts +6 -0
- package/lib/theme/Schema/index.js +240 -31
- package/lib/theme/SchemaItem/index.js +64 -36
- package/lib/theme/SchemaTabs/index.d.ts +8 -1
- package/lib/theme/SchemaTabs/index.js +14 -2
- package/lib/theme/StatusCodes/index.d.ts +1 -1
- package/lib/theme/StatusCodes/index.js +11 -2
- package/lib/theme/styles.scss +15 -0
- package/lib/theme/translationIds.d.ts +90 -0
- package/lib/theme/translationIds.js +114 -0
- package/package.json +28 -28
- package/src/markdown/schema.ts +17 -1
- package/src/theme/ApiExplorer/Authorization/index.tsx +51 -10
- package/src/theme/ApiExplorer/Authorization/slice.ts +1 -1
- package/src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx +77 -0
- package/src/theme/ApiExplorer/Body/FormBodyItem/index.tsx +120 -0
- package/src/theme/ApiExplorer/Body/index.tsx +262 -198
- package/{lib/types.js → src/theme/ApiExplorer/Body/json2xml.d.ts} +2 -2
- package/src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts +155 -0
- package/src/theme/ApiExplorer/Body/slice.ts +40 -1
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +43 -29
- package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +5 -1
- package/src/theme/ApiExplorer/CodeTabs/index.tsx +6 -5
- package/src/theme/ApiExplorer/ContentType/index.tsx +1 -1
- package/src/theme/ApiExplorer/FormFileUpload/index.tsx +6 -1
- package/src/theme/ApiExplorer/FormItem/index.tsx +8 -1
- package/src/theme/ApiExplorer/FormTextInput/index.tsx +10 -1
- package/src/theme/ApiExplorer/LiveEditor/index.tsx +11 -4
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx +16 -6
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx +12 -4
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +12 -4
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx +12 -3
- package/src/theme/ApiExplorer/ParamOptions/index.tsx +10 -2
- package/src/theme/ApiExplorer/ParamOptions/slice.ts +1 -1
- package/src/theme/ApiExplorer/Request/index.tsx +108 -17
- package/src/theme/ApiExplorer/Request/makeRequest.ts +106 -25
- package/src/theme/ApiExplorer/Response/index.tsx +30 -8
- package/src/theme/ApiExplorer/SchemaSelection/index.ts +13 -0
- package/src/theme/ApiExplorer/SchemaSelection/slice.ts +46 -0
- package/src/theme/ApiExplorer/SecuritySchemes/index.tsx +157 -69
- package/src/theme/ApiExplorer/Server/index.tsx +12 -4
- package/src/theme/ApiExplorer/buildPostmanRequest.ts +47 -63
- package/src/theme/ApiExplorer/index.tsx +5 -0
- package/src/theme/ApiExplorer/{persistanceMiddleware.ts → persistenceMiddleware.ts} +23 -13
- package/src/theme/ApiExplorer/storage-utils.ts +4 -4
- package/src/theme/ApiItem/Layout/index.tsx +1 -1
- package/src/theme/ApiItem/index.tsx +13 -7
- package/src/theme/ApiItem/store.ts +2 -0
- package/src/theme/ApiTabs/index.tsx +6 -1
- package/src/theme/Example/_Example.scss +11 -0
- package/src/theme/Example/index.tsx +168 -0
- package/src/theme/Markdown/index.d.ts +8 -0
- package/src/theme/ParamsDetails/index.tsx +10 -1
- package/src/theme/ParamsItem/index.tsx +38 -54
- package/src/theme/RequestSchema/index.tsx +60 -35
- package/src/theme/ResponseExamples/index.tsx +23 -3
- package/src/theme/ResponseSchema/index.tsx +73 -61
- package/src/theme/Schema/index.tsx +307 -55
- package/src/theme/SchemaItem/index.tsx +51 -33
- package/src/theme/SchemaTabs/index.tsx +19 -5
- package/src/theme/StatusCodes/index.tsx +13 -3
- package/src/theme/styles.scss +15 -0
- package/src/theme/translationIds.ts +111 -0
- package/src/theme-openapi.d.ts +7 -275
- package/src/{types.ts → types.d.ts} +9 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/theme/ApiExplorer/persistanceMiddleware.d.ts +0 -3
- package/lib/types.d.ts +0 -46
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import React from "react";
|
|
8
|
+
import React, { useCallback } from "react";
|
|
9
9
|
|
|
10
|
+
import { translate } from "@docusaurus/Translate";
|
|
11
|
+
import { setSchemaSelection } from "@theme/ApiExplorer/SchemaSelection/slice";
|
|
12
|
+
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
10
13
|
import { ClosingArrayBracket, OpeningArrayBracket } from "@theme/ArrayBrackets";
|
|
11
14
|
import Details from "@theme/Details";
|
|
12
15
|
import DiscriminatorTabs from "@theme/DiscriminatorTabs";
|
|
@@ -14,6 +17,7 @@ import Markdown from "@theme/Markdown";
|
|
|
14
17
|
import SchemaItem from "@theme/SchemaItem";
|
|
15
18
|
import SchemaTabs from "@theme/SchemaTabs";
|
|
16
19
|
import TabItem from "@theme/TabItem";
|
|
20
|
+
import { OPENAPI_SCHEMA_ITEM } from "@theme/translationIds";
|
|
17
21
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
18
22
|
import { merge } from "allof-merge";
|
|
19
23
|
import clsx from "clsx";
|
|
@@ -89,12 +93,29 @@ const Summary: React.FC<SummaryProps> = ({
|
|
|
89
93
|
{(isRequired || deprecated || nullable) && (
|
|
90
94
|
<span className="openapi-schema__divider" />
|
|
91
95
|
)}
|
|
92
|
-
{nullable &&
|
|
96
|
+
{nullable && (
|
|
97
|
+
<span className="openapi-schema__nullable">
|
|
98
|
+
{translate({
|
|
99
|
+
id: OPENAPI_SCHEMA_ITEM.NULLABLE,
|
|
100
|
+
message: "nullable",
|
|
101
|
+
})}
|
|
102
|
+
</span>
|
|
103
|
+
)}
|
|
93
104
|
{isRequired && (
|
|
94
|
-
<span className="openapi-schema__required">
|
|
105
|
+
<span className="openapi-schema__required">
|
|
106
|
+
{translate({
|
|
107
|
+
id: OPENAPI_SCHEMA_ITEM.REQUIRED,
|
|
108
|
+
message: "required",
|
|
109
|
+
})}
|
|
110
|
+
</span>
|
|
95
111
|
)}
|
|
96
112
|
{deprecated && (
|
|
97
|
-
<span className="openapi-schema__deprecated">
|
|
113
|
+
<span className="openapi-schema__deprecated">
|
|
114
|
+
{translate({
|
|
115
|
+
id: OPENAPI_SCHEMA_ITEM.DEPRECATED,
|
|
116
|
+
message: "deprecated",
|
|
117
|
+
})}
|
|
118
|
+
</span>
|
|
98
119
|
)}
|
|
99
120
|
</span>
|
|
100
121
|
</summary>
|
|
@@ -105,31 +126,102 @@ const Summary: React.FC<SummaryProps> = ({
|
|
|
105
126
|
interface SchemaProps {
|
|
106
127
|
schema: SchemaObject;
|
|
107
128
|
schemaType: "request" | "response";
|
|
129
|
+
/**
|
|
130
|
+
* Optional path identifier for tracking anyOf/oneOf selections.
|
|
131
|
+
* When provided, tab selections will be dispatched to Redux state
|
|
132
|
+
* to enable dynamic body example updates.
|
|
133
|
+
*/
|
|
134
|
+
schemaPath?: string;
|
|
108
135
|
}
|
|
109
136
|
|
|
110
|
-
const AnyOneOf: React.FC<SchemaProps> = ({
|
|
111
|
-
|
|
137
|
+
const AnyOneOf: React.FC<SchemaProps> = ({
|
|
138
|
+
schema,
|
|
139
|
+
schemaType,
|
|
140
|
+
schemaPath,
|
|
141
|
+
}) => {
|
|
142
|
+
const key = schema.oneOf ? "oneOf" : "anyOf";
|
|
143
|
+
const type = schema.oneOf
|
|
144
|
+
? translate({ id: OPENAPI_SCHEMA_ITEM.ONE_OF, message: "oneOf" })
|
|
145
|
+
: translate({ id: OPENAPI_SCHEMA_ITEM.ANY_OF, message: "anyOf" });
|
|
146
|
+
|
|
147
|
+
// Generate a unique ID for this anyOf/oneOf to prevent tab value collisions
|
|
148
|
+
const uniqueId = React.useMemo(
|
|
149
|
+
() => Math.random().toString(36).substring(7),
|
|
150
|
+
[]
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// Try to get Redux dispatch - will be undefined if not inside a Provider
|
|
154
|
+
let dispatch: ReturnType<typeof useTypedDispatch> | undefined;
|
|
155
|
+
try {
|
|
156
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
157
|
+
dispatch = useTypedDispatch();
|
|
158
|
+
} catch {
|
|
159
|
+
// Not inside a Redux Provider, which is fine for response schemas
|
|
160
|
+
dispatch = undefined;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Handle tab change - dispatch to Redux if schemaPath is provided
|
|
164
|
+
const handleTabChange = useCallback(
|
|
165
|
+
(index: number) => {
|
|
166
|
+
if (schemaPath && dispatch) {
|
|
167
|
+
dispatch(setSchemaSelection({ path: schemaPath, index }));
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
[schemaPath, dispatch]
|
|
171
|
+
);
|
|
172
|
+
|
|
112
173
|
return (
|
|
113
174
|
<>
|
|
114
175
|
<span className="badge badge--info" style={{ marginBottom: "1rem" }}>
|
|
115
176
|
{type}
|
|
116
177
|
</span>
|
|
117
|
-
<SchemaTabs
|
|
118
|
-
{schema
|
|
119
|
-
|
|
178
|
+
<SchemaTabs
|
|
179
|
+
groupId={`schema-${uniqueId}`}
|
|
180
|
+
lazy
|
|
181
|
+
onChange={handleTabChange}
|
|
182
|
+
>
|
|
183
|
+
{schema[key]?.map((anyOneSchema: any, index: number) => {
|
|
184
|
+
// Use getSchemaName to include format info (e.g., "string<date-time>")
|
|
185
|
+
const computedSchemaName = getSchemaName(anyOneSchema);
|
|
186
|
+
|
|
187
|
+
// Determine label for the tab
|
|
188
|
+
// Prefer explicit title, then computed schema name, then raw type
|
|
189
|
+
let label =
|
|
190
|
+
anyOneSchema.title || computedSchemaName || anyOneSchema.type;
|
|
191
|
+
if (!label) {
|
|
192
|
+
if (anyOneSchema.oneOf) {
|
|
193
|
+
label = translate({
|
|
194
|
+
id: OPENAPI_SCHEMA_ITEM.ONE_OF,
|
|
195
|
+
message: "oneOf",
|
|
196
|
+
});
|
|
197
|
+
} else if (anyOneSchema.anyOf) {
|
|
198
|
+
label = translate({
|
|
199
|
+
id: OPENAPI_SCHEMA_ITEM.ANY_OF,
|
|
200
|
+
message: "anyOf",
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
label = `Option ${index + 1}`;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Build the nested schemaPath for child anyOf/oneOf
|
|
208
|
+
const childSchemaPath = schemaPath
|
|
209
|
+
? `${schemaPath}.${index}`
|
|
210
|
+
: undefined;
|
|
211
|
+
|
|
120
212
|
return (
|
|
121
213
|
// @ts-ignore
|
|
122
214
|
<TabItem
|
|
123
215
|
key={index}
|
|
124
216
|
label={label}
|
|
125
|
-
value={`${index}-item
|
|
217
|
+
value={`${uniqueId}-${index}-item`}
|
|
126
218
|
>
|
|
127
219
|
{/* Handle primitive types directly */}
|
|
128
220
|
{(isPrimitive(anyOneSchema) || anyOneSchema.const) && (
|
|
129
221
|
<SchemaItem
|
|
130
222
|
collapsible={false}
|
|
131
223
|
name={undefined}
|
|
132
|
-
schemaName={
|
|
224
|
+
schemaName={computedSchemaName}
|
|
133
225
|
qualifierMessage={getQualifierMessage(anyOneSchema)}
|
|
134
226
|
schema={anyOneSchema}
|
|
135
227
|
discriminator={false}
|
|
@@ -146,7 +238,7 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
146
238
|
<SchemaItem
|
|
147
239
|
collapsible={false}
|
|
148
240
|
name={undefined}
|
|
149
|
-
schemaName={
|
|
241
|
+
schemaName={computedSchemaName}
|
|
150
242
|
qualifierMessage={getQualifierMessage(anyOneSchema)}
|
|
151
243
|
schema={anyOneSchema}
|
|
152
244
|
discriminator={false}
|
|
@@ -155,20 +247,42 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
155
247
|
)}
|
|
156
248
|
|
|
157
249
|
{/* Handle actual object types with properties or nested schemas */}
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
250
|
+
{/* Note: In OpenAPI, properties implies type: object even if not explicitly set */}
|
|
251
|
+
{(anyOneSchema.type === "object" || !anyOneSchema.type) &&
|
|
252
|
+
anyOneSchema.properties && (
|
|
253
|
+
<Properties
|
|
254
|
+
schema={anyOneSchema}
|
|
255
|
+
schemaType={schemaType}
|
|
256
|
+
schemaPath={childSchemaPath}
|
|
257
|
+
/>
|
|
258
|
+
)}
|
|
161
259
|
{anyOneSchema.allOf && (
|
|
162
|
-
<SchemaNode
|
|
260
|
+
<SchemaNode
|
|
261
|
+
schema={anyOneSchema}
|
|
262
|
+
schemaType={schemaType}
|
|
263
|
+
schemaPath={childSchemaPath}
|
|
264
|
+
/>
|
|
163
265
|
)}
|
|
164
266
|
{anyOneSchema.oneOf && (
|
|
165
|
-
<SchemaNode
|
|
267
|
+
<SchemaNode
|
|
268
|
+
schema={anyOneSchema}
|
|
269
|
+
schemaType={schemaType}
|
|
270
|
+
schemaPath={childSchemaPath}
|
|
271
|
+
/>
|
|
166
272
|
)}
|
|
167
273
|
{anyOneSchema.anyOf && (
|
|
168
|
-
<SchemaNode
|
|
274
|
+
<SchemaNode
|
|
275
|
+
schema={anyOneSchema}
|
|
276
|
+
schemaType={schemaType}
|
|
277
|
+
schemaPath={childSchemaPath}
|
|
278
|
+
/>
|
|
169
279
|
)}
|
|
170
280
|
{anyOneSchema.items && (
|
|
171
|
-
<Items
|
|
281
|
+
<Items
|
|
282
|
+
schema={anyOneSchema}
|
|
283
|
+
schemaType={schemaType}
|
|
284
|
+
schemaPath={childSchemaPath}
|
|
285
|
+
/>
|
|
172
286
|
)}
|
|
173
287
|
</TabItem>
|
|
174
288
|
);
|
|
@@ -178,7 +292,11 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
178
292
|
);
|
|
179
293
|
};
|
|
180
294
|
|
|
181
|
-
const Properties: React.FC<SchemaProps> = ({
|
|
295
|
+
const Properties: React.FC<SchemaProps> = ({
|
|
296
|
+
schema,
|
|
297
|
+
schemaType,
|
|
298
|
+
schemaPath,
|
|
299
|
+
}) => {
|
|
182
300
|
const discriminator = schema.discriminator;
|
|
183
301
|
if (discriminator && !discriminator.mapping) {
|
|
184
302
|
const anyOneOf = schema.oneOf ?? schema.anyOf ?? {};
|
|
@@ -222,6 +340,7 @@ const Properties: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
222
340
|
}
|
|
223
341
|
discriminator={discriminator}
|
|
224
342
|
schemaType={schemaType}
|
|
343
|
+
schemaPath={schemaPath ? `${schemaPath}.${key}` : undefined}
|
|
225
344
|
/>
|
|
226
345
|
)
|
|
227
346
|
)}
|
|
@@ -254,7 +373,12 @@ const PropertyDiscriminator: React.FC<SchemaEdgeProps> = ({
|
|
|
254
373
|
)}
|
|
255
374
|
{required && <span className="openapi-schema__divider"></span>}
|
|
256
375
|
{required && (
|
|
257
|
-
<span className="openapi-schema__required">
|
|
376
|
+
<span className="openapi-schema__required">
|
|
377
|
+
{translate({
|
|
378
|
+
id: OPENAPI_SCHEMA_ITEM.REQUIRED,
|
|
379
|
+
message: "required",
|
|
380
|
+
})}
|
|
381
|
+
</span>
|
|
258
382
|
)}
|
|
259
383
|
</span>
|
|
260
384
|
<div style={{ marginLeft: "1rem" }}>
|
|
@@ -474,6 +598,7 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
474
598
|
schema,
|
|
475
599
|
required,
|
|
476
600
|
schemaType,
|
|
601
|
+
schemaPath,
|
|
477
602
|
}) => {
|
|
478
603
|
return (
|
|
479
604
|
<SchemaItem collapsible={true}>
|
|
@@ -493,7 +618,11 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
493
618
|
{getQualifierMessage(schema) && (
|
|
494
619
|
<MarkdownWrapper text={getQualifierMessage(schema)} />
|
|
495
620
|
)}
|
|
496
|
-
<SchemaNode
|
|
621
|
+
<SchemaNode
|
|
622
|
+
schema={schema}
|
|
623
|
+
schemaType={schemaType}
|
|
624
|
+
schemaPath={schemaPath}
|
|
625
|
+
/>
|
|
497
626
|
</div>
|
|
498
627
|
</Details>
|
|
499
628
|
</SchemaItem>
|
|
@@ -503,7 +632,8 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
503
632
|
const Items: React.FC<{
|
|
504
633
|
schema: any;
|
|
505
634
|
schemaType: "request" | "response";
|
|
506
|
-
|
|
635
|
+
schemaPath?: string;
|
|
636
|
+
}> = ({ schema, schemaType, schemaPath }) => {
|
|
507
637
|
// Process schema.items to handle allOf merging
|
|
508
638
|
let itemsSchema = schema.items;
|
|
509
639
|
if (schema.items?.allOf) {
|
|
@@ -515,15 +645,26 @@ const Items: React.FC<{
|
|
|
515
645
|
const hasProperties = itemsSchema?.properties;
|
|
516
646
|
const hasAdditionalProperties = itemsSchema?.additionalProperties;
|
|
517
647
|
|
|
648
|
+
// Build the items schema path
|
|
649
|
+
const itemsSchemaPath = schemaPath ? `${schemaPath}.items` : undefined;
|
|
650
|
+
|
|
518
651
|
if (hasOneOfAnyOf || hasProperties || hasAdditionalProperties) {
|
|
519
652
|
return (
|
|
520
653
|
<>
|
|
521
654
|
<OpeningArrayBracket />
|
|
522
655
|
{hasOneOfAnyOf && (
|
|
523
|
-
<AnyOneOf
|
|
656
|
+
<AnyOneOf
|
|
657
|
+
schema={itemsSchema}
|
|
658
|
+
schemaType={schemaType}
|
|
659
|
+
schemaPath={itemsSchemaPath}
|
|
660
|
+
/>
|
|
524
661
|
)}
|
|
525
662
|
{hasProperties && (
|
|
526
|
-
<Properties
|
|
663
|
+
<Properties
|
|
664
|
+
schema={itemsSchema}
|
|
665
|
+
schemaType={schemaType}
|
|
666
|
+
schemaPath={itemsSchemaPath}
|
|
667
|
+
/>
|
|
527
668
|
)}
|
|
528
669
|
{hasAdditionalProperties && (
|
|
529
670
|
<AdditionalProperties schema={itemsSchema} schemaType={schemaType} />
|
|
@@ -588,6 +729,7 @@ interface SchemaEdgeProps {
|
|
|
588
729
|
nullable?: boolean | undefined;
|
|
589
730
|
discriminator?: any;
|
|
590
731
|
schemaType: "request" | "response";
|
|
732
|
+
schemaPath?: string;
|
|
591
733
|
}
|
|
592
734
|
|
|
593
735
|
const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
@@ -596,6 +738,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
596
738
|
required,
|
|
597
739
|
discriminator,
|
|
598
740
|
schemaType,
|
|
741
|
+
schemaPath,
|
|
599
742
|
}) => {
|
|
600
743
|
if (
|
|
601
744
|
(schemaType === "request" && schema.readOnly) ||
|
|
@@ -629,6 +772,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
629
772
|
required={required}
|
|
630
773
|
schema={schema}
|
|
631
774
|
nullable={schema.nullable}
|
|
775
|
+
schemaPath={schemaPath}
|
|
632
776
|
/>
|
|
633
777
|
);
|
|
634
778
|
}
|
|
@@ -642,6 +786,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
642
786
|
required={required}
|
|
643
787
|
schema={schema}
|
|
644
788
|
nullable={schema.nullable}
|
|
789
|
+
schemaPath={schemaPath}
|
|
645
790
|
/>
|
|
646
791
|
);
|
|
647
792
|
}
|
|
@@ -655,6 +800,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
655
800
|
required={required}
|
|
656
801
|
schema={schema}
|
|
657
802
|
nullable={schema.nullable}
|
|
803
|
+
schemaPath={schemaPath}
|
|
658
804
|
/>
|
|
659
805
|
);
|
|
660
806
|
}
|
|
@@ -668,11 +814,12 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
668
814
|
nullable={schema.nullable}
|
|
669
815
|
schema={schema}
|
|
670
816
|
schemaType={schemaType}
|
|
817
|
+
schemaPath={schemaPath}
|
|
671
818
|
/>
|
|
672
819
|
);
|
|
673
820
|
}
|
|
674
821
|
|
|
675
|
-
if (schema.items?.anyOf || schema.items?.oneOf) {
|
|
822
|
+
if (schema.items?.anyOf || schema.items?.oneOf || schema.items?.allOf) {
|
|
676
823
|
return (
|
|
677
824
|
<SchemaNodeDetails
|
|
678
825
|
name={name}
|
|
@@ -681,6 +828,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
681
828
|
nullable={schema.nullable}
|
|
682
829
|
schema={schema}
|
|
683
830
|
schemaType={schemaType}
|
|
831
|
+
schemaPath={schemaPath}
|
|
684
832
|
/>
|
|
685
833
|
);
|
|
686
834
|
}
|
|
@@ -725,13 +873,12 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
725
873
|
name={name}
|
|
726
874
|
schemaName={mergedSchemaName}
|
|
727
875
|
required={
|
|
728
|
-
Array.isArray(
|
|
729
|
-
? mergedSchemas.required.includes(name)
|
|
730
|
-
: mergedSchemas.required
|
|
876
|
+
Array.isArray(required) ? required.includes(name) : required
|
|
731
877
|
}
|
|
732
878
|
nullable={mergedSchemas.nullable}
|
|
733
879
|
schema={mergedSchemas}
|
|
734
880
|
schemaType={schemaType}
|
|
881
|
+
schemaPath={schemaPath}
|
|
735
882
|
/>
|
|
736
883
|
);
|
|
737
884
|
}
|
|
@@ -742,30 +889,30 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
742
889
|
name={name}
|
|
743
890
|
schemaName={mergedSchemaName}
|
|
744
891
|
required={
|
|
745
|
-
Array.isArray(
|
|
746
|
-
? mergedSchemas.required.includes(name)
|
|
747
|
-
: mergedSchemas.required
|
|
892
|
+
Array.isArray(required) ? required.includes(name) : required
|
|
748
893
|
}
|
|
749
894
|
nullable={mergedSchemas.nullable}
|
|
750
895
|
schema={mergedSchemas}
|
|
751
896
|
schemaType={schemaType}
|
|
897
|
+
schemaPath={schemaPath}
|
|
752
898
|
/>
|
|
753
899
|
);
|
|
754
900
|
}
|
|
755
901
|
|
|
756
902
|
if (mergedSchemas.items?.properties) {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
?
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
903
|
+
return (
|
|
904
|
+
<SchemaNodeDetails
|
|
905
|
+
name={name}
|
|
906
|
+
schemaName={mergedSchemaName}
|
|
907
|
+
required={
|
|
908
|
+
Array.isArray(required) ? required.includes(name) : required
|
|
909
|
+
}
|
|
910
|
+
nullable={mergedSchemas.nullable}
|
|
911
|
+
schema={mergedSchemas}
|
|
912
|
+
schemaType={schemaType}
|
|
913
|
+
schemaPath={schemaPath}
|
|
914
|
+
/>
|
|
915
|
+
);
|
|
769
916
|
}
|
|
770
917
|
|
|
771
918
|
return (
|
|
@@ -798,24 +945,51 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
798
945
|
|
|
799
946
|
function renderChildren(
|
|
800
947
|
schema: SchemaObject,
|
|
801
|
-
schemaType: "request" | "response"
|
|
948
|
+
schemaType: "request" | "response",
|
|
949
|
+
schemaPath?: string
|
|
802
950
|
) {
|
|
803
951
|
return (
|
|
804
952
|
<>
|
|
805
|
-
{schema.oneOf &&
|
|
806
|
-
|
|
953
|
+
{schema.oneOf && (
|
|
954
|
+
<AnyOneOf
|
|
955
|
+
schema={schema}
|
|
956
|
+
schemaType={schemaType}
|
|
957
|
+
schemaPath={schemaPath}
|
|
958
|
+
/>
|
|
959
|
+
)}
|
|
960
|
+
{schema.anyOf && (
|
|
961
|
+
<AnyOneOf
|
|
962
|
+
schema={schema}
|
|
963
|
+
schemaType={schemaType}
|
|
964
|
+
schemaPath={schemaPath}
|
|
965
|
+
/>
|
|
966
|
+
)}
|
|
807
967
|
{schema.properties && (
|
|
808
|
-
<Properties
|
|
968
|
+
<Properties
|
|
969
|
+
schema={schema}
|
|
970
|
+
schemaType={schemaType}
|
|
971
|
+
schemaPath={schemaPath}
|
|
972
|
+
/>
|
|
809
973
|
)}
|
|
810
974
|
{schema.additionalProperties && (
|
|
811
975
|
<AdditionalProperties schema={schema} schemaType={schemaType} />
|
|
812
976
|
)}
|
|
813
|
-
{schema.items &&
|
|
977
|
+
{schema.items && (
|
|
978
|
+
<Items
|
|
979
|
+
schema={schema}
|
|
980
|
+
schemaType={schemaType}
|
|
981
|
+
schemaPath={schemaPath}
|
|
982
|
+
/>
|
|
983
|
+
)}
|
|
814
984
|
</>
|
|
815
985
|
);
|
|
816
986
|
}
|
|
817
987
|
|
|
818
|
-
const SchemaNode: React.FC<SchemaProps> = ({
|
|
988
|
+
const SchemaNode: React.FC<SchemaProps> = ({
|
|
989
|
+
schema,
|
|
990
|
+
schemaType,
|
|
991
|
+
schemaPath,
|
|
992
|
+
}) => {
|
|
819
993
|
if (
|
|
820
994
|
(schemaType === "request" && schema.readOnly) ||
|
|
821
995
|
(schemaType === "response" && schema.writeOnly)
|
|
@@ -836,6 +1010,63 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
836
1010
|
|
|
837
1011
|
// Handle allOf, oneOf, anyOf without discriminators
|
|
838
1012
|
if (schema.allOf) {
|
|
1013
|
+
// Check if allOf contains multiple oneOf/anyOf items that should be rendered separately
|
|
1014
|
+
const oneOfItems = schema.allOf.filter(
|
|
1015
|
+
(item: any) => item.oneOf || item.anyOf
|
|
1016
|
+
);
|
|
1017
|
+
const hasMultipleChoices = oneOfItems.length > 1;
|
|
1018
|
+
|
|
1019
|
+
if (hasMultipleChoices) {
|
|
1020
|
+
// Render each oneOf/anyOf constraint first, then shared properties
|
|
1021
|
+
const mergedSchemas = mergeAllOf(schema) as SchemaObject;
|
|
1022
|
+
|
|
1023
|
+
if (
|
|
1024
|
+
(schemaType === "request" && mergedSchemas.readOnly) ||
|
|
1025
|
+
(schemaType === "response" && mergedSchemas.writeOnly)
|
|
1026
|
+
) {
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
return (
|
|
1031
|
+
<div>
|
|
1032
|
+
{/* Render all oneOf/anyOf constraints first */}
|
|
1033
|
+
{schema.allOf.map((item: any, index: number) => {
|
|
1034
|
+
if (item.oneOf || item.anyOf) {
|
|
1035
|
+
const itemSchemaPath = schemaPath
|
|
1036
|
+
? `${schemaPath}.allOf.${index}`
|
|
1037
|
+
: undefined;
|
|
1038
|
+
return (
|
|
1039
|
+
<div key={index}>
|
|
1040
|
+
<AnyOneOf
|
|
1041
|
+
schema={item}
|
|
1042
|
+
schemaType={schemaType}
|
|
1043
|
+
schemaPath={itemSchemaPath}
|
|
1044
|
+
/>
|
|
1045
|
+
</div>
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
return null;
|
|
1049
|
+
})}
|
|
1050
|
+
{/* Then render shared properties from the merge */}
|
|
1051
|
+
{mergedSchemas.properties && (
|
|
1052
|
+
<Properties
|
|
1053
|
+
schema={mergedSchemas}
|
|
1054
|
+
schemaType={schemaType}
|
|
1055
|
+
schemaPath={schemaPath}
|
|
1056
|
+
/>
|
|
1057
|
+
)}
|
|
1058
|
+
{mergedSchemas.items && (
|
|
1059
|
+
<Items
|
|
1060
|
+
schema={mergedSchemas}
|
|
1061
|
+
schemaType={schemaType}
|
|
1062
|
+
schemaPath={schemaPath}
|
|
1063
|
+
/>
|
|
1064
|
+
)}
|
|
1065
|
+
</div>
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// For other allOf cases, use standard merge behavior
|
|
839
1070
|
const mergedSchemas = mergeAllOf(schema) as SchemaObject;
|
|
840
1071
|
|
|
841
1072
|
if (
|
|
@@ -848,16 +1079,32 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
848
1079
|
return (
|
|
849
1080
|
<div>
|
|
850
1081
|
{mergedSchemas.oneOf && (
|
|
851
|
-
<AnyOneOf
|
|
1082
|
+
<AnyOneOf
|
|
1083
|
+
schema={mergedSchemas}
|
|
1084
|
+
schemaType={schemaType}
|
|
1085
|
+
schemaPath={schemaPath}
|
|
1086
|
+
/>
|
|
852
1087
|
)}
|
|
853
1088
|
{mergedSchemas.anyOf && (
|
|
854
|
-
<AnyOneOf
|
|
1089
|
+
<AnyOneOf
|
|
1090
|
+
schema={mergedSchemas}
|
|
1091
|
+
schemaType={schemaType}
|
|
1092
|
+
schemaPath={schemaPath}
|
|
1093
|
+
/>
|
|
855
1094
|
)}
|
|
856
1095
|
{mergedSchemas.properties && (
|
|
857
|
-
<Properties
|
|
1096
|
+
<Properties
|
|
1097
|
+
schema={mergedSchemas}
|
|
1098
|
+
schemaType={schemaType}
|
|
1099
|
+
schemaPath={schemaPath}
|
|
1100
|
+
/>
|
|
858
1101
|
)}
|
|
859
1102
|
{mergedSchemas.items && (
|
|
860
|
-
<Items
|
|
1103
|
+
<Items
|
|
1104
|
+
schema={mergedSchemas}
|
|
1105
|
+
schemaType={schemaType}
|
|
1106
|
+
schemaPath={schemaPath}
|
|
1107
|
+
/>
|
|
861
1108
|
)}
|
|
862
1109
|
</div>
|
|
863
1110
|
);
|
|
@@ -888,7 +1135,7 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
888
1135
|
);
|
|
889
1136
|
}
|
|
890
1137
|
|
|
891
|
-
return renderChildren(schema, schemaType);
|
|
1138
|
+
return renderChildren(schema, schemaType, schemaPath);
|
|
892
1139
|
};
|
|
893
1140
|
|
|
894
1141
|
export default SchemaNode;
|
|
@@ -904,5 +1151,10 @@ const PRIMITIVE_TYPES: Record<PrimitiveSchemaType, true> = {
|
|
|
904
1151
|
} as const;
|
|
905
1152
|
|
|
906
1153
|
const isPrimitive = (schema: SchemaObject) => {
|
|
1154
|
+
// Enum-only schemas (without explicit type) should be treated as primitives
|
|
1155
|
+
// This is valid JSON Schema where enum values define the constraints
|
|
1156
|
+
if (schema.enum && !schema.type) {
|
|
1157
|
+
return true;
|
|
1158
|
+
}
|
|
907
1159
|
return PRIMITIVE_TYPES[schema.type as PrimitiveSchemaType];
|
|
908
1160
|
};
|