docusaurus-plugin-openapi-docs 0.0.0-722 → 0.0.0-723

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.
@@ -34,6 +34,7 @@ const createSchema_1 = require("./createSchema");
34
34
  describe("createNodes", () => {
35
35
  it("should create readable MODs for oneOf primitive properties", () => {
36
36
  const schema = {
37
+ "x-tags": ["clown"],
37
38
  type: "object",
38
39
  properties: {
39
40
  oneOfProperty: {
@@ -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;
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;
65
65
  // TODO: Find a better way to handle this
66
66
  let items = [];
67
67
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
@@ -324,42 +324,47 @@ function createItems(openapiData, options, sidebarOptions) {
324
324
  items.push(apiPage);
325
325
  }
326
326
  }
327
- if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true) {
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 : {})
329
+ .flatMap(([_, s]) => s["x-tags"])
330
+ .filter((item) => !!item).length > 0) {
328
331
  // Gather schemas
329
- for (let [schema, schemaObject] of 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 : {})) {
330
- const baseIdSpaces = (_3 = (_2 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _2 === void 0 ? void 0 : _2.replace(" ", "-").toLowerCase()) !== null && _3 !== void 0 ? _3 : "";
331
- const baseId = (0, kebabCase_1.default)(baseIdSpaces);
332
- const schemaDescription = schemaObject.description;
333
- let splitDescription;
334
- if (schemaDescription) {
335
- splitDescription = schemaDescription.match(/[^\r\n]+/g);
336
- }
337
- const schemaPage = {
338
- type: "schema",
339
- id: baseId,
340
- infoId: infoId !== null && infoId !== void 0 ? infoId : "",
341
- unversionedId: baseId,
342
- title: schemaObject.title
343
- ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
344
- : schema,
345
- description: schemaObject.description
346
- ? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
347
- : "",
348
- frontMatter: {
349
- description: splitDescription
350
- ? splitDescription[0]
351
- .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
352
- .replace(/\s+$/, "")
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 : {})) {
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 : "";
335
+ const baseId = (0, kebabCase_1.default)(baseIdSpaces);
336
+ const schemaDescription = schemaObject.description;
337
+ let splitDescription;
338
+ if (schemaDescription) {
339
+ splitDescription = schemaDescription.match(/[^\r\n]+/g);
340
+ }
341
+ const schemaPage = {
342
+ type: "schema",
343
+ id: baseId,
344
+ infoId: infoId !== null && infoId !== void 0 ? infoId : "",
345
+ unversionedId: baseId,
346
+ title: schemaObject.title
347
+ ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
348
+ : schema,
349
+ description: schemaObject.description
350
+ ? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
353
351
  : "",
354
- },
355
- schema: schemaObject,
356
- };
357
- items.push(schemaPage);
352
+ frontMatter: {
353
+ description: splitDescription
354
+ ? splitDescription[0]
355
+ .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
356
+ .replace(/\s+$/, "")
357
+ : "",
358
+ },
359
+ schema: schemaObject,
360
+ };
361
+ items.push(schemaPage);
362
+ }
358
363
  }
359
364
  }
360
365
  if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
361
366
  // Get global tags
362
- const tags = (_4 = openapiData.tags) !== null && _4 !== void 0 ? _4 : [];
367
+ const tags = (_6 = openapiData.tags) !== null && _6 !== void 0 ? _6 : [];
363
368
  // Get operation tags
364
369
  const apiItems = items.filter((item) => {
365
370
  return item.type === "api";
@@ -17,6 +17,7 @@ const _1 = require(".");
17
17
  describe("openapi", () => {
18
18
  describe("readOpenapiFiles", () => {
19
19
  it("readOpenapiFiles", async () => {
20
+ var _a, _b;
20
21
  const results = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/examples")));
21
22
  const categoryMeta = results.find((x) => x.source.endsWith("_category_.json"));
22
23
  expect(categoryMeta).toBeFalsy();
@@ -26,6 +27,7 @@ describe("openapi", () => {
26
27
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.sourceDirName).toBe(".");
27
28
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.data.tags).toBeDefined();
28
29
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.data["x-tagGroups"]).toBeDefined();
30
+ expect((_b = (_a = yaml === null || yaml === void 0 ? void 0 : yaml.data.components) === null || _a === void 0 ? void 0 : _a.schemas) === null || _b === void 0 ? void 0 : _b.HelloString["x-tags"]).toBeDefined();
29
31
  });
30
32
  });
31
33
  });
@@ -278,6 +278,7 @@ export type SchemaObject = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf"
278
278
  externalDocs?: ExternalDocumentationObject;
279
279
  example?: any;
280
280
  deprecated?: boolean;
281
+ "x-tags"?: string[];
281
282
  };
282
283
  export type SchemaObjectWithRef = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf" | "not" | "items" | "properties" | "additionalProperties"> & {
283
284
  type?: "string" | "number" | "integer" | "boolean" | "object" | "array";
@@ -24,7 +24,7 @@ function isSchemaItem(item) {
24
24
  return item.type === "schema";
25
25
  }
26
26
  function groupByTags(items, sidebarOptions, options, tags, docPath) {
27
- let { outputDir, label } = options;
27
+ let { outputDir, label, showSchemas } = options;
28
28
  // Remove trailing slash before proceeding
29
29
  outputDir = outputDir.replace(/\/$/, "");
30
30
  const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
@@ -43,16 +43,19 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
43
43
  const operationTags = (0, uniq_1.default)(apiItems
44
44
  .flatMap((item) => item.api.tags)
45
45
  .filter((item) => !!item));
46
- // Combine globally defined tags with operation tags
47
- // Only include global tag if referenced in operation tags
46
+ const schemaTags = (0, uniq_1.default)(schemaItems
47
+ .flatMap((item) => item.schema["x-tags"])
48
+ .filter((item) => !!item));
49
+ // Combine globally defined tags with operation and schema tags
50
+ // Only include global tag if referenced in operation/schema tags
48
51
  let apiTags = [];
49
52
  tags.flat().forEach((tag) => {
50
53
  // Should we also check x-displayName?
51
- if (operationTags.includes(tag.name)) {
54
+ if (operationTags.includes(tag.name) || schemaTags.includes(tag.name)) {
52
55
  apiTags.push(tag.name);
53
56
  }
54
57
  });
55
- apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
58
+ apiTags = (0, uniq_1.default)(apiTags.concat(operationTags, schemaTags));
56
59
  const basePath = docPath
57
60
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
58
61
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
@@ -68,7 +71,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
68
71
  }, item.api.method)
69
72
  : (0, clsx_1.default)({
70
73
  "menu__list-item--deprecated": item.schema.deprecated,
71
- });
74
+ }, "schema");
72
75
  return {
73
76
  type: "doc",
74
77
  id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
@@ -126,15 +129,15 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
126
129
  : (0, utils_1.posixPath)(path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(tag))),
