docusaurus-plugin-openapi-docs 1.1.4 → 1.1.7
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/createRequestBodyDetails.d.ts +9 -2
- package/lib/markdown/createRequestBodyDetails.js +2 -2
- package/lib/markdown/createRequestSchema.d.ts +21 -0
- package/lib/markdown/createRequestSchema.js +680 -0
- package/lib/markdown/createResponseSchema.d.ts +14 -0
- package/lib/markdown/createResponseSchema.js +641 -0
- package/lib/markdown/createSchemaDetails.d.ts +1 -1
- package/lib/markdown/createSchemaDetails.js +116 -42
- package/lib/markdown/createStatusCodes.d.ts +2 -0
- package/lib/markdown/createStatusCodes.js +58 -56
- package/lib/markdown/index.js +5 -1
- package/lib/openapi/createExample.js +27 -14
- package/lib/openapi/openapi.d.ts +1 -1
- package/lib/openapi/openapi.js +21 -10
- package/lib/openapi/types.d.ts +1 -1
- package/lib/sidebars/index.d.ts +1 -1
- package/lib/sidebars/index.js +11 -3
- package/package.json +2 -3
- package/src/markdown/createRequestBodyDetails.ts +11 -4
- package/src/markdown/createRequestSchema.ts +848 -0
- package/src/markdown/{createSchemaDetails.ts → createResponseSchema.ts} +128 -73
- package/src/markdown/createStatusCodes.ts +53 -61
- package/src/markdown/index.ts +17 -1
- package/src/openapi/createExample.ts +31 -14
- package/src/openapi/openapi.ts +16 -8
- package/src/openapi/types.ts +1 -1
- package/src/sidebars/index.ts +13 -5
- package/LICENSE +0 -21
|
@@ -9,6 +9,10 @@ import { MediaTypeObject, SchemaObject } from "../openapi/types";
|
|
|
9
9
|
import { createDescription } from "./createDescription";
|
|
10
10
|
import { createDetails } from "./createDetails";
|
|
11
11
|
import { createDetailsSummary } from "./createDetailsSummary";
|
|
12
|
+
import {
|
|
13
|
+
createResponseExample,
|
|
14
|
+
createResponseExamples,
|
|
15
|
+
} from "./createStatusCodes";
|
|
12
16
|
import { getQualifierMessage, getSchemaName } from "./schema";
|
|
13
17
|
import { create, guard } from "./utils";
|
|
14
18
|
|
|
@@ -227,8 +231,12 @@ function createItems(schema: SchemaObject) {
|
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
if (schema.items?.allOf !== undefined) {
|
|
230
|
-
|
|
231
|
-
|
|
234
|
+
// TODO: figure out if and how we should pass merged required array
|
|
235
|
+
const {
|
|
236
|
+
mergedSchemas,
|
|
237
|
+
}: { mergedSchemas: SchemaObject; required: string[] } = mergeAllOf(
|
|
238
|
+
schema.items?.allOf
|
|
239
|
+
);
|
|
232
240
|
|
|
233
241
|
// Handles combo anyOf/oneOf + properties
|
|
234
242
|
if (
|
|
@@ -387,7 +395,7 @@ function createDetailsNode(
|
|
|
387
395
|
name: string,
|
|
388
396
|
schemaName: string,
|
|
389
397
|
schema: SchemaObject,
|
|
390
|
-
required:
|
|
398
|
+
required: string[] | boolean
|
|
391
399
|
): any {
|
|
392
400
|
return create("SchemaItem", {
|
|
393
401
|
collapsible: true,
|
|
@@ -402,7 +410,7 @@ function createDetailsNode(
|
|
|
402
410
|
style: { opacity: "0.6" },
|
|
403
411
|
children: ` ${schemaName}`,
|
|
404
412
|
}),
|
|
405
|
-
guard(required, () => [
|
|
413
|
+
guard(schema.required && schema.required === true, () => [
|
|
406
414
|
create("strong", {
|
|
407
415
|
style: {
|
|
408
416
|
fontSize: "var(--ifm-code-font-size)",
|
|
@@ -446,7 +454,7 @@ function createPropertyDiscriminator(
|
|
|
446
454
|
schemaName: string,
|
|
447
455
|
schema: SchemaObject,
|
|
448
456
|
discriminator: any,
|
|
449
|
-
required:
|
|
457
|
+
required: string[] | boolean
|
|
450
458
|
): any {
|
|
451
459
|
if (schema === undefined) {
|
|
452
460
|
return undefined;
|
|
@@ -515,7 +523,7 @@ function createPropertyDiscriminator(
|
|
|
515
523
|
interface EdgeProps {
|
|
516
524
|
name: string;
|
|
517
525
|
schema: SchemaObject;
|
|
518
|
-
required: boolean;
|
|
526
|
+
required: string[] | boolean;
|
|
519
527
|
discriminator?: any | unknown;
|
|
520
528
|
}
|
|
521
529
|
|
|
@@ -548,9 +556,8 @@ function createEdges({
|
|
|
548
556
|
const {
|
|
549
557
|
mergedSchemas,
|
|
550
558
|
required,
|
|
551
|
-
}: { mergedSchemas: SchemaObject; required:
|
|
552
|
-
schema.allOf
|
|
553
|
-
);
|
|
559
|
+
}: { mergedSchemas: SchemaObject; required: string[] | boolean } =
|
|
560
|
+
mergeAllOf(schema.allOf);
|
|
554
561
|
const mergedSchemaName = getSchemaName(mergedSchemas);
|
|
555
562
|
|
|
556
563
|
if (
|
|
@@ -573,14 +580,18 @@ function createEdges({
|
|
|
573
580
|
return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
|
|
574
581
|
}
|
|
575
582
|
|
|
583
|
+
if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
|
|
584
|
+
return undefined;
|
|
585
|
+
}
|
|
586
|
+
|
|
576
587
|
return create("SchemaItem", {
|
|
577
588
|
collapsible: false,
|
|
578
589
|
name,
|
|
579
|
-
required,
|
|
590
|
+
required: false,
|
|
580
591
|
schemaDescription: mergedSchemas.description,
|
|
581
592
|
schemaName: schemaName,
|
|
582
593
|
qualifierMessage: getQualifierMessage(schema),
|
|
583
|
-
defaultValue:
|
|
594
|
+
defaultValue: mergedSchemas.default,
|
|
584
595
|
});
|
|
585
596
|
}
|
|
586
597
|
|
|
@@ -597,11 +608,15 @@ function createEdges({
|
|
|
597
608
|
return createDetailsNode(name, schemaName, schema, required);
|
|
598
609
|
}
|
|
599
610
|
|
|
611
|
+
if (schema.writeOnly && schema.writeOnly === true) {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
|
|
600
615
|
// primitives and array of non-objects
|
|
601
616
|
return create("SchemaItem", {
|
|
602
617
|
collapsible: false,
|
|
603
618
|
name,
|
|
604
|
-
required,
|
|
619
|
+
required: false,
|
|
605
620
|
schemaDescription: schema.description,
|
|
606
621
|
schemaName: schemaName,
|
|
607
622
|
qualifierMessage: getQualifierMessage(schema),
|
|
@@ -634,7 +649,8 @@ function createNodes(schema: SchemaObject): any {
|
|
|
634
649
|
return createProperties(schema);
|
|
635
650
|
}
|
|
636
651
|
|
|
637
|
-
if
|
|
652
|
+
// Could be set to false to just check if evals to true
|
|
653
|
+
if (schema.additionalProperties) {
|
|
638
654
|
return createAdditionalProperties(schema);
|
|
639
655
|
}
|
|
640
656
|
|
|
@@ -685,11 +701,11 @@ interface Props {
|
|
|
685
701
|
[key: string]: MediaTypeObject;
|
|
686
702
|
};
|
|
687
703
|
description?: string;
|
|
688
|
-
required?: boolean;
|
|
704
|
+
required?: string[] | boolean;
|
|
689
705
|
};
|
|
690
706
|
}
|
|
691
707
|
|
|
692
|
-
export function
|
|
708
|
+
export function createResponseSchema({ title, body, ...rest }: Props) {
|
|
693
709
|
if (
|
|
694
710
|
body === undefined ||
|
|
695
711
|
body.content === undefined ||
|
|
@@ -699,64 +715,103 @@ export function createSchemaDetails({ title, body, ...rest }: Props) {
|
|
|
699
715
|
return undefined;
|
|
700
716
|
}
|
|
701
717
|
|
|
702
|
-
//
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
718
|
+
// Get all MIME types, including vendor-specific
|
|
719
|
+
const mimeTypes = Object.keys(body.content);
|
|
720
|
+
|
|
721
|
+
if (mimeTypes && mimeTypes.length) {
|
|
722
|
+
return create("MimeTabs", {
|
|
723
|
+
groupId: "mime-type",
|
|
724
|
+
children: mimeTypes.map((mimeType: any) => {
|
|
725
|
+
const responseExamples = body.content![mimeType].examples;
|
|
726
|
+
const responseExample = body.content![mimeType].example;
|
|
727
|
+
const firstBody = body.content![mimeType].schema;
|
|
728
|
+
|
|
729
|
+
if (
|
|
730
|
+
firstBody === undefined &&
|
|
731
|
+
responseExample === undefined &&
|
|
732
|
+
responseExamples === undefined
|
|
733
|
+
) {
|
|
734
|
+
return undefined;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (firstBody?.properties !== undefined) {
|
|
738
|
+
if (Object.keys(firstBody?.properties).length === 0) {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
return create("TabItem", {
|
|
744
|
+
label: `${mimeType}`,
|
|
745
|
+
value: `${mimeType}`,
|
|
746
|
+
children: [
|
|
747
|
+
create("SchemaTabs", {
|
|
748
|
+
groupId: "schema-tabs",
|
|
749
|
+
children: [
|
|
750
|
+
firstBody &&
|
|
751
|
+
create("TabTtem", {
|
|
752
|
+
label: `${title}`,
|
|
753
|
+
value: `${title}`,
|
|
754
|
+
children: [
|
|
755
|
+
createDetails({
|
|
756
|
+
"data-collapsed": false,
|
|
757
|
+
open: true,
|
|
758
|
+
...rest,
|
|
759
|
+
children: [
|
|
760
|
+
createDetailsSummary({
|
|
761
|
+
style: { textAlign: "left" },
|
|
762
|
+
children: [
|
|
763
|
+
create("strong", { children: `${title}` }),
|
|
764
|
+
guard(firstBody!.type === "array", (format) =>
|
|
765
|
+
create("span", {
|
|
766
|
+
style: { opacity: "0.6" },
|
|
767
|
+
children: ` array`,
|
|
768
|
+
})
|
|
769
|
+
),
|
|
770
|
+
guard(
|
|
771
|
+
body.required && body.required === true,
|
|
772
|
+
() => [
|
|
773
|
+
create("strong", {
|
|
774
|
+
style: {
|
|
775
|
+
fontSize: "var(--ifm-code-font-size)",
|
|
776
|
+
color: "var(--openapi-required)",
|
|
777
|
+
},
|
|
778
|
+
children: " required",
|
|
779
|
+
}),
|
|
780
|
+
]
|
|
781
|
+
),
|
|
782
|
+
],
|
|
783
|
+
}),
|
|
784
|
+
create("div", {
|
|
785
|
+
style: { textAlign: "left", marginLeft: "1rem" },
|
|
786
|
+
children: [
|
|
787
|
+
guard(body.description, () => [
|
|
788
|
+
create("div", {
|
|
789
|
+
style: {
|
|
790
|
+
marginTop: "1rem",
|
|
791
|
+
marginBottom: "1rem",
|
|
792
|
+
},
|
|
793
|
+
children: createDescription(body.description),
|
|
794
|
+
}),
|
|
795
|
+
]),
|
|
796
|
+
],
|
|
797
|
+
}),
|
|
798
|
+
create("ul", {
|
|
799
|
+
style: { marginLeft: "1rem" },
|
|
800
|
+
children: createNodes(firstBody!),
|
|
801
|
+
}),
|
|
802
|
+
],
|
|
803
|
+
}),
|
|
804
|
+
],
|
|
805
|
+
}),
|
|
806
|
+
responseExamples && createResponseExamples(responseExamples),
|
|
807
|
+
responseExample && createResponseExample(responseExample),
|
|
808
|
+
],
|
|
752
809
|
}),
|
|
753
|
-
]
|
|
754
|
-
|
|
755
|
-
}),
|
|
756
|
-
create("ul", {
|
|
757
|
-
style: { marginLeft: "1rem" },
|
|
758
|
-
children: createNodes(firstBody),
|
|
810
|
+
],
|
|
811
|
+
});
|
|
759
812
|
}),
|
|
760
|
-
|
|
761
|
-
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return undefined;
|
|
762
817
|
}
|
|
@@ -9,7 +9,7 @@ import { ApiItem } from "../types";
|
|
|
9
9
|
import { createDescription } from "./createDescription";
|
|
10
10
|
import { createDetails } from "./createDetails";
|
|
11
11
|
import { createDetailsSummary } from "./createDetailsSummary";
|
|
12
|
-
import {
|
|
12
|
+
import { createResponseSchema } from "./createResponseSchema";
|
|
13
13
|
import { create } from "./utils";
|
|
14
14
|
import { guard } from "./utils";
|
|
15
15
|
|
|
@@ -67,19 +67,30 @@ function createResponseHeaders(responseHeaders: any) {
|
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
function createResponseExamples(responseExamples: any) {
|
|
70
|
+
export function createResponseExamples(responseExamples: any) {
|
|
71
71
|
return Object.entries(responseExamples).map(
|
|
72
72
|
([exampleName, exampleValue]: any) => {
|
|
73
73
|
const camelToSpaceName = exampleName.replace(/([A-Z])/g, " $1");
|
|
74
74
|
let finalFormattedName =
|
|
75
75
|
camelToSpaceName.charAt(0).toUpperCase() + camelToSpaceName.slice(1);
|
|
76
76
|
|
|
77
|
+
if (typeof exampleValue.value === "object") {
|
|
78
|
+
return create("TabItem", {
|
|
79
|
+
label: `${finalFormattedName}`,
|
|
80
|
+
value: `${finalFormattedName}`,
|
|
81
|
+
children: [
|
|
82
|
+
create("ResponseSamples", {
|
|
83
|
+
responseExample: JSON.stringify(exampleValue.value, null, 2),
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
77
88
|
return create("TabItem", {
|
|
78
89
|
label: `${finalFormattedName}`,
|
|
79
90
|
value: `${finalFormattedName}`,
|
|
80
91
|
children: [
|
|
81
92
|
create("ResponseSamples", {
|
|
82
|
-
responseExample:
|
|
93
|
+
responseExample: exampleValue.value,
|
|
83
94
|
}),
|
|
84
95
|
],
|
|
85
96
|
});
|
|
@@ -87,6 +98,29 @@ function createResponseExamples(responseExamples: any) {
|
|
|
87
98
|
);
|
|
88
99
|
}
|
|
89
100
|
|
|
101
|
+
export function createResponseExample(responseExample: any) {
|
|
102
|
+
if (typeof responseExample === "object") {
|
|
103
|
+
return create("TabItem", {
|
|
104
|
+
label: `Example`,
|
|
105
|
+
value: `Example`,
|
|
106
|
+
children: [
|
|
107
|
+
create("ResponseSamples", {
|
|
108
|
+
responseExample: JSON.stringify(responseExample, null, 2),
|
|
109
|
+
}),
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return create("TabItem", {
|
|
114
|
+
label: `Example`,
|
|
115
|
+
value: `Example`,
|
|
116
|
+
children: [
|
|
117
|
+
create("ResponseSamples", {
|
|
118
|
+
responseExample: responseExample,
|
|
119
|
+
}),
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
90
124
|
export function createStatusCodes({ responses }: Props) {
|
|
91
125
|
if (responses === undefined) {
|
|
92
126
|
return undefined;
|
|
@@ -100,14 +134,10 @@ export function createStatusCodes({ responses }: Props) {
|
|
|
100
134
|
return create("div", {
|
|
101
135
|
children: [
|
|
102
136
|
create("ApiTabs", {
|
|
137
|
+
// TODO: determine if we should persist status code selection
|
|
138
|
+
// groupId: "api-tabs",
|
|
103
139
|
children: codes.map((code) => {
|
|
104
140
|
const responseHeaders: any = responses[code].headers;
|
|
105
|
-
const responseContent: any = responses[code].content;
|
|
106
|
-
const responseContentKey: any =
|
|
107
|
-
responseContent && Object.keys(responseContent)[0];
|
|
108
|
-
const responseExamples: any =
|
|
109
|
-
responseContentKey && responseContent[responseContentKey].examples;
|
|
110
|
-
|
|
111
141
|
return create("TabItem", {
|
|
112
142
|
label: code,
|
|
113
143
|
value: code,
|
|
@@ -115,68 +145,30 @@ export function createStatusCodes({ responses }: Props) {
|
|
|
115
145
|
create("div", {
|
|
116
146
|
children: createDescription(responses[code].description),
|
|
117
147
|
}),
|
|
118
|
-
|
|
119
|
-
create("SchemaTabs", {
|
|
120
|
-
children: [
|
|
121
|
-
create("TabTtem", {
|
|
122
|
-
label: "Schema",
|
|
123
|
-
value: "Schema",
|
|
124
|
-
children: [
|
|
125
|
-
responseHeaders &&
|
|
126
|
-
createDetails({
|
|
127
|
-
"data-collaposed": false,
|
|
128
|
-
open: true,
|
|
129
|
-
style: { textAlign: "left" },
|
|
130
|
-
children: [
|
|
131
|
-
createDetailsSummary({
|
|
132
|
-
children: [
|
|
133
|
-
create("strong", {
|
|
134
|
-
children: "Response Headers",
|
|
135
|
-
}),
|
|
136
|
-
],
|
|
137
|
-
}),
|
|
138
|
-
createResponseHeaders(responseHeaders),
|
|
139
|
-
],
|
|
140
|
-
}),
|
|
141
|
-
create("div", {
|
|
142
|
-
children: createSchemaDetails({
|
|
143
|
-
title: "Schema",
|
|
144
|
-
body: {
|
|
145
|
-
content: responses[code].content,
|
|
146
|
-
},
|
|
147
|
-
}),
|
|
148
|
-
}),
|
|
149
|
-
],
|
|
150
|
-
}),
|
|
151
|
-
createResponseExamples(responseExamples),
|
|
152
|
-
],
|
|
153
|
-
})
|
|
154
|
-
),
|
|
155
|
-
guard(responseHeaders, () =>
|
|
148
|
+
responseHeaders &&
|
|
156
149
|
createDetails({
|
|
157
150
|
"data-collaposed": false,
|
|
158
151
|
open: true,
|
|
159
|
-
style: { textAlign: "left" },
|
|
152
|
+
style: { textAlign: "left", marginBottom: "1rem" },
|
|
160
153
|
children: [
|
|
161
154
|
createDetailsSummary({
|
|
162
155
|
children: [
|
|
163
|
-
create("strong", {
|
|
156
|
+
create("strong", {
|
|
157
|
+
children: "Response Headers",
|
|
158
|
+
}),
|
|
164
159
|
],
|
|
165
160
|
}),
|
|
166
161
|
createResponseHeaders(responseHeaders),
|
|
167
162
|
],
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}),
|
|
178
|
-
})
|
|
179
|
-
),
|
|
163
|
+
}),
|
|
164
|
+
create("div", {
|
|
165
|
+
children: createResponseSchema({
|
|
166
|
+
title: "Schema",
|
|
167
|
+
body: {
|
|
168
|
+
content: responses[code].content,
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
}),
|
|
180
172
|
],
|
|
181
173
|
});
|
|
182
174
|
}),
|
package/src/markdown/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { escape } from "lodash";
|
|
|
10
10
|
import {
|
|
11
11
|
ContactObject,
|
|
12
12
|
LicenseObject,
|
|
13
|
+
MediaTypeObject,
|
|
13
14
|
SecuritySchemeObject,
|
|
14
15
|
} from "../openapi/types";
|
|
15
16
|
import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
|
|
@@ -26,6 +27,17 @@ import { createTermsOfService } from "./createTermsOfService";
|
|
|
26
27
|
import { createVersionBadge } from "./createVersionBadge";
|
|
27
28
|
import { render } from "./utils";
|
|
28
29
|
|
|
30
|
+
interface Props {
|
|
31
|
+
title: string;
|
|
32
|
+
body: {
|
|
33
|
+
content?: {
|
|
34
|
+
[key: string]: MediaTypeObject;
|
|
35
|
+
};
|
|
36
|
+
description?: string;
|
|
37
|
+
required?: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
export function createApiPageMD({
|
|
30
42
|
title,
|
|
31
43
|
api: {
|
|
@@ -39,6 +51,7 @@ export function createApiPageMD({
|
|
|
39
51
|
}: ApiPageMetadata) {
|
|
40
52
|
return render([
|
|
41
53
|
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
54
|
+
`import MimeTabs from "@theme/MimeTabs";\n`,
|
|
42
55
|
`import ParamsItem from "@theme/ParamsItem";\n`,
|
|
43
56
|
`import ResponseSamples from "@theme/ResponseSamples";\n`,
|
|
44
57
|
`import SchemaItem from "@theme/SchemaItem"\n`,
|
|
@@ -52,7 +65,10 @@ export function createApiPageMD({
|
|
|
52
65
|
createParamsDetails({ parameters, type: "query" }),
|
|
53
66
|
createParamsDetails({ parameters, type: "header" }),
|
|
54
67
|
createParamsDetails({ parameters, type: "cookie" }),
|
|
55
|
-
createRequestBodyDetails({
|
|
68
|
+
createRequestBodyDetails({
|
|
69
|
+
title: "Request Body",
|
|
70
|
+
body: requestBody,
|
|
71
|
+
} as Props),
|
|
56
72
|
createStatusCodes({ responses }),
|
|
57
73
|
]);
|
|
58
74
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
|
|
10
|
+
import { mergeAllOf } from "../markdown/createRequestSchema";
|
|
10
11
|
import { SchemaObject } from "./types";
|
|
11
12
|
|
|
12
13
|
interface OASTypeToTypeMap {
|
|
@@ -29,6 +30,7 @@ const primitives: Primitives = {
|
|
|
29
30
|
default: () => "string",
|
|
30
31
|
email: () => "user@example.com",
|
|
31
32
|
date: () => new Date().toISOString().substring(0, 10),
|
|
33
|
+
"date-time": () => new Date().toISOString().substring(0, 10),
|
|
32
34
|
uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
33
35
|
hostname: () => "example.com",
|
|
34
36
|
ipv4: () => "198.51.100.42",
|
|
@@ -58,21 +60,16 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
if (allOf) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
properties
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (item.properties) {
|
|
69
|
-
obj.properties = {
|
|
70
|
-
...obj.properties,
|
|
71
|
-
...item.properties,
|
|
72
|
-
};
|
|
63
|
+
const { mergedSchemas }: { mergedSchemas: SchemaObject } =
|
|
64
|
+
mergeAllOf(allOf);
|
|
65
|
+
if (mergedSchemas.properties) {
|
|
66
|
+
for (const [key, value] of Object.entries(mergedSchemas.properties)) {
|
|
67
|
+
if (value.readOnly && value.readOnly === true) {
|
|
68
|
+
delete mergedSchemas.properties[key];
|
|
69
|
+
}
|
|
73
70
|
}
|
|
74
71
|
}
|
|
75
|
-
return sampleFromSchema(
|
|
72
|
+
return sampleFromSchema(mergedSchemas);
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
if (!type) {
|
|
@@ -88,6 +85,22 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
88
85
|
if (type === "object") {
|
|
89
86
|
let obj: any = {};
|
|
90
87
|
for (let [name, prop] of Object.entries(properties ?? {})) {
|
|
88
|
+
if (prop.properties) {
|
|
89
|
+
for (const [key, value] of Object.entries(prop.properties)) {
|
|
90
|
+
if (value.readOnly && value.readOnly === true) {
|
|
91
|
+
delete prop.properties[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (prop.items && prop.items.properties) {
|
|
97
|
+
for (const [key, value] of Object.entries(prop.items.properties)) {
|
|
98
|
+
if (value.readOnly && value.readOnly === true) {
|
|
99
|
+
delete prop.items.properties[key];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
91
104
|
if (prop.deprecated) {
|
|
92
105
|
continue;
|
|
93
106
|
}
|
|
@@ -115,6 +128,10 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
115
128
|
return normalizeArray(schema.enum)[0];
|
|
116
129
|
}
|
|
117
130
|
|
|
131
|
+
if (schema.readOnly && schema.readOnly === true) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
118
135
|
return primitive(schema);
|
|
119
136
|
} catch (err) {
|
|
120
137
|
console.error(
|
|
@@ -131,7 +148,7 @@ function primitive(schema: SchemaObject = {}) {
|
|
|
131
148
|
return;
|
|
132
149
|
}
|
|
133
150
|
|
|
134
|
-
let fn = primitives[type].default;
|
|
151
|
+
let fn = schema.default ? () => schema.default : primitives[type].default;
|
|
135
152
|
|
|
136
153
|
if (format !== undefined) {
|
|
137
154
|
fn = primitives[type][format] || fn;
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -124,9 +124,7 @@ function createItems(
|
|
|
124
124
|
securitySchemes: openapiData.components?.securitySchemes,
|
|
125
125
|
info: {
|
|
126
126
|
...openapiData.info,
|
|
127
|
-
tags: openapiData.tags
|
|
128
|
-
getTagDisplayName(tagName.name!, openapiData.tags ?? [])
|
|
129
|
-
),
|
|
127
|
+
tags: openapiData.tags,
|
|
130
128
|
title: openapiData.info.title ?? "Introduction",
|
|
131
129
|
logo: openapiData.info["x-logo"]! as any,
|
|
132
130
|
darkLogo: openapiData.info["x-dark-logo"]! as any,
|
|
@@ -175,6 +173,18 @@ function createItems(
|
|
|
175
173
|
jsonRequestBodyExample = sampleFromSchema(body.schema);
|
|
176
174
|
}
|
|
177
175
|
|
|
176
|
+
// Handle vendor JSON media types
|
|
177
|
+
const bodyContent = operationObject.requestBody?.content;
|
|
178
|
+
if (bodyContent) {
|
|
179
|
+
const firstBodyContentKey = Object.keys(bodyContent)[0];
|
|
180
|
+
if (firstBodyContentKey.endsWith("+json")) {
|
|
181
|
+
const firstBody = bodyContent[firstBodyContentKey];
|
|
182
|
+
if (firstBody?.schema) {
|
|
183
|
+
jsonRequestBodyExample = sampleFromSchema(firstBody.schema);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
178
188
|
// TODO: Don't include summary temporarilly
|
|
179
189
|
const { summary, ...defaults } = operationObject;
|
|
180
190
|
|
|
@@ -188,9 +198,7 @@ function createItems(
|
|
|
188
198
|
frontMatter: {},
|
|
189
199
|
api: {
|
|
190
200
|
...defaults,
|
|
191
|
-
tags: operationObject.tags
|
|
192
|
-
getTagDisplayName(tagName, openapiData.tags ?? [])
|
|
193
|
-
),
|
|
201
|
+
tags: operationObject.tags,
|
|
194
202
|
method,
|
|
195
203
|
path,
|
|
196
204
|
servers,
|
|
@@ -291,7 +299,7 @@ export async function readOpenapiFiles(
|
|
|
291
299
|
export async function processOpenapiFiles(
|
|
292
300
|
files: OpenApiFiles[],
|
|
293
301
|
sidebarOptions: SidebarOptions
|
|
294
|
-
): Promise<[ApiMetadata[], TagObject[]]> {
|
|
302
|
+
): Promise<[ApiMetadata[], TagObject[][]]> {
|
|
295
303
|
const promises = files.map(async (file) => {
|
|
296
304
|
if (file.data !== undefined) {
|
|
297
305
|
const processedFile = await processOpenapiFile(file.data, sidebarOptions);
|
|
@@ -326,7 +334,7 @@ export async function processOpenapiFiles(
|
|
|
326
334
|
// Remove undefined tags due to transient parsing errors
|
|
327
335
|
return x !== undefined;
|
|
328
336
|
});
|
|
329
|
-
return [items as ApiMetadata[], tags as TagObject[]];
|
|
337
|
+
return [items as ApiMetadata[], tags as TagObject[][]];
|
|
330
338
|
}
|
|
331
339
|
|
|
332
340
|
export async function processOpenapiFile(
|
package/src/openapi/types.ts
CHANGED