docusaurus-plugin-openapi-docs 4.7.1 → 5.0.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.
Files changed (34) hide show
  1. package/README.md +11 -8
  2. package/lib/index.js +4 -4
  3. package/lib/markdown/createLicense.js +5 -1
  4. package/lib/markdown/createSchema.js +3 -34
  5. package/lib/markdown/schema.d.ts +0 -1
  6. package/lib/markdown/schema.js +0 -105
  7. package/lib/markdown/utils.js +3 -1
  8. package/lib/openapi/createSchemaExample.test.js +26 -0
  9. package/lib/openapi/openapi.js +17 -13
  10. package/lib/openapi/openapi.test.js +152 -0
  11. package/lib/openapi/types.d.ts +1 -0
  12. package/lib/openapi/utils/loadAndResolveSpec.js +5 -4
  13. package/lib/openapi/utils/utils/openapi.d.ts +0 -2
  14. package/lib/openapi/utils/utils/openapi.js +0 -82
  15. package/lib/sidebars/index.js +24 -8
  16. package/lib/sidebars/index.test.js +68 -0
  17. package/package.json +13 -13
  18. package/src/index.ts +4 -4
  19. package/src/markdown/__snapshots__/createSchema.test.ts.snap +0 -100
  20. package/src/markdown/createLicense.ts +7 -1
  21. package/src/markdown/createSchema.ts +4 -43
  22. package/src/markdown/schema.ts +0 -126
  23. package/src/markdown/utils.ts +3 -1
  24. package/src/openapi/createSchemaExample.test.ts +32 -0
  25. package/src/openapi/openapi.test.ts +176 -0
  26. package/src/openapi/openapi.ts +31 -15
  27. package/src/openapi/types.ts +1 -0
  28. package/src/openapi/utils/loadAndResolveSpec.ts +8 -6
  29. package/src/openapi/utils/utils/openapi.ts +0 -110
  30. package/src/sidebars/index.test.ts +94 -0
  31. package/src/sidebars/index.ts +28 -9
  32. package/lib/markdown/schema.test.js +0 -181
  33. package/src/markdown/schema.test.ts +0 -208
  34. /package/lib/{markdown/schema.test.d.ts → sidebars/index.test.d.ts} +0 -0
@@ -22,8 +22,6 @@ exports.getSerializedValue = getSerializedValue;
22
22
  exports.langFromMime = langFromMime;
23
23
  exports.isNamedDefinition = isNamedDefinition;
24
24
  exports.getDefinitionName = getDefinitionName;
25
- exports.humanizeNumberRange = humanizeNumberRange;
26
- exports.humanizeConstraints = humanizeConstraints;
27
25
  exports.sortByRequired = sortByRequired;
28
26
  exports.sortByField = sortByField;
29
27
  exports.mergeParams = mergeParams;
@@ -366,86 +364,6 @@ function getDefinitionName(pointer) {
366
364
  const [name] = ((_a = pointer === null || pointer === void 0 ? void 0 : pointer.match(DEFINITION_NAME_REGEX)) === null || _a === void 0 ? void 0 : _a.reverse()) || [];
367
365
  return name;
368
366
  }
