docusaurus-plugin-openapi-docs 1.1.8 → 1.1.11

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.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { LoadContext, Plugin } from "@docusaurus/types";
2
2
  import type { PluginOptions, LoadedContent } from "./types";
3
3
  export declare function isURL(str: string): boolean;
4
- export declare function getDocsData(dataArray: any[], filter: string): Object | undefined;
4
+ export declare function getDocsPluginConfig(presetsPlugins: any[], pluginId: string): Object | undefined;
5
5
  declare function pluginOpenAPIDocs(context: LoadContext, options: PluginOptions): Plugin<LoadedContent>;
6
6
  declare namespace pluginOpenAPIDocs {
7
7
  var validateOptions: ({ options, validate }: any) => any;
package/lib/index.js CHANGED
@@ -9,7 +9,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.getDocsData = exports.isURL = void 0;
12
+ exports.getDocsPluginConfig = exports.isURL = void 0;
13
13
  const fs_1 = __importDefault(require("fs"));
14
14
  const path_1 = __importDefault(require("path"));
15
15
  const utils_1 = require("@docusaurus/utils");
@@ -23,36 +23,44 @@ function isURL(str) {
23
23
  return /^(https?:)\/\//m.test(str);
24
24
  }
25
25
  exports.isURL = isURL;
26
- function getDocsData(dataArray, filter) {
26
+ function getDocsPluginConfig(presetsPlugins, pluginId) {
27
27
  // eslint-disable-next-line array-callback-return
28
- const filteredData = dataArray.filter((data) => {
29
- if (data[0] === filter) {
28
+ const filteredConfig = presetsPlugins.filter((data) => {
29
+ if (data[0] === pluginId) {
30
30
  return data[1];
31
31
  }
32
32
  // Search plugin-content-docs instances
33
33
  if (data[0] === "@docusaurus/plugin-content-docs") {
34
- const pluginId = data[1].id ? data[1].id : "default";
35
- if (pluginId === filter) {
34
+ const configPluginId = data[1].id ? data[1].id : "default";
35
+ if (configPluginId === pluginId) {
36
36
  return data[1];
37
37
  }
38
38
  }
39
39
  })[0];
40
- if (filteredData) {
40
+ if (filteredConfig) {
41
41
  // Search presets, e.g. "classic"
42
- if (filteredData[0] === filter) {
43
- return filteredData[1].docs;
42
+ if (filteredConfig[0] === pluginId) {
43
+ return filteredConfig[1].docs;
44
44
  }
45
45
  // Search plugin-content-docs instances
46
- if (filteredData[0] === "@docusaurus/plugin-content-docs") {
47
- const pluginId = filteredData[1].id ? filteredData[1].id : "default";
48
- if (pluginId === filter) {
49
- return filteredData[1];
46
+ if (filteredConfig[0] === "@docusaurus/plugin-content-docs") {
47
+ const configPluginId = filteredConfig[1].id
48
+ ? filteredConfig[1].id
49
+ : "default";
50
+ if (configPluginId === pluginId) {
51
+ return filteredConfig[1];
50
52
  }
51
53
  }
52
54
  }
53
55
  return;
54
56
  }
55
- exports.getDocsData = getDocsData;
57
+ exports.getDocsPluginConfig = getDocsPluginConfig;
58
+ function getPluginConfig(plugins, pluginId) {
59
+ return plugins.filter((data) => data[1].id === pluginId)[0][1];
60
+ }
61
+ function getPluginInstances(plugins) {
62
+ return plugins.filter((data) => data[0] === "docusaurus-plugin-openapi-docs");
63
+ }
56
64
  function pluginOpenAPIDocs(context, options) {
57
65
  const { config, docsPluginId } = options;
58
66
  const { siteDir, siteConfig } = context;
@@ -60,7 +68,7 @@ function pluginOpenAPIDocs(context, options) {
60
68
  const presets = siteConfig.presets;
61
69
  const plugins = siteConfig.plugins;
62
70
  const presetsPlugins = presets.concat(plugins);
63
- const docData = getDocsData(presetsPlugins, docsPluginId);
71
+ const docData = getDocsPluginConfig(presetsPlugins, docsPluginId);
64
72
  const docRouteBasePath = docData ? docData.routeBasePath : undefined;
65
73
  const docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
66
74
  async function generateApiDocs(options) {
@@ -83,9 +91,7 @@ function pluginOpenAPIDocs(context, options) {
83
91
  // TODO: figure out better way to set default
84
92
  if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
85
93
  const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath);
86
- const sidebarSliceTemplate = template
87
- ? fs_1.default.readFileSync(template).toString()
88
- : `module.exports = {{{slice}}};`;
94
+ const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
89
95
  const view = (0, mustache_1.render)(sidebarSliceTemplate, {
90
96
  slice: JSON.stringify(sidebarSlice),
91
97
  });
@@ -129,12 +135,11 @@ info_path: {{{infoPath}}}
129
135
 
130
136
  {{{markdown}}}
131
137
  `;
132
- const infoMdTemplate = template
133
- ? fs_1.default.readFileSync(template).toString()
134
- : `---
138
+ const infoMdTemplate = `---
135
139
  id: {{{id}}}
136
140
  sidebar_label: {{{title}}}
137
141
  hide_title: true
142
+ custom_edit_url: null
138
143
  ---
139
144
 
140
145
  {{{markdown}}}
@@ -146,12 +151,11 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
146
151
  <DocCardList items={useCurrentSidebarCategory().items}/>
147
152
  \`\`\`
148
153
  `;
149
- const tagMdTemplate = template
150
- ? fs_1.default.readFileSync(template).toString()
151
- : `---
154
+ const tagMdTemplate = `---
152
155
  id: {{{id}}}
153
156
  title: {{{description}}}
154
157
  description: {{{description}}}
158
+ custom_edit_url: null
155
159
  ---
156
160
 
157
161
  {{{markdown}}}
@@ -296,22 +300,45 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
296
300
  .description(`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`)
297
301
  .usage("<id>")
298
302
  .arguments("<id>")
299
- .action(async (id) => {
303
+ .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
304
+ .action(async (id, instance) => {
305
+ var _a;
306
+ const options = instance.opts();
307
+ const pluginId = options.pluginId;
308
+ const pluginInstances = getPluginInstances(plugins);
309
+ let targetConfig;
310
+ if (pluginId) {
311
+ try {
312
+ const pluginConfig = getPluginConfig(plugins, pluginId);
313
+ targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
314
+ }
315
+ catch {
316
+ console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
317
+ return;
318
+ }
319
+ }
320
+ else {
321
+ if (pluginInstances.length > 1) {
322
+ console.error(chalk_1.default.red("OpenAPI docs plugin ID must be specified when more than one plugin instance exists."));
323
+ return;
324
+ }
325
+ targetConfig = config;
326
+ }
300
327
  if (id === "all") {
301
- if (config[id]) {
328
+ if (targetConfig[id]) {
302
329
  console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
303
330
  }
304
331
  else {
305
- Object.keys(config).forEach(async function (key) {
306
- await generateApiDocs(config[key]);
332
+ Object.keys(targetConfig).forEach(async function (key) {
333
+ await generateApiDocs(targetConfig[key]);
307
334
  });
308
335
  }
309
336
  }
310
- else if (!config[id]) {
337
+ else if (!targetConfig[id]) {
311
338
  console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
312
339
  }
313
340
  else {
314
- await generateApiDocs(config[id]);
341
+ await generateApiDocs(targetConfig[id]);
315
342
  }
316
343
  });
317
344
  cli
@@ -319,15 +346,38 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
319
346
  .description(`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`)
320
347
  .usage("<id:version>")
321
348
  .arguments("<id:version>")
322
- .action(async (id) => {
349
+ .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
350
+ .action(async (id, instance) => {
351
+ var _a;
352
+ const options = instance.opts();
353
+ const pluginId = options.pluginId;
354
+ const pluginInstances = getPluginInstances(plugins);
355
+ let targetConfig;
356
+ if (pluginId) {
357
+ try {
358
+ const pluginConfig = getPluginConfig(plugins, pluginId);
359
+ targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
360
+ }
361
+ catch {
362
+ console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
363
+ return;
364
+ }
365
+ }
366
+ else {
367
+ if (pluginInstances.length > 1) {
368
+ console.error(chalk_1.default.red("OpenAPI docs plugin ID must be specified when more than one plugin instance exists."));
369
+ return;
370
+ }
371
+ targetConfig = config;
372
+ }
323
373
  const [parentId, versionId] = id.split(":");
324
- const parentConfig = Object.assign({}, config[parentId]);
374
+ const parentConfig = Object.assign({}, targetConfig[parentId]);
325
375
  const version = parentConfig.version;
326
376
  const label = parentConfig.label;
327
377
  const baseUrl = parentConfig.baseUrl;
328
378
  let parentVersion = {};
329
379
  parentVersion[version] = { label: label, baseUrl: baseUrl };
330
- const { versions } = config[parentId];
380
+ const { versions } = targetConfig[parentId];
331
381
  const mergedVersions = Object.assign(parentVersion, versions);
332
382
  // Prepare for merge
333
383
  delete parentConfig.versions;
@@ -369,19 +419,42 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
369
419
  .description(`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`)
370
420
  .usage("<id>")
371
421
  .arguments("<id>")
372
- .action(async (id) => {
422
+ .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
423
+ .action(async (id, instance) => {
424
+ var _a;
425
+ const options = instance.opts();
426
+ const pluginId = options.pluginId;
427
+ const pluginInstances = getPluginInstances(plugins);
428
+ let targetConfig;
429
+ if (pluginId) {
430
+ try {
431
+ const pluginConfig = getPluginConfig(plugins, pluginId);
432
+ targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
433
+ }
434
+ catch {
435
+ console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
436
+ return;
437
+ }
438
+ }
439
+ else {
440
+ if (pluginInstances.length > 1) {
441
+ console.error(chalk_1.default.red("OpenAPI docs plugin ID must be specified when more than one plugin instance exists."));
442
+ return;
443
+ }
444
+ targetConfig = config;
445
+ }
373
446
  if (id === "all") {
374
- if (config[id]) {
447
+ if (targetConfig[id]) {
375
448
  console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
376
449
  }
377
450
  else {
378
- Object.keys(config).forEach(async function (key) {
379
- await cleanApiDocs(config[key]);
451
+ Object.keys(targetConfig).forEach(async function (key) {
452
+ await cleanApiDocs(targetConfig[key]);
380
453
  });
381
454
  }
382
455
  }
383
456
  else {
384
- await cleanApiDocs(config[id]);
457
+ await cleanApiDocs(targetConfig[id]);
385
458
  }
386
459
  });
387
460
  cli
@@ -389,10 +462,33 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
389
462
  .description(`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`)
390
463
  .usage("<id:version>")
391
464
  .arguments("<id:version>")
392
- .action(async (id) => {
465
+ .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
466
+ .action(async (id, instance) => {
467
+ var _a;
468
+ const options = instance.opts();
469
+ const pluginId = options.pluginId;
470
+ const pluginInstances = getPluginInstances(plugins);
471
+ let targetConfig;
472
+ if (pluginId) {
473
+ try {
474
+ const pluginConfig = getPluginConfig(plugins, pluginId);
475
+ targetConfig = (_a = pluginConfig.config) !== null && _a !== void 0 ? _a : {};
476
+ }
477
+ catch {
478
+ console.error(chalk_1.default.red(`OpenAPI docs plugin ID '${pluginId}' not found.`));
479
+ return;
480
+ }
481
+ }
482
+ else {
483
+ if (pluginInstances.length > 1) {
484
+ console.error(chalk_1.default.red("OpenAPI docs plugin ID must be specified when more than one plugin instance exists."));
485
+ return;
486
+ }
487
+ targetConfig = config;
488
+ }
393
489
  const [parentId, versionId] = id.split(":");
394
- const { versions } = config[parentId];
395
- const parentConfig = Object.assign({}, config[parentId]);
490
+ const { versions } = targetConfig[parentId];
491
+ const parentConfig = Object.assign({}, targetConfig[parentId]);
396
492
  delete parentConfig.versions;
397
493
  if (versionId === "all") {
398
494
  if (versions[id]) {
@@ -25,6 +25,7 @@ function mergeAllOf(allOf) {
25
25
  example: function () {
26
26
  return true;
27
27
  },
28
+ ignoreAdditionalProperties: true,
28
29
  },
29
30
  });
30
31
  const required = allOf.reduce((acc, cur) => {
@@ -235,90 +236,100 @@ function createItems(schema) {
235
236
  /**
236
237
  * For handling discriminators that do not map to a same-level property
237
238
  */
238
- function createDiscriminator(schema) {
239
- var _a;
240
- const discriminator = schema.discriminator;
241
- const propertyName = discriminator === null || discriminator === void 0 ? void 0 : discriminator.propertyName;
242
- const propertyType = "string"; // should always be string
243
- const mapping = discriminator === null || discriminator === void 0 ? void 0 : discriminator.mapping;
244
- // Explicit mapping is required since we can't support implicit
245
- if (mapping === undefined) {
246
- return undefined;
247
- }
248
- // Attempt to get the property description we want to display
249
- // TODO: how to make it predictable when handling allOf
250
- let propertyDescription;
251
- const firstMappingSchema = mapping[Object.keys(mapping)[0]];
252
- if (firstMappingSchema.properties !== undefined) {
253
- propertyDescription =
254
- firstMappingSchema.properties[propertyName].description;
255
- }
256
- if (firstMappingSchema.allOf !== undefined) {
257
- const { mergedSchemas } = mergeAllOf(firstMappingSchema.allOf);
258
- if (mergedSchemas.properties !== undefined) {
259
- propertyDescription =
260
- (_a = mergedSchemas.properties[propertyName]) === null || _a === void 0 ? void 0 : _a.description;
261
- }
262
- }
263
- if (propertyDescription === undefined) {
264
- if (schema.properties !== undefined &&
265
- schema.properties[propertyName] !== undefined) {
266
- propertyDescription = schema.properties[propertyName].description;
267
- }
268
- }
269
- return (0, utils_1.create)("div", {
270
- className: "discriminatorItem",
271
- children: (0, utils_1.create)("div", {
272
- children: [
273
- (0, utils_1.create)("strong", {
274
- style: { paddingLeft: "1rem" },
275
- children: propertyName,
276
- }),
277
- (0, utils_1.guard)(propertyType, (name) => (0, utils_1.create)("span", {
278
- style: { opacity: "0.6" },
279
- children: ` ${propertyType}`,
280
- })),
281
- (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema.discriminator), (message) => (0, utils_1.create)("div", {
282
- style: {
283
- paddingLeft: "1rem",
284
- },
285
- children: (0, createDescription_1.createDescription)(message),
286
- })),
287
- (0, utils_1.guard)(propertyDescription, (description) => (0, utils_1.create)("div", {
288
- style: {
289
- paddingLeft: "1rem",
290
- },
291
- children: (0, createDescription_1.createDescription)(description),
292
- })),
293
- (0, utils_1.create)("DiscriminatorTabs", {
294
- children: Object.keys(mapping).map((key, index) => {
295
- if (mapping[key].allOf !== undefined) {
296
- const { mergedSchemas } = mergeAllOf(mapping[key].allOf);
297
- // Cleanup duplicate property from mapping schema
298
- delete mergedSchemas.properties[propertyName];
299
- mapping[key] = mergedSchemas;
300
- }
301
- if (mapping[key].properties !== undefined) {
302
- // Cleanup duplicate property from mapping schema
303
- delete mapping[key].properties[propertyName];
304
- }
305
- const label = key;
306
- return (0, utils_1.create)("TabItem", {
307
- label: label,
308
- value: `${index}-item-discriminator`,
309
- children: [
310
- (0, utils_1.create)("div", {
311
- style: { marginLeft: "-4px" },
312
- children: createNodes(mapping[key]),
313
- }),
314
- ],
315
- });
316
- }),
317
- }),
318
- ],
319
- }),
320
- });
321
- }
239
+ // function createDiscriminator(schema: SchemaObject) {
240
+ // const discriminator = schema.discriminator;
241
+ // const propertyName = discriminator?.propertyName;
242
+ // const propertyType = "string"; // should always be string
243
+ // const mapping: any = discriminator?.mapping;
244
+ // // Explicit mapping is required since we can't support implicit
245
+ // if (mapping === undefined) {
246
+ // return undefined;
247
+ // }
248
+ // // Attempt to get the property description we want to display
249
+ // // TODO: how to make it predictable when handling allOf
250
+ // let propertyDescription;
251
+ // const firstMappingSchema = mapping[Object.keys(mapping)[0]];
252
+ // if (firstMappingSchema.properties !== undefined) {
253
+ // propertyDescription =
254
+ // firstMappingSchema.properties![propertyName!].description;
255
+ // }
256
+ // if (firstMappingSchema.allOf !== undefined) {
257
+ // const { mergedSchemas }: { mergedSchemas: SchemaObject } = mergeAllOf(
258
+ // firstMappingSchema.allOf
259
+ // );
260
+ // if (mergedSchemas.properties !== undefined) {
261
+ // propertyDescription =
262
+ // mergedSchemas.properties[propertyName!]?.description;
263
+ // }
264
+ // }
265
+ // if (propertyDescription === undefined) {
266
+ // if (
267
+ // schema.properties !== undefined &&
268
+ // schema.properties![propertyName!] !== undefined
269
+ // ) {
270
+ // propertyDescription = schema.properties![propertyName!].description;
271
+ // }
272
+ // }
273
+ // return create("div", {
274
+ // className: "discriminatorItem",
275
+ // children: create("div", {
276
+ // children: [
277
+ // create("strong", {
278
+ // style: { paddingLeft: "1rem" },
279
+ // children: propertyName,
280
+ // }),
281
+ // guard(propertyType, (name) =>
282
+ // create("span", {
283
+ // style: { opacity: "0.6" },
284
+ // children: ` ${propertyType}`,
285
+ // })
286
+ // ),
287
+ // guard(getQualifierMessage(schema.discriminator as any), (message) =>
288
+ // create("div", {
289
+ // style: {
290
+ // paddingLeft: "1rem",
291
+ // },
292
+ // children: createDescription(message),
293
+ // })
294
+ // ),
295
+ // guard(propertyDescription, (description) =>
296
+ // create("div", {
297
+ // style: {
298
+ // paddingLeft: "1rem",
299
+ // },
300
+ // children: createDescription(description),
301
+ // })
302
+ // ),
303
+ // create("DiscriminatorTabs", {
304
+ // children: Object.keys(mapping!).map((key, index) => {
305
+ // if (mapping[key].allOf !== undefined) {
306
+ // const { mergedSchemas }: { mergedSchemas: SchemaObject } =
307
+ // mergeAllOf(mapping[key].allOf);
308
+ // // Cleanup duplicate property from mapping schema
309
+ // delete mergedSchemas.properties![propertyName!];
310
+ // mapping[key] = mergedSchemas;
311
+ // }
312
+ // if (mapping[key].properties !== undefined) {
313
+ // // Cleanup duplicate property from mapping schema
314
+ // delete mapping[key].properties![propertyName!];
315
+ // }
316
+ // const label = key;
317
+ // return create("TabItem", {
318
+ // label: label,
319
+ // value: `${index}-item-discriminator`,
320
+ // children: [
321
+ // create("div", {
322
+ // style: { marginLeft: "-4px" },
323
+ // children: createNodes(mapping[key]),
324
+ // }),
325
+ // ],
326
+ // });
327
+ // }),
328
+ // }),
329
+ // ],
330
+ // }),
331
+ // });
332
+ // }
322
333
  function createDetailsNode(name, schemaName, schema, required) {
323
334
  return (0, utils_1.create)("SchemaItem", {
324
335
  collapsible: true,
@@ -333,7 +344,9 @@ function createDetailsNode(name, schemaName, schema, required) {
333
344
  style: { opacity: "0.6" },
334
345
  children: ` ${schemaName}`,
335
346
  }),
336
- (0, utils_1.guard)(schema.required && schema.required === true, () => [
347
+ (0, utils_1.guard)(Array.isArray(required)
348
+ ? required.includes(name)
349
+ : required === true, () => [
337
350
  (0, utils_1.create)("strong", {
338
351
  style: {
339
352
  fontSize: "var(--ifm-code-font-size)",
@@ -493,9 +506,9 @@ function createEdges({ name, schema, required, discriminator, }) {
493
506
  * Creates a hierarchical level of a schema tree. Nodes produce edges that can branch into sub-nodes with edges, recursively.
494
507
  */
495
508
  function createNodes(schema) {
496
- if (schema.discriminator !== undefined) {
497
- return createDiscriminator(schema);
498
- }
509
+ // if (schema.discriminator !== undefined) {
510
+ // return createDiscriminator(schema);
511
+ // }
499
512
  if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
500
513
  return createAnyOneOf(schema);
501
514
  }
@@ -1,4 +1,11 @@
1
- import { MediaTypeObject } from "../openapi/types";
1
+ import { MediaTypeObject, SchemaObject } from "../openapi/types";
2
+ /**
3
+ * Returns a merged representation of allOf array of schemas.
4
+ */
5
+ export declare function mergeAllOf(allOf: SchemaObject[]): {
6
+ mergedSchemas: any;
7
+ required: any;
8
+ };
2
9
  interface Props {
3
10
  style?: any;
4
11
  title: string;