docusaurus-plugin-openapi-docs 1.1.11 → 1.2.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.
package/lib/index.js CHANGED
@@ -68,11 +68,17 @@ function pluginOpenAPIDocs(context, options) {
68
68
  const presets = siteConfig.presets;
69
69
  const plugins = siteConfig.plugins;
70
70
  const presetsPlugins = presets.concat(plugins);
71
- const docData = getDocsPluginConfig(presetsPlugins, docsPluginId);
72
- const docRouteBasePath = docData ? docData.routeBasePath : undefined;
73
- const docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
74
- async function generateApiDocs(options) {
71
+ let docData = getDocsPluginConfig(presetsPlugins, docsPluginId);
72
+ let docRouteBasePath = docData ? docData.routeBasePath : undefined;
73
+ let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
74
+ async function generateApiDocs(options, pluginId) {
75
75
  let { specPath, outputDir, template, sidebarOptions } = options;
76
+ // Override docPath if pluginId provided
77
+ if (pluginId) {
78
+ docData = getDocsPluginConfig(presetsPlugins, pluginId);
79
+ docRouteBasePath = docData ? docData.routeBasePath : undefined;
80
+ docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
81
+ }
76
82
  const contentPath = isURL(specPath)
77
83
  ? specPath
78
84
  : path_1.default.resolve(siteDir, specPath);
@@ -109,6 +115,8 @@ function pluginOpenAPIDocs(context, options) {
109
115
  ? fs_1.default.readFileSync(template).toString()
110
116
  : `---
111
117
  id: {{{id}}}
118
+ title: "{{{title}}}"
119
+ description: "{{{description}}}"
112
120
  {{^api}}
113
121
  sidebar_label: Introduction
114
122
  {{/api}}
@@ -137,6 +145,8 @@ info_path: {{{infoPath}}}
137
145
  `;
138
146
  const infoMdTemplate = `---
139
147
  id: {{{id}}}
148
+ title: "{{{title}}}"
149
+ description: "{{{description}}}"
140
150
  sidebar_label: {{{title}}}
141
151
  hide_title: true
142
152
  custom_edit_url: null
@@ -153,8 +163,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
153
163
  `;
154
164
  const tagMdTemplate = `---
155
165
  id: {{{id}}}
156
- title: {{{description}}}
157
- description: {{{description}}}
166
+ title: "{{{description}}}"
167
+ description: "{{{description}}}"
158
168
  custom_edit_url: null
159
169
  ---
160
170
 
@@ -192,6 +202,10 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
192
202
  if (item.type === "api") {
193
203
  if (!fs_1.default.existsSync(`${outputDir}/${item.id}.api.mdx`)) {
194
204
  try {
205
+ // kebabCase(arg) returns 0-length string when arg is undefined
206
+ if (item.id.length === 0) {
207
+ throw Error("Operation must have summary or operationId defined");
208
+ }
195
209
  fs_1.default.writeFileSync(`${outputDir}/${item.id}.api.mdx`, view, "utf8");
196
210
  console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.api.mdx"`));
197
211
  }
@@ -307,10 +321,12 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
307
321
  const pluginId = options.pluginId;
308
322
  const pluginInstances = getPluginInstances(plugins);
309
323
  let targetConfig;
324
+ let targetDocsPluginId;
310
325
  if (pluginId) {
311
326
  try {
312
327
  const pluginConfig = getPluginConfig(plugins, pluginId);
313
328
  targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
329
+ targetDocsPluginId = pluginConfig.docsPluginId;
314
330
  }
315
331
  catch {
316
332
  console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
@@ -330,7 +346,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
330
346
  }
331
347
  else {
332
348
  Object.keys(targetConfig).forEach(async function (key) {
333
- await generateApiDocs(targetConfig[key]);
349
+ await generateApiDocs(targetConfig[key], targetDocsPluginId);
334
350
  });
335
351
  }
336
352
  }
@@ -338,7 +354,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
338
354
  console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
339
355
  }
340
356
  else {
341
- await generateApiDocs(targetConfig[id]);
357
+ await generateApiDocs(targetConfig[id], targetDocsPluginId);
342
358
  }
