docusaurus-plugin-openapi-docs 0.0.0-824 → 0.0.0-832

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/README.md CHANGED
@@ -174,13 +174,15 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
174
174
 
175
175
  `sidebarOptions` can be configured with the following options:
176
176
 
177
- | Name | Type | Default | Description |
178
- | -------------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
179
- | `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by `tag` and `tagGroup`. |
180
- | `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br/><br/>The supported options are as follows: <br/><br/> `tag`: Sets the category link config type to `generated-index` and uses the tag description as the link config description. <br/><br/>`info`: Sets the category link config type to `doc` and renders the `info` section as the category link (recommended only for multi/micro-spec scenarios). <br/><br/>`none`: Does not create pages for categories, only groups that can be expanded/collapsed. |
181
- | `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
182
- | `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
183
- | `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
177
+ | Name | Type | Default | Description |
178
+ | -------------------- | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
179
+ | `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by `tag` and `tagGroup`. |
180
+ | `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br/><br/>The supported options are as follows: <br/><br/> `tag`: Sets the category link config type to `generated-index` and uses the tag description as the link config description. <br/><br/>`info`: Sets the category link config type to `doc` and renders the `info` section as the category link (recommended only for multi/micro-spec scenarios). <br/><br/>`none`: Does not create pages for categories, only groups that can be expanded/collapsed. |
181
+ | `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
182
+ | `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
183
+ | `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
184
+ | `sidebarGenerators` | `object` | `null` | Optional: Customize sidebar rendering with callback functions. |
185
+ | `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object, which allows for customisation of sidebar items. For example, add a class name in certain conditions, or add `customProps` to provide custom rendering. See below for a list of supported operations. |
184
186
 
185
187
  > You may optionally configure a `sidebarOptions`. In doing so, an individual `sidebar.js` slice with the configured options will be generated within the respective `outputDir`.
186
188
 
@@ -206,6 +208,14 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
206
208
  | `createTagPageMD` | `function` | `null` | _Optional:_ Returns a string of the raw markdown body for tag pages.<br/><br/>**Function type:** `(pageData: TagPageMetadata) => string` |
207
209
  | `createSchemaPageMD` | `function` | `null` | _Optional:_ Returns a string of the raw markdown body for schema pages.<br/><br/>**Function type:** `(pageData: SchemaPageMetadata) => string` |
208
210
 
211
+ ### sidebarGenerators
212
+
213
+ `sidebarGenerators` can be configured with the following options:
214
+
215
+ | Name | Type | Default | Description |
216
+ | --------------- | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
217
+ | `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.<br/><br/>**Function type** `(item: ApiPageMetadata | SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` |
218
+
209
219
  ## CLI Usage
210
220
 