369
- function humanizeMultipleOfConstraint(multipleOf) {
370
- if (multipleOf === undefined) {
371
- return;
372
- }
373
- const strigifiedMultipleOf = multipleOf.toString(10);
374
- if (!/^0\.0*1$/.test(strigifiedMultipleOf)) {
375
- return `multiple of ${strigifiedMultipleOf}`;
376
- }
377
- return `decimal places <= ${strigifiedMultipleOf.split(".")[1].length}`;
378
- }
379
- function humanizeRangeConstraint(description, min, max) {
380
- let stringRange;
381
- if (min !== undefined && max !== undefined) {
382
- if (min === max) {
383
- stringRange = `= ${min} ${description}`;
384
- }
385
- else {
386
- stringRange = `[ ${min} .. ${max} ] ${description}`;
387
- }
388
- }
389
- else if (max !== undefined) {
390
- stringRange = `<= ${max} ${description}`;
391
- }
392
- else if (min !== undefined) {
393
- if (min === 1) {
394
- stringRange = "non-empty";
395
- }
396
- else {
397
- stringRange = `>= ${min} ${description}`;
398
- }
399
- }
400
- return stringRange;
401
- }
402
- function humanizeNumberRange(schema) {
403
- var _a, _b;
404
- const minimum = typeof schema.exclusiveMinimum === "number"
405
- ? Math.min(schema.exclusiveMinimum, (_a = schema.minimum) !== null && _a !== void 0 ? _a : Infinity)
406
- : schema.minimum;
407
- const maximum = typeof schema.exclusiveMaximum === "number"
408
- ? Math.max(schema.exclusiveMaximum, (_b = schema.maximum) !== null && _b !== void 0 ? _b : -Infinity)
409
- : schema.maximum;
410
- const exclusiveMinimum = typeof schema.exclusiveMinimum === "number" || schema.exclusiveMinimum;
411
- const exclusiveMaximum = typeof schema.exclusiveMaximum === "number" || schema.exclusiveMaximum;
412
- if (minimum !== undefined && maximum !== undefined) {
413
- return `${exclusiveMinimum ? "( " : "[ "}${minimum} .. ${maximum}${exclusiveMaximum ? " )" : " ]"}`;
414
- }
415
- else if (maximum !== undefined) {
416
- return `${exclusiveMaximum ? "< " : "<= "}${maximum}`;
417
- }
418
- else if (minimum !== undefined) {
419
- return `${exclusiveMinimum ? "> " : ">= "}${minimum}`;
420
- }
421
- }
422
- function humanizeConstraints(schema) {
423
- const res = [];
424
- const stringRange = humanizeRangeConstraint("characters", schema.minLength, schema.maxLength);
425
- if (stringRange !== undefined) {
426
- res.push(stringRange);
427
- }
428
- const arrayRange = humanizeRangeConstraint("items", schema.minItems, schema.maxItems);
429
- if (arrayRange !== undefined) {
430
- res.push(arrayRange);
431
- }
432
- const propertiesRange = humanizeRangeConstraint("properties", schema.minProperties, schema.maxProperties);
433
- if (propertiesRange !== undefined) {
434
- res.push(propertiesRange);
435
- }
436
- const multipleOfConstraint = humanizeMultipleOfConstraint(schema.multipleOf);
437
- if (multipleOfConstraint !== undefined) {
438
- res.push(multipleOfConstraint);
439
- }
440
- const numberRange = humanizeNumberRange(schema);
441
- if (numberRange !== undefined) {
442
- res.push(numberRange);
443
- }
444
- if (schema.uniqueItems) {
445
- res.push("unique");
446
- }
447
- return res;
448
- }
449
367
  function sortByRequired(fields, order = []) {
450
368
  const unrequiredFields = [];
451
369
  const orderedFields = [];
@@ -45,7 +45,7 @@ const createDocItem = (item, { sidebarOptions: { customProps }, basePath }) => {
45
45
  className: className ? className : undefined,
46
46
  };
47
47
  };
48
- function groupByTags(items, sidebarOptions, options, tags, docPath) {
48
+ function groupByTags(items, sidebarOptions, options, tags, docPath, tagGroupKey) {
49
49
  var _a, _b;
50
50
  let { outputDir, label, showSchemas } = options;
51
51
  // Remove trailing slash before proceeding
@@ -83,9 +83,8 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
83
83
  }
84
84
  // Extract base path from outputDir, handling cases where docPath may not be in outputDir
85
85
  const getBasePathFromOutput = (output, doc) => {
86
- var _a, _b;
87
- if (doc && output.includes(doc)) {
88
- return (_b = (_a = output.split(doc)[1]) === null || _a === void 0 ? void 0 : _a.replace(/^\/+/g, "")) !== null && _b !== void 0 ? _b : "";
86
+ if (doc && output.startsWith(doc + "/")) {
87
+ return output.substring((doc + "/").length);
89
88
  }
90
89
  const slashIndex = output.indexOf("/", 1);
91
90
  return slashIndex === -1
@@ -102,9 +101,11 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
102
101
  if (infoItems.length === 1) {
103
102
  const infoItem = infoItems[0];
104
103
  const id = infoItem.id;
104
+ const docId = basePath === "" || undefined ? `${id}` : `${basePath}/${id}`;
105
105
  rootIntroDoc = {
106
106
  type: "doc",
107
- id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
107
+ id: docId,
108
+ ...(tagGroupKey && { key: (0, lodash_1.kebabCase)(`${tagGroupKey}-${docId}`) }),
108
109
  };
109
110
  }
110
111
  const tagged = apiTags
@@ -146,13 +147,27 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
146
147
  }
147
148
  const taggedApiItems = apiItems.filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
148
149
  const taggedSchemaItems = schemaItems.filter((item) => { var _a; return !!((_a = item.schema["x-tags"]) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
150
+ const categoryLabel = (_a = tagObject === null || tagObject === void 0 ? void 0 : tagObject["x-displayName"]) !== null && _a !== void 0 ? _a : tag;
151
+ const categoryKey = tagGroupKey
152
+ ? (0, lodash_1.kebabCase)(`${tagGroupKey}-${categoryLabel}`)
153
+ : undefined;
149
154
  return {
150
155
  type: "category",
151
- label: (_a = tagObject === null || tagObject === void 0 ? void 0 : tagObject["x-displayName"]) !== null && _a !== void 0 ? _a : tag,
156
+ label: categoryLabel,
157
+ ...(categoryKey && { key: categoryKey }),
152
158
  link: linkConfig,
153
159
  collapsible: sidebarCollapsible,
154
160
  collapsed: sidebarCollapsed,
155
- items: [...taggedSchemaItems, ...taggedApiItems].map((item) => createDocItemFn(item, createDocItemFnContext)),
161
+ items: [...taggedSchemaItems, ...taggedApiItems].map((item) => {
162
+ const docItem = createDocItemFn(item, createDocItemFnContext);
163
+ if (tagGroupKey && docItem.type === "doc") {
164
+ return {
165
+ ...docItem,
166
+ key: (0, lodash_1.kebabCase)(`${tagGroupKey}-${tag}-${docItem.id}`),
167
+ };
168
+ }
169
+ return docItem;
170
+ }),
156
171
  };
157
172
  })
158
173
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
@@ -208,12 +223,13 @@ function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGr
208
223
  filteredTags.push(tag);
209
224
  }
210
225
  });