127
130
  };
128
131
  }
132
+ const taggedApiItems = apiItems.filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
133
+ const taggedSchemaItems = schemaItems.filter((item) => { var _a; return !!((_a = item.schema["x-tags"]) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
129
134
  return {
130
135
  type: "category",
131
136
  label: (_a = tagObject === null || tagObject === void 0 ? void 0 : tagObject["x-displayName"]) !== null && _a !== void 0 ? _a : tag,
132
137
  link: linkConfig,
133
138
  collapsible: sidebarCollapsible,
134
139
  collapsed: sidebarCollapsed,
135
- items: apiItems
136
- .filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); })
137
- .map(createDocItem),
140
+ items: [...taggedSchemaItems, ...taggedApiItems].map(createDocItem),
138
141
  };
139
142
  })
140
143
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
@@ -157,14 +160,16 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
157
160
  ];
158
161
  }
159
162
  let schemas = [];
160
- if (schemaItems.length > 0) {
163
+ if (showSchemas && schemaItems.length > 0) {
161
164
  schemas = [
162
165
  {
163
166
  type: "category",
164
167
  label: "Schemas",
165
168
  collapsible: sidebarCollapsible,
166
169
  collapsed: sidebarCollapsed,
167
- items: schemaItems.map(createDocItem),
170
+ items: schemaItems
171
+ .filter(({ schema }) => !schema["x-tags"])
172
+ .map(createDocItem),
168
173
  },
169
174
  ];
170
175
  }
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-722",
4
+ "version": "0.0.0-723",
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": "d580c447cf347d6917d449590e25c25bb5936c6e"
63
+ "gitHead": "3263dd6299867edd790defa2dda09b79c59cb9cb"
64
64
  }