211
221
  ```bash
@@ -61,7 +61,7 @@ async function createPostmanCollection(openapiData) {
61
61
  return await jsonToCollection(data);
62
62
  }
63
63
  function createItems(openapiData, options, sidebarOptions) {
64
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
65
65
  // TODO: Find a better way to handle this
66
66
  let items = [];
67
67
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
@@ -212,15 +212,15 @@ function createItems(openapiData, options, sidebarOptions) {
212
212
  }
213
213
  }
214
214
  // Gather x-webhooks endpoints
215
- for (let [path, pathObject] of Object.entries((_p = openapiData["x-webhooks"]) !== null && _p !== void 0 ? _p : {})) {
215
+ for (let [path, pathObject] of Object.entries((_q = (_p = openapiData["x-webhooks"]) !== null && _p !== void 0 ? _p : openapiData["webhooks"]) !== null && _q !== void 0 ? _q : {})) {
216
216
  path = "webhook";
217
217
  const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
218
218
  for (let [method, operationObject] of Object.entries({ ...rest })) {
219
219
  method = "event";
220
- const title = (_r = (_q = operationObject.summary) !== null && _q !== void 0 ? _q : operationObject.operationId) !== null && _r !== void 0 ? _r : "Missing summary";
220
+ const title = (_s = (_r = operationObject.summary) !== null && _r !== void 0 ? _r : operationObject.operationId) !== null && _s !== void 0 ? _s : "Missing summary";
221
221
  if (operationObject.description === undefined) {
222
222
  operationObject.description =
223
- (_t = (_s = operationObject.summary) !== null && _s !== void 0 ? _s : operationObject.operationId) !== null && _t !== void 0 ? _t : "";
223
+ (_u = (_t = operationObject.summary) !== null && _t !== void 0 ? _t : operationObject.operationId) !== null && _u !== void 0 ? _u : "";
224
224
  }
225
225
  const baseId = operationObject.operationId
226
226
  ? (0, kebabCase_1.default)(operationObject.operationId)
@@ -232,10 +232,10 @@ function createItems(openapiData, options, sidebarOptions) {
232
232
  extensions.push({ key, value });
233
233
  }
234
234
  }
235
- const servers = (_v = (_u = operationObject.servers) !== null && _u !== void 0 ? _u : pathObject.servers) !== null && _v !== void 0 ? _v : openapiData.servers;
236
- const security = (_w = operationObject.security) !== null && _w !== void 0 ? _w : openapiData.security;
235
+ const servers = (_w = (_v = operationObject.servers) !== null && _v !== void 0 ? _v : pathObject.servers) !== null && _w !== void 0 ? _w : openapiData.servers;
236
+ const security = (_x = operationObject.security) !== null && _x !== void 0 ? _x : openapiData.security;
237
237
  // Add security schemes so we know how to handle security.
238
- const securitySchemes = (_x = openapiData.components) === null || _x === void 0 ? void 0 : _x.securitySchemes;
238
+ const securitySchemes = (_y = openapiData.components) === null || _y === void 0 ? void 0 : _y.securitySchemes;
239
239
  // Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
240
240
  if (securitySchemes) {
241
241
  for (let securityScheme of Object.values(securitySchemes)) {
@@ -245,7 +245,7 @@ function createItems(openapiData, options, sidebarOptions) {
245
245
  }
246
246
  }
247
247
  let jsonRequestBodyExample;
248
- const content = (_y = operationObject.requestBody) === null || _y === void 0 ? void 0 : _y.content;
248
+ const content = (_z = operationObject.requestBody) === null || _z === void 0 ? void 0 : _z.content;
249
249
  let body;
250
250
  for (let key in content) {
251
251
  if (key.toLowerCase() === "application/json" ||
@@ -258,7 +258,7 @@ function createItems(openapiData, options, sidebarOptions) {
258
258
  jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(body.schema);
259
259
  }
260
260
  // Handle vendor JSON media types
261
- const bodyContent = (_z = operationObject.requestBody) === null || _z === void 0 ? void 0 : _z.content;
261
+ const bodyContent = (_0 = operationObject.requestBody) === null || _0 === void 0 ? void 0 : _0.content;
262
262
  if (bodyContent) {
263
263
  const firstBodyContentKey = Object.keys(bodyContent)[0];
264
264
  if (firstBodyContentKey.endsWith("+json")) {
@@ -325,13 +325,13 @@ function createItems(openapiData, options, sidebarOptions) {
325
325
  }
326
326
  }
327
327
  if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
328
- Object.entries((_1 = (_0 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _0 === void 0 ? void 0 : _0.schemas) !== null && _1 !== void 0 ? _1 : {})
328
+ Object.entries((_2 = (_1 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _1 === void 0 ? void 0 : _1.schemas) !== null && _2 !== void 0 ? _2 : {})
329
329
  .flatMap(([_, s]) => s["x-tags"])
330
330
  .filter((item) => !!item).length > 0) {
331
331
  // Gather schemas
332
- for (let [schema, schemaObject] of Object.entries((_3 = (_2 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _2 === void 0 ? void 0 : _2.schemas) !== null && _3 !== void 0 ? _3 : {})) {
332
+ for (let [schema, schemaObject] of Object.entries((_4 = (_3 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _3 === void 0 ? void 0 : _3.schemas) !== null && _4 !== void 0 ? _4 : {})) {
333
333
  if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true || schemaObject["x-tags"]) {
334
- const baseIdSpaces = (_5 = (_4 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _4 === void 0 ? void 0 : _4.replace(" ", "-").toLowerCase()) !== null && _5 !== void 0 ? _5 : "";
334
+ const baseIdSpaces = (_6 = (_5 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _5 === void 0 ? void 0 : _5.replace(" ", "-").toLowerCase()) !== null && _6 !== void 0 ? _6 : "";
335
335
  const baseId = (0, kebabCase_1.default)(baseIdSpaces);
336
336
  const schemaDescription = schemaObject.description;
337
337
  let splitDescription;
@@ -364,7 +364,7 @@ function createItems(openapiData, options, sidebarOptions) {
364
364
  }
365
365
  if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
366
366
  // Get global tags
367
- const tags = (_6 = openapiData.tags) !== null && _6 !== void 0 ? _6 : [];
367
+ const tags = (_7 = openapiData.tags) !== null && _7 !== void 0 ? _7 : [];
368
368
  // Get operation tags
369
369
  const apiItems = items.filter((item) => {
370
370
  return item.type === "api";
@@ -12,6 +12,7 @@ export interface OpenApiObject {
12
12
  tags?: TagObject[];
13
13
  externalDocs?: ExternalDocumentationObject;
14
14
  swagger?: string;
15
+ webhooks?: PathsObject;
15
16
  "x-webhooks"?: PathsObject;
16
17
  "x-tagGroups"?: TagGroupObject[];
17
18
  }
package/lib/options.js CHANGED
@@ -8,12 +8,16 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.OptionsSchema = void 0;
10
10
  const utils_validation_1 = require("@docusaurus/utils-validation");
11
+ const sidebarGenerators = utils_validation_1.Joi.object({
12
+ createDocItem: utils_validation_1.Joi.function(),
13
+ });
11
14
  const sidebarOptions = utils_validation_1.Joi.object({
12
15
  groupPathsBy: utils_validation_1.Joi.string().valid("tag", "tagGroup"),
13
16
  categoryLinkSource: utils_validation_1.Joi.string().valid("tag", "info", "auto"),
14
17
  customProps: utils_validation_1.Joi.object(),
15
18
  sidebarCollapsible: utils_validation_1.Joi.boolean(),
16
19
  sidebarCollapsed: utils_validation_1.Joi.boolean(),
20
+ sidebarGenerators: sidebarGenerators,
17
21
  });
18
22
  const markdownGenerators = utils_validation_1.Joi.object({
19
23
  createApiPageMD: utils_validation_1.Joi.function(),
@@ -23,11 +23,33 @@ function isInfoItem(item) {
23
23
  function isSchemaItem(item) {
24
24
  return item.type === "schema";
25
25
  }
26
+ const createDocItem = (item, { sidebarOptions: { customProps }, basePath }) => {
27
+ var _a, _b;
28
+ const sidebar_label = item.frontMatter.sidebar_label;
29
+ const title = item.title;
30
+ const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
31
+ const className = item.type === "api"
32
+ ? (0, clsx_1.default)({
33
+ "menu__list-item--deprecated": item.api.deprecated,
34
+ "api-method": !!item.api.method,
35
+ }, item.api.method)
36
+ : (0, clsx_1.default)({
37
+ "menu__list-item--deprecated": item.schema.deprecated,
38
+ }, "schema");
39
+ return {
40
+ type: "doc",
41
+ id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
42
+ label: (_b = (_a = sidebar_label) !== null && _a !== void 0 ? _a : title) !== null && _b !== void 0 ? _b : id,
43
+ customProps: customProps,
44
+ className: className ? className : undefined,
45
+ };
46
+ };
26
47
  function groupByTags(items, sidebarOptions, options, tags, docPath) {
48
+ var _a, _b;
27
49
  let { outputDir, label, showSchemas } = options;
28
50
  // Remove trailing slash before proceeding
29
51
  outputDir = outputDir.replace(/\/$/, "");
30
- const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
52
+ const { sidebarCollapsed, sidebarCollapsible, categoryLinkSource } = sidebarOptions;
31
53
  const apiItems = items.filter(isApiItem);
32
54
  const infoItems = items.filter(isInfoItem);
33
55
  const schemaItems = items.filter(isSchemaItem);
@@ -61,27 +83,11 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
61
83
  const basePath = docPath
62
84
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
63
85
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
64
- function createDocItem(item) {
65
- var _a, _b;
66
- const sidebar_label = item.frontMatter.sidebar_label;
67
- const title = item.title;
68
- const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
69
- const className = item.type === "api"
70
- ? (0, clsx_1.default)({
71
- "menu__list-item--deprecated": item.api.deprecated,
72
- "api-method": !!item.api.method,
73
- }, item.api.method)
74
- : (0, clsx_1.default)({
75
- "menu__list-item--deprecated": item.schema.deprecated,
76
- }, "schema");
77
- return {
78
- type: "doc",
79
- id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
80
- label: (_b = (_a = sidebar_label) !== null && _a !== void 0 ? _a : title) !== null && _b !== void 0 ? _b : id,
81
- customProps: customProps,
82
- className: className ? className : undefined,
83
- };
84
- }
86
+ const createDocItemFnContext = {
87
+ sidebarOptions,
88
+ basePath,
89
+ };
90
+ const createDocItemFn = (_b = (_a = sidebarOptions.sidebarGenerators) === null || _a === void 0 ? void 0 : _a.createDocItem) !== null && _b !== void 0 ? _b : createDocItem;
85
91
  let rootIntroDoc = undefined;
86
92
  if (infoItems.length === 1) {
87
93
  const infoItem = infoItems[0];
@@ -139,14 +145,14 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
139
145
  link: linkConfig,
140
146
  collapsible: sidebarCollapsible,
141
147
  collapsed: sidebarCollapsed,
142
- items: [...taggedSchemaItems, ...taggedApiItems].map(createDocItem),
148
+ items: [...taggedSchemaItems, ...taggedApiItems].map((item) => createDocItemFn(item, createDocItemFnContext)),
143
149
  };
144
150
  })
145
151
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
146
152
  // Handle items with no tag
147
153
  const untaggedItems = apiItems
148
154
  .filter(({ api }) => api.tags === undefined || api.tags.length === 0)
149
- .map(createDocItem);
155
+ .map((item) => createDocItemFn(item, createDocItemFnContext));
150
156
  let untagged = [];
151
157
  if (untaggedItems.length > 0) {
152
158
  untagged = [
@@ -157,7 +163,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
157
163
  collapsed: sidebarCollapsed,
158
164
  items: apiItems
159
165
  .filter(({ api }) => api.tags === undefined || api.tags.length === 0)
160
- .map(createDocItem),
166
+ .map((item) => createDocItemFn(item, createDocItemFnContext)),
161
167
  },
162
168
  ];
163
169
  }
@@ -171,7 +177,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
171
177
  collapsed: sidebarCollapsed,
172
178
  items: schemaItems
173
179
  .filter(({ schema }) => !schema["x-tags"])
174
- .map(createDocItem),
180
+ .map((item) => createDocItemFn(item, createDocItemFnContext)),
175
181
  },
176
182
  ];
177
183
  }
package/lib/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { SidebarItemDoc } from "@docusaurus/plugin-content-docs/src/sidebars/types";
1
2
  import type Request from "postman-collection";
2
3
  import { InfoObject, OperationObject, SchemaObject, SecuritySchemeObject, TagObject } from "./openapi/types";
3
4
  export type { PropSidebarItemCategory, SidebarItemLink, PropSidebar, PropSidebarItem, } from "@docusaurus/plugin-content-docs-types";
@@ -34,6 +35,13 @@ export interface MarkdownGenerator {
34
35
  createTagPageMD?: (pageData: TagPageMetadata) => string;
35
36
  createSchemaPageMD?: (pageData: SchemaPageMetadata) => string;
36
37
  }
38
+ export type ApiDocItemGenerator = (item: ApiPageMetadata | SchemaPageMetadata, context: {
39
+ sidebarOptions: SidebarOptions;
40
+ basePath: string;
41
+ }) => SidebarItemDoc;
42
+ export interface SidebarGenerators {
43
+ createDocItem?: ApiDocItemGenerator;
44
+ }
37
45
  export interface SidebarOptions {
38
46
  groupPathsBy?: string;
39
47
  categoryLinkSource?: "info" | "tag" | "auto";
@@ -42,6 +50,7 @@ export interface SidebarOptions {
42
50
  };
43
51
  sidebarCollapsible?: boolean;
44
52
  sidebarCollapsed?: boolean;
53
+ sidebarGenerators?: SidebarGenerators;
45
54
  }
46
55
  export interface APIVersionOptions {
47
56
  specPath: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-plugin-openapi-docs",
3
3
  "description": "OpenAPI plugin for Docusaurus.",
4
- "version": "0.0.0-824",
4
+ "version": "0.0.0-832",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -62,5 +62,5 @@
62
62
  "engines": {
63
63
  "node": ">=14"
64
64
  },
65
- "gitHead": "34abb2de0893a52b7e236e054e8d391f01ff0bc1"
65
+ "gitHead": "ea399ebfb6b1c0ec7e50ed4bfb299d634705b06a"
66
66
  }
@@ -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
  }
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 {