docusaurus-plugin-openapi-docs 1.1.3 → 1.1.6
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/{createSchemaDetails.d.ts → createResponseSchema.d.ts} +2 -2
- package/lib/markdown/{createSchemaDetails.js → createResponseSchema.js} +110 -63
- 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 -2
- package/src/markdown/createRequestBodyDetails.ts +11 -4
- package/src/markdown/createRequestSchema.ts +848 -0
- package/src/markdown/{createSchemaDetails.ts → createResponseSchema.ts} +134 -72
- 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
|
@@ -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 (
|
|
@@ -568,13 +575,23 @@ function createEdges({
|
|
|
568
575
|
return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
|
|
569
576
|
}
|
|
570
577
|
|
|
578
|
+
// array of objects
|
|
579
|
+
if (mergedSchemas.items?.properties !== undefined) {
|
|
580
|
+
return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
|
|
584
|
+
return undefined;
|
|
585
|
+
}
|
|
586
|
+
|
|
571
587
|
return create("SchemaItem", {
|
|
572
588
|
collapsible: false,
|
|
573
589
|
name,
|
|
574
|
-
required,
|
|
590
|
+
required: false,
|
|
575
591
|
schemaDescription: mergedSchemas.description,
|
|
576
592
|
schemaName: schemaName,
|
|
577
593
|
qualifierMessage: getQualifierMessage(schema),
|
|
594
|
+
defaultValue: mergedSchemas.default,
|
|
578
595
|
});
|
|
579
596
|
}
|
|
580
597
|
|
|
@@ -591,14 +608,19 @@ function createEdges({
|
|
|
591
608
|
return createDetailsNode(name, schemaName, schema, required);
|
|
592
609
|
}
|
|
593
610
|
|
|
611
|
+
if (schema.writeOnly && schema.writeOnly === true) {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
|
|
594
615
|
// primitives and array of non-objects
|
|
595
616
|
return create("SchemaItem", {
|
|
596
617
|
collapsible: false,
|
|
597
618
|
name,
|
|
598
|
-
required,
|
|
619
|
+
required: false,
|
|
599
620
|
schemaDescription: schema.description,
|
|
600
621
|
schemaName: schemaName,
|
|
601
622
|
qualifierMessage: getQualifierMessage(schema),
|
|
623
|
+
defaultValue: schema.default,
|
|
602
624
|
});
|
|
603
625
|
}
|
|
604
626
|
|
|
@@ -627,7 +649,8 @@ function createNodes(schema: SchemaObject): any {
|
|
|
627
649
|
return createProperties(schema);
|
|
628
650
|
}
|
|
629
651
|
|
|
630
|
-
if
|
|
652
|
+
// Could be set to false to just check if evals to true
|
|
653
|
+
if (schema.additionalProperties) {
|
|
631
654
|
return createAdditionalProperties(schema);
|
|
632
655
|
}
|
|
633
656
|
|
|
@@ -678,11 +701,11 @@ interface Props {
|
|
|
678
701
|
[key: string]: MediaTypeObject;
|
|
679
702
|
};
|
|
680
703
|
description?: string;
|
|
681
|
-
required?: boolean;
|
|
704
|
+
required?: string[] | boolean;
|
|
682
705
|
};
|
|
683
706
|
}
|
|
684
707
|
|
|
685
|
-
export function
|
|
708
|
+
export function createResponseSchema({ title, body, ...rest }: Props) {
|
|
686
709
|
if (
|
|
687
710
|
body === undefined ||
|
|
688
711
|
body.content === undefined ||
|
|
@@ -692,64 +715,103 @@ export function createSchemaDetails({ title, body, ...rest }: Props) {
|
|
|
692
715
|
return undefined;
|
|
693
716
|
}
|
|
694
717
|
|
|
695
|
-
//
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
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
|
-
|
|
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
|
+
],
|
|
745
809
|
}),
|
|
746
|
-
]
|
|
747
|
-
|
|
748
|
-
}),
|
|
749
|
-
create("ul", {
|
|
750
|
-
style: { marginLeft: "1rem" },
|
|
751
|
-
children: createNodes(firstBody),
|
|
810
|
+
],
|
|
811
|
+
});
|
|
752
812
|
}),
|
|
753
|
-
|
|
754
|
-
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return undefined;
|
|
755
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