343
359
  });
344
360
  cli
@@ -353,10 +369,12 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
353
369
  const pluginId = options.pluginId;
354
370
  const pluginInstances = getPluginInstances(plugins);
355
371
  let targetConfig;
372
+ let targetDocsPluginId;
356
373
  if (pluginId) {
357
374
  try {
358
375
  const pluginConfig = getPluginConfig(plugins, pluginId);
359
376
  targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
377
+ targetDocsPluginId = pluginConfig.docsPluginId;
360
378
  }
361
379
  catch {
362
380
  console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
@@ -397,7 +415,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
397
415
  ...parentConfig,
398
416
  ...versionConfig,
399
417
  };
400
- await generateApiDocs(mergedConfig);
418
+ await generateApiDocs(mergedConfig, targetDocsPluginId);
401
419
  });
402
420
  }
403
421
  }
@@ -411,7 +429,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
411
429
  ...versionConfig,
412
430
  };
413
431
  await generateVersions(mergedVersions, parentConfig.outputDir);
414
- await generateApiDocs(mergedConfig);
432
+ await generateApiDocs(mergedConfig, targetDocsPluginId);
415
433
  }
416
434
  });
417
435
  cli
@@ -43,7 +43,7 @@ exports.mergeAllOf = mergeAllOf;
43
43
  */