226
+ const tagGroupKey = (0, lodash_1.kebabCase)(tagGroup.name);
211
227
  const groupCategory = {
212
228
  type: "category",
213
229
  label: tagGroup.name,
214
230
  collapsible: true,
215
231
  collapsed: true,
216
- items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath),
232
+ items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath, tagGroupKey),
217
233
  };
218
234
  if (options.showSchemas) {
219
235
  // For the first tagGroup, save the generated "Schemas" category for later.
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const index_1 = __importDefault(require("./index"));
13
+ describe("generateSidebarSlice", () => {
14
+ describe("tagGroup with overlapping tags", () => {
15
+ const mockApiItems = [
16
+ {
17
+ type: "api",
18
+ id: "get-books",
19
+ unversionedId: "get-books",
20
+ title: "Get Books",
21
+ description: "",
22
+ source: "",
23
+ sourceDirName: "",
24
+ permalink: "/get-books",
25
+ frontMatter: {},
26
+ api: {
27
+ method: "get",
28
+ path: "/books",
29
+ tags: ["Books", "Deprecated"],
30
+ jsonRequestBodyExample: "",
31
+ info: { title: "Test API", version: "1.0.0" },
32
+ },
33
+ },
34
+ ];
35
+ const mockTags = [
36
+ [
37
+ { name: "Books", description: "Book operations" },
38
+ { name: "Deprecated", description: "Deprecated endpoints" },
39
+ ],
40
+ ];
41
+ const mockTagGroups = [
42
+ { name: "Library", tags: ["Books"] },
43
+ { name: "Deprecation", tags: ["Deprecated"] },
44
+ ];
45
+ function collectKeys(obj) {
46
+ const keys = [];
47
+ JSON.stringify(obj, (k, v) => {
48
+ if (k === "key" && typeof v === "string") {
49
+ keys.push(v);
50
+ }
51
+ return v;
52
+ });
53
+ return keys;
54
+ }
55
+ it("should generate unique keys for items appearing in multiple tagGroups", () => {
56
+ const result = (0, index_1.default)({ groupPathsBy: "tagGroup" }, { outputDir: "docs/test", specPath: "" }, mockApiItems, mockTags, "", mockTagGroups);
57
+ const keys = collectKeys(result);
58
+ expect(keys.length).toBeGreaterThan(0);
59
+ expect(new Set(keys).size).toBe(keys.length);
60
+ });
61
+ it("should include tagGroup name in keys to differentiate same items", () => {
62
+ const result = (0, index_1.default)({ groupPathsBy: "tagGroup" }, { outputDir: "docs/test", specPath: "" }, mockApiItems, mockTags, "", mockTagGroups);
63
+ const keys = collectKeys(result);
64
+ expect(keys.filter((k) => k.includes("library")).length).toBeGreaterThan(0);
65
+ expect(keys.filter((k) => k.includes("deprecation")).length).toBeGreaterThan(0);
66
+ });
67
+ });
68
+ });
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": "4.7.1",
4
+ "version": "5.0.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,10 +28,10 @@
28
28
  "watch": "tsc --watch"
29
29
  },