@@ -13,6 +13,7 @@ import { SchemaObject } from "../openapi/types";
13
13
  describe("createNodes", () => {
14
14
  it("should create readable MODs for oneOf primitive properties", () => {
15
15
  const schema: SchemaObject = {
16
+ "x-tags": ["clown"],
16
17
  type: "object",
17
18
  properties: {
18
19
  oneOfProperty: {
@@ -40,3 +40,10 @@ x-tagGroups:
40
40
  tags:
41
41
  - tag3
42
42
  - tag4
43
+
44
+ components:
45
+ schemas:
46
+ HelloString:
47
+ x-tags:
48
+ - tag1
49
+ type: string
@@ -31,6 +31,10 @@ describe("openapi", () => {
31
31
 
32
32
  expect(yaml?.data.tags).toBeDefined();
33
33
  expect(yaml?.data["x-tagGroups"]).toBeDefined();
34
+
35
+ expect(
36
+ yaml?.data.components?.schemas?.HelloString["x-tags"]
37
+ ).toBeDefined();
34
38
  });
35
39
  });
36
40
  });
@@ -410,43 +410,53 @@ function createItems(
410
410
  }
411
411
  }
412
412
 
413
- if (options?.showSchemas === true) {
413
+ if (
414
+ options?.showSchemas === true ||
415
+ Object.entries(openapiData?.components?.schemas ?? {})
416
+ .flatMap(([_, s]) => s["x-tags"])
417
+ .filter((item) => !!item).length > 0
418
+ ) {
414
419
  // Gather schemas
415
420
  for (let [schema, schemaObject] of Object.entries(
416
421
  openapiData?.components?.schemas ?? {}
417
422
  )) {
418
- const baseIdSpaces =
419
- schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
420
- const baseId = kebabCase(baseIdSpaces);
421
-
422
- const schemaDescription = schemaObject.description;
423
- let splitDescription: any;
424
- if (schemaDescription) {
425
- splitDescription = schemaDescription.match(/[^\r\n]+/g);
426
- }
423
+ if (options?.showSchemas === true || schemaObject["x-tags"]) {
424
+ const baseIdSpaces =
425
+ schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
426
+ const baseId = kebabCase(baseIdSpaces);
427
+
428
+ const schemaDescription = schemaObject.description;
429
+ let splitDescription: any;
430
+ if (schemaDescription) {
431
+ splitDescription = schemaDescription.match(/[^\r\n]+/g);
432
+ }
427
433
 
428
- const schemaPage: PartialPage<SchemaPageMetadata> = {
429
- type: "schema",
430
- id: baseId,
431
- infoId: infoId ?? "",
432
- unversionedId: baseId,
433
- title: schemaObject.title
434
- ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
435
- : schema,
436
- description: schemaObject.description
437
- ? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
438
- : "",
439
- frontMatter: {
440
- description: splitDescription
441
- ? splitDescription[0]
442
- .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
443
- .replace(/\s+$/, "")
434
+ const schemaPage: PartialPage<SchemaPageMetadata> = {
435
+ type: "schema",
436
+ id: baseId,
437
+ infoId: infoId ?? "",
438
+ unversionedId: baseId,
439
+ title: schemaObject.title
440
+ ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
441
+ : schema,
442
+ description: schemaObject.description
443
+ ? schemaObject.description.replace(
444
+ /((?:^|[^\\])(?:\\{2})*)"/g,
445
+ "$1'"
446
+ )
444
447
  : "",
445
- },
446
- schema: schemaObject,
447
- };
448
+ frontMatter: {
449
+ description: splitDescription
450
+ ? splitDescription[0]
451
+ .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
452
+ .replace(/\s+$/, "")
453
+ : "",
454
+ },
455
+ schema: schemaObject,
456
+ };
448
457
 
449
- items.push(schemaPage);
458
+ items.push(schemaPage);
459
+ }
450
460
  }
451
461
  }
452
462
 
@@ -352,6 +352,7 @@ export type SchemaObject = Omit<
352
352
  externalDocs?: ExternalDocumentationObject;
353
353
  example?: any;
354
354
  deprecated?: boolean;
355
+ "x-tags"?: string[];
355
356
  };
356
357
 
357
358
  export type SchemaObjectWithRef = Omit<
@@ -25,6 +25,7 @@ import type {
25
25
  APIOptions,
26
26
  ApiPageMetadata,
27
27
  ApiMetadata,
28
+ InfoPageMetadata,
28
29
  SchemaPageMetadata,
29
30
  } from "../types";
30
31
 
@@ -41,13 +42,13 @@ function isSchemaItem(item: ApiMetadata): item is ApiMetadata {
41
42
  }
42
43
 
43
44
  function groupByTags(
44
- items: ApiPageMetadata[],
45
+ items: ApiMetadata[],
45
46
  sidebarOptions: SidebarOptions,
46
47
  options: APIOptions,
47
48
  tags: TagObject[][],
48
49
  docPath: string
49
50
  ): ProcessedSidebar {
50
- let { outputDir, label } = options;
51
+ let { outputDir, label, showSchemas } = options;
51
52
 
52
53
  // Remove trailing slash before proceeding
53
54
  outputDir = outputDir.replace(/\/$/, "");
@@ -59,9 +60,9 @@ function groupByTags(
59
60
  categoryLinkSource,
60
61
  } = sidebarOptions;
61
62
 
62
- const apiItems = items.filter(isApiItem);
63
- const infoItems = items.filter(isInfoItem);
64
- const schemaItems = items.filter(isSchemaItem);
63
+ const apiItems = items.filter(isApiItem) as ApiPageMetadata[];
64
+ const infoItems = items.filter(isInfoItem) as InfoPageMetadata[];
65
+ const schemaItems = items.filter(isSchemaItem) as SchemaPageMetadata[];
65
66
  const intros = infoItems.map((item: any) => {
66
67
  return {
67
68
  id: item.id,
@@ -77,17 +78,22 @@ function groupByTags(
77
78
  .flatMap((item) => item.api.tags)
78
79
  .filter((item): item is string => !!item)
79
80
  );
81
+ const schemaTags = uniq(
82
+ schemaItems
83
+ .flatMap((item) => item.schema["x-tags"])
84
+ .filter((item): item is string => !!item)
85
+ );
80
86
 
81
- // Combine globally defined tags with operation tags
82
- // Only include global tag if referenced in operation tags
87
+ // Combine globally defined tags with operation and schema tags
88
+ // Only include global tag if referenced in operation/schema tags
83
89
  let apiTags: string[] = [];
84
90
  tags.flat().forEach((tag) => {
85
91
  // Should we also check x-displayName?
86
- if (operationTags.includes(tag.name!)) {
92
+ if (operationTags.includes(tag.name!) || schemaTags.includes(tag.name!)) {
87
93
  apiTags.push(tag.name!);
88
94
  }
89
95
  });
90
- apiTags = uniq(apiTags.concat(operationTags));
96
+ apiTags = uniq(apiTags.concat(operationTags, schemaTags));
91
97
 
92
98
  const basePath = docPath
93
99
  ? outputDir.split(docPath!)[1].replace(/^\/+/g, "")
@@ -107,9 +113,12 @@ function groupByTags(
107
113
  },
108
114
  item.api.method
109
115
  )
110
- : clsx({
111
- "menu__list-item--deprecated": item.schema.deprecated,
112
- });
116
+ : clsx(
117
+ {
118
+ "menu__list-item--deprecated": item.schema.deprecated,
119
+ },
120
+ "schema"
121
+ );
113
122
  return {
114
123
  type: "doc" as const,
115
124
  id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
@@ -183,15 +192,20 @@ function groupByTags(
183
192
  } as SidebarItemCategoryLinkConfig;
184
193
  }
185
194
 
195
+ const taggedApiItems = apiItems.filter(
196
+ (item) => !!item.api.tags?.includes(tag)
197
+ );
198
+ const taggedSchemaItems = schemaItems.filter(
199
+ (item) => !!item.schema["x-tags"]?.includes(tag)
200
+ );
201
+
186
202
  return {
187
203
  type: "category" as const,
188
204
  label: tagObject?.["x-displayName"] ?? tag,
189
205
  link: linkConfig,
190
206
  collapsible: sidebarCollapsible,
191
207
  collapsed: sidebarCollapsed,
192
- items: apiItems
193
- .filter((item) => !!item.api.tags?.includes(tag))
194
- .map(createDocItem),
208
+ items: [...taggedSchemaItems, ...taggedApiItems].map(createDocItem),
195
209
  };
196
210
  })
197
211
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
@@ -216,14 +230,16 @@ function groupByTags(
216
230
  }
217
231
 
218
232
  let schemas: SidebarItemCategory[] = [];
219
- if (schemaItems.length > 0) {
233
+ if (showSchemas && schemaItems.length > 0) {
220
234
  schemas = [
221
235
  {
222
236
  type: "category" as const,
223
237
  label: "Schemas",
224
238
  collapsible: sidebarCollapsible!,
225
239
  collapsed: sidebarCollapsed!,
226
- items: schemaItems.map(createDocItem),
240
+ items: schemaItems
241
+ .filter(({ schema }) => !schema["x-tags"])
242
+ .map(createDocItem),
227
243
  },
228
244
  ];
229
245
  }
@@ -263,7 +279,7 @@ export default function generateSidebarSlice(
263
279
  collapsible: true,
264
280
  collapsed: true,
265
281
  items: groupByTags(
266
- api as ApiPageMetadata[],
282
+ api,
267
283
  sidebarOptions,
268
284
  options,
269
285
  [filteredTags],
@@ -274,13 +290,7 @@ export default function generateSidebarSlice(
274
290
  sidebarSlice.push(groupCategory);
275
291
  });
276
292
  } else if (sidebarOptions.groupPathsBy === "tag") {
277
- sidebarSlice = groupByTags(
278
- api as ApiPageMetadata[],
279
- sidebarOptions,
280
- options,
281
- tags,
282
- docPath
283
- );
293
+ sidebarSlice = groupByTags(api, sidebarOptions, options, tags, docPath);
284
294
  }
285
295
 
286
296
  return sidebarSlice;