44
44
  function createAnyOneOf(schema) {
45
45
  const type = schema.oneOf ? "oneOf" : "anyOf";
46
- return (0, utils_1.create)("li", {
46
+ return (0, utils_1.create)("div", {
47
47
  children: [
48
48
  (0, utils_1.create)("div", {
49
49
  children: [
@@ -44,7 +44,7 @@ exports.mergeAllOf = mergeAllOf;
44
44
  */
45
45
  function createAnyOneOf(schema) {
46
46
  const type = schema.oneOf ? "oneOf" : "anyOf";
47
- return (0, utils_1.create)("li", {
47
+ return (0, utils_1.create)("div", {
48
48
  children: [
49
49
  (0, utils_1.create)("div", {
50
50
  children: [
@@ -68,7 +68,7 @@ function createResponseHeaders(responseHeaders) {
68
68
  Object.entries(responseHeaders).map(([headerName, headerObj]) => {
69
69
  const { description, schema: { type }, example, } = headerObj;
70
70
  return (0, utils_1.create)("li", {
71
- class: "schemaItem",
71
+ className: "schemaItem",
72
72
  children: [
73
73
  (0, createDetailsSummary_1.createDetailsSummary)({
74
74
  children: [
@@ -95,7 +95,9 @@ function createItems(openapiData, sidebarOptions) {
95
95
  id: infoId,
96
96
  unversionedId: infoId,
97
97
  title: openapiData.info.title,
98
- description: openapiData.info.description,
98
+ description: openapiData.info.description
99
+ ? openapiData.info.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
100
+ : "",
99
101
  frontMatter: {},
100
102
  securitySchemes: (_b = openapiData.components) === null || _b === void 0 ? void 0 : _b.securitySchemes,
101
103
  info: {
@@ -155,7 +157,9 @@ function createItems(openapiData, sidebarOptions) {
155
157
  infoId: infoId !== null && infoId !== void 0 ? infoId : "",
156
158
  unversionedId: baseId,
157
159
  title: title,
158
- description: description !== null && description !== void 0 ? description : "",
160
+ description: operationObject.description
161
+ ? operationObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
162
+ : "",
159
163
  frontMatter: {},
160
164
  api: {
161
165
  ...defaults,
@@ -28,12 +28,15 @@ function serializer(replacer, cycleReplacer) {
28
28
  // Resolve discriminator ref pointers
29
29
  if ((value === null || value === void 0 ? void 0 : value.discriminator) !== undefined) {
30
30
  const parser = new OpenAPIParser_1.OpenAPIParser(stack[0]);
31
- for (let [k, v] of Object.entries(value.discriminator.mapping)) {
32
- const discriminator = k;
33
- if (typeof v === "string" && v.charAt(0) === "#") {
34
- const ref = v;
35
- const resolvedRef = parser.byRef(ref);
36
- value.discriminator.mapping[discriminator] = resolvedRef;
31
+ if (value.discriminator.mapping &&
32
+ typeof value.discriminator.mapping === "object") {
33
+ for (let [k, v] of Object.entries(value.discriminator.mapping)) {
34
+ const discriminator = k;
35
+ if (typeof v === "string" && v.charAt(0) === "#") {
36
+ const ref = v;
37
+ const resolvedRef = parser.byRef(ref);
38
+ value.discriminator.mapping[discriminator] = resolvedRef;
39
+ }
37
40
  }
38
41
  }
39
42
  }
@@ -36,13 +36,12 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
36
36
  const operationTags = (0, uniq_1.default)(apiItems
37
37
  .flatMap((item) => item.api.tags)
38
38
  .filter((item) => !!item));
39
- // Only include operation tags that are globally defined
40
- const apiTags = [];
39
+ // Combine globally defined tags with operation tags
40
+ let apiTags = [];
41
41
  tags.flat().forEach((tag) => {
42
- if (operationTags.includes(tag.name)) {
43
- apiTags.push(tag.name);
44
- }
42
+ apiTags.push(tag.name);
45
43
  });
44
+ apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
46
45
  const basePath = docPath
47
46
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
48
47
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
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.1.11",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -40,10 +40,10 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@apidevtools/json-schema-ref-parser": "^9.0.9",
43
- "@docusaurus/mdx-loader": "2.0.1",
44
- "@docusaurus/plugin-content-docs": "2.0.1",
45
- "@docusaurus/utils": "2.0.1",
46
- "@docusaurus/utils-validation": "2.0.1",
43
+ "@docusaurus/mdx-loader": "^2.0.1",
44
+ "@docusaurus/plugin-content-docs": "^2.0.1",
45
+ "@docusaurus/utils": "^2.0.1",
46
+ "@docusaurus/utils-validation": "^2.0.1",
47
47
  "@paloaltonetworks/openapi-to-postmanv2": "3.1.0-hotfix.1",
48
48
  "@paloaltonetworks/postman-collection": "^4.1.0",
49
49
  "@redocly/openapi-core": "^1.0.0-beta.103",
@@ -68,5 +68,5 @@
68
68
  "engines": {
69
69
  "node": ">=14"
70
70
  },
71
- "gitHead": "329709c2d588d2a689a2f84d392b5cc11d6cdd02"
71
+ "gitHead": "fdbc413e36c3b7c202cc31606124c0a8eb76811b"
72
72
  }
package/src/index.ts CHANGED
@@ -79,13 +79,20 @@ export default function pluginOpenAPIDocs(
79
79
  const presets: any = siteConfig.presets;
80
80
  const plugins: any = siteConfig.plugins;
81
81
  const presetsPlugins = presets.concat(plugins);
82
- const docData: any = getDocsPluginConfig(presetsPlugins, docsPluginId);
83
- const docRouteBasePath = docData ? docData.routeBasePath : undefined;
84
- const docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
82
+ let docData: any = getDocsPluginConfig(presetsPlugins, docsPluginId);
83
+ let docRouteBasePath = docData ? docData.routeBasePath : undefined;
84
+ let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
85
85
 
86
- async function generateApiDocs(options: APIOptions) {
86
+ async function generateApiDocs(options: APIOptions, pluginId: any) {
87
87
  let { specPath, outputDir, template, sidebarOptions } = options;
88
88
 
89
+ // Override docPath if pluginId provided
90
+ if (pluginId) {
91
+ docData = getDocsPluginConfig(presetsPlugins, pluginId);
92
+ docRouteBasePath = docData ? docData.routeBasePath : undefined;
93
+ docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
94
+ }
95
+
89
96
  const contentPath = isURL(specPath)
90
97
  ? specPath
91
98
  : path.resolve(siteDir, specPath);
@@ -143,6 +150,8 @@ export default function pluginOpenAPIDocs(
143
150
  ? fs.readFileSync(template).toString()
144
151
  : `---
145
152
  id: {{{id}}}
153
+ title: "{{{title}}}"
154
+ description: "{{{description}}}"
146
155
  {{^api}}
147
156
  sidebar_label: Introduction
148
157
  {{/api}}
@@ -172,6 +181,8 @@ info_path: {{{infoPath}}}
172
181
 
173
182
  const infoMdTemplate = `---
174
183
  id: {{{id}}}
184
+ title: "{{{title}}}"
185
+ description: "{{{description}}}"
175
186
  sidebar_label: {{{title}}}
176
187
  hide_title: true
177
188
  custom_edit_url: null
@@ -189,8 +200,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
189
200
 
190
201
  const tagMdTemplate = `---
191
202
  id: {{{id}}}
192
- title: {{{description}}}
193
- description: {{{description}}}
203
+ title: "{{{description}}}"
204
+ description: "{{{description}}}"
194
205
  custom_edit_url: null
195
206
  ---
196
207
 
@@ -231,6 +242,12 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
231
242
  if (item.type === "api") {
232
243
  if (!fs.existsSync(`${outputDir}/${item.id}.api.mdx`)) {
233
244
  try {
245
+ // kebabCase(arg) returns 0-length string when arg is undefined
246
+ if (item.id.length === 0) {
247
+ throw Error(
248
+ "Operation must have summary or operationId defined"
249
+ );
250
+ }
234
251
  fs.writeFileSync(`${outputDir}/${item.id}.api.mdx`, view, "utf8");
235
252
  console.log(
236
253
  chalk.green(
@@ -404,10 +421,12 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
404
421
  const pluginId = options.pluginId;
405
422
  const pluginInstances = getPluginInstances(plugins);
406
423
  let targetConfig: any;
424
+ let targetDocsPluginId: any;
407
425
  if (pluginId) {
408
426
  try {
409
427
  const pluginConfig = getPluginConfig(plugins, pluginId);
410
428
  targetConfig = pluginConfig.config ?? {};
429
+ targetDocsPluginId = pluginConfig.docsPluginId;
411
430
  } catch {
412
431
  console.error(
413
432
  chalk.red(`OpenAPI docs plugin ID '${pluginId}' not found.`)
@@ -435,7 +454,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
435
454
  );
436
455
  } else {
437
456
  Object.keys(targetConfig).forEach(async function (key) {
438
- await generateApiDocs(targetConfig[key]);
457
+ await generateApiDocs(targetConfig[key], targetDocsPluginId);
439
458
  });
440
459
  }
441
460
  } else if (!targetConfig[id]) {
@@ -443,7 +462,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
443
462
  chalk.red(`ID '${id}' does not exist in OpenAPI docs config.`)
444
463
  );
445
464
  } else {
446
- await generateApiDocs(targetConfig[id]);
465
+ await generateApiDocs(targetConfig[id], targetDocsPluginId);
447
466
  }
448
467
  });
449
468
 
@@ -460,10 +479,12 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
460
479
  const pluginId = options.pluginId;
461
480
  const pluginInstances = getPluginInstances(plugins);
462
481
  let targetConfig: any;
482
+ let targetDocsPluginId: any;
463
483
  if (pluginId) {
464
484
  try {
465
485
  const pluginConfig = getPluginConfig(plugins, pluginId);
466
486
  targetConfig = pluginConfig.config ?? {};
487
+ targetDocsPluginId = pluginConfig.docsPluginId;
467
488
  } catch {
468
489
  console.error(
469
490
  chalk.red(`OpenAPI docs plugin ID '${pluginId}' not found.`)
@@ -516,7 +537,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
516
537
  ...parentConfig,
517
538
  ...versionConfig,
518
539
  };
519
- await generateApiDocs(mergedConfig);
540
+ await generateApiDocs(mergedConfig, targetDocsPluginId);
520
541
  });
521
542
  }
522
543
  } else if (!versions[versionId]) {
@@ -532,7 +553,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
532
553
  ...versionConfig,
533
554
  };
534
555
  await generateVersions(mergedVersions, parentConfig.outputDir);
535
- await generateApiDocs(mergedConfig);
556
+ await generateApiDocs(mergedConfig, targetDocsPluginId);
536
557
  }
537
558
  });
538
559
 
@@ -46,7 +46,7 @@ export function mergeAllOf(allOf: SchemaObject[]) {
46
46
  */
47
47
  function createAnyOneOf(schema: SchemaObject): any {
48
48
  const type = schema.oneOf ? "oneOf" : "anyOf";
49
- return create("li", {
49
+ return create("div", {
50
50
  children: [
51
51
  create("div", {
52
52
  children: [
@@ -51,7 +51,7 @@ export function mergeAllOf(allOf: SchemaObject[]) {
51
51
  */
52
52
  function createAnyOneOf(schema: SchemaObject): any {
53
53
  const type = schema.oneOf ? "oneOf" : "anyOf";
54
- return create("li", {
54
+ return create("div", {
55
55
  children: [
56
56
  create("div", {
57
57
  children: [
@@ -70,7 +70,7 @@ function createResponseHeaders(responseHeaders: any) {
70
70
  }: any = headerObj;
71
71
 
72
72
  return create("li", {
73
- class: "schemaItem",
73
+ className: "schemaItem",
74
74
  children: [
75
75
  createDetailsSummary({
76
76
  children: [
@@ -119,7 +119,12 @@ function createItems(
119
119
  id: infoId,
120
120
  unversionedId: infoId,
121
121
  title: openapiData.info.title,
122
- description: openapiData.info.description,
122
+ description: openapiData.info.description
123
+ ? openapiData.info.description.replace(
124
+ /((?:^|[^\\])(?:\\{2})*)"/g,
125
+ "$1'"
126
+ )
127
+ : "",
123
128
  frontMatter: {},
124
129
  securitySchemes: openapiData.components?.securitySchemes,
125
130
  info: {
@@ -194,7 +199,12 @@ function createItems(
194
199
  infoId: infoId ?? "",
195
200
  unversionedId: baseId,
196
201
  title: title,
197
- description: description ?? "",
202
+ description: operationObject.description
203
+ ? operationObject.description.replace(
204
+ /((?:^|[^\\])(?:\\{2})*)"/g,
205
+ "$1'"
206
+ )
207
+ : "",
198
208
  frontMatter: {},
199
209
  api: {
200
210
  ...defaults,
@@ -30,12 +30,17 @@ function serializer(replacer: any, cycleReplacer: any) {
30
30
  // Resolve discriminator ref pointers
31
31
  if (value?.discriminator !== undefined) {
32
32
  const parser = new OpenAPIParser(stack[0]);
33
- for (let [k, v] of Object.entries(value.discriminator.mapping)) {
34
- const discriminator = k as string;
35
- if (typeof v === "string" && v.charAt(0) === "#") {
36
- const ref = v as string;
37
- const resolvedRef = parser.byRef(ref);
38
- value.discriminator.mapping[discriminator] = resolvedRef;
33
+ if (
34
+ value.discriminator.mapping &&
35
+ typeof value.discriminator.mapping === "object"
36
+ ) {
37
+ for (let [k, v] of Object.entries(value.discriminator.mapping)) {
38
+ const discriminator = k as string;
39
+ if (typeof v === "string" && v.charAt(0) === "#") {
40
+ const ref = v as string;
41
+ const resolvedRef = parser.byRef(ref);
42
+ value.discriminator.mapping[discriminator] = resolvedRef;
43
+ }
39
44
  }
40
45
  }
41
46
  }
@@ -66,13 +66,12 @@ function groupByTags(
66
66
  .filter((item): item is string => !!item)
67
67
  );
68
68
 
69
- // Only include operation tags that are globally defined
70
- const apiTags: string[] = [];
69
+ // Combine globally defined tags with operation tags
70
+ let apiTags: string[] = [];
71
71
  tags.flat().forEach((tag) => {
72
- if (operationTags.includes(tag.name!)) {
73
- apiTags.push(tag.name!);
74
- }
72
+ apiTags.push(tag.name!);
75
73
  });
74
+ apiTags = uniq(apiTags.concat(operationTags));
76
75
 
77
76
  const basePath = docPath
78
77
  ? outputDir.split(docPath!)[1].replace(/^\/+/g, "")