docusaurus-plugin-openapi-docs 4.5.1 → 4.7.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 (39) hide show
  1. package/README.md +110 -22
  2. package/lib/index.js +122 -50
  3. package/lib/markdown/createHeading.js +1 -1
  4. package/lib/markdown/createRequestHeader.js +5 -3
  5. package/lib/markdown/createSchema.js +2 -2
  6. package/lib/markdown/index.js +3 -2
  7. package/lib/markdown/schema.js +5 -0
  8. package/lib/markdown/utils.d.ts +38 -1
  9. package/lib/markdown/utils.js +100 -2
  10. package/lib/openapi/createSchemaExample.js +16 -2
  11. package/lib/openapi/createSchemaExample.test.d.ts +1 -0
  12. package/lib/openapi/createSchemaExample.test.js +48 -0
  13. package/lib/openapi/openapi.js +38 -17
  14. package/lib/openapi/openapi.test.js +48 -0
  15. package/lib/openapi/webhooks.test.d.ts +1 -0
  16. package/lib/openapi/webhooks.test.js +23 -0
  17. package/lib/options.js +4 -0
  18. package/lib/sidebars/index.js +12 -3
  19. package/package.json +16 -16
  20. package/src/index.ts +165 -62
  21. package/src/markdown/createHeading.ts +2 -2
  22. package/src/markdown/createRequestHeader.ts +9 -11
  23. package/src/markdown/createSchema.ts +4 -2
  24. package/src/markdown/index.ts +3 -2
  25. package/src/markdown/schema.ts +6 -0
  26. package/src/markdown/utils.ts +153 -3
  27. package/src/openapi/__fixtures__/webhook/openapi.yaml +17 -0
  28. package/src/openapi/createSchemaExample.test.ts +57 -0
  29. package/src/openapi/createSchemaExample.ts +26 -2
  30. package/src/openapi/openapi.test.ts +58 -0
  31. package/src/openapi/openapi.ts +35 -6
  32. package/src/openapi/webhooks.test.ts +30 -0
  33. package/src/options.ts +4 -0
  34. package/src/plugin-openapi.d.ts +1 -1
  35. package/src/sidebars/index.ts +15 -3
  36. package/src/{types.ts → types.d.ts} +12 -2
  37. package/lib/types.d.ts +0 -135
  38. package/lib/types.js +0 -8
  39. package/src/plugin-content-docs-types.d.ts +0 -42
@@ -37,7 +37,8 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
37
37
  `import StatusCodes from "@theme/StatusCodes";\n`,
38
38
  `import OperationTabs from "@theme/OperationTabs";\n`,
39
39
  `import TabItem from "@theme/TabItem";\n`,
40
- `import Heading from "@theme/Heading";\n\n`,
40
+ `import Heading from "@theme/Heading";\n`,
41
+ `import Translate from "@docusaurus/Translate";\n\n`,
41
42
  (0, createHeading_1.createHeading)(title),
42
43
  (0, createMethodEndpoint_1.createMethodEndpoint)(method, path),
43
44
  infoPath && (0, createAuthorization_1.createAuthorization)(infoPath),
