docusaurus-theme-openapi-docs 4.6.0 → 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 +5 -0
- package/lib/theme/ApiExplorer/Body/index.js +263 -128
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.d.ts +13 -0
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.js +133 -0
- 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/persistenceMiddleware.d.ts +2 -0
- package/lib/theme/ApiItem/hooks.d.ts +1 -0
- package/lib/theme/ApiItem/index.js +1 -0
- package/lib/theme/ApiItem/store.d.ts +6 -0
- package/lib/theme/ApiItem/store.js +6 -2
- package/lib/theme/RequestSchema/index.js +58 -52
- package/lib/theme/Schema/index.d.ts +6 -0
- package/lib/theme/Schema/index.js +135 -9
- package/lib/theme/SchemaTabs/index.d.ts +8 -1
- package/lib/theme/SchemaTabs/index.js +10 -1
- package/lib/theme/StatusCodes/index.d.ts +1 -1
- package/lib/theme/styles.scss +10 -0
- package/package.json +3 -3
- package/src/markdown/schema.ts +6 -0
- package/src/theme/ApiExplorer/Body/index.tsx +206 -122
- package/src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts +155 -0
- package/{lib/types.js → src/theme/ApiExplorer/SchemaSelection/index.ts} +7 -2
- package/src/theme/ApiExplorer/SchemaSelection/slice.ts +46 -0
- package/src/theme/ApiItem/index.tsx +1 -0
- package/src/theme/ApiItem/store.ts +2 -0
- package/src/theme/RequestSchema/index.tsx +49 -39
- package/src/theme/Schema/index.tsx +184 -27
- package/src/theme/SchemaTabs/index.tsx +15 -4
- package/src/theme/StatusCodes/index.tsx +1 -2
- package/src/theme/styles.scss +10 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +0 -54
- /package/src/{types.ts → types.d.ts} +0 -0
|
@@ -45,7 +45,7 @@ const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
|
|
|
45
45
|
|
|
46
46
|
if (mimeTypes.length > 1) {
|
|
47
47
|
return (
|
|
48
|
-
<MimeTabs className="openapi-tabs__mime" schemaType="request">
|
|
48
|
+
<MimeTabs className="openapi-tabs__mime" schemaType="request" lazy>
|
|
49
49
|
{mimeTypes.map((mimeType) => {
|
|
50
50
|
const firstBody = body.content![mimeType].schema;
|
|
51
51
|
if (
|
|
@@ -58,43 +58,49 @@ const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
|
|
|
58
58
|
return (
|
|
59
59
|
// @ts-ignore
|
|
60
60
|
<TabItem key={mimeType} label={mimeType} value={mimeType}>
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
61
|
+
<div style={{ marginTop: "1rem" }}>
|
|
62
|
+
<Details
|
|
63
|
+
className="openapi-markdown__details mime"
|
|
64
|
+
data-collapsed={false}
|
|
65
|
+
open={true}
|
|
66
|
+
style={style}
|
|
67
|
+
summary={
|
|
68
|
+
<>
|
|
69
|
+
<summary>
|
|
70
|
+
<h3 className="openapi-markdown__details-summary-header-body">
|
|
71
|
+
{translate({
|
|
72
|
+
id: OPENAPI_REQUEST.BODY_TITLE,
|
|
73
|
+
message: title,
|
|
74
|
+
})}
|
|
75
|
+
{body.required === true && (
|
|
76
|
+
<span className="openapi-schema__required">
|
|
77
|
+
{translate({
|
|
78
|
+
id: OPENAPI_SCHEMA_ITEM.REQUIRED,
|
|
79
|
+
message: "required",
|
|
80
|
+
})}
|
|
81
|
+
</span>
|
|
82
|
+
)}
|
|
83
|
+
</h3>
|
|
84
|
+
</summary>
|
|
85
|
+
</>
|
|
86
|
+
}
|
|
87
|
+
>
|
|
88
|
+
<div style={{ textAlign: "left", marginLeft: "1rem" }}>
|
|
89
|
+
{body.description && (
|
|
90
|
+
<div style={{ marginTop: "1rem", marginBottom: "1rem" }}>
|
|
91
|
+
<Markdown>{body.description}</Markdown>
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
<ul style={{ marginLeft: "1rem" }}>
|
|
96
|
+
<SchemaNode
|
|
97
|
+
schema={firstBody}
|
|
98
|
+
schemaType="request"
|
|
99
|
+
schemaPath="requestBody"
|
|
100
|
+
/>
|
|
101
|
+
</ul>
|
|
102
|
+
</Details>
|
|
103
|
+
</div>
|
|
98
104
|
</TabItem>
|
|
99
105
|
);
|
|
100
106
|
})}
|
|
@@ -151,7 +157,11 @@ const RequestSchemaComponent: React.FC<Props> = ({ title, body, style }) => {
|
|
|
151
157
|
)}
|
|
152
158
|
</div>
|
|
153
159
|
<ul style={{ marginLeft: "1rem" }}>
|
|
154
|
-
<SchemaNode
|
|
160
|
+
<SchemaNode
|
|
161
|
+
schema={firstBody}
|
|
162
|
+
schemaType="request"
|
|
163
|
+
schemaPath="requestBody"
|
|
164
|
+
/>
|
|
155
165
|
</ul>
|
|
156
166
|
</Details>
|
|
157
167
|
</TabItem>
|
|
@@ -5,9 +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
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
|
+
import { setSchemaSelection } from "@theme/ApiExplorer/SchemaSelection/slice";
|
|
12
|
+
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
11
13
|
import { ClosingArrayBracket, OpeningArrayBracket } from "@theme/ArrayBrackets";
|
|
12
14
|
import Details from "@theme/Details";
|
|
13
15
|
import DiscriminatorTabs from "@theme/DiscriminatorTabs";
|
|
@@ -124,9 +126,19 @@ const Summary: React.FC<SummaryProps> = ({
|
|
|
124
126
|
interface SchemaProps {
|
|
125
127
|
schema: SchemaObject;
|
|
126
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;
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
const AnyOneOf: React.FC<SchemaProps> = ({
|
|
137
|
+
const AnyOneOf: React.FC<SchemaProps> = ({
|
|
138
|
+
schema,
|
|
139
|
+
schemaType,
|
|
140
|
+
schemaPath,
|
|
141
|
+
}) => {
|
|
130
142
|
const key = schema.oneOf ? "oneOf" : "anyOf";
|
|
131
143
|
const type = schema.oneOf
|
|
132
144
|
? translate({ id: OPENAPI_SCHEMA_ITEM.ONE_OF, message: "oneOf" })
|
|
@@ -138,12 +150,36 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
138
150
|
[]
|
|
139
151
|
);
|
|
140
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
|
+
|
|
141
173
|
return (
|
|
142
174
|
<>
|
|
143
175
|
<span className="badge badge--info" style={{ marginBottom: "1rem" }}>
|
|
144
176
|
{type}
|
|
145
177
|
</span>
|
|
146
|
-
<SchemaTabs
|
|
178
|
+
<SchemaTabs
|
|
179
|
+
groupId={`schema-${uniqueId}`}
|
|
180
|
+
lazy
|
|
181
|
+
onChange={handleTabChange}
|
|
182
|
+
>
|
|
147
183
|
{schema[key]?.map((anyOneSchema: any, index: number) => {
|
|
148
184
|
// Use getSchemaName to include format info (e.g., "string<date-time>")
|
|
149
185
|
const computedSchemaName = getSchemaName(anyOneSchema);
|
|
@@ -167,6 +203,12 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
167
203
|
label = `Option ${index + 1}`;
|
|
168
204
|
}
|
|
169
205
|
}
|
|
206
|
+
|
|
207
|
+
// Build the nested schemaPath for child anyOf/oneOf
|
|
208
|
+
const childSchemaPath = schemaPath
|
|
209
|
+
? `${schemaPath}.${index}`
|
|
210
|
+
: undefined;
|
|
211
|
+
|
|
170
212
|
return (
|
|
171
213
|
// @ts-ignore
|
|
172
214
|
<TabItem
|
|
@@ -208,19 +250,39 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
208
250
|
{/* Note: In OpenAPI, properties implies type: object even if not explicitly set */}
|
|
209
251
|
{(anyOneSchema.type === "object" || !anyOneSchema.type) &&
|
|
210
252
|
anyOneSchema.properties && (
|
|
211
|
-
<Properties
|
|
253
|
+
<Properties
|
|
254
|
+
schema={anyOneSchema}
|
|
255
|
+
schemaType={schemaType}
|
|
256
|
+
schemaPath={childSchemaPath}
|
|
257
|
+
/>
|
|
212
258
|
)}
|
|
213
259
|
{anyOneSchema.allOf && (
|
|
214
|
-
<SchemaNode
|
|
260
|
+
<SchemaNode
|
|
261
|
+
schema={anyOneSchema}
|
|
262
|
+
schemaType={schemaType}
|
|
263
|
+
schemaPath={childSchemaPath}
|
|
264
|
+
/>
|
|
215
265
|
)}
|
|
216
266
|
{anyOneSchema.oneOf && (
|
|
217
|
-
<SchemaNode
|
|
267
|
+
<SchemaNode
|
|
268
|
+
schema={anyOneSchema}
|
|
269
|
+
schemaType={schemaType}
|
|
270
|
+
schemaPath={childSchemaPath}
|
|
271
|
+
/>
|
|
218
272
|
)}
|
|
219
273
|
{anyOneSchema.anyOf && (
|
|
220
|
-
<SchemaNode
|
|
274
|
+
<SchemaNode
|
|
275
|
+
schema={anyOneSchema}
|
|
276
|
+
schemaType={schemaType}
|
|
277
|
+
schemaPath={childSchemaPath}
|
|
278
|
+
/>
|
|
221
279
|
)}
|
|
222
280
|
{anyOneSchema.items && (
|
|
223
|
-
<Items
|
|
281
|
+
<Items
|
|
282
|
+
schema={anyOneSchema}
|
|
283
|
+
schemaType={schemaType}
|
|
284
|
+
schemaPath={childSchemaPath}
|
|
285
|
+
/>
|
|
224
286
|
)}
|
|
225
287
|
</TabItem>
|
|
226
288
|
);
|
|
@@ -230,7 +292,11 @@ const AnyOneOf: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
230
292
|
);
|
|
231
293
|
};
|
|
232
294
|
|
|
233
|
-
const Properties: React.FC<SchemaProps> = ({
|
|
295
|
+
const Properties: React.FC<SchemaProps> = ({
|
|
296
|
+
schema,
|
|
297
|
+
schemaType,
|
|
298
|
+
schemaPath,
|
|
299
|
+
}) => {
|
|
234
300
|
const discriminator = schema.discriminator;
|
|
235
301
|
if (discriminator && !discriminator.mapping) {
|
|
236
302
|
const anyOneOf = schema.oneOf ?? schema.anyOf ?? {};
|
|
@@ -274,6 +340,7 @@ const Properties: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
274
340
|
}
|
|
275
341
|
discriminator={discriminator}
|
|
276
342
|
schemaType={schemaType}
|
|
343
|
+
schemaPath={schemaPath ? `${schemaPath}.${key}` : undefined}
|
|
277
344
|
/>
|
|
278
345
|
)
|
|
279
346
|
)}
|
|
@@ -531,6 +598,7 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
531
598
|
schema,
|
|
532
599
|
required,
|
|
533
600
|
schemaType,
|
|
601
|
+
schemaPath,
|
|
534
602
|
}) => {
|
|
535
603
|
return (
|
|
536
604
|
<SchemaItem collapsible={true}>
|
|
@@ -550,7 +618,11 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
550
618
|
{getQualifierMessage(schema) && (
|
|
551
619
|
<MarkdownWrapper text={getQualifierMessage(schema)} />
|
|
552
620
|
)}
|
|
553
|
-
<SchemaNode
|
|
621
|
+
<SchemaNode
|
|
622
|
+
schema={schema}
|
|
623
|
+
schemaType={schemaType}
|
|
624
|
+
schemaPath={schemaPath}
|
|
625
|
+
/>
|
|
554
626
|
</div>
|
|
555
627
|
</Details>
|
|
556
628
|
</SchemaItem>
|
|
@@ -560,7 +632,8 @@ const SchemaNodeDetails: React.FC<SchemaEdgeProps> = ({
|
|
|
560
632
|
const Items: React.FC<{
|
|
561
633
|
schema: any;
|
|
562
634
|
schemaType: "request" | "response";
|
|
563
|
-
|
|
635
|
+
schemaPath?: string;
|
|
636
|
+
}> = ({ schema, schemaType, schemaPath }) => {
|
|
564
637
|
// Process schema.items to handle allOf merging
|
|
565
638
|
let itemsSchema = schema.items;
|
|
566
639
|
if (schema.items?.allOf) {
|
|
@@ -572,15 +645,26 @@ const Items: React.FC<{
|
|
|
572
645
|
const hasProperties = itemsSchema?.properties;
|
|
573
646
|
const hasAdditionalProperties = itemsSchema?.additionalProperties;
|
|
574
647
|
|
|
648
|
+
// Build the items schema path
|
|
649
|
+
const itemsSchemaPath = schemaPath ? `${schemaPath}.items` : undefined;
|
|
650
|
+
|
|
575
651
|
if (hasOneOfAnyOf || hasProperties || hasAdditionalProperties) {
|
|
576
652
|
return (
|
|
577
653
|
<>
|
|
578
654
|
<OpeningArrayBracket />
|
|
579
655
|
{hasOneOfAnyOf && (
|
|
580
|
-
<AnyOneOf
|
|
656
|
+
<AnyOneOf
|
|
657
|
+
schema={itemsSchema}
|
|
658
|
+
schemaType={schemaType}
|
|
659
|
+
schemaPath={itemsSchemaPath}
|
|
660
|
+
/>
|
|
581
661
|
)}
|
|
582
662
|
{hasProperties && (
|
|
583
|
-
<Properties
|
|
663
|
+
<Properties
|
|
664
|
+
schema={itemsSchema}
|
|
665
|
+
schemaType={schemaType}
|
|
666
|
+
schemaPath={itemsSchemaPath}
|
|
667
|
+
/>
|
|
584
668
|
)}
|
|
585
669
|
{hasAdditionalProperties && (
|
|
586
670
|
<AdditionalProperties schema={itemsSchema} schemaType={schemaType} />
|
|
@@ -645,6 +729,7 @@ interface SchemaEdgeProps {
|
|
|
645
729
|
nullable?: boolean | undefined;
|
|
646
730
|
discriminator?: any;
|
|
647
731
|
schemaType: "request" | "response";
|
|
732
|
+
schemaPath?: string;
|
|
648
733
|
}
|
|
649
734
|
|
|
650
735
|
const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
@@ -653,6 +738,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
653
738
|
required,
|
|
654
739
|
discriminator,
|
|
655
740
|
schemaType,
|
|
741
|
+
schemaPath,
|
|
656
742
|
}) => {
|
|
657
743
|
if (
|
|
658
744
|
(schemaType === "request" && schema.readOnly) ||
|
|
@@ -686,6 +772,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
686
772
|
required={required}
|
|
687
773
|
schema={schema}
|
|
688
774
|
nullable={schema.nullable}
|
|
775
|
+
schemaPath={schemaPath}
|
|
689
776
|
/>
|
|
690
777
|
);
|
|
691
778
|
}
|
|
@@ -699,6 +786,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
699
786
|
required={required}
|
|
700
787
|
schema={schema}
|
|
701
788
|
nullable={schema.nullable}
|
|
789
|
+
schemaPath={schemaPath}
|
|
702
790
|
/>
|
|
703
791
|
);
|
|
704
792
|
}
|
|
@@ -712,6 +800,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
712
800
|
required={required}
|
|
713
801
|
schema={schema}
|
|
714
802
|
nullable={schema.nullable}
|
|
803
|
+
schemaPath={schemaPath}
|
|
715
804
|
/>
|
|
716
805
|
);
|
|
717
806
|
}
|
|
@@ -725,6 +814,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
725
814
|
nullable={schema.nullable}
|
|
726
815
|
schema={schema}
|
|
727
816
|
schemaType={schemaType}
|
|
817
|
+
schemaPath={schemaPath}
|
|
728
818
|
/>
|
|
729
819
|
);
|
|
730
820
|
}
|
|
@@ -738,6 +828,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
738
828
|
nullable={schema.nullable}
|
|
739
829
|
schema={schema}
|
|
740
830
|
schemaType={schemaType}
|
|
831
|
+
schemaPath={schemaPath}
|
|
741
832
|
/>
|
|
742
833
|
);
|
|
743
834
|
}
|
|
@@ -787,6 +878,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
787
878
|
nullable={mergedSchemas.nullable}
|
|
788
879
|
schema={mergedSchemas}
|
|
789
880
|
schemaType={schemaType}
|
|
881
|
+
schemaPath={schemaPath}
|
|
790
882
|
/>
|
|
791
883
|
);
|
|
792
884
|
}
|
|
@@ -802,6 +894,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
802
894
|
nullable={mergedSchemas.nullable}
|
|
803
895
|
schema={mergedSchemas}
|
|
804
896
|
schemaType={schemaType}
|
|
897
|
+
schemaPath={schemaPath}
|
|
805
898
|
/>
|
|
806
899
|
);
|
|
807
900
|
}
|
|
@@ -817,6 +910,7 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
817
910
|
nullable={mergedSchemas.nullable}
|
|
818
911
|
schema={mergedSchemas}
|
|
819
912
|
schemaType={schemaType}
|
|
913
|
+
schemaPath={schemaPath}
|
|
820
914
|
/>
|
|
821
915
|
);
|
|
822
916
|
}
|
|
@@ -851,24 +945,51 @@ const SchemaEdge: React.FC<SchemaEdgeProps> = ({
|
|
|
851
945
|
|
|
852
946
|
function renderChildren(
|
|
853
947
|
schema: SchemaObject,
|
|
854
|
-
schemaType: "request" | "response"
|
|
948
|
+
schemaType: "request" | "response",
|
|
949
|
+
schemaPath?: string
|
|
855
950
|
) {
|
|
856
951
|
return (
|
|
857
952
|
<>
|
|
858
|
-
{schema.oneOf &&
|
|
859
|
-
|
|
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
|
+
)}
|
|
860
967
|
{schema.properties && (
|
|
861
|
-
<Properties
|
|
968
|
+
<Properties
|
|
969
|
+
schema={schema}
|
|
970
|
+
schemaType={schemaType}
|
|
971
|
+
schemaPath={schemaPath}
|
|
972
|
+
/>
|
|
862
973
|
)}
|
|
863
974
|
{schema.additionalProperties && (
|
|
864
975
|
<AdditionalProperties schema={schema} schemaType={schemaType} />
|
|
865
976
|
)}
|
|
866
|
-
{schema.items &&
|
|
977
|
+
{schema.items && (
|
|
978
|
+
<Items
|
|
979
|
+
schema={schema}
|
|
980
|
+
schemaType={schemaType}
|
|
981
|
+
schemaPath={schemaPath}
|
|
982
|
+
/>
|
|
983
|
+
)}
|
|
867
984
|
</>
|
|
868
985
|
);
|
|
869
986
|
}
|
|
870
987
|
|
|
871
|
-
const SchemaNode: React.FC<SchemaProps> = ({
|
|
988
|
+
const SchemaNode: React.FC<SchemaProps> = ({
|
|
989
|
+
schema,
|
|
990
|
+
schemaType,
|
|
991
|
+
schemaPath,
|
|
992
|
+
}) => {
|
|
872
993
|
if (
|
|
873
994
|
(schemaType === "request" && schema.readOnly) ||
|
|
874
995
|
(schemaType === "response" && schema.writeOnly)
|
|
@@ -911,9 +1032,16 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
911
1032
|
{/* Render all oneOf/anyOf constraints first */}
|
|
912
1033
|
{schema.allOf.map((item: any, index: number) => {
|
|
913
1034
|
if (item.oneOf || item.anyOf) {
|
|
1035
|
+
const itemSchemaPath = schemaPath
|
|
1036
|
+
? `${schemaPath}.allOf.${index}`
|
|
1037
|
+
: undefined;
|
|
914
1038
|
return (
|
|
915
1039
|
<div key={index}>
|
|
916
|
-
<AnyOneOf
|
|
1040
|
+
<AnyOneOf
|
|
1041
|
+
schema={item}
|
|
1042
|
+
schemaType={schemaType}
|
|
1043
|
+
schemaPath={itemSchemaPath}
|
|
1044
|
+
/>
|
|
917
1045
|
</div>
|
|
918
1046
|
);
|
|
919
1047
|
}
|
|
@@ -921,10 +1049,18 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
921
1049
|
})}
|
|
922
1050
|
{/* Then render shared properties from the merge */}
|
|
923
1051
|
{mergedSchemas.properties && (
|
|
924
|
-
<Properties
|
|
1052
|
+
<Properties
|
|
1053
|
+
schema={mergedSchemas}
|
|
1054
|
+
schemaType={schemaType}
|
|
1055
|
+
schemaPath={schemaPath}
|
|
1056
|
+
/>
|
|
925
1057
|
)}
|
|
926
1058
|
{mergedSchemas.items && (
|
|
927
|
-
<Items
|
|
1059
|
+
<Items
|
|
1060
|
+
schema={mergedSchemas}
|
|
1061
|
+
schemaType={schemaType}
|
|
1062
|
+
schemaPath={schemaPath}
|
|
1063
|
+
/>
|
|
928
1064
|
)}
|
|
929
1065
|
</div>
|
|
930
1066
|
);
|
|
@@ -943,16 +1079,32 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
943
1079
|
return (
|
|
944
1080
|
<div>
|
|
945
1081
|
{mergedSchemas.oneOf && (
|
|
946
|
-
<AnyOneOf
|
|
1082
|
+
<AnyOneOf
|
|
1083
|
+
schema={mergedSchemas}
|
|
1084
|
+
schemaType={schemaType}
|
|
1085
|
+
schemaPath={schemaPath}
|
|
1086
|
+
/>
|
|
947
1087
|
)}
|
|
948
1088
|
{mergedSchemas.anyOf && (
|
|
949
|
-
<AnyOneOf
|
|
1089
|
+
<AnyOneOf
|
|
1090
|
+
schema={mergedSchemas}
|
|
1091
|
+
schemaType={schemaType}
|
|
1092
|
+
schemaPath={schemaPath}
|
|
1093
|
+
/>
|
|
950
1094
|
)}
|
|
951
1095
|
{mergedSchemas.properties && (
|
|
952
|
-
<Properties
|
|
1096
|
+
<Properties
|
|
1097
|
+
schema={mergedSchemas}
|
|
1098
|
+
schemaType={schemaType}
|
|
1099
|
+
schemaPath={schemaPath}
|
|
1100
|
+
/>
|
|
953
1101
|
)}
|
|
954
1102
|
{mergedSchemas.items && (
|
|
955
|
-
<Items
|
|
1103
|
+
<Items
|
|
1104
|
+
schema={mergedSchemas}
|
|
1105
|
+
schemaType={schemaType}
|
|
1106
|
+
schemaPath={schemaPath}
|
|
1107
|
+
/>
|
|
956
1108
|
)}
|
|
957
1109
|
</div>
|
|
958
1110
|
);
|
|
@@ -983,7 +1135,7 @@ const SchemaNode: React.FC<SchemaProps> = ({ schema, schemaType }) => {
|
|
|
983
1135
|
);
|
|
984
1136
|
}
|
|
985
1137
|
|
|
986
|
-
return renderChildren(schema, schemaType);
|
|
1138
|
+
return renderChildren(schema, schemaType, schemaPath);
|
|
987
1139
|
};
|
|
988
1140
|
|
|
989
1141
|
export default SchemaNode;
|
|
@@ -999,5 +1151,10 @@ const PRIMITIVE_TYPES: Record<PrimitiveSchemaType, true> = {
|
|
|
999
1151
|
} as const;
|
|
1000
1152
|
|
|
1001
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
|
+
}
|
|
1002
1159
|
return PRIMITIVE_TYPES[schema.type as PrimitiveSchemaType];
|
|
1003
1160
|
};
|
|
@@ -25,13 +25,22 @@ import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
|
25
25
|
import clsx from "clsx";
|
|
26
26
|
import flatten from "lodash/flatten";
|
|
27
27
|
|
|
28
|
+
export interface SchemaTabsProps extends TabProps {
|
|
29
|
+
/**
|
|
30
|
+
* Optional callback fired when the selected tab changes.
|
|
31
|
+
* Receives the index of the newly selected tab.
|
|
32
|
+
*/
|
|
33
|
+
onChange?: (index: number) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
function TabList({
|
|
29
37
|
className,
|
|
30
38
|
block,
|
|
31
39
|
selectedValue,
|
|
32
40
|
selectValue,
|
|
33
41
|
tabValues,
|
|
34
|
-
|
|
42
|
+
onChange,
|
|
43
|
+
}: SchemaTabsProps & ReturnType<typeof useTabs>) {
|
|
35
44
|
const tabRefs: (HTMLLIElement | null)[] = [];
|
|
36
45
|
const { blockElementScrollPositionUntilNextRender } =
|
|
37
46
|
useScrollPositionBlocker();
|
|
@@ -49,6 +58,8 @@ function TabList({
|
|
|
49
58
|
if (newTabValue !== selectedValue) {
|
|
50
59
|
blockElementScrollPositionUntilNextRender(newTab);
|
|
51
60
|
selectValue(newTabValue);
|
|
61
|
+
// Notify parent component of the tab change
|
|
62
|
+
onChange?.(newTabIndex);
|
|
52
63
|
}
|
|
53
64
|
};
|
|
54
65
|
|
|
@@ -177,7 +188,7 @@ function TabContent({
|
|
|
177
188
|
lazy,
|
|
178
189
|
children,
|
|
179
190
|
selectedValue,
|
|
180
|
-
}:
|
|
191
|
+
}: SchemaTabsProps & ReturnType<typeof useTabs>) {
|
|
181
192
|
const childTabs = (Array.isArray(children) ? children : [children]).filter(
|
|
182
193
|
Boolean
|
|
183
194
|
) as ReactElement<TabItemProps>[];
|
|
@@ -203,7 +214,7 @@ function TabContent({
|
|
|
203
214
|
</div>
|
|
204
215
|
);
|
|
205
216
|
}
|
|
206
|
-
function TabsComponent(props:
|
|
217
|
+
function TabsComponent(props: SchemaTabsProps): React.JSX.Element {
|
|
207
218
|
const tabs = useTabs(props);
|
|
208
219
|
return (
|
|
209
220
|
<div className="openapi-tabs__schema-container">
|
|
@@ -212,7 +223,7 @@ function TabsComponent(props: TabProps): React.JSX.Element {
|
|
|
212
223
|
</div>
|
|
213
224
|
);
|
|
214
225
|
}
|
|
215
|
-
export default function SchemaTabs(props:
|
|
226
|
+
export default function SchemaTabs(props: SchemaTabsProps): React.JSX.Element {
|
|
216
227
|
const isBrowser = useIsBrowser();
|
|
217
228
|
return (
|
|
218
229
|
<TabsComponent
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
|
-
|
|
12
11
|
import ApiTabs from "@theme/ApiTabs";
|
|
13
12
|
import Details from "@theme/Details";
|
|
14
13
|
import Markdown from "@theme/Markdown";
|
|
@@ -16,7 +15,7 @@ import ResponseHeaders from "@theme/ResponseHeaders";
|
|
|
16
15
|
import ResponseSchema from "@theme/ResponseSchema";
|
|
17
16
|
import TabItem from "@theme/TabItem";
|
|
18
17
|
import { OPENAPI_STATUS_CODES } from "@theme/translationIds";
|
|
19
|
-
import { ApiItem } from "docusaurus-plugin-openapi-docs/
|
|
18
|
+
import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types";
|
|
20
19
|
|
|
21
20
|
interface Props {
|
|
22
21
|
id?: string;
|
package/src/theme/styles.scss
CHANGED
|
@@ -166,6 +166,16 @@
|
|
|
166
166
|
border-right: thin solid var(--ifm-toc-border-color);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
@media (min-width: 997px) {
|
|
170
|
+
.openapi-right-panel__container {
|
|
171
|
+
position: sticky;
|
|
172
|
+
top: calc(var(--ifm-navbar-height) + 1rem);
|
|
173
|
+
max-height: calc(100vh - var(--ifm-navbar-height) - 2rem);
|
|
174
|
+
overflow-y: auto;
|
|
175
|
+
align-self: flex-start;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
169
179
|
@media (max-width: 997px) {
|
|
170
180
|
.schema {
|
|
171
181
|
margin-bottom: 1rem;
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/plugin-content-docs.d.ts","./src/postman-code-generators.d.ts","./src/react-magic-dropzone.d.ts","./src/theme-classic.d.ts","./src/theme-openapi.d.ts","./src/types.ts","./src/markdown/createDescription.ts","./src/markdown/schema.ts","./src/markdown/utils.test.ts","./src/markdown/utils.ts","./src/theme/translationIds.ts","./src/theme/ApiExplorer/buildPostmanRequest.ts","./src/theme/ApiExplorer/index.tsx","./src/theme/ApiExplorer/persistenceMiddleware.ts","./src/theme/ApiExplorer/storage-utils.ts","./src/theme/ApiExplorer/Accept/index.tsx","./src/theme/ApiExplorer/Accept/slice.ts","./src/theme/ApiExplorer/ApiCodeBlock/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Container/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/Element.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx","./src/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Line/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.tsx","./src/theme/ApiExplorer/Authorization/auth-types.ts","./src/theme/ApiExplorer/Authorization/index.tsx","./src/theme/ApiExplorer/Authorization/slice.ts","./src/theme/ApiExplorer/Body/index.tsx","./src/theme/ApiExplorer/Body/json2xml.d.ts","./src/theme/ApiExplorer/Body/slice.ts","./src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx","./src/theme/ApiExplorer/Body/FormBodyItem/index.tsx","./src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts","./src/theme/ApiExplorer/CodeSnippets/index.tsx","./src/theme/ApiExplorer/CodeSnippets/languages.ts","./src/theme/ApiExplorer/CodeTabs/index.tsx","./src/theme/ApiExplorer/ContentType/index.tsx","./src/theme/ApiExplorer/ContentType/slice.ts","./src/theme/ApiExplorer/Export/index.tsx","./src/theme/ApiExplorer/FloatingButton/index.tsx","./src/theme/ApiExplorer/FormFileUpload/index.tsx","./src/theme/ApiExplorer/FormItem/index.tsx","./src/theme/ApiExplorer/FormMultiSelect/index.tsx","./src/theme/ApiExplorer/FormSelect/index.tsx","./src/theme/ApiExplorer/FormTextInput/index.tsx","./src/theme/ApiExplorer/LiveEditor/index.tsx","./src/theme/ApiExplorer/MethodEndpoint/index.tsx","./src/theme/ApiExplorer/ParamOptions/index.tsx","./src/theme/ApiExplorer/ParamOptions/slice.ts","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx","./src/theme/ApiExplorer/Request/index.tsx","./src/theme/ApiExplorer/Request/makeRequest.ts","./src/theme/ApiExplorer/Response/index.tsx","./src/theme/ApiExplorer/Response/slice.ts","./src/theme/ApiExplorer/SecuritySchemes/index.tsx","./src/theme/ApiExplorer/Server/index.tsx","./src/theme/ApiExplorer/Server/slice.ts","./src/theme/ApiItem/hooks.ts","./src/theme/ApiItem/index.tsx","./src/theme/ApiItem/store.ts","./src/theme/ApiItem/Layout/index.tsx","./src/theme/ApiLogo/index.tsx","./src/theme/ApiTabs/index.tsx","./src/theme/ArrayBrackets/index.tsx","./src/theme/CodeSamples/index.tsx","./src/theme/DiscriminatorTabs/index.tsx","./src/theme/Example/index.tsx","./src/theme/Markdown/index.d.ts","./src/theme/MimeTabs/index.tsx","./src/theme/OperationTabs/index.tsx","./src/theme/ParamsDetails/index.tsx","./src/theme/ParamsItem/index.tsx","./src/theme/RequestSchema/index.tsx","./src/theme/ResponseExamples/index.tsx","./src/theme/ResponseHeaders/index.tsx","./src/theme/ResponseSchema/index.tsx","./src/theme/Schema/index.tsx","./src/theme/SchemaItem/index.tsx","./src/theme/SchemaTabs/index.tsx","./src/theme/SkeletonLoader/index.tsx","./src/theme/StatusCodes/index.tsx"],"version":"5.9.3"}
|
|
1
|
+
{"root":["./src/index.ts","./src/plugin-content-docs.d.ts","./src/postman-code-generators.d.ts","./src/react-magic-dropzone.d.ts","./src/theme-classic.d.ts","./src/theme-openapi.d.ts","./src/types.d.ts","./src/markdown/createDescription.ts","./src/markdown/schema.ts","./src/markdown/utils.test.ts","./src/markdown/utils.ts","./src/theme/translationIds.ts","./src/theme/ApiExplorer/buildPostmanRequest.ts","./src/theme/ApiExplorer/index.tsx","./src/theme/ApiExplorer/persistenceMiddleware.ts","./src/theme/ApiExplorer/storage-utils.ts","./src/theme/ApiExplorer/Accept/index.tsx","./src/theme/ApiExplorer/Accept/slice.ts","./src/theme/ApiExplorer/ApiCodeBlock/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Container/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/Element.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx","./src/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/Line/index.tsx","./src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.tsx","./src/theme/ApiExplorer/Authorization/auth-types.ts","./src/theme/ApiExplorer/Authorization/index.tsx","./src/theme/ApiExplorer/Authorization/slice.ts","./src/theme/ApiExplorer/Body/index.tsx","./src/theme/ApiExplorer/Body/json2xml.d.ts","./src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts","./src/theme/ApiExplorer/Body/slice.ts","./src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx","./src/theme/ApiExplorer/Body/FormBodyItem/index.tsx","./src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts","./src/theme/ApiExplorer/CodeSnippets/index.tsx","./src/theme/ApiExplorer/CodeSnippets/languages.ts","./src/theme/ApiExplorer/CodeTabs/index.tsx","./src/theme/ApiExplorer/ContentType/index.tsx","./src/theme/ApiExplorer/ContentType/slice.ts","./src/theme/ApiExplorer/Export/index.tsx","./src/theme/ApiExplorer/FloatingButton/index.tsx","./src/theme/ApiExplorer/FormFileUpload/index.tsx","./src/theme/ApiExplorer/FormItem/index.tsx","./src/theme/ApiExplorer/FormMultiSelect/index.tsx","./src/theme/ApiExplorer/FormSelect/index.tsx","./src/theme/ApiExplorer/FormTextInput/index.tsx","./src/theme/ApiExplorer/LiveEditor/index.tsx","./src/theme/ApiExplorer/MethodEndpoint/index.tsx","./src/theme/ApiExplorer/ParamOptions/index.tsx","./src/theme/ApiExplorer/ParamOptions/slice.ts","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx","./src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx","./src/theme/ApiExplorer/Request/index.tsx","./src/theme/ApiExplorer/Request/makeRequest.ts","./src/theme/ApiExplorer/Response/index.tsx","./src/theme/ApiExplorer/Response/slice.ts","./src/theme/ApiExplorer/SchemaSelection/index.ts","./src/theme/ApiExplorer/SchemaSelection/slice.ts","./src/theme/ApiExplorer/SecuritySchemes/index.tsx","./src/theme/ApiExplorer/Server/index.tsx","./src/theme/ApiExplorer/Server/slice.ts","./src/theme/ApiItem/hooks.ts","./src/theme/ApiItem/index.tsx","./src/theme/ApiItem/store.ts","./src/theme/ApiItem/Layout/index.tsx","./src/theme/ApiLogo/index.tsx","./src/theme/ApiTabs/index.tsx","./src/theme/ArrayBrackets/index.tsx","./src/theme/CodeSamples/index.tsx","./src/theme/DiscriminatorTabs/index.tsx","./src/theme/Example/index.tsx","./src/theme/Markdown/index.d.ts","./src/theme/MimeTabs/index.tsx","./src/theme/OperationTabs/index.tsx","./src/theme/ParamsDetails/index.tsx","./src/theme/ParamsItem/index.tsx","./src/theme/RequestSchema/index.tsx","./src/theme/ResponseExamples/index.tsx","./src/theme/ResponseHeaders/index.tsx","./src/theme/ResponseSchema/index.tsx","./src/theme/Schema/index.tsx","./src/theme/SchemaItem/index.tsx","./src/theme/SchemaTabs/index.tsx","./src/theme/SkeletonLoader/index.tsx","./src/theme/StatusCodes/index.tsx"],"version":"5.9.3"}
|