docusaurus-plugin-openapi-docs 1.4.2 → 1.4.4

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/index.js CHANGED
@@ -125,7 +125,7 @@ description: "{{{frontMatter.description}}}"
125
125
  sidebar_label: Introduction
126
126
  {{/api}}
127
127
  {{#api}}
128
- sidebar_label: {{{title}}}
128
+ sidebar_label: "{{{title}}}"
129
129
  {{/api}}
130
130
  {{^api}}
131
131
  sidebar_position: 0
@@ -151,7 +151,7 @@ info_path: {{{infoPath}}}
151
151
  id: {{{id}}}
152
152
  title: "{{{title}}}"
153
153
  description: "{{{frontMatter.description}}}"
154
- sidebar_label: {{{title}}}
154
+ sidebar_label: "{{{title}}}"
155
155
  hide_title: true
156
156
  custom_edit_url: null
157
157
  ---
@@ -259,7 +259,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
259
259
  }
260
260
  async function cleanApiDocs(options) {
261
261
  const { outputDir } = options;
262
- const apiDir = path_1.default.join(siteDir, outputDir);
262
+ const apiDir = (0, utils_1.posixPath)(path_1.default.join(siteDir, outputDir));
263
263
  const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
264
264
  cwd: path_1.default.resolve(apiDir),
265
265
  deep: 1,
@@ -25,6 +25,9 @@ function mergeAllOf(allOf) {
25
25
  example: function () {
26
26
  return true;
27
27
  },
28
+ "x-examples": function () {
29
+ return true;
30
+ },
28
31
  ignoreAdditionalProperties: true,
29
32
  },
30
33
  });
@@ -26,6 +26,9 @@ function mergeAllOf(allOf) {
26
26
  example: function () {
27
27
  return true;
28
28
  },
29
+ "x-examples": function () {
30
+ return true;
31
+ },
29
32
  },
30
33
  ignoreAdditionalProperties: true,
31
34
  });
@@ -19,6 +19,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
19
19
  const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
20
20
  const kebabCase_1 = __importDefault(require("lodash/kebabCase"));
21
21
  const unionBy_1 = __importDefault(require("lodash/unionBy"));
22
+ const uniq_1 = __importDefault(require("lodash/uniq"));
22
23
  const index_1 = require("../index");
23
24
  const createRequestExample_1 = require("./createRequestExample");
24
25
  const loadAndResolveSpec_1 = require("./utils/loadAndResolveSpec");
