docusaurus-plugin-openapi-docs 4.0.1 → 4.2.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.
Files changed (55) hide show
  1. package/README.md +11 -0
  2. package/lib/index.js +4 -0
  3. package/lib/markdown/createCallbackMethodEndpoint.d.ts +1 -0
  4. package/lib/markdown/createCallbackMethodEndpoint.js +21 -0
  5. package/lib/markdown/createCallbacks.js +2 -2
  6. package/lib/markdown/createContactInfo.js +1 -1
  7. package/lib/markdown/createDeprecationNotice.js +5 -6
  8. package/lib/markdown/createMethodEndpoint.js +8 -1
  9. package/lib/markdown/createParamsDetails.d.ts +1 -2
  10. package/lib/markdown/createParamsDetails.js +7 -36
  11. package/lib/markdown/createRequestBodyDetails.d.ts +1 -1
  12. package/lib/markdown/createRequestSchema.d.ts +1 -1
  13. package/lib/markdown/createRequestSchema.js +8 -132
  14. package/lib/markdown/createResponseSchema.d.ts +1 -1
  15. package/lib/markdown/createResponseSchema.js +8 -94
  16. package/lib/markdown/createSchema.d.ts +1 -4
  17. package/lib/markdown/createSchema.js +35 -50
  18. package/lib/markdown/createSchema.test.js +48 -0
  19. package/lib/markdown/createStatusCodes.d.ts +1 -4
  20. package/lib/markdown/createStatusCodes.js +10 -259
  21. package/lib/markdown/index.js +11 -22
  22. package/lib/markdown/utils.d.ts +4 -0
  23. package/lib/openapi/createRequestExample.js +2 -2
  24. package/lib/openapi/createResponseExample.js +2 -2
  25. package/lib/openapi/openapi.js +16 -14
  26. package/lib/openapi/types.d.ts +4 -0
  27. package/lib/openapi/utils/services/OpenAPIParser.js +1 -1
  28. package/lib/options.js +5 -0
  29. package/lib/sidebars/index.js +32 -26
  30. package/lib/types.d.ts +9 -0
  31. package/package.json +7 -7
  32. package/src/index.ts +4 -0
  33. package/src/markdown/__snapshots__/createSchema.test.ts.snap +142 -0
  34. package/src/markdown/createCallbackMethodEndpoint.ts +19 -0
  35. package/src/markdown/createCallbacks.ts +2 -2
  36. package/src/markdown/createContactInfo.ts +1 -1
  37. package/src/markdown/createDeprecationNotice.ts +3 -2
  38. package/src/markdown/createMethodEndpoint.ts +8 -1
  39. package/src/markdown/createParamsDetails.ts +7 -42
  40. package/src/markdown/createRequestSchema.ts +9 -143
  41. package/src/markdown/createResponseSchema.ts +9 -112
  42. package/src/markdown/createSchema.test.ts +64 -0
  43. package/src/markdown/createSchema.ts +30 -50
  44. package/src/markdown/createStatusCodes.ts +9 -268
  45. package/src/markdown/index.ts +11 -22
  46. package/src/markdown/utils.ts +4 -0
  47. package/src/openapi/createRequestExample.ts +2 -5
  48. package/src/openapi/createResponseExample.ts +2 -5
  49. package/src/openapi/openapi.ts +4 -2
  50. package/src/openapi/types.ts +4 -0
  51. package/src/openapi/utils/loadAndResolveSpec.ts +1 -1
  52. package/src/openapi/utils/services/OpenAPIParser.ts +1 -0
  53. package/src/options.ts +6 -0
  54. package/src/sidebars/index.ts +47 -40
  55. package/src/types.ts +11 -0
@@ -5,11 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { createDescription } from "./createDescription";
9
- import { createDetails } from "./createDetails";
10
- import { createDetailsSummary } from "./createDetailsSummary";
11
- import { createNodes } from "./createSchema";
12
- import { create, guard } from "./utils";
8
+ import { create } from "./utils";
13
9
  import { MediaTypeObject } from "../openapi/types";
14
10
 
