docusaurus-plugin-openapi-docs 4.0.0 → 4.1.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.
@@ -104,6 +104,11 @@ function createAnyOneOf(schema: SchemaObject): any {
104
104
  delete anyOneSchema.allOf;
105
105
  }
106
106
 
107
+ if (anyOneSchema.oneOf !== undefined) {
108
+ anyOneChildren.push(createNodes(anyOneSchema, SCHEMA_TYPE));
109
+ delete anyOneSchema.oneOf;
110
+ }
111
+
107
112
  if (anyOneSchema.items !== undefined) {
108
113
  anyOneChildren.push(createItems(anyOneSchema));
109
114
  delete anyOneSchema.items;
@@ -411,16 +416,16 @@ function createDetailsNode(
411
416
  create("div", {
412
417
  style: { marginLeft: "1rem" },
413
418
  children: [
414
- guard(getQualifierMessage(schema), (message) =>
419
+ guard(schema.description, (description) =>
415
420
  create("div", {
416
421
  style: { marginTop: ".5rem", marginBottom: ".5rem" },
417
- children: createDescription(message),
422
+ children: createDescription(description),
418
423
  })
419
424
  ),
420
- guard(schema.description, (description) =>
425
+ guard(getQualifierMessage(schema), (message) =>
421
426
  create("div", {
422
427
  style: { marginTop: ".5rem", marginBottom: ".5rem" },
423
- children: createDescription(description),
428
+ children: createDescription(message),
424
429
  })
425
430
  ),
426
431
  createNodes(schema, SCHEMA_TYPE),
@@ -524,8 +529,9 @@ function createPropertyDiscriminator(
524
529
  return undefined;
525
530
  }
526
531
 
532
+ // render as a simple property if there's no mapping
527
533
  if (discriminator.mapping === undefined) {
528
- return undefined;
534
+ return createEdges({ name, schema, required });
529
535
  }
530
536
 
531
537
  return create("div", {
@@ -553,20 +559,20 @@ function createPropertyDiscriminator(
553
559
  ]),
554
560
  ],
555
561
  }),
556
- guard(getQualifierMessage(discriminator), (message) =>
562
+ guard(schema.description, (description) =>
557
563
  create("div", {
558
564
  style: {
559
565
  paddingLeft: "1rem",
560
566
  },
561
- children: createDescription(message),
567
+ children: createDescription(description),
562
568
  })
563
569
  ),
564
- guard(schema.description, (description) =>
570
+ guard(getQualifierMessage(discriminator), (message) =>
565
571
  create("div", {
566
572
  style: {
567
573
  paddingLeft: "1rem",
568
574
  },
569
- children: createDescription(description),
575
+ children: createDescription(message),
570
576
  })
571
577
  ),
572
578
  create("DiscriminatorTabs", {
@@ -681,50 +687,57 @@ function createEdges({
681
687
  const { mergedSchemas }: { mergedSchemas: SchemaObject } = mergeAllOf(
682
688
  schema.allOf
683
689
  );
690
+ delete schema.allOf;
691
+ const combinedSchemas = { ...schema, ...mergedSchemas };
684
692
 
685
693
  if (SCHEMA_TYPE === "request") {
686
- if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
694
+ if (combinedSchemas.readOnly && combinedSchemas.readOnly === true) {
687
695
  return undefined;
688
696
  }
689
697
  }
690
698
 
691
699
  if (SCHEMA_TYPE === "response") {
692
- if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
700
+ if (combinedSchemas.writeOnly && combinedSchemas.writeOnly === true) {
693
701
  return undefined;
694
702
  }
695
703
  }
696
704
 
697
- const mergedSchemaName = getSchemaName(mergedSchemas);
705
+ const mergedSchemaName = getSchemaName(combinedSchemas);
706
+
707
+ if (name === "eventName") {
708
+ console.log(mergedSchemaName, combinedSchemas);
709
+ }
710
+
698
711
  if (
699
- mergedSchemas.oneOf !== undefined ||
700
- mergedSchemas.anyOf !== undefined
712
+ combinedSchemas.oneOf !== undefined ||
713
+ combinedSchemas.anyOf !== undefined
701
714
  ) {
702
715
  return createDetailsNode(
703
716
  name,
704
717
  mergedSchemaName,
705
- mergedSchemas,
718
+ combinedSchemas,
706
719
  required,
707
- schema.nullable
720
+ combinedSchemas.nullable
708
721
  );
709
722
  }
710
723
 
711
- if (mergedSchemas.properties !== undefined) {
724
+ if (combinedSchemas.properties !== undefined) {
712
725
  return createDetailsNode(
713
726
  name,
714
727
  mergedSchemaName,
715
- mergedSchemas,
728
+ combinedSchemas,
716
729
  required,
717
- schema.nullable
730
+ combinedSchemas.nullable
718
731
  );
719
732
  }
720
733
 
721
- if (mergedSchemas.additionalProperties !== undefined) {
734
+ if (combinedSchemas.additionalProperties !== undefined) {
722
735
  return createDetailsNode(
723
736
  name,
724
737
  mergedSchemaName,
725
- mergedSchemas,
738
+ combinedSchemas,
726
739
  required,
727
- schema.nullable
740
+ combinedSchemas.nullable
728
741
  );
729
742
  }
730
743
 
@@ -733,9 +746,9 @@ function createEdges({
733
746
  return createDetailsNode(
734
747
  name,
735
748
  mergedSchemaName,
736
- mergedSchemas,
749
+ combinedSchemas,
737
750
  required,
738
- schema.nullable
751
+ combinedSchemas.nullable
739
752
  );
740
753
  }
741
754
 
@@ -744,8 +757,8 @@ function createEdges({
744
757
  name,
745
758
  required: Array.isArray(required) ? required.includes(name) : required,
746
759
  schemaName: mergedSchemaName,
747
- qualifierMessage: getQualifierMessage(mergedSchemas),
748
- schema: mergedSchemas,
760
+ qualifierMessage: getQualifierMessage(combinedSchemas),
761
+ schema: combinedSchemas,
749
762
  });
750
763
  }
751
764
 
@@ -5,6 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
+ /**
9
+ * Children in the plugin does not accept DOM elements, when compared with Children in the theme.
10
+ * It is designed for rendering HTML a strings.
11
+ */
8
12
  export type Children = string | undefined | (string | string[] | undefined)[];
9
13
 
10
14
  export type Props = Record<string, any> & { children?: Children };
@@ -269,7 +269,7 @@ function createItems(
269
269
 
270
270
  // Gather x-webhooks endpoints
271
271
  for (let [path, pathObject] of Object.entries(
272
- openapiData["x-webhooks"] ?? {}
272
+ openapiData["x-webhooks"] ?? openapiData["webhooks"] ?? {}
273
273
  )) {
274
274
  path = "webhook";
275
275
  const { $ref, description, parameters, servers, summary, ...rest } =
@@ -21,6 +21,7 @@ export interface OpenApiObject {
21
21
  tags?: TagObject[];
22
22
  externalDocs?: ExternalDocumentationObject;
23
23
  swagger?: string;
24
+ webhooks?: PathsObject;
24
25
  "x-webhooks"?: PathsObject;
25
26
  "x-tagGroups"?: TagGroupObject[];
26
27
  }
@@ -197,6 +198,7 @@ export interface ParameterObject {
197
198
  param?: Object;
198
199
  // ignoring stylings: matrix, label, form, simple, spaceDelimited,
199
200
  // pipeDelimited and deepObject
201
+ "x-enumDescriptions"?: Record<string, string>;
200
202
  }
201
203
 
202
204
  export interface ParameterObjectWithRef {
@@ -353,6 +355,7 @@ export type SchemaObject = Omit<
353
355
  example?: any;
354
356
  deprecated?: boolean;
355
357
  "x-tags"?: string[];
358
+ "x-enumDescriptions"?: Record<string, string>;
356
359
  };
357
360
 
358
361
  export type SchemaObjectWithRef = Omit<
@@ -270,6 +270,7 @@ export class OpenAPIParser {
270
270
  const {
271
271
  type,
272
272
  enum: enumProperty,
273
+ "x-enumDescription": enumDescription,
273
274
  properties,
274
275
  items,
275
276
  required,
package/src/options.ts CHANGED
@@ -7,12 +7,17 @@
7
7
 
8
8
  import { Joi } from "@docusaurus/utils-validation";
9
9
 
10
+ const sidebarGenerators = Joi.object({
11
+ createDocItem: Joi.function(),
12
+ });
13
+
10
14
  const sidebarOptions = Joi.object({
11
15
  groupPathsBy: Joi.string().valid("tag", "tagGroup"),
12
16
  categoryLinkSource: Joi.string().valid("tag", "info", "auto"),
13
17
  customProps: Joi.object(),
14
18
  sidebarCollapsible: Joi.boolean(),
15
19
  sidebarCollapsed: Joi.boolean(),
20
+ sidebarGenerators: sidebarGenerators,
16
21
  });
17
22
 
18
23
  const markdownGenerators = Joi.object({
@@ -12,7 +12,6 @@ import {
12
12
  ProcessedSidebar,
13
13
  SidebarItemCategory,
14
14
  SidebarItemCategoryLinkConfig,
15
- SidebarItemDoc,
16
15
  } from "@docusaurus/plugin-content-docs/src/sidebars/types";
17
16
  import { posixPath } from "@docusaurus/utils";
18
17
  import clsx from "clsx";
@@ -27,6 +26,7 @@ import type {
27
26
  ApiMetadata,
28
27
  InfoPageMetadata,
29
28
  SchemaPageMetadata,
29
+ ApiDocItemGenerator,
30
30
  } from "../types";
31
31
 
32
32
  function isApiItem(item: ApiMetadata): item is ApiMetadata {
@@ -41,6 +41,37 @@ function isSchemaItem(item: ApiMetadata): item is ApiMetadata {
41
41
  return item.type === "schema";
42
42
  }
43
43
 
44
+ const createDocItem: ApiDocItemGenerator = (
45
+ item,
46
+ { sidebarOptions: { customProps }, basePath }
47
+ ) => {
48
+ const sidebar_label = item.frontMatter.sidebar_label;
49
+ const title = item.title;
50
+ const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
51
+ const className =
52
+ item.type === "api"
53
+ ? clsx(
54
+ {
55
+ "menu__list-item--deprecated": item.api.deprecated,
56
+ "api-method": !!item.api.method,
57
+ },
58
+ item.api.method
59
+ )
60
+ : clsx(
61
+ {
62
+ "menu__list-item--deprecated": item.schema.deprecated,
63
+ },
64
+ "schema"
65
+ );
66
+ return {
67
+ type: "doc" as const,
68
+ id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
69
+ label: (sidebar_label as string) ?? title ?? id,
70
+ customProps: customProps,
71
+ className: className ? className : undefined,
72
+ };
73
+ };
74
+
44
75
  function groupByTags(
45
76
  items: ApiMetadata[],
46
77
  sidebarOptions: SidebarOptions,
@@ -53,12 +84,8 @@ function groupByTags(
53
84
  // Remove trailing slash before proceeding
54
85
  outputDir = outputDir.replace(/\/$/, "");
55
86
 
56
- const {
57
- sidebarCollapsed,
58
- sidebarCollapsible,
59
- customProps,
60
- categoryLinkSource,
61
- } = sidebarOptions;
87
+ const { sidebarCollapsed, sidebarCollapsible, categoryLinkSource } =
88
+ sidebarOptions;
62
89
 
63
90
  const apiItems = items.filter(isApiItem) as ApiPageMetadata[];
64
91
  const infoItems = items.filter(isInfoItem) as InfoPageMetadata[];
@@ -101,35 +128,13 @@ function groupByTags(
101
128
  const basePath = docPath
102
129
  ? outputDir.split(docPath!)[1].replace(/^\/+/g, "")
103
130
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
104
- function createDocItem(
105
- item: ApiPageMetadata | SchemaPageMetadata
106
- ): SidebarItemDoc {
107
- const sidebar_label = item.frontMatter.sidebar_label;
108
- const title = item.title;
109
- const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
110
- const className =
111
- item.type === "api"
112
- ? clsx(
113
- {
114
- "menu__list-item--deprecated": item.api.deprecated,
115
- "api-method": !!item.api.method,
116
- },
117
- item.api.method
118
- )
119
- : clsx(
120
- {
121
- "menu__list-item--deprecated": item.schema.deprecated,
122
- },
123
- "schema"
124
- );
125
- return {
126
- type: "doc" as const,
127
- id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
128
- label: (sidebar_label as string) ?? title ?? id,
129
- customProps: customProps,
130
- className: className ? className : undefined,
131
- };
132
- }
131
+
132
+ const createDocItemFnContext = {
133
+ sidebarOptions,
134
+ basePath,
135
+ };
136
+ const createDocItemFn =
137
+ sidebarOptions.sidebarGenerators?.createDocItem ?? createDocItem;
133
138
 
134
139
  let rootIntroDoc = undefined;
135
140
  if (infoItems.length === 1) {
@@ -208,7 +213,9 @@ function groupByTags(
208
213
  link: linkConfig,
209
214
  collapsible: sidebarCollapsible,
210
215
  collapsed: sidebarCollapsed,
211
- items: [...taggedSchemaItems, ...taggedApiItems].map(createDocItem),
216
+ items: [...taggedSchemaItems, ...taggedApiItems].map((item) =>
217
+ createDocItemFn(item, createDocItemFnContext)
218
+ ),
212
219
  };
213
220
  })
214
221
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
@@ -216,7 +223,7 @@ function groupByTags(
216
223
  // Handle items with no tag
217
224
  const untaggedItems = apiItems
218
225
  .filter(({ api }) => api.tags === undefined || api.tags.length === 0)
219
- .map(createDocItem);
226
+ .map((item) => createDocItemFn(item, createDocItemFnContext));
220
227
  let untagged: SidebarItemCategory[] = [];
221
228
  if (untaggedItems.length > 0) {
222
229
  untagged = [
@@ -227,7 +234,7 @@ function groupByTags(
227
234
  collapsed: sidebarCollapsed!,
228
235
  items: apiItems
229
236
  .filter(({ api }) => api.tags === undefined || api.tags.length === 0)
230
- .map(createDocItem),
237
+ .map((item) => createDocItemFn(item, createDocItemFnContext)),
231
238
  },
232
239
  ];
233
240
  }
@@ -242,7 +249,7 @@ function groupByTags(
242
249
  collapsed: sidebarCollapsed!,
243
250
  items: schemaItems
244
251
  .filter(({ schema }) => !schema["x-tags"])
245
- .map(createDocItem),
252
+ .map((item) => createDocItemFn(item, createDocItemFnContext)),
246
253
  },
247
254
  ];
248
255
  }
package/src/types.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
+ import { SidebarItemDoc } from "@docusaurus/plugin-content-docs/src/sidebars/types";
8
9
  import type Request from "postman-collection";
9
10
 
10
11
  import {
@@ -57,12 +58,22 @@ export interface MarkdownGenerator {
57
58
  createSchemaPageMD?: (pageData: SchemaPageMetadata) => string;
58
59
  }
59
60
 
61
+ export type ApiDocItemGenerator = (
62
+ item: ApiPageMetadata | SchemaPageMetadata,
63
+ context: { sidebarOptions: SidebarOptions; basePath: string }
64
+ ) => SidebarItemDoc;
65
+
66
+ export interface SidebarGenerators {
67
+ createDocItem?: ApiDocItemGenerator;
68
+ }
69
+
60
70
  export interface SidebarOptions {
61
71
  groupPathsBy?: string;
62
72
  categoryLinkSource?: "info" | "tag" | "auto";
63
73
  customProps?: { [key: string]: unknown };
64
74
  sidebarCollapsible?: boolean;
65
75
  sidebarCollapsed?: boolean;
76
+ sidebarGenerators?: SidebarGenerators;
66
77
  }
67
78
 
68
79
  export interface APIVersionOptions {