30
30
  "devDependencies": {
31
- "@docusaurus/plugin-content-docs": "^3.5.0",
32
- "@docusaurus/types": "^3.5.0",
33
- "@docusaurus/utils": "^3.5.0",
34
- "@docusaurus/utils-validation": "^3.5.0",
31
+ "@docusaurus/plugin-content-docs": "^3.10.0",
32
+ "@docusaurus/types": "^3.10.0",
33
+ "@docusaurus/utils": "^3.10.0",
34
+ "@docusaurus/utils-validation": "^3.10.0",
35
35
  "@types/fs-extra": "^11.0.4",
36
36
  "@types/json-pointer": "^1.0.34",
37
37
  "@types/json-schema": "^7.0.15",
@@ -40,30 +40,30 @@
40
40
  "eslint-plugin-prettier": "^5.5.1"
41
41
  },
42
42
  "dependencies": {
43
- "@apidevtools/json-schema-ref-parser": "^11.5.4",
44
- "@redocly/openapi-core": "^1.34.3",
43
+ "@apidevtools/json-schema-ref-parser": "^15.3.3",
44
+ "@redocly/openapi-core": "^2.25.2",
45
45
  "allof-merge": "^0.6.6",
46
- "chalk": "^4.1.2",
46
+ "chalk": "^5.6.2",
47
47
  "clsx": "^2.1.1",
48
48
  "fs-extra": "^11.3.0",
49
49
  "json-pointer": "^0.6.2",
50
50
  "json5": "^2.2.3",
51
51
  "lodash": "^4.17.21",
52
52
  "mustache": "^4.2.0",
53
- "openapi-to-postmanv2": "^5.0.0",
53
+ "openapi-to-postmanv2": "^6.0.0",
54
54
  "postman-collection": "^5.0.2",
55
55
  "slugify": "^1.6.6",
56
56
  "swagger2openapi": "^7.0.8",
57
57
  "xml-formatter": "^3.6.6"
58
58
  },
59
59
  "peerDependencies": {
60
- "@docusaurus/plugin-content-docs": "^3.5.0",
61
- "@docusaurus/utils": "^3.5.0",
62
- "@docusaurus/utils-validation": "^3.5.0",
60
+ "@docusaurus/plugin-content-docs": "^3.10.0",
61
+ "@docusaurus/utils": "^3.10.0",
62
+ "@docusaurus/utils-validation": "^3.10.0",
63
63
  "react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0"
64
64
  },
65
65
  "engines": {
66
66
  "node": ">=14"
67
67
  },
68
- "gitHead": "0a89b9db05458cff9591eb065160e26c05f64a18"
68
+ "gitHead": "516bd48c628fb16b7fe90d8f996168ab75ce5562"
69
69
  }
package/src/index.ts CHANGED
@@ -764,7 +764,7 @@ custom_edit_url: null
764
764
  let targetDocsPluginId: any;
765
765
  if (pluginId) {
766
766
  try {
767
- const pluginConfig = getPluginConfig(plugins, pluginId);
767
+ const pluginConfig = getPluginConfig(pluginInstances, pluginId);
768
768
  targetConfig = pluginConfig.config ?? {};
769
769
  targetDocsPluginId = pluginConfig.docsPluginId;
770
770
  } catch {
@@ -835,7 +835,7 @@ custom_edit_url: null
835
835
  let targetDocsPluginId: any;
836
836
  if (pluginId) {
837
837
  try {
838
- const pluginConfig = getPluginConfig(plugins, pluginId);
838
+ const pluginConfig = getPluginConfig(pluginInstances, pluginId);
839
839
  targetConfig = pluginConfig.config ?? {};
840
840
  targetDocsPluginId = pluginConfig.docsPluginId;
841
841
  } catch {
@@ -933,7 +933,7 @@ custom_edit_url: null
933
933
  let targetConfig: any;
934
934
  if (pluginId) {
935
935
  try {
936
- const pluginConfig = getPluginConfig(plugins, pluginId);
936
+ const pluginConfig = getPluginConfig(pluginInstances, pluginId);
937
937
  targetConfig = pluginConfig.config ?? {};
938
938
  } catch {
939
939
  console.error(
@@ -992,7 +992,7 @@ custom_edit_url: null
992
992
  let targetConfig: any;
993
993
  if (pluginId) {
994
994
  try {
995
- const pluginConfig = getPluginConfig(plugins, pluginId);
995
+ const pluginConfig = getPluginConfig(pluginInstances, pluginId);
996
996
  targetConfig = pluginConfig.config ?? {};
997
997
  } catch {
998
998
  console.error(