15
11
  interface Props {
@@ -25,142 +21,12 @@ interface Props {
25
21
  }
26
22
 
27
23
  export function createRequestSchema({ title, body, ...rest }: Props) {
28
- if (
29
- body === undefined ||
30
- body.content === undefined ||
31
- Object.keys(body).length === 0 ||
32
- Object.keys(body.content).length === 0
33
- ) {
34
- return undefined;
35
- }
36
-
37
- // Get all MIME types, including vendor-specific
38
- const mimeTypes = Object.keys(body.content);
39
-
40
- if (mimeTypes && mimeTypes.length > 1) {
41
- return create("MimeTabs", {
42
- className: "openapi-tabs__mime",
43
- schemaType: "request",
44
- children: mimeTypes.map((mimeType) => {
45
- const firstBody = body.content![mimeType].schema;
46
- if (firstBody === undefined) {
47
- return undefined;
48
- }
49
- if (firstBody.properties !== undefined) {
50
- if (Object.keys(firstBody.properties).length === 0) {
51
- return undefined;
52
- }
53
- }
54
- return create("TabItem", {
55
- label: mimeType,
56
- value: `${mimeType}`,
57
- children: [
58
- createDetails({
59
- className: "openapi-markdown__details mime",
60
- "data-collapsed": false,
61
- open: true,
62
- ...rest,
63
- children: [
64
- createDetailsSummary({
65
- className: "openapi-markdown__details-summary-mime",
66
- children: [
67
- create("h3", {
68
- className:
69
- "openapi-markdown__details-summary-header-body",
70
- children: `${title}`,
71
- }),
72
- guard(body.required && body.required === true, () => [
73
- create("span", {
74
- className: "openapi-schema__required",
75
- children: "required",
76
- }),
77
- ]),
78
- ],
79
- }),
80
- create("div", {
81
- style: { textAlign: "left", marginLeft: "1rem" },
82
- children: [
83
- guard(body.description, () => [
84
- create("div", {
85
- style: { marginTop: "1rem", marginBottom: "1rem" },
86
- children: createDescription(body.description),
87
- }),
88
- ]),
89
- ],
90
- }),
91
- create("ul", {
92
- style: { marginLeft: "1rem" },
93
- children: createNodes(firstBody, "request"),
94
- }),
95
- ],
96
- }),
97
- ],
98
- });
99
- }),
100
- });
101
- }
102
-
103
- const randomFirstKey = Object.keys(body.content)[0];
104
- const firstBody: any =
105
- body.content[randomFirstKey].schema ?? body.content![randomFirstKey];
106
-
107
- if (firstBody === undefined) {
108
- return undefined;
109
- }
110
-
111
- return create("MimeTabs", {
112
- className: "openapi-tabs__mime",
113
- children: [
114
- create("TabItem", {
115
- label: randomFirstKey,
116
- value: `${randomFirstKey}-schema`,
117
- children: [
118
- createDetails({
119
- className: "openapi-markdown__details mime",
120
- "data-collapsed": false,
121
- open: true,
122
- ...rest,
123
- children: [
124
- createDetailsSummary({
125
- className: "openapi-markdown__details-summary-mime",
126
- children: [
127
- create("h3", {
128
- className: "openapi-markdown__details-summary-header-body",
129
- children: `${title}`,
130
- }),
131
- guard(firstBody.type === "array", (format) =>
132
- create("span", {
133
- style: { opacity: "0.6" },
134
- children: ` array`,
135
- })
136
- ),
137
- guard(body.required, () => [
138
- create("strong", {
139
- className: "openapi-schema__required",
140
- children: "required",
141
- }),
142
- ]),
143
- ],
144
- }),
145
- create("div", {
146
- style: { textAlign: "left", marginLeft: "1rem" },
147
- children: [
148
- guard(body.description, () => [
149
- create("div", {
150
- style: { marginTop: "1rem", marginBottom: "1rem" },
151
- children: createDescription(body.description),
152
- }),
153
- ]),
154
- ],
155
- }),
156
- create("ul", {
157
- style: { marginLeft: "1rem" },
158
- children: createNodes(firstBody, "request"),
159
- }),
160
- ],
161
- }),
162
- ],
163
- }),
164
- ],
165
- });
24
+ return [
25
+ create("RequestSchema", {
26
+ title: title,
27
+ body: body,
28
+ ...rest,
29
+ }),
30
+ "\n\n",
31
+ ];
166
32
  }
@@ -5,16 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { createDescription } from "./createDescription";
9
- import { createDetails } from "./createDetails";
10
- import { createDetailsSummary } from "./createDetailsSummary";
11
- import { createNodes } from "./createSchema";
12
- import {
13
- createExampleFromSchema,
14
- createResponseExample,
15
- createResponseExamples,
16
- } from "./createStatusCodes";
17
- import { create, guard } from "./utils";
8
+ import { create } from "./utils";
18
9
  import { MediaTypeObject } from "../openapi/types";
19
10
 
20
11
  interface Props {
@@ -30,106 +21,12 @@ interface Props {
30
21
  }
31
22
 
32
23
  export function createResponseSchema({ title, body, ...rest }: Props) {
33
- if (
34
- body === undefined ||
35
- body.content === undefined ||
36
- Object.keys(body).length === 0 ||
37
- Object.keys(body.content).length === 0
38
- ) {
39
- return undefined;
40
- }
41
-
42
- // Get all MIME types, including vendor-specific
43
- const mimeTypes = Object.keys(body.content);
44
-
45
- if (mimeTypes && mimeTypes.length) {
46
- return create("MimeTabs", {
47
- className: "openapi-tabs__mime",
48
- schemaType: "response",
49
- children: mimeTypes.map((mimeType: any) => {
50
- const responseExamples = body.content![mimeType].examples;
51
- const responseExample = body.content![mimeType].example;
52
- const firstBody: any =
53
- body.content![mimeType].schema ?? body.content![mimeType];
54
-
55
- if (
56
- firstBody === undefined &&
57
- responseExample === undefined &&
58
- responseExamples === undefined
59
- ) {
60
- return undefined;
61
- }
62
-
63
- return create("TabItem", {
64
- label: `${mimeType}`,
65
- value: `${mimeType}`,
66
- children: [
67
- create("SchemaTabs", {
68
- className: "openapi-tabs__schema",
69
- // TODO: determine if we should persist this
70
- // groupId: "schema-tabs",
71
- children: [
72
- firstBody &&
73
- create("TabItem", {
74
- label: `${title}`,
75
- value: `${title}`,
76
- children: [
77
- createDetails({
78
- className: "openapi-markdown__details response",
79
- "data-collapsed": false,
80
- open: true,
81
- ...rest,
82
- children: [
83
- createDetailsSummary({
84
- className:
85
- "openapi-markdown__details-summary-response",
86
- children: [
87
- create("strong", { children: `${title}` }),
88
- guard(
89
- body.required && body.required === true,
90
- () => [
91
- create("span", {
92
- className: "openapi-schema__required",
93
- children: "required",
94
- }),
95
- ]
96
- ),
97
- ],
98
- }),
99
- create("div", {
100
- style: { textAlign: "left", marginLeft: "1rem" },
101
- children: [
102
- guard(body.description, () => [
103
- create("div", {
104
- style: {
105
- marginTop: "1rem",
106
- marginBottom: "1rem",
107
- },
108
- children: createDescription(body.description),
109
- }),
110
- ]),
111
- ],
112
- }),
113
- create("ul", {
114
- style: { marginLeft: "1rem" },
115
- children: createNodes(firstBody!, "response"),
116
- }),
117
- ],
118
- }),
119
- ],
120
- }),
121
- firstBody && createExampleFromSchema(firstBody, mimeType),
122
- responseExamples &&
123
- createResponseExamples(responseExamples, mimeType),
124
- responseExample &&
125
- createResponseExample(responseExample, mimeType),
126
- ],
127
- }),
128
- ],
129
- });
130
- }),
131
- });
132
- }
133
-
134
- return undefined;
24
+ return [
25
+ create("ResponseSchema", {
26
+ title: title,
27
+ body: body,
28
+ ...rest,
29
+ }),
30
+ "\n\n",
31
+ ];
135
32
  }
@@ -246,6 +246,70 @@ describe("createNodes", () => {
246
246
  });
247
247
  });
248
248
 
249
+ describe("anyOf", () => {
250
+ it("should render primitives within anyOf", async () => {
251
+ const schema: SchemaObject = {
252
+ type: "object",
253
+ properties: {
254
+ oneOfProperty: {
255
+ anyOf: [
256
+ {
257
+ type: "integer",
258
+ },
259
+ {
260
+ type: "boolean",
261
+ },
262
+ ],
263
+ title: "One of int or bool",
264
+ },
265
+ },
266
+ };
267
+
268
+ expect(
269
+ await Promise.all(
270
+ createNodes(schema, "response").map(
271
+ async (md: any) => await prettier.format(md, { parser: "babel" })
272
+ )
273
+ )
274
+ ).toMatchSnapshot();
275
+ });
276
+
277
+ it("should render oneOf within anyOf", async () => {
278
+ const schema: SchemaObject = {
279
+ type: "object",
280
+ properties: {
281
+ oneOfProperty: {
282
+ anyOf: [
283
+ {
284
+ oneOf: [
285
+ {
286
+ type: "integer",
287
+ },
288
+ {
289
+ type: "boolean",
290
+ },
291
+ ],
292
+ title: "An int or a bool",
293
+ },
294
+ {
295
+ type: "string",
296
+ },
297
+ ],
298
+ title: "One of int or bool, or a string",
299
+ },
300
+ },
301
+ };
302
+
303
+ expect(
304
+ await Promise.all(
305
+ createNodes(schema, "response").map(
306
+ async (md: any) => await prettier.format(md, { parser: "babel" })
307
+ )
308
+ )
309
+ ).toMatchSnapshot();
310
+ });
311
+ });
312
+
249
313
  describe("allOf", () => {
250
314
  it("should render same-level properties with allOf", async () => {
251
315
  const schema: SchemaObject = {
@@ -5,6 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
+ // eslint-disable-next-line import/no-extraneous-dependencies
9
+ import { merge } from "allof-merge";
8
10
  import clsx from "clsx";
9
11
  import isEmpty from "lodash/isEmpty";
10
12
 
@@ -19,41 +21,18 @@ import { getQualifierMessage, getSchemaName } from "./schema";
19
21
  import { create, guard } from "./utils";
20
22
  import { SchemaObject } from "../openapi/types";
21
23
 
22
- const jsonSchemaMergeAllOf = require("json-schema-merge-allof");
23
-
24
24
  let SCHEMA_TYPE: "request" | "response";
25
25
 
26
26
  /**
27
27
  * Returns a merged representation of allOf array of schemas.
28
28
  */
29
- export function mergeAllOf(allOf: SchemaObject[]) {
30
- const mergedSchemas = jsonSchemaMergeAllOf(allOf, {
31
- resolvers: {
32
- readOnly: function () {
33
- return true;
34
- },
35
- writeOnly: function () {
36
- return true;
37
- },
38
- example: function () {
39
- return true;
40
- },
41
- "x-examples": function () {
42
- return true;
43
- },
44
- },
45
- ignoreAdditionalProperties: true,
46
- });
47
-
48
- const mergedRequired = allOf.reduce((acc, cur) => {
49
- if (Array.isArray(cur.required)) {
50
- const next = [...acc, ...cur.required];
51
- return next;
52
- }
53
- return acc;
54
- }, [] as any);
29
+ export function mergeAllOf(allOf: SchemaObject) {
30
+ const onMergeError = (msg: string) => {
31
+ console.warn(msg);
32
+ };
55
33
 
56
- return { mergedSchemas, mergedRequired };
34
+ const mergedSchemas = merge(allOf, { onMergeError }) as SchemaObject;
35
+ return mergedSchemas;
57
36
  }
58
37
 
59
38
  /**
@@ -104,6 +83,11 @@ function createAnyOneOf(schema: SchemaObject): any {
104
83
  delete anyOneSchema.allOf;
105
84
  }
106
85
 
86
+ if (anyOneSchema.oneOf !== undefined) {
87
+ anyOneChildren.push(createNodes(anyOneSchema, SCHEMA_TYPE));
88
+ delete anyOneSchema.oneOf;
89
+ }
90
+
107
91
  if (anyOneSchema.items !== undefined) {
108
92
  anyOneChildren.push(createItems(anyOneSchema));
109
93
  delete anyOneSchema.items;
@@ -266,10 +250,7 @@ function createItems(schema: SchemaObject) {
266
250
 
267
251
  if (schema.items?.allOf !== undefined) {
268
252
  // TODO: figure out if and how we should pass merged required array
269
- const {
270
- mergedSchemas,
271
- }: { mergedSchemas: SchemaObject; mergedRequired: string[] | boolean } =
272
- mergeAllOf(schema.items?.allOf);
253
+ const mergedSchemas = mergeAllOf(schema.items) as SchemaObject;
273
254
 
274
255
  // Handles combo anyOf/oneOf + properties
275
256
  if (
@@ -411,16 +392,16 @@ function createDetailsNode(
411
392
  create("div", {
412
393
  style: { marginLeft: "1rem" },
413
394
  children: [
414
- guard(getQualifierMessage(schema), (message) =>
395
+ guard(schema.description, (description) =>
415
396
  create("div", {
416
397
  style: { marginTop: ".5rem", marginBottom: ".5rem" },
417
- children: createDescription(message),
398
+ children: createDescription(description),
418
399
  })
419
400
  ),
420
- guard(schema.description, (description) =>
401
+ guard(getQualifierMessage(schema), (message) =>
421
402
  create("div", {
422
403
  style: { marginTop: ".5rem", marginBottom: ".5rem" },
423
- children: createDescription(description),
404
+ children: createDescription(message),
424
405
  })
425
406
  ),
426
407
  createNodes(schema, SCHEMA_TYPE),
@@ -554,20 +535,20 @@ function createPropertyDiscriminator(
554
535
  ]),
555
536
  ],
556
537
  }),
557
- guard(getQualifierMessage(discriminator), (message) =>
538
+ guard(schema.description, (description) =>
558
539
  create("div", {
559
540
  style: {
560
541
  paddingLeft: "1rem",
561
542
  },
562
- children: createDescription(message),
543
+ children: createDescription(description),
563
544
  })
564
545
  ),
565
- guard(schema.description, (description) =>
546
+ guard(getQualifierMessage(discriminator), (message) =>
566
547
  create("div", {
567
548
  style: {
568
549
  paddingLeft: "1rem",
569
550
  },
570
- children: createDescription(description),
551
+ children: createDescription(message),
571
552
  })
572
553
  ),
573
554
  create("DiscriminatorTabs", {
@@ -678,10 +659,8 @@ function createEdges({
678
659
  );
679
660
  }
680
661
 
681
- if (schema.allOf !== undefined) {
682
- const { mergedSchemas }: { mergedSchemas: SchemaObject } = mergeAllOf(
683
- schema.allOf
684
- );
662
+ if (schema.items?.allOf !== undefined) {
663
+ const mergedSchemas = mergeAllOf(schema.items);
685
664
 
686
665
  if (SCHEMA_TYPE === "request") {
687
666
  if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
@@ -696,6 +675,7 @@ function createEdges({
696
675
  }
697
676
 
698
677
  const mergedSchemaName = getSchemaName(mergedSchemas);
678
+
699
679
  if (
700
680
  mergedSchemas.oneOf !== undefined ||
701
681
  mergedSchemas.anyOf !== undefined
@@ -705,7 +685,7 @@ function createEdges({
705
685
  mergedSchemaName,
706
686
  mergedSchemas,
707
687
  required,
708
- schema.nullable
688
+ mergedSchemas.nullable
709
689
  );
710
690
  }
711
691
 
@@ -715,7 +695,7 @@ function createEdges({
715
695
  mergedSchemaName,
716
696
  mergedSchemas,
717
697
  required,
718
- schema.nullable
698
+ mergedSchemas.nullable
719
699
  );
720
700
  }
721
701
 
@@ -725,7 +705,7 @@ function createEdges({
725
705
  mergedSchemaName,
726
706
  mergedSchemas,
727
707
  required,
728
- schema.nullable
708
+ mergedSchemas.nullable
729
709
  );
730
710
  }
731
711
 
@@ -736,7 +716,7 @@ function createEdges({
736
716
  mergedSchemaName,
737
717
  mergedSchemas,
738
718
  required,
739
- schema.nullable
719
+ mergedSchemas.nullable
740
720
  );
741
721
  }
742
722
 
@@ -803,7 +783,7 @@ export function createNodes(
803
783
  }
804
784
 
805
785
  if (schema.allOf !== undefined) {
806
- const { mergedSchemas } = mergeAllOf(schema.allOf);
786
+ const mergedSchemas = mergeAllOf(schema) as SchemaObject;
807
787
 
808
788
  if (
809
789
  mergedSchemas.oneOf !== undefined ||