@@ -64,41 +65,9 @@ function createItems(openapiData, sidebarOptions) {
64
65
  // TODO: Find a better way to handle this
65
66
  let items = [];
66
67
  const infoId = (0, kebabCase_1.default)(openapiData.info.title);
67
- if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
68
- // Only create an tag pages if categoryLinkSource set to tag.
69
- const tags = (_a = openapiData.tags) !== null && _a !== void 0 ? _a : [];
70
- // eslint-disable-next-line array-callback-return
71
- tags
72
- .filter((tag) => { var _a; return !((_a = tag.description) === null || _a === void 0 ? void 0 : _a.includes("SchemaDefinition")); })
73
- // eslint-disable-next-line array-callback-return
74
- .map((tag) => {
75
- var _a;
76
- const description = getTagDisplayName(tag.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []);
77
- const tagId = (0, kebabCase_1.default)(tag.name);
78
- const splitDescription = description.match(/[^\r\n]+/g);
79
- const tagPage = {
80
- type: "tag",
81
- id: tagId,
82
- unversionedId: tagId,
83
- title: description !== null && description !== void 0 ? description : "",
84
- description: description !== null && description !== void 0 ? description : "",
85
- frontMatter: {
86
- description: splitDescription
87
- ? splitDescription[0]
88
- .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
89
- .replace(/\s+$/, "")
90
- : "",
91
- },
92
- tag: {
93
- ...tag,
94
- },
95
- };
96
- items.push(tagPage);
97
- });
98
- }
99
68
  if (openapiData.info.description) {
100
69
  // Only create an info page if we have a description.
101
- const infoDescription = (_b = openapiData.info) === null || _b === void 0 ? void 0 : _b.description;
70
+ const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
102
71
  let splitDescription;
103
72
  if (infoDescription) {
104
73
  splitDescription = infoDescription.match(/[^\r\n]+/g);
@@ -107,7 +76,9 @@ function createItems(openapiData, sidebarOptions) {
107
76
  type: "info",
108
77
  id: infoId,
109
78
  unversionedId: infoId,
110
- title: openapiData.info.title,
79
+ title: openapiData.info.title
80
+ ? openapiData.info.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
81
+ : "",
111
82
  description: openapiData.info.description
112
83
  ? openapiData.info.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
113
84
  : "",
@@ -118,11 +89,11 @@ function createItems(openapiData, sidebarOptions) {
118
89
  .replace(/\s+$/, "")
119
90
  : "",
120
91
  },
121
- securitySchemes: (_c = openapiData.components) === null || _c === void 0 ? void 0 : _c.securitySchemes,
92
+ securitySchemes: (_b = openapiData.components) === null || _b === void 0 ? void 0 : _b.securitySchemes,
122
93
  info: {
123
94
  ...openapiData.info,
124
95
  tags: openapiData.tags,
125
- title: (_d = openapiData.info.title) !== null && _d !== void 0 ? _d : "Introduction",
96
+ title: (_c = openapiData.info.title) !== null && _c !== void 0 ? _c : "Introduction",
126
97
  logo: openapiData.info["x-logo"],
127
98
  darkLogo: openapiData.info["x-dark-logo"],
128
99
  },
@@ -132,18 +103,18 @@ function createItems(openapiData, sidebarOptions) {
132
103
  for (let [path, pathObject] of Object.entries(openapiData.paths)) {
133
104
  const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
134
105
  for (let [method, operationObject] of Object.entries({ ...rest })) {
135
- const title = (_f = (_e = operationObject.summary) !== null && _e !== void 0 ? _e : operationObject.operationId) !== null && _f !== void 0 ? _f : "Missing summary";
106
+ const title = (_e = (_d = operationObject.summary) !== null && _d !== void 0 ? _d : operationObject.operationId) !== null && _e !== void 0 ? _e : "Missing summary";
136
107
  if (operationObject.description === undefined) {
137
108
  operationObject.description =
138
- (_h = (_g = operationObject.summary) !== null && _g !== void 0 ? _g : operationObject.operationId) !== null && _h !== void 0 ? _h : "";
109
+ (_g = (_f = operationObject.summary) !== null && _f !== void 0 ? _f : operationObject.operationId) !== null && _g !== void 0 ? _g : "";
139
110
  }
140
111
  const baseId = operationObject.operationId
141
112
  ? (0, kebabCase_1.default)(operationObject.operationId)
142
113
  : (0, kebabCase_1.default)(operationObject.summary);
143
- const servers = (_k = (_j = operationObject.servers) !== null && _j !== void 0 ? _j : pathObject.servers) !== null && _k !== void 0 ? _k : openapiData.servers;
144
- const security = (_l = operationObject.security) !== null && _l !== void 0 ? _l : openapiData.security;
114
+ const servers = (_j = (_h = operationObject.servers) !== null && _h !== void 0 ? _h : pathObject.servers) !== null && _j !== void 0 ? _j : openapiData.servers;
115
+ const security = (_k = operationObject.security) !== null && _k !== void 0 ? _k : openapiData.security;
145
116
  // Add security schemes so we know how to handle security.
146
- const securitySchemes = (_m = openapiData.components) === null || _m === void 0 ? void 0 : _m.securitySchemes;
117
+ const securitySchemes = (_l = openapiData.components) === null || _l === void 0 ? void 0 : _l.securitySchemes;
147
118
  // Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
148
119
  if (securitySchemes) {
149
120
  for (let securityScheme of Object.values(securitySchemes)) {
@@ -153,12 +124,12 @@ function createItems(openapiData, sidebarOptions) {
153
124
  }
154
125
  }
155
126
  let jsonRequestBodyExample;
156
- const body = (_p = (_o = operationObject.requestBody) === null || _o === void 0 ? void 0 : _o.content) === null || _p === void 0 ? void 0 : _p["application/json"];
127
+ const body = (_o = (_m = operationObject.requestBody) === null || _m === void 0 ? void 0 : _m.content) === null || _o === void 0 ? void 0 : _o["application/json"];
157
128
  if (body === null || body === void 0 ? void 0 : body.schema) {
158
129
  jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(body.schema);
159
130
  }
160
131
  // Handle vendor JSON media types
161
- const bodyContent = (_q = operationObject.requestBody) === null || _q === void 0 ? void 0 : _q.content;
132
+ const bodyContent = (_p = operationObject.requestBody) === null || _p === void 0 ? void 0 : _p.content;
162
133
  if (bodyContent) {
163
134
  const firstBodyContentKey = Object.keys(bodyContent)[0];
164
135
  if (firstBodyContentKey.endsWith("+json")) {
@@ -190,7 +161,7 @@ function createItems(openapiData, sidebarOptions) {
190
161
  id: baseId,
191
162
  infoId: infoId !== null && infoId !== void 0 ? infoId : "",
192
163
  unversionedId: baseId,
193
- title: title,
164
+ title: title ? title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'") : "",
194
165
  description: operationObject.description
195
166
  ? operationObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
196
167
  : "",
@@ -216,6 +187,45 @@ function createItems(openapiData, sidebarOptions) {
216
187
  items.push(apiPage);
217
188
  }
218
189
  }
190
+ if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
191
+ // Get global tags
192
+ const tags = (_q = openapiData.tags) !== null && _q !== void 0 ? _q : [];
193
+ // Get operation tags
194
+ const apiItems = items.filter((item) => {
195
+ return item.type === "api";
196
+ });
197
+ const operationTags = (0, uniq_1.default)(apiItems
198
+ .flatMap((item) => item.api.tags)
199
+ .filter((item) => !!item));
200
+ // eslint-disable-next-line array-callback-return
201
+ tags
202
+ .filter((tag) => operationTags.includes(tag.name)) // include only tags referenced by operation
203
+ // eslint-disable-next-line array-callback-return
204
+ .map((tag) => {
205
+ var _a;
206
+ const description = getTagDisplayName(tag.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []);
207
+ const tagId = (0, kebabCase_1.default)(tag.name);
208
+ const splitDescription = description.match(/[^\r\n]+/g);
209
+ const tagPage = {
210
+ type: "tag",
211
+ id: tagId,
212
+ unversionedId: tagId,
213
+ title: description !== null && description !== void 0 ? description : "",
214
+ description: description !== null && description !== void 0 ? description : "",
215
+ frontMatter: {
216
+ description: splitDescription
217
+ ? splitDescription[0]
218
+ .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
219
+ .replace(/\s+$/, "")
220
+ : "",
221
+ },
222
+ tag: {
223
+ ...tag,
224
+ },
225
+ };
226
+ items.push(tagPage);
227
+ });
228
+ }
219
229
  return items;
220
230
  }
221
231
  /**
@@ -251,7 +261,7 @@ async function readOpenapiFiles(openapiPath, options) {
251
261
  const sources = allFiles.filter((x) => !x.includes("_category_")); // todo: regex exclude?
252
262
  return Promise.all(sources.map(async (source) => {
253
263
  // TODO: make a function for this
254
- const fullPath = path_1.default.join(openapiPath, source);
264
+ const fullPath = (0, utils_1.posixPath)(path_1.default.join(openapiPath, source));
255
265
  const data = (await (0, loadAndResolveSpec_1.loadAndResolveSpec)(fullPath));
256
266
  return {
257
267
  source: fullPath,
@@ -10,12 +10,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const path_1 = __importDefault(require("path"));
13
+ const utils_1 = require("@docusaurus/utils");
13
14
  const _1 = require(".");
14
15
  // npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
15
16
  describe("openapi", () => {
16
17
  describe("readOpenapiFiles", () => {
17
18
  it("readOpenapiFiles", async () => {
18
- const results = await (0, _1.readOpenapiFiles)(path_1.default.join(__dirname, "__fixtures__/examples"), { specPath: "./", outputDir: "./" });
19
+ const results = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/examples")), { specPath: "./", outputDir: "./" });
19
20
  const categoryMeta = results.find((x) => x.source.endsWith("_category_.json"));
20
21
  expect(categoryMeta).toBeFalsy();
21
22
  // console.log(results);
@@ -10,6 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const path_1 = __importDefault(require("path"));
13
+ const utils_1 = require("@docusaurus/utils");
13
14
  const clsx_1 = __importDefault(require("clsx"));
14
15
  const lodash_1 = require("lodash");
15
16
  const uniq_1 = __importDefault(require("lodash/uniq"));
@@ -37,9 +38,13 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
37
38
  .flatMap((item) => item.api.tags)
38
39
  .filter((item) => !!item));
39
40
  // Combine globally defined tags with operation tags
41
+ // Only include global tag if referenced in operation tags
40
42
  let apiTags = [];
41
43
  tags.flat().forEach((tag) => {
42
- apiTags.push(tag.name);
44
+ // Should we also check x-displayName?
45
+ if (operationTags.includes(tag.name)) {
46
+ apiTags.push(tag.name);
47
+ }
43
48
  });
44
49
  apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
45
50
  const basePath = docPath
@@ -106,8 +111,8 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
106
111
  type: "generated-index",
107
112
  title: tag,
108
113
  slug: label
109
- ? path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(label), (0, lodash_1.kebabCase)(tag))
110
- : path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(tag)),
114
+ ? (0, utils_1.posixPath)(path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(label), (0, lodash_1.kebabCase)(tag)))
115
+ : (0, utils_1.posixPath)(path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(tag))),
111
116
  };
112
117
  }
113
118
  return {
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": "1.4.2",
4
+ "version": "1.4.4",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,8 +28,8 @@
28
28
  "watch": "tsc --watch"
29
29
  },
30
30
  "devDependencies": {
31
- "@docusaurus/module-type-aliases": "2.0.1",
32
- "@docusaurus/types": "2.0.1",
31
+ "@docusaurus/module-type-aliases": "^2.0.1",
32
+ "@docusaurus/types": "^2.0.1",
33
33
  "@types/fs-extra": "^9.0.13",
34
34
  "@types/js-yaml": "^4.0.5",
35
35
  "@types/json-pointer": "^1.0.31",
@@ -68,5 +68,5 @@
68
68
  "engines": {
69
69
  "node": ">=14"
70
70
  },
71
- "gitHead": "e5337f7fecf3b082c0781f798a479b2a63237432"
71
+ "gitHead": "05860ecc586244bcb84b5daa095a4110b807a95c"
72
72
  }
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@ import fs from "fs";
9
9
  import path from "path";
10
10
 
11
11
  import type { LoadContext, Plugin } from "@docusaurus/types";
12
- import { Globby } from "@docusaurus/utils";
12
+ import { Globby, posixPath } from "@docusaurus/utils";
13
13
  import chalk from "chalk";
14
14
  import { render } from "mustache";
15
15
 
@@ -164,7 +164,7 @@ description: "{{{frontMatter.description}}}"
164
164
  sidebar_label: Introduction
165
165
  {{/api}}
166
166
  {{#api}}
167
- sidebar_label: {{{title}}}
167
+ sidebar_label: "{{{title}}}"
168
168
  {{/api}}
169
169
  {{^api}}
170
170
  sidebar_position: 0
@@ -191,7 +191,7 @@ info_path: {{{infoPath}}}
191
191
  id: {{{id}}}
192
192
  title: "{{{title}}}"
193
193
  description: "{{{frontMatter.description}}}"
194
- sidebar_label: {{{title}}}
194
+ sidebar_label: "{{{title}}}"
195
195
  hide_title: true
196
196
  custom_edit_url: null
197
197
  ---
@@ -338,7 +338,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
338
338
 
339
339
  async function cleanApiDocs(options: APIOptions) {
340
340
  const { outputDir } = options;
341
- const apiDir = path.join(siteDir, outputDir);
341
+ const apiDir = posixPath(path.join(siteDir, outputDir));
342
342
  const apiMdxFiles = await Globby(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
343
343
  cwd: path.resolve(apiDir),
344
344
  deep: 1,
@@ -26,6 +26,9 @@ export function mergeAllOf(allOf: SchemaObject[]) {
26
26
  example: function () {
27
27
  return true;
28
28
  },
29
+ "x-examples": function () {
30
+ return true;
31
+ },
29
32
  ignoreAdditionalProperties: true,
30
33
  },
31
34
  });
@@ -31,6 +31,9 @@ export function mergeAllOf(allOf: SchemaObject[]) {
31
31
  example: function () {
32
32
  return true;
33
33
  },
34
+ "x-examples": function () {
35
+ return true;
36
+ },
34
37
  },
35
38
  ignoreAdditionalProperties: true,
36
39
  });
@@ -7,6 +7,8 @@
7
7
 
8
8
  import path from "path";
9
9
 
10
+ import { posixPath } from "@docusaurus/utils";
11
+
10
12
  import { readOpenapiFiles } from ".";
11
13
 
12
14
  // npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
@@ -15,7 +17,7 @@ describe("openapi", () => {
15
17
  describe("readOpenapiFiles", () => {
16
18
  it("readOpenapiFiles", async () => {
17
19
  const results = await readOpenapiFiles(
18
- path.join(__dirname, "__fixtures__/examples"),
20
+ posixPath(path.join(__dirname, "__fixtures__/examples")),
19
21
  { specPath: "./", outputDir: "./" }
20
22
  );
21
23
  const categoryMeta = results.find((x) =>
@@ -7,7 +7,7 @@
7
7
 
8
8
  import path from "path";
9
9
 
10
- import { Globby, GlobExcludeDefault } from "@docusaurus/utils";
10
+ import { Globby, GlobExcludeDefault, posixPath } from "@docusaurus/utils";
11
11
  import Converter from "@paloaltonetworks/openapi-to-postmanv2";
12
12
  import sdk from "@paloaltonetworks/postman-collection";
13
13
  import Collection from "@paloaltonetworks/postman-collection";
@@ -16,6 +16,7 @@ import fs from "fs-extra";
16
16
  import cloneDeep from "lodash/cloneDeep";
17
17
  import kebabCase from "lodash/kebabCase";
18
18
  import unionBy from "lodash/unionBy";
19
+ import uniq from "lodash/uniq";
19
20
 
20
21
  import { isURL } from "../index";
21
22
  import {
@@ -85,41 +86,6 @@ function createItems(
85
86
  let items: PartialPage<ApiMetadata>[] = [];
86
87
  const infoId = kebabCase(openapiData.info.title);
87
88
 
88
- if (sidebarOptions?.categoryLinkSource === "tag") {
89
- // Only create an tag pages if categoryLinkSource set to tag.
90
- const tags: TagObject[] = openapiData.tags ?? [];
91
- // eslint-disable-next-line array-callback-return
92
- tags
93
- .filter((tag) => !tag.description?.includes("SchemaDefinition"))
94
- // eslint-disable-next-line array-callback-return
95
- .map((tag) => {
96
- const description = getTagDisplayName(
97
- tag.name!,
98
- openapiData.tags ?? []
99
- );
100
- const tagId = kebabCase(tag.name);
101
- const splitDescription = description.match(/[^\r\n]+/g);
102
- const tagPage: PartialPage<TagPageMetadata> = {
103
- type: "tag",
104
- id: tagId,
105
- unversionedId: tagId,
106
- title: description ?? "",
107
- description: description ?? "",
108
- frontMatter: {
109
- description: splitDescription
110
- ? splitDescription[0]
111
- .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
112
- .replace(/\s+$/, "")
113
- : "",
114
- },
115
- tag: {
116
- ...tag,
117
- },
118
- };
119
- items.push(tagPage);
120
- });
121
- }
122
-
123
89
  if (openapiData.info.description) {
124
90
  // Only create an info page if we have a description.
125
91
  const infoDescription = openapiData.info?.description;
@@ -131,7 +97,9 @@ function createItems(
131
97
  type: "info",
132
98
  id: infoId,
133
99
  unversionedId: infoId,
134
- title: openapiData.info.title,
100
+ title: openapiData.info.title
101
+ ? openapiData.info.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
102
+ : "",
135
103
  description: openapiData.info.description
136
104
  ? openapiData.info.description.replace(
137
105
  /((?:^|[^\\])(?:\\{2})*)"/g,
@@ -237,7 +205,7 @@ function createItems(
237
205
  id: baseId,
238
206
  infoId: infoId ?? "",
239
207
  unversionedId: baseId,
240
- title: title,
208
+ title: title ? title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'") : "",
241
209
  description: operationObject.description
242
210
  ? operationObject.description.replace(
243
211
  /((?:^|[^\\])(?:\\{2})*)"/g,
@@ -268,6 +236,52 @@ function createItems(
268
236
  }
269
237
  }
270
238
 
239
+ if (sidebarOptions?.categoryLinkSource === "tag") {
240
+ // Get global tags
241
+ const tags: TagObject[] = openapiData.tags ?? [];
242
+
243
+ // Get operation tags
244
+ const apiItems = items.filter((item) => {
245
+ return item.type === "api";
246
+ }) as ApiPageMetadata[];
247
+ const operationTags = uniq(
248
+ apiItems
249
+ .flatMap((item) => item.api.tags)
250
+ .filter((item): item is string => !!item)
251
+ );
252
+
253
+ // eslint-disable-next-line array-callback-return
254
+ tags
255
+ .filter((tag) => operationTags.includes(tag.name!)) // include only tags referenced by operation
256
+ // eslint-disable-next-line array-callback-return
257
+ .map((tag) => {
258
+ const description = getTagDisplayName(
259
+ tag.name!,
260
+ openapiData.tags ?? []
261
+ );
262
+ const tagId = kebabCase(tag.name);
263
+ const splitDescription = description.match(/[^\r\n]+/g);
264
+ const tagPage: PartialPage<TagPageMetadata> = {
265
+ type: "tag",
266
+ id: tagId,
267
+ unversionedId: tagId,
268
+ title: description ?? "",
269
+ description: description ?? "",
270
+ frontMatter: {
271
+ description: splitDescription
272
+ ? splitDescription[0]
273
+ .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
274
+ .replace(/\s+$/, "")
275
+ : "",
276
+ },
277
+ tag: {
278
+ ...tag,
279
+ },
280
+ };
281
+ items.push(tagPage);
282
+ });
283
+ }
284
+
271
285
  return items as ApiMetadata[];
272
286
  }
273
287
 
@@ -320,7 +334,7 @@ export async function readOpenapiFiles(
320
334
  return Promise.all(
321
335
  sources.map(async (source) => {
322
336
  // TODO: make a function for this
323
- const fullPath = path.join(openapiPath, source);
337
+ const fullPath = posixPath(path.join(openapiPath, source));
324
338
  const data = (await loadAndResolveSpec(
325
339
  fullPath
326
340
  )) as unknown as OpenApiObject;
@@ -13,6 +13,7 @@ import {
13
13
  SidebarItemCategoryLinkConfig,
14
14
  SidebarItemDoc,
15
15
  } from "@docusaurus/plugin-content-docs/src/sidebars/types";
16
+ import { posixPath } from "@docusaurus/utils";
16
17
  import clsx from "clsx";
17
18
  import { kebabCase } from "lodash";
18
19
  import uniq from "lodash/uniq";
@@ -67,9 +68,13 @@ function groupByTags(
67
68
  );
68
69
 
69
70
  // Combine globally defined tags with operation tags
71
+ // Only include global tag if referenced in operation tags
70
72
  let apiTags: string[] = [];
71
73
  tags.flat().forEach((tag) => {
72
- apiTags.push(tag.name!);
74
+ // Should we also check x-displayName?
75
+ if (operationTags.includes(tag.name!)) {
76
+ apiTags.push(tag.name!);
77
+ }
73
78
  });
74
79
  apiTags = uniq(apiTags.concat(operationTags));
75
80
 
@@ -148,8 +153,15 @@ function groupByTags(
148
153
  type: "generated-index" as "generated-index",
149
154
  title: tag,
150
155
  slug: label
151
- ? path.join("/category", basePath, kebabCase(label), kebabCase(tag))
152
- : path.join("/category", basePath, kebabCase(tag)),
156
+ ? posixPath(
157
+ path.join(
158
+ "/category",
159
+ basePath,
160
+ kebabCase(label),
161
+ kebabCase(tag)
162
+ )
163
+ )
164
+ : posixPath(path.join("/category", basePath, kebabCase(tag))),
153
165
  } as SidebarItemCategoryLinkConfig;
154
166
  }
155
167