@@ -82,7 +83,7 @@ function createSchemaPageMD({ schema }) {
82
83
  return (0, utils_1.render)([
83
84
  `import Schema from "@theme/Schema";\n`,
84
85
  `import Heading from "@theme/Heading";\n\n`,
85
- (0, createHeading_1.createHeading)(title.replace(utils_1.lessThan, "<").replace(utils_1.greaterThan, ">")),
86
+ (0, createHeading_1.createHeading)(title),
86
87
  (0, createDescription_1.createDescription)(description),
87
88
  (0, utils_1.create)("Schema", {
88
89
  schema: schema,
@@ -10,6 +10,11 @@ exports.getSchemaName = getSchemaName;
10
10
  exports.getQualifierMessage = getQualifierMessage;
11
11
  function prettyName(schema, circular) {
12
12
  var _a, _b, _c, _d, _e;
13
+ // Handle enum-only schemas (valid in JSON Schema)
14
+ // When enum is present without explicit type, treat as string
15
+ if (schema.enum && !schema.type) {
16
+ return "string";
17
+ }
13
18
  if (schema.format) {
14
19
  if (schema.type) {
15
20
  return `${schema.type}<${schema.format}>`;
@@ -1,6 +1,38 @@
1
+ /**
2
+ * Represents an external JSON file to be written alongside the MDX.
3
+ */
4
+ export interface ExternalFile {
5
+ /** The filename for the JSON file (relative to outputDir) */
6
+ filename: string;
7
+ /** The JSON content to write */
8
+ content: string;
9
+ }
10
+ /**
11
+ * Result of running MDX generation with externalization.
12
+ */
13
+ export interface ExternalizationResult<T> {
14
+ /** The result of the generation function */
15
+ result: T;
16
+ /** External JSON files to write */
17
+ files: ExternalFile[];
18
+ }
19
+ /**
20
+ * Runs a function with externalization enabled.
21
+ * Any calls to create() within the function will externalize eligible component props.
22
+ *
23
+ * @param baseFilename - Base filename for the MDX file (without extension)
24
+ * @param fn - Function to run with externalization enabled
25
+ * @returns The function result and any external files that were collected
26
+ *
27
+ * @example
28
+ * const { result: mdx, files } = runWithExternalization("add-pet", () => {
29
+ * return createApiPageMD(item);
30
+ * });
31
+ */
32
+ export declare function runWithExternalization<T>(baseFilename: string, fn: () => T): ExternalizationResult<T>;
1
33
  /**
2
34
  * Children in the plugin does not accept DOM elements, when compared with Children in the theme.
3
- * It is designed for rendering HTML a strings.
35
+ * It is designed for rendering HTML as strings.
4
36
  */
5
37
  export type Children = string | undefined | (string | string[] | undefined)[];
6
38
  export type Props = Record<string, any> & {
@@ -9,6 +41,11 @@ export type Props = Record<string, any> & {
9
41
  export type Options = {
10
42
  inline?: boolean;
11
43
  };
44
+ /**
45
+ * Creates a JSX component string with the given tag, props, and options.
46
+ * When called within runWithExternalization(), props for eligible
47
+ * components are externalized to a single JSON file and spread.
48
+ */
12
49
  export declare function create(tag: string, props: Props, options?: Options): string;
13
50
  export declare function guard<T>(value: T | undefined, cb: (value: T) => Children): string;
14
51
  export declare function render(children: Children): string;
@@ -7,15 +7,82 @@
7
7
  * ========================================================================== */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.codeBlock = exports.curlyBrackets = exports.codeFence = exports.greaterThan = exports.lessThan = void 0;
10
+ exports.runWithExternalization = runWithExternalization;
10
11
  exports.create = create;
11
12
  exports.guard = guard;
12
13
  exports.render = render;
13
14
  exports.clean = clean;
15
+ /**
16
+ * Module-level externalization context.
17
+ * Note: AsyncLocalStorage would be cleaner but isn't available in browser bundles.
18
+ */
19
+ let externalizationContext = null;
20
+ /**
21
+ * Components whose props should be externalized to separate JSON files.
22
+ * These are the components that typically receive large JSON objects.
23
+ */
24
+ const EXTERNALIZABLE_COMPONENTS = new Set([
25
+ "StatusCodes",
26
+ "ParamsDetails",
27
+ "RequestSchema",
28
+ "Schema",
29
+ "SchemaItem",
30
+ ]);
31
+ /**
32
+ * Runs a function with externalization enabled.
33
+ * Any calls to create() within the function will externalize eligible component props.
34
+ *
35
+ * @param baseFilename - Base filename for the MDX file (without extension)
36
+ * @param fn - Function to run with externalization enabled
37
+ * @returns The function result and any external files that were collected
38
+ *
39
+ * @example
40
+ * const { result: mdx, files } = runWithExternalization("add-pet", () => {
41
+ * return createApiPageMD(item);
42
+ * });
43
+ */
44
+ function runWithExternalization(baseFilename, fn) {
45
+ // Set up context
46
+ externalizationContext = {
47
+ baseFilename,
48
+ componentCounters: {},
49
+ files: [],
50
+ };
51
+ try {
52
+ const result = fn();
53
+ const files = externalizationContext.files;
54
+ return { result, files };
55
+ }
56
+ finally {
57
+ // Always clear context
58
+ externalizationContext = null;
59
+ }
60
+ }
61
+ /**
62
+ * Creates a JSX component string with the given tag, props, and options.
63
+ * When called within runWithExternalization(), props for eligible
64
+ * components are externalized to a single JSON file and spread.
65
+ */
14
66
  function create(tag, props, options = {}) {
15
67
  const { children, ...rest } = props;
16
68
  let propString = "";
17
- for (const [key, value] of Object.entries(rest)) {
18
- propString += `\n ${key}={${JSON.stringify(value)}}`;
69
+ // Check if this component's props should be externalized
70
+ if (shouldExternalizeComponent(tag, rest)) {
71
+ const filename = generateExternalFilename(tag);
72
+ const content = JSON.stringify(rest);
73
+ // Add to external files
74
+ externalizationContext.files.push({
75
+ filename,
76
+ content,
77
+ });
78
+ // Use spread syntax with require
79
+ propString = `\n {...require("./${filename}")}`;
80
+ }
81
+ else {
82
+ // Inline props as usual
83
+ for (const [key, value] of Object.entries(rest)) {
84
+ propString += `\n ${key}={${JSON.stringify(value)}}`;
85
+ }
19
86
  }
20
87
  let indentedChildren = render(children).replace(/^/gm, " ");
21
88
  if (options.inline) {
@@ -26,6 +93,37 @@ function create(tag, props, options = {}) {
26
93
  indentedChildren += indentedChildren ? "\n" : "";
27
94
  return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
28
95
  }
96
+ /**
97
+ * Determines if a component's props should be externalized.
98
+ */
99
+ function shouldExternalizeComponent(tag, props) {
100
+ // No context means externalization is not enabled
101
+ if (!externalizationContext) {
102
+ return false;
103
+ }
104
+ if (!EXTERNALIZABLE_COMPONENTS.has(tag)) {
105
+ return false;
106
+ }
107
+ // Don't externalize if props are empty or only contain undefined/null
108
+ const hasContent = Object.values(props).some((v) => v !== undefined && v !== null);
109
+ if (!hasContent) {
110
+ return false;
111
+ }
112
+ return true;
113
+ }
114
+ /**
115
+ * Generates a unique filename for an externalized component's props.
116
+ */
117
+ function generateExternalFilename(componentName) {
118
+ var _a;
119
+ if (!externalizationContext) {
120
+ throw new Error("Externalization context not set");
121
+ }
122
+ const count = ((_a = externalizationContext.componentCounters[componentName]) !== null && _a !== void 0 ? _a : 0) + 1;
123
+ externalizationContext.componentCounters[componentName] = count;
124
+ const suffix = count > 1 ? `.${count}` : "";
125
+ return `${externalizationContext.baseFilename}.${componentName}${suffix}.json`;
126
+ }
29
127
  function guard(value, cb) {
30
128
  if (!!value || value === 0) {
31
129
  const children = cb(value);
@@ -58,7 +58,14 @@ function sampleFromProp(name, prop, obj, context) {
58
58
  return obj;
59
59
  }
60
60
  // TODO: handle discriminators
61
- if (prop.oneOf) {
61
+ // Check for explicit example/examples first (OAS 3.1 support)
62
+ if (prop.example !== undefined) {
63
+ obj[name] = prop.example;
64
+ }
65
+ else if (prop.examples !== undefined && prop.examples.length > 0) {
66
+ obj[name] = prop.examples[0];
67
+ }
68
+ else if (prop.oneOf) {
62
69
  obj[name] = (0, exports.sampleFromSchema)(prop.oneOf[0], context);
63
70
  }
64
71
  else if (prop.anyOf) {
@@ -77,10 +84,14 @@ const sampleFromSchema = (schema = {}, context) => {
77
84
  try {
78
85
  // deep copy schema before processing
79
86
  let schemaCopy = JSON.parse(JSON.stringify(schema));
80
- let { type, example, allOf, properties, items, oneOf, anyOf } = schemaCopy;
87
+ let { type, example, examples, allOf, properties, items, oneOf, anyOf, const: constant, } = schemaCopy;
81
88
  if (example !== undefined) {
82
89
  return example;
83
90
  }
91
+ // OAS 3.1 / JSON Schema: examples is an array
92
+ if (examples !== undefined && examples.length > 0) {
93
+ return examples[0];
94
+ }
84
95
  if (oneOf) {
85
96
  if (properties) {
86
97
  const combinedSchemas = (0, merge_1.default)(schemaCopy, oneOf[0]);
@@ -169,6 +180,9 @@ const sampleFromSchema = (schema = {}, context) => {
169
180
  if (shouldExcludeProperty(schemaCopy, context)) {
170
181
  return undefined;
171
182
  }
183
+ if (constant) {
184
+ return constant;
185
+ }
172
186
  return primitive(schemaCopy);
173
187
  }
174
188
  catch (err) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const createSchemaExample_1 = require("./createSchemaExample");
10
+ describe("sampleFromSchema", () => {
11
+ describe("const support", () => {
12
+ it("should return default string value when const is not present", () => {
13
+ const schema = {
14
+ type: "string",
15
+ };
16
+ const context = { type: "request" };
17
+ const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
18
+ expect(result).toBe("string");
19
+ });
20
+ it("should return const value when const is present", () => {
21
+ const schema = {
22
+ type: "string",
23
+ const: "example",
24
+ };
25
+ const context = { type: "request" };
26
+ const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
27
+ expect(result).toBe("example");
28
+ });
29
+ it("should handle anyOf with const values", () => {
30
+ const schema = {
31
+ type: "string",
32
+ anyOf: [
33
+ {
34
+ type: "string",
35
+ const: "dog",
36
+ },
37
+ {
38
+ type: "string",
39
+ const: "cat",
40
+ },
41
+ ],
42
+ };
43
+ const context = { type: "request" };
44
+ const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
45
+ expect(result).toBe("dog");
46
+ });
47
+ });
48
+ });
@@ -65,11 +65,16 @@ const loadAndResolveSpec_1 = require("./utils/loadAndResolveSpec");
65
65
  */
66
66
  function jsonToCollection(data) {
67
67
  return new Promise((resolve, reject) => {
68
+ var _a, _b;
68
69
  let schemaPack = new openapi_to_postmanv2_1.default.SchemaPack({ type: "json", data }, { schemaFaker: false });
69
70
  schemaPack.computedOptions.schemaFaker = false;
71
+ // Make sure the schema was properly validated or reject with error
72
+ if (!((_a = schemaPack.validationResult) === null || _a === void 0 ? void 0 : _a.result)) {
73
+ return reject((_b = schemaPack.validationResult) === null || _b === void 0 ? void 0 : _b.reason);
74
+ }
70
75
  schemaPack.convert((_err, conversionResult) => {
71
- if (!conversionResult.result) {
72
- return reject(conversionResult.reason);
76
+ if (_err || !conversionResult.result) {
77
+ return reject(_err || conversionResult.reason);
73
78
  }
74
79
  return resolve(new sdk.Collection(conversionResult.output[0].data));
75
80
  });
@@ -98,13 +103,15 @@ async function createPostmanCollection(openapiData) {
98
103
  return await jsonToCollection(data);
99
104
  }
100
105
  function createItems(openapiData, options, sidebarOptions) {
101
- 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;
106
+ 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, _8;
102
107
  // TODO: Find a better way to handle this
103
108
  let items = [];
104
109
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
105
110
  const infoId = (0, kebabCase_1.default)(infoIdSpaces);
106
- if (openapiData.info.description || openapiData.info.title) {
107
- // Only create an info page if we have a description.
111
+ const schemasOnly = (options === null || options === void 0 ? void 0 : options.schemasOnly) === true;
112
+ // Only create an info page if we have a description/title AND showInfoPage is not false
113
+ if ((openapiData.info.description || openapiData.info.title) &&
114
+ (options === null || options === void 0 ? void 0 : options.showInfoPage) !== false) {
108
115
  const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
109
116
  let splitDescription;
110
117
  if (infoDescription) {
@@ -231,6 +238,9 @@ function createItems(openapiData, options, sidebarOptions) {
231
238
  ...((options === null || options === void 0 ? void 0 : options.showExtensions) && {
232
239
  show_extensions: options.showExtensions,
233
240
  }),
241
+ ...((options === null || options === void 0 ? void 0 : options.maskCredentials) === false && {
242
+ mask_credentials_disabled: true,
243
+ }),
234
244
  },
235
245
  api: {
236
246
  ...defaults,
@@ -251,10 +261,15 @@ function createItems(openapiData, options, sidebarOptions) {
251
261
  }
252
262
  // Gather x-webhooks endpoints
253
263
  for (let [path, pathObject] of Object.entries((_q = (_p = openapiData["x-webhooks"]) !== null && _p !== void 0 ? _p : openapiData["webhooks"]) !== null && _q !== void 0 ? _q : {})) {
264
+ const eventName = path;
254
265
  path = "webhook";
255
266
  const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
256
267
  for (let [method, operationObject] of Object.entries({ ...rest })) {
257
268
  method = "event";
269
+ if (operationObject.summary === undefined &&
270
+ operationObject.operationId === undefined) {
271
+ operationObject.summary = eventName;
272
+ }
258
273
  const title = (_s = (_r = operationObject.summary) !== null && _r !== void 0 ? _r : operationObject.operationId) !== null && _s !== void 0 ? _s : "Missing summary";
259
274
  if (operationObject.description === undefined) {
260
275
  operationObject.description =
@@ -262,7 +277,7 @@ function createItems(openapiData, options, sidebarOptions) {
262
277
  }
263
278
  const baseId = operationObject.operationId
264
279
  ? (0, kebabCase_1.default)(operationObject.operationId)
265
- : (0, kebabCase_1.default)(operationObject.summary);
280
+ : (0, kebabCase_1.default)((_v = operationObject.summary) !== null && _v !== void 0 ? _v : eventName);
266
281
  const extensions = [];
267
282
  const commonExtensions = ["x-codeSamples"];
268
283
  for (const [key, value] of Object.entries(operationObject)) {
@@ -270,10 +285,10 @@ function createItems(openapiData, options, sidebarOptions) {
270
285
  extensions.push({ key, value });
271
286
  }
272
287
  }
273
- const servers = (_w = (_v = operationObject.servers) !== null && _v !== void 0 ? _v : pathObject.servers) !== null && _w !== void 0 ? _w : openapiData.servers;
274
- const security = (_x = operationObject.security) !== null && _x !== void 0 ? _x : openapiData.security;
288
+ const servers = (_x = (_w = operationObject.servers) !== null && _w !== void 0 ? _w : pathObject.servers) !== null && _x !== void 0 ? _x : openapiData.servers;
289
+ const security = (_y = operationObject.security) !== null && _y !== void 0 ? _y : openapiData.security;
275
290
  // Add security schemes so we know how to handle security.
276
- const securitySchemes = (_y = openapiData.components) === null || _y === void 0 ? void 0 : _y.securitySchemes;
291
+ const securitySchemes = (_z = openapiData.components) === null || _z === void 0 ? void 0 : _z.securitySchemes;
277
292
  // Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
278
293
  if (securitySchemes) {
279
294
  for (let securityScheme of Object.values(securitySchemes)) {
@@ -283,7 +298,7 @@ function createItems(openapiData, options, sidebarOptions) {
283
298
  }
284
299
  }
285
300
  let jsonRequestBodyExample;
286
- const content = (_z = operationObject.requestBody) === null || _z === void 0 ? void 0 : _z.content;
301
+ const content = (_0 = operationObject.requestBody) === null || _0 === void 0 ? void 0 : _0.content;
287
302
  let body;
288
303
  for (let key in content) {
289
304
  if (key.toLowerCase() === "application/json" ||
@@ -296,7 +311,7 @@ function createItems(openapiData, options, sidebarOptions) {
296
311
  jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(body.schema);
297
312
  }
298
313
  // Handle vendor JSON media types
299
- const bodyContent = (_0 = operationObject.requestBody) === null || _0 === void 0 ? void 0 : _0.content;
314
+ const bodyContent = (_1 = operationObject.requestBody) === null || _1 === void 0 ? void 0 : _1.content;
300
315
  if (bodyContent) {
301
316
  const firstBodyContentKey = Object.keys(bodyContent)[0];
302
317
  if (firstBodyContentKey.endsWith("+json")) {
@@ -345,6 +360,9 @@ function createItems(openapiData, options, sidebarOptions) {
345
360
  ...((options === null || options === void 0 ? void 0 : options.showExtensions) && {
346
361
  show_extensions: options.showExtensions,
347
362
  }),
363
+ ...((options === null || options === void 0 ? void 0 : options.maskCredentials) === false && {
364
+ mask_credentials_disabled: true,
365
+ }),
348
366
  },
349
367
  api: {
350
368
  ...defaults,
@@ -362,14 +380,17 @@ function createItems(openapiData, options, sidebarOptions) {
362
380
  items.push(apiPage);
363
381
  }
364
382
  }
365
- if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
366
- 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 : {})
383
+ if (schemasOnly ||
384
+ (options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
385
+ 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 : {})
367
386
  .flatMap(([_, s]) => s["x-tags"])
368
387
  .filter((item) => !!item).length > 0) {
369
388
  // Gather schemas
370
- 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 : {})) {
371
- if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true || schemaObject["x-tags"]) {
372
- 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 : "";
389
+ for (let [schema, schemaObject] of Object.entries((_5 = (_4 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _4 === void 0 ? void 0 : _4.schemas) !== null && _5 !== void 0 ? _5 : {})) {
390
+ if (schemasOnly ||
391
+ (options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
392
+ schemaObject["x-tags"]) {
393
+ const baseIdSpaces = (_7 = (_6 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _6 === void 0 ? void 0 : _6.replace(" ", "-").toLowerCase()) !== null && _7 !== void 0 ? _7 : "";
373
394
  const baseId = (0, kebabCase_1.default)(baseIdSpaces);
374
395
  const schemaDescription = schemaObject.description;
375
396
  let splitDescription;
@@ -403,7 +424,7 @@ function createItems(openapiData, options, sidebarOptions) {
403
424
  }
404
425
  if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
405
426
  // Get global tags
406
- const tags = (_7 = openapiData.tags) !== null && _7 !== void 0 ? _7 : [];
427
+ const tags = (_8 = openapiData.tags) !== null && _8 !== void 0 ? _8 : [];
407
428
  // Get operation tags
408
429
  const apiItems = items.filter((item) => {
409
430
  return item.type === "api";
@@ -13,6 +13,7 @@ const path_1 = __importDefault(require("path"));
13
13
  // eslint-disable-next-line import/no-extraneous-dependencies
14
14
  const utils_1 = require("@docusaurus/utils");
15
15
  const _1 = require(".");
16
+ const openapi_1 = require("./openapi");
16
17
  // npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
17
18
  describe("openapi", () => {
18
19
  describe("readOpenapiFiles", () => {
@@ -30,4 +31,51 @@ describe("openapi", () => {
30
31
  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();
31
32
  });
32
33
  });
34
+ describe("schemasOnly", () => {
35
+ it("includes schema metadata when showSchemas is disabled", async () => {
36
+ const openapiData = {
37
+ openapi: "3.0.0",
38
+ info: {
39
+ title: "Schema Only",
40
+ version: "1.0.0",
41
+ },
42
+ paths: {
43
+ "/ping": {
44
+ get: {
45
+ summary: "Ping",
46
+ responses: {
47
+ "200": {
48
+ description: "OK",
49
+ },
50
+ },
51
+ },
52
+ },
53
+ },
54
+ components: {
55
+ schemas: {
56
+ WithoutTags: {
57
+ title: "Without Tags",
58
+ type: "object",
59
+ properties: {
60
+ value: {
61
+ type: "string",
62
+ },
63
+ },
64
+ },
65
+ },
66
+ },
67
+ };
68
+ const options = {
69
+ specPath: "dummy", // required by the type but unused in this context
70
+ outputDir: "build",
71
+ showSchemas: false,
72
+ schemasOnly: true,
73
+ };
74
+ const sidebarOptions = {};
75
+ const [items] = await (0, openapi_1.processOpenapiFile)(openapiData, options, sidebarOptions);
76
+ const schemaItems = items.filter((item) => item.type === "schema");
77
+ expect(schemaItems).toHaveLength(1);
78
+ expect(schemaItems[0].id).toBe("without-tags");
79
+ });
80
+ });
33
81
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
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 path_1 = __importDefault(require("path"));
13
+ // eslint-disable-next-line import/no-extraneous-dependencies
14
+ const utils_1 = require("@docusaurus/utils");
15
+ const _1 = require(".");
16
+ describe("webhooks", () => {
17
+ it("uses event name when summary and operationId are missing", async () => {
18
+ const files = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/webhook/openapi.yaml")));
19
+ const [items] = await (0, _1.processOpenapiFiles)(files, { specPath: "", outputDir: "" }, {});
20
+ const webhookItem = items.find((item) => item.type === "api");
21
+ expect(webhookItem === null || webhookItem === void 0 ? void 0 : webhookItem.id).toBe("order-created");
22
+ });
23
+ });
package/lib/options.js CHANGED
@@ -44,7 +44,11 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
44
44
  sidebarOptions: sidebarOptions,
45
45
  markdownGenerators: markdownGenerators,
46
46
  showSchemas: utils_validation_1.Joi.boolean(),
47
+ showInfoPage: utils_validation_1.Joi.boolean(),
48
+ schemasOnly: utils_validation_1.Joi.boolean(),
47
49
  disableCompression: utils_validation_1.Joi.boolean(),
50
+ maskCredentials: utils_validation_1.Joi.boolean(),
51
+ externalJsonProps: utils_validation_1.Joi.boolean().default(true),
48
52
  version: utils_validation_1.Joi.string().when("versions", {
49
53
  is: utils_validation_1.Joi.exist(),
50
54
  then: utils_validation_1.Joi.required(),
@@ -81,9 +81,18 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
81
81
  if (sidebarOptions.groupPathsBy !== "tagGroup") {
82
82
  apiTags = (0, uniq_1.default)(apiTags.concat(operationTags, schemaTags));
83
83
  }
84
- const basePath = docPath
85
- ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
86
- : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
84
+ // Extract base path from outputDir, handling cases where docPath may not be in outputDir
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 : "";
89
+ }
90
+ const slashIndex = output.indexOf("/", 1);
91
+ return slashIndex === -1
92
+ ? ""
93
+ : output.slice(slashIndex).replace(/^\/+/g, "");
94
+ };
95
+ const basePath = getBasePathFromOutput(outputDir, docPath);
87
96
  const createDocItemFnContext = {
88
97
  sidebarOptions,
89
98
  basePath,
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.5.1",
4
+ "version": "4.7.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -32,29 +32,29 @@
32
32
  "@docusaurus/types": "^3.5.0",
33
33
  "@docusaurus/utils": "^3.5.0",
34
34
  "@docusaurus/utils-validation": "^3.5.0",
35
- "@types/fs-extra": "^9.0.13",
36
- "@types/json-pointer": "^1.0.31",
37
- "@types/json-schema": "^7.0.9",
38
- "@types/lodash": "^4.14.176",
39
- "@types/mustache": "^4.1.2",
40
- "eslint-plugin-prettier": "^5.0.1"
35
+ "@types/fs-extra": "^11.0.4",
36
+ "@types/json-pointer": "^1.0.34",
37
+ "@types/json-schema": "^7.0.15",
38
+ "@types/lodash": "^4.17.20",
39
+ "@types/mustache": "^4.2.6",
40
+ "eslint-plugin-prettier": "^5.5.1"
41
41
  },
42
42
  "dependencies": {
43
43
  "@apidevtools/json-schema-ref-parser": "^11.5.4",
44
- "@redocly/openapi-core": "^1.10.5",
44
+ "@redocly/openapi-core": "^1.34.3",
45
45
  "allof-merge": "^0.6.6",
46
46
  "chalk": "^4.1.2",
47
- "clsx": "^1.1.1",
48
- "fs-extra": "^9.0.1",
47
+ "clsx": "^2.1.1",
48
+ "fs-extra": "^11.3.0",
49
49
  "json-pointer": "^0.6.2",
50
50
  "json5": "^2.2.3",
51
- "lodash": "^4.17.20",
51
+ "lodash": "^4.17.21",
52
52
  "mustache": "^4.2.0",
53
- "openapi-to-postmanv2": "^4.21.0",
54
- "postman-collection": "^4.4.0",
55
- "slugify": "^1.6.5",
53
+ "openapi-to-postmanv2": "^5.0.0",
54
+ "postman-collection": "^5.0.2",
55
+ "slugify": "^1.6.6",
56
56
  "swagger2openapi": "^7.0.8",
57
- "xml-formatter": "^2.6.1"
57
+ "xml-formatter": "^3.6.6"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@docusaurus/plugin-content-docs": "^3.5.0",
@@ -65,5 +65,5 @@
65
65
  "engines": {
66
66
  "node": ">=14"
67
67
  },
68
- "gitHead": "dab3823034dd9ea74a713ee9d729bd45455d3e5c"
68
+ "gitHead": "f5829b8e478b0ee76344ba31edd67efdfea18990"
69
69
  }