docusaurus-plugin-openapi-docs 0.0.0-699 → 0.0.0-700

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
@@ -92,7 +92,7 @@ function pluginOpenAPIDocs(context, options) {
92
92
  : path_1.default.resolve(siteDir, specPath);
93
93
  try {
94
94
  const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath);
95
- const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, options, sidebarOptions);
95
+ const [loadedApi, tags, tagGroups] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, options, sidebarOptions);
96
96
  if (!fs_1.default.existsSync(outputDir)) {
97
97
  try {
98
98
  fs_1.default.mkdirSync(outputDir, { recursive: true });
@@ -104,7 +104,7 @@ function pluginOpenAPIDocs(context, options) {
104
104
  }
105
105
  // TODO: figure out better way to set default
106
106
  if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
107
- const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath);
107
+ const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath, tagGroups);
108
108
  const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
109
109
  const view = (0, mustache_1.render)(sidebarSliceTemplate, {
110
110
  slice: JSON.stringify(sidebarSlice),
@@ -1,12 +1,12 @@
1
1
  import { ApiMetadata, APIOptions, SidebarOptions } from "../types";
2
- import { OpenApiObject, TagObject } from "./types";
2
+ import { OpenApiObject, TagGroupObject, TagObject } from "./types";
3
3
  interface OpenApiFiles {
4
4
  source: string;
5
5
  sourceDirName: string;
6
6
  data: OpenApiObject;
7
7
  }
8
8
  export declare function readOpenapiFiles(openapiPath: string): Promise<OpenApiFiles[]>;
9
- export declare function processOpenapiFiles(files: OpenApiFiles[], options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[][]]>;
10
- export declare function processOpenapiFile(openapiData: OpenApiObject, options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[]]>;
9
+ export declare function processOpenapiFiles(files: OpenApiFiles[], options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[][], TagGroupObject[]]>;
10
+ export declare function processOpenapiFile(openapiData: OpenApiObject, options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[], TagGroupObject[]]>;
11
11
  export declare function getTagDisplayName(tagName: string, tags: TagObject[]): string;
12
12
  export {};
@@ -461,7 +461,8 @@ async function processOpenapiFiles(files, options, sidebarOptions) {
461
461
  ...item,
462
462
  }));
463
463
  const tags = processedFile[1];
464
- return [itemsObjectsArray, tags];
464
+ const tagGroups = processedFile[2];
465
+ return [itemsObjectsArray, tags, tagGroups];
465
466
  }
466
467
  console.warn(chalk_1.default.yellow(`WARNING: the following OpenAPI spec returned undefined: ${file.source}`));
467
468
  return [];
@@ -484,7 +485,20 @@ async function processOpenapiFiles(files, options, sidebarOptions) {
484
485
  // Remove undefined tags due to transient parsing errors
485
486
  return x !== undefined;
486
487
  });
487
- return [items, tags];
488
+ const tagGroups = metadata
489
+ .map(function (x) {
490
+ return x[2];
491
+ })
492
+ .flat()
493
+ .filter(function (x) {
494
+ // Remove undefined tags due to transient parsing errors
495
+ return x !== undefined;
496
+ });
497
+ return [
498
+ items,
499
+ tags,
500
+ tagGroups,
501
+ ];
488
502
  }
489
503
  exports.processOpenapiFiles = processOpenapiFiles;
490
504
  async function processOpenapiFile(openapiData, options, sidebarOptions) {
@@ -495,7 +509,11 @@ async function processOpenapiFile(openapiData, options, sidebarOptions) {
495
509
  if (openapiData.tags !== undefined) {
496
510
  tags = openapiData.tags;
497
511
  }
498
- return [items, tags];
512
+ let tagGroups = [];
513
+ if (openapiData["x-tagGroups"] !== undefined) {
514
+ tagGroups = openapiData["x-tagGroups"];
515
+ }
516
+ return [items, tags, tagGroups];
499
517
  }
500
518
  exports.processOpenapiFile = processOpenapiFile;
501
519
  // order for picking items as a display name of tags
@@ -24,6 +24,8 @@ describe("openapi", () => {
24
24
  const yaml = results.find((x) => x.source.endsWith("openapi.yaml"));
25
25
  expect(yaml).toBeTruthy();
26
26
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.sourceDirName).toBe(".");
27
+ expect(yaml === null || yaml === void 0 ? void 0 : yaml.data.tags).toBeDefined();
28
+ expect(yaml === null || yaml === void 0 ? void 0 : yaml.data["x-tagGroups"]).toBeDefined();
27
29
  });
28
30
  });
29
31
  });
@@ -13,6 +13,7 @@ export interface OpenApiObject {
13
13
  externalDocs?: ExternalDocumentationObject;
14
14
  swagger?: string;
15
15
  "x-webhooks"?: PathsObject;
16
+ "x-tagGroups"?: TagGroupObject[];
16
17
  }
17
18
  export interface OpenApiObjectWithRef {
18
19
  openapi: string;
@@ -252,6 +253,10 @@ export interface TagObject {
252
253
  externalDocs?: ExternalDocumentationObject;
253
254
  "x-displayName"?: string;
254
255
  }
256
+ export interface TagGroupObject {
257
+ name: string;
258
+ tags: string[];
259
+ }
255
260
  export interface ReferenceObject {
256
261
  $ref: string;
257
262
  }
package/lib/options.js CHANGED
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.OptionsSchema = void 0;
10
10
  const utils_validation_1 = require("@docusaurus/utils-validation");
11
11
  const sidebarOptions = utils_validation_1.Joi.object({
12
- groupPathsBy: utils_validation_1.Joi.string().valid("tag"),
12
+ groupPathsBy: utils_validation_1.Joi.string().valid("tag", "tagGroup"),
13
13
  categoryLinkSource: utils_validation_1.Joi.string().valid("tag", "info", "auto"),
14
14
  customProps: utils_validation_1.Joi.object(),
15
15
  sidebarCollapsible: utils_validation_1.Joi.boolean(),
@@ -1,4 +1,4 @@
1
1
  import { ProcessedSidebar } from "@docusaurus/plugin-content-docs/src/sidebars/types";
2
- import { TagObject } from "../openapi/types";
2
+ import { TagGroupObject, TagObject } from "../openapi/types";
3
3
  import type { SidebarOptions, APIOptions, ApiMetadata } from "../types";
4
- export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[], tags: TagObject[][], docPath: string): ProcessedSidebar;
4
+ export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[], tags: TagObject[][], docPath: string, tagGroups?: TagGroupObject[]): ProcessedSidebar;
@@ -52,7 +52,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
52
52
  apiTags.push(tag.name);
53
53
  }
54
54
  });
55
- apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
55
+ // apiTags = uniq(apiTags.concat(operationTags));
56
56
  const basePath = docPath
57
57
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
58
58
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
@@ -175,9 +175,28 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
175
175
  }
176
176
  return [...tagged, ...untagged, ...schemas];
177
177
  }
178
- function generateSidebarSlice(sidebarOptions, options, api, tags, docPath) {
178
+ function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGroups) {
179
179
  let sidebarSlice = [];
180
- if (sidebarOptions.groupPathsBy === "tag") {
180
+ if (sidebarOptions.groupPathsBy === "tagGroup") {
181
+ tagGroups === null || tagGroups === void 0 ? void 0 : tagGroups.forEach((tagGroup) => {
182
+ //filter tags only included in group
183
+ const filteredTags = [];
184
+ tags[0].forEach((tag) => {
185
+ if (tagGroup.tags.includes(tag.name)) {
186
+ filteredTags.push(tag);
187
+ }
188
+ });
189
+ const groupCategory = {
190
+ type: "category",
191
+ label: tagGroup.name,
192
+ collapsible: true,
193
+ collapsed: true,
194
+ items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath),
195
+ };
196
+ sidebarSlice.push(groupCategory);
197
+ });
198
+ }
199
+ else if (sidebarOptions.groupPathsBy === "tag") {
181
200
  sidebarSlice = groupByTags(api, sidebarOptions, options, tags, docPath);
182
201
  }
183
202
  return sidebarSlice;
package/lib/types.d.ts CHANGED
@@ -107,6 +107,12 @@ export interface SchemaPageMetadata extends ApiMetadataBase {
107
107
  schema: SchemaObject;
108
108
  markdown?: string;
109
109
  }
110
+ export interface TagGroupPageMetadata extends ApiMetadataBase {
111
+ type: "tagGroup";
112
+ name: string;
113
+ tags: TagObject[];
114
+ markdown?: string;
115
+ }
110
116
  export declare type ApiInfo = InfoObject;
111
117
  export interface ApiNavLink {
112
118
  title: 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-699",
4
+ "version": "0.0.0-700",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -60,5 +60,5 @@
60
60
  "engines": {
61
61
  "node": ">=14"
62
62
  },
63
- "gitHead": "ef318267f54c34bedf50f0b309c9bb30fd665b53"
63
+ "gitHead": "309ea5d0c101d526975380a13915decebca3e86b"
64
64
  }
package/src/index.ts CHANGED
@@ -131,7 +131,7 @@ export default function pluginOpenAPIDocs(
131
131
 
132
132
  try {
133
133
  const openapiFiles = await readOpenapiFiles(contentPath);
134
- const [loadedApi, tags] = await processOpenapiFiles(
134
+ const [loadedApi, tags, tagGroups] = await processOpenapiFiles(
135
135
  openapiFiles,
136
136
  options,
137
137
  sidebarOptions!
@@ -155,7 +155,8 @@ export default function pluginOpenAPIDocs(
155
155
  options,
156
156
  loadedApi,
157
157
  tags,
158
- docPath
158
+ docPath,
159
+ tagGroups
159
160
  );
160
161
 
161
162
  const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
@@ -11,3 +11,32 @@ paths:
11
11
  responses:
12
12
  200:
13
13
  description: OK
14
+
15
+ tags:
16
+ - name: tag1
17
+ description: Everything about your Pets
18
+ x-displayName: Tag 1
19
+ - name: tag2
20
+ description: Tag 2 description
21
+ x-displayName: Tag 2
22
+ - name: tag3
23
+ description: Tag 3 description
24
+ x-displayName: Tag 3
25
+ - name: tag4
26
+ description: Tag 4 description
27
+ x-displayName: Tag 4
28
+
29
+ x-tagGroups:
30
+ - name: Tag 1 & 2
31
+ tags:
32
+ - tag1
33
+ - tag2
34
+ - name: Trinity
35
+ tags:
36
+ - tag1
37
+ - tag2
38
+ - tag3
39
+ - name: Last Two
40
+ tags:
41
+ - tag3
42
+ - tag4
@@ -28,6 +28,9 @@ describe("openapi", () => {
28
28
  const yaml = results.find((x) => x.source.endsWith("openapi.yaml"));
29
29
  expect(yaml).toBeTruthy();
30
30
  expect(yaml?.sourceDirName).toBe(".");
31
+
32
+ expect(yaml?.data.tags).toBeDefined();
33
+ expect(yaml?.data["x-tagGroups"]).toBeDefined();
31
34
  });
32
35
  });
33
36
  });
@@ -29,7 +29,7 @@ import {
29
29
  TagPageMetadata,
30
30
  } from "../types";
31
31
  import { sampleRequestFromSchema } from "./createRequestExample";
32
- import { OpenApiObject, TagObject } from "./types";
32
+ import { OpenApiObject, TagGroupObject, TagObject } from "./types";
33
33
  import { loadAndResolveSpec } from "./utils/loadAndResolveSpec";
34
34
 
35
35
  /**
@@ -579,7 +579,7 @@ export async function processOpenapiFiles(
579
579
  files: OpenApiFiles[],
580
580
  options: APIOptions,
581
581
  sidebarOptions: SidebarOptions
582
- ): Promise<[ApiMetadata[], TagObject[][]]> {
582
+ ): Promise<[ApiMetadata[], TagObject[][], TagGroupObject[]]> {
583
583
  const promises = files.map(async (file) => {
584
584
  if (file.data !== undefined) {
585
585
  const processedFile = await processOpenapiFile(
@@ -591,7 +591,8 @@ export async function processOpenapiFiles(
591
591
  ...item,
592
592
  }));
593
593
  const tags = processedFile[1];
594
- return [itemsObjectsArray, tags];
594
+ const tagGroups = processedFile[2];
595
+ return [itemsObjectsArray, tags, tagGroups];
595
596
  }
596
597
  console.warn(
597
598
  chalk.yellow(
@@ -610,6 +611,7 @@ export async function processOpenapiFiles(
610
611
  // Remove undefined items due to transient parsing errors
611
612
  return x !== undefined;
612
613
  });
614
+
613
615
  const tags = metadata
614
616
  .map(function (x) {
615
617
  return x[1];
@@ -618,14 +620,29 @@ export async function processOpenapiFiles(
618
620
  // Remove undefined tags due to transient parsing errors
619
621
  return x !== undefined;
620
622
  });
621
- return [items as ApiMetadata[], tags as TagObject[][]];
623
+
624
+ const tagGroups = metadata
625
+ .map(function (x) {
626
+ return x[2];
627
+ })
628
+ .flat()
629
+ .filter(function (x) {
630
+ // Remove undefined tags due to transient parsing errors
631
+ return x !== undefined;
632
+ });
633
+
634
+ return [
635
+ items as ApiMetadata[],
636
+ tags as TagObject[][],
637
+ tagGroups as TagGroupObject[],
638
+ ];
622
639
  }
623
640
 
624
641
  export async function processOpenapiFile(
625
642
  openapiData: OpenApiObject,
626
643
  options: APIOptions,
627
644
  sidebarOptions: SidebarOptions
628
- ): Promise<[ApiMetadata[], TagObject[]]> {
645
+ ): Promise<[ApiMetadata[], TagObject[], TagGroupObject[]]> {
629
646
  const postmanCollection = await createPostmanCollection(openapiData);
630
647
  const items = createItems(openapiData, options, sidebarOptions);
631
648
 
@@ -635,7 +652,13 @@ export async function processOpenapiFile(
635
652
  if (openapiData.tags !== undefined) {
636
653
  tags = openapiData.tags;
637
654
  }
638
- return [items, tags];
655
+
656
+ let tagGroups: TagGroupObject[] = [];
657
+ if (openapiData["x-tagGroups"] !== undefined) {
658
+ tagGroups = openapiData["x-tagGroups"];
659
+ }
660
+
661
+ return [items, tags, tagGroups];
639
662
  }
640
663
 
641
664
  // order for picking items as a display name of tags
@@ -22,6 +22,7 @@ export interface OpenApiObject {
22
22
  externalDocs?: ExternalDocumentationObject;
23
23
  swagger?: string;
24
24
  "x-webhooks"?: PathsObject;
25
+ "x-tagGroups"?: TagGroupObject[];
25
26
  }
26
27
 
27
28
  export interface OpenApiObjectWithRef {
@@ -311,6 +312,11 @@ export interface TagObject {
311
312
  "x-displayName"?: string;
312
313
  }
313
314
 
315
+ export interface TagGroupObject {
316
+ name: string;
317
+ tags: string[];
318
+ }
319
+
314
320
  export interface ReferenceObject {
315
321
  $ref: string;
316
322
  }
package/src/options.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  import { Joi } from "@docusaurus/utils-validation";
9
9
 
10
10
  const sidebarOptions = Joi.object({
11
- groupPathsBy: Joi.string().valid("tag"),
11
+ groupPathsBy: Joi.string().valid("tag", "tagGroup"),
12
12
  categoryLinkSource: Joi.string().valid("tag", "info", "auto"),
13
13
  customProps: Joi.object(),
14
14
  sidebarCollapsible: Joi.boolean(),
@@ -7,6 +7,7 @@
7
7
 
8
8
  import path from "path";
9
9
 
10
+ import { ProcessedSidebarItem } from "@docusaurus/plugin-content-docs/lib/sidebars/types";
10
11
  import {
11
12
  ProcessedSidebar,
12
13
  SidebarItemCategory,
@@ -18,7 +19,7 @@ import clsx from "clsx";
18
19
  import { kebabCase } from "lodash";
19
20
  import uniq from "lodash/uniq";
20
21
 
21
- import { TagObject } from "../openapi/types";
22
+ import { TagGroupObject, TagObject } from "../openapi/types";
22
23
  import type {
23
24
  SidebarOptions,
24
25
  APIOptions,
@@ -86,7 +87,7 @@ function groupByTags(
86
87
  apiTags.push(tag.name!);
87
88
  }
88
89
  });
89
- apiTags = uniq(apiTags.concat(operationTags));
90
+ // apiTags = uniq(apiTags.concat(operationTags));
90
91
 
91
92
  const basePath = docPath
92
93
  ? outputDir.split(docPath!)[1].replace(/^\/+/g, "")
@@ -241,11 +242,38 @@ export default function generateSidebarSlice(
241
242
  options: APIOptions,
242
243
  api: ApiMetadata[],
243
244
  tags: TagObject[][],
244
- docPath: string
245
+ docPath: string,
246
+ tagGroups?: TagGroupObject[]
245
247
  ) {
246
248
  let sidebarSlice: ProcessedSidebar = [];
247
249
 
248
- if (sidebarOptions.groupPathsBy === "tag") {
250
+ if (sidebarOptions.groupPathsBy === "tagGroup") {
251
+ tagGroups?.forEach((tagGroup) => {
252
+ //filter tags only included in group
253
+ const filteredTags: TagObject[] = [];
254
+ tags[0].forEach((tag) => {
255
+ if (tagGroup.tags.includes(tag.name as string)) {
256
+ filteredTags.push(tag);
257
+ }
258
+ });
259
+
260
+ const groupCategory = {
261
+ type: "category" as const,
262
+ label: tagGroup.name,
263
+ collapsible: true,
264
+ collapsed: true,
265
+ items: groupByTags(
266
+ api as ApiPageMetadata[],
267
+ sidebarOptions,
268
+ options,
269
+ [filteredTags],
270
+ docPath
271
+ ),
272
+ } as ProcessedSidebarItem;
273
+
274
+ sidebarSlice.push(groupCategory);
275
+ });
276
+ } else if (sidebarOptions.groupPathsBy === "tag") {
249
277
  sidebarSlice = groupByTags(
250
278
  api as ApiPageMetadata[],
251
279
  sidebarOptions,
@@ -254,5 +282,6 @@ export default function generateSidebarSlice(
254
282
  docPath
255
283
  );
256
284
  }
285
+
257
286
  return sidebarSlice;
258
287
  }
package/src/types.ts CHANGED
@@ -144,6 +144,13 @@ export interface SchemaPageMetadata extends ApiMetadataBase {
144
144
  markdown?: string;
145
145
  }
146
146
 
147
+ export interface TagGroupPageMetadata extends ApiMetadataBase {
148
+ type: "tagGroup";
149
+ name: string;
150
+ tags: TagObject[];
151
+ markdown?: string;
152
+ }
153
+
147
154
  export type ApiInfo = InfoObject;
148
155
 
149
156
  export interface ApiNavLink {