docusaurus-plugin-openapi-docs 0.0.0-1074 → 0.0.0-1076
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/README.md +63 -20
- package/lib/index.js +68 -45
- package/lib/openapi/openapi.js +6 -2
- package/lib/openapi/openapi.test.js +48 -0
- package/lib/types.d.ts +1 -0
- package/package.json +2 -2
- package/src/index.ts +89 -57
- package/src/openapi/openapi.test.ts +58 -0
- package/src/openapi/openapi.ts +7 -1
- package/src/types.ts +1 -0
package/README.md
CHANGED
|
@@ -156,26 +156,26 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
156
156
|
|
|
157
157
|
`config` can be configured with the following options:
|
|
158
158
|
|
|
159
|
-
| Name | Type | Default | Description
|
|
160
|
-
| -------------------- | --------- | ------- |
|
|
161
|
-
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files.
|
|
162
|
-
| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files.
|
|
163
|
-
| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser.
|
|
164
|
-
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template.
|
|
165
|
-
| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only.
|
|
166
|
-
| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only.
|
|
167
|
-
| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only.
|
|
168
|
-
| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc)
|
|
169
|
-
| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel.
|
|
170
|
-
| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions.
|
|
171
|
-
| `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security.
|
|
172
|
-
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options.
|
|
173
|
-
| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`.
|
|
174
|
-
| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu.
|
|
175
|
-
| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown.
|
|
176
|
-
| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options.
|
|
177
|
-
| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options.
|
|
178
|
-
| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar.
|
|
159
|
+
| Name | Type | Default | Description |
|
|
160
|
+
| -------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
+
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
|
|
162
|
+
| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. |
|
|
163
|
+
| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. |
|
|
164
|
+
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
|
|
165
|
+
| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. |
|
|
166
|
+
| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. |
|
|
167
|
+
| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. |
|
|
168
|
+
| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) |
|
|
169
|
+
| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. |
|
|
170
|
+
| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. |
|
|
171
|
+
| `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security. |
|
|
172
|
+
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
|
|
173
|
+
| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. |
|
|
174
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. |
|
|
175
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. |
|
|
176
|
+
| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. |
|
|
177
|
+
| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. |
|
|
178
|
+
| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. |
|
|
179
179
|
|
|
180
180
|
### sidebarOptions
|
|
181
181
|
|
|
@@ -224,6 +224,31 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
224
224
|
| --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
225
225
|
| `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.<br/><br/>**Function type:** `(item: ApiPageMetadata \| SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` |
|
|
226
226
|
|
|
227
|
+
## Theme Configuration Options
|
|
228
|
+
|
|
229
|
+
The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`:
|
|
230
|
+
|
|
231
|
+
| Name | Type | Default | Description |
|
|
232
|
+
| ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
233
|
+
| `proxy` | `string` | `null` | _Optional:_ Site-wide proxy URL to prepend to base URL when performing API requests. Can be overridden per-spec via plugin config. |
|
|
234
|
+
| `authPersistance` | `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. |
|
|
235
|
+
| `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. |
|
|
236
|
+
|
|
237
|
+
Example:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// docusaurus.config.ts
|
|
241
|
+
{
|
|
242
|
+
themeConfig: {
|
|
243
|
+
api: {
|
|
244
|
+
proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config)
|
|
245
|
+
authPersistance: "localStorage",
|
|
246
|
+
requestTimeout: 60000, // 60 seconds
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
227
252
|
## Supported Vendor Extensions
|
|
228
253
|
|
|
229
254
|
The plugin extracts a number of vendor extensions from the OpenAPI spec to enrich the generated docs. The theme renders some of these values as part of the UI.
|
|
@@ -303,6 +328,16 @@ yarn docusaurus gen-api-docs all --all-versions
|
|
|
303
328
|
|
|
304
329
|
> This will generate API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
|
|
305
330
|
|
|
331
|
+
To generate only schema MDX files—without updating the sidebar or requiring `showSchemas` in your plugin config—use the `--schemas-only` flag:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
yarn docusaurus gen-api-docs petstore --schemas-only
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
> This command writes the schema pages to the configured output directory while leaving other generated docs untouched.
|
|
338
|
+
|
|
339
|
+
The `--schemas-only` flag is also available for `gen-api-docs:version`.
|
|
340
|
+
|
|
306
341
|
### Cleaning API Docs
|
|
307
342
|
|
|
308
343
|
To clean/remove all API Docs, run the following command from the root directory of your project:
|
|
@@ -335,6 +370,14 @@ yarn docusaurus clean-api-docs all --all-versions
|
|
|
335
370
|
|
|
336
371
|
> This will clean API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
|
|
337
372
|
|
|
373
|
+
To clean only schema docs while leaving API, info, and tag docs untouched, use the `--schemas-only` flag:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
yarn docusaurus clean-api-docs petstore --schemas-only
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
> The `--schemas-only` flag is also available for `clean-api-docs:version`.
|
|
380
|
+
|
|
338
381
|
### Versioning OpenAPI docs
|
|
339
382
|
|
|
340
383
|
To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
|
package/lib/index.js
CHANGED
|
@@ -78,7 +78,8 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
78
78
|
let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
|
|
79
79
|
async function generateApiDocs(options, pluginId) {
|
|
80
80
|
var _a, _b, _c, _d;
|
|
81
|
-
let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, disableCompression, } = options;
|
|
81
|
+
let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, schemasOnly, disableCompression, } = options;
|
|
82
|
+
const isSchemasOnly = schemasOnly === true;
|
|
82
83
|
// Remove trailing slash before proceeding
|
|
83
84
|
outputDir = outputDir.replace(/\/$/, "");
|
|
84
85
|
// Override docPath if pluginId provided
|
|
@@ -103,7 +104,7 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
// TODO: figure out better way to set default
|
|
106
|
-
if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
107
|
+
if (!isSchemasOnly && Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
107
108
|
const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath, tagGroups);
|
|
108
109
|
let sidebarSliceTemplate = `import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";\n\n`;
|
|
109
110
|
sidebarSliceTemplate += `const sidebar: SidebarsConfig = {{{slice}}};\n\n`;
|
|
@@ -238,6 +239,9 @@ custom_edit_url: null
|
|
|
238
239
|
}
|
|
239
240
|
const markdown = pageGeneratorByType[item.type](item);
|
|
240
241
|
item.markdown = markdown;
|
|
242
|
+
if (isSchemasOnly && item.type !== "schema") {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
241
245
|
if (item.type === "api") {
|
|
242
246
|
// opportunity to compress JSON
|
|
243
247
|
// const serialize = (o: any) => {
|
|
@@ -338,25 +342,36 @@ custom_edit_url: null
|
|
|
338
342
|
throw e;
|
|
339
343
|
}
|
|
340
344
|
}
|
|
341
|
-
async function cleanApiDocs(options) {
|
|
345
|
+
async function cleanApiDocs(options, schemasOnly = false) {
|
|
342
346
|
const { outputDir } = options;
|
|
343
347
|
const apiDir = (0, utils_1.posixPath)(path_1.default.join(siteDir, outputDir));
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
348
|
+
// When schemasOnly is true, only clean the schemas directory
|
|
349
|
+
if (!schemasOnly) {
|
|
350
|
+
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
|
|
351
|
+
cwd: path_1.default.resolve(apiDir),
|
|
352
|
+
deep: 1,
|
|
353
|
+
});
|
|
354
|
+
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js", "sidebar.ts"], {
|
|
355
|
+
cwd: path_1.default.resolve(apiDir),
|
|
356
|
+
deep: 1,
|
|
357
|
+
});
|
|
358
|
+
apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
359
|
+
if (err) {
|
|
360
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${mdx}"`), chalk_1.default.yellow(err));
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
|
|
364
|
+
}
|
|
365
|
+
}));
|
|
366
|
+
sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
367
|
+
if (err) {
|
|
368
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`));
|
|
372
|
+
}
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
360
375
|
try {
|
|
361
376
|
fs_1.default.rmSync(`${apiDir}/schemas`, { recursive: true });
|
|
362
377
|
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/schemas"`));
|
|
@@ -366,14 +381,6 @@ custom_edit_url: null
|
|
|
366
381
|
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/schemas"`), chalk_1.default.yellow(err));
|
|
367
382
|
}
|
|
368
383
|
}
|
|
369
|
-
sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
370
|
-
if (err) {
|
|
371
|
-
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`));
|
|
375
|
-
}
|
|
376
|
-
}));
|
|
377
384
|
}
|
|
378
385
|
async function generateVersions(versions, outputDir) {
|
|
379
386
|
let versionsArray = [];
|
|
@@ -445,19 +452,21 @@ custom_edit_url: null
|
|
|
445
452
|
});
|
|
446
453
|
}
|
|
447
454
|
}
|
|
448
|
-
async function cleanAllVersions(options) {
|
|
455
|
+
async function cleanAllVersions(options, schemasOnly = false) {
|
|
449
456
|
const parentOptions = Object.assign({}, options);
|
|
450
457
|
const { versions } = parentOptions;
|
|
451
458
|
delete parentOptions.versions;
|
|
452
459
|
if (versions != null && Object.keys(versions).length > 0) {
|
|
453
|
-
|
|
460
|
+
if (!schemasOnly) {
|
|
461
|
+
await cleanVersions(parentOptions.outputDir);
|
|
462
|
+
}
|
|
454
463
|
Object.keys(versions).forEach(async (key) => {
|
|
455
464
|
const versionOptions = versions[key];
|
|
456
465
|
const mergedOptions = {
|
|
457
466
|
...parentOptions,
|
|
458
467
|
...versionOptions,
|
|
459
468
|
};
|
|
460
|
-
await cleanApiDocs(mergedOptions);
|
|
469
|
+
await cleanApiDocs(mergedOptions, schemasOnly);
|
|
461
470
|
});
|
|
462
471
|
}
|
|
463
472
|
}
|
|
@@ -471,11 +480,13 @@ custom_edit_url: null
|
|
|
471
480
|
.arguments("<id>")
|
|
472
481
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
473
482
|
.option("--all-versions", "Generate all versions.")
|
|
483
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
474
484
|
.action(async (id, instance) => {
|
|
475
485
|
var _a;
|
|
476
486
|
const options = instance.opts();
|
|
477
487
|
const pluginId = options.pluginId;
|
|
478
488
|
const allVersions = options.allVersions;
|
|
489
|
+
const schemasOnly = options.schemasOnly;
|
|
479
490
|
const pluginInstances = getPluginInstances(plugins);
|
|
480
491
|
let targetConfig;
|
|
481
492
|
let targetDocsPluginId;
|
|
@@ -497,15 +508,17 @@ custom_edit_url: null
|
|
|
497
508
|
}
|
|
498
509
|
targetConfig = config;
|
|
499
510
|
}
|
|
511
|
+
const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
500
512
|
if (id === "all") {
|
|
501
513
|
if (targetConfig[id]) {
|
|
502
514
|
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
503
515
|
}
|
|
504
516
|
else {
|
|
505
517
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
506
|
-
|
|
518
|
+
const apiOptions = withSchemaOverride(targetConfig[key]);
|
|
519
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
507
520
|
if (allVersions) {
|
|
508
|
-
await generateAllVersions(
|
|
521
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
509
522
|
}
|
|
510
523
|
});
|
|
511
524
|
}
|
|
@@ -514,9 +527,10 @@ custom_edit_url: null
|
|
|
514
527
|
console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
|
|
515
528
|
}
|
|
516
529
|
else {
|
|
517
|
-
|
|
530
|
+
const apiOptions = withSchemaOverride(targetConfig[id]);
|
|
531
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
518
532
|
if (allVersions) {
|
|
519
|
-
await generateAllVersions(
|
|
533
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
520
534
|
}
|
|
521
535
|
}
|
|
522
536
|
});
|
|
@@ -526,10 +540,12 @@ custom_edit_url: null
|
|
|
526
540
|
.usage("<id:version>")
|
|
527
541
|
.arguments("<id:version>")
|
|
528
542
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
543
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
529
544
|
.action(async (id, instance) => {
|
|
530
545
|
var _a;
|
|
531
546
|
const options = instance.opts();
|
|
532
547
|
const pluginId = options.pluginId;
|
|
548
|
+
const schemasOnly = options.schemasOnly;
|
|
533
549
|
const pluginInstances = getPluginInstances(plugins);
|
|
534
550
|
let targetConfig;
|
|
535
551
|
let targetDocsPluginId;
|
|
@@ -553,6 +569,7 @@ custom_edit_url: null
|
|
|
553
569
|
}
|
|
554
570
|
const [parentId, versionId] = id.split(":");
|
|
555
571
|
const parentConfig = Object.assign({}, targetConfig[parentId]);
|
|
572
|
+
const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
556
573
|
const version = parentConfig.version;
|
|
557
574
|
const label = parentConfig.label;
|
|
558
575
|
const baseUrl = parentConfig.baseUrl;
|
|
@@ -575,10 +592,10 @@ custom_edit_url: null
|
|
|
575
592
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
576
593
|
Object.keys(versions).forEach(async (key) => {
|
|
577
594
|
const versionConfig = versions[key];
|
|
578
|
-
const mergedConfig = {
|
|
595
|
+
const mergedConfig = withSchemaOverride({
|
|
579
596
|
...parentConfig,
|
|
580
597
|
...versionConfig,
|
|
581
|
-
};
|
|
598
|
+
});
|
|
582
599
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
583
600
|
});
|
|
584
601
|
}
|
|
@@ -588,10 +605,10 @@ custom_edit_url: null
|
|
|
588
605
|
}
|
|
589
606
|
else {
|
|
590
607
|
const versionConfig = versions[versionId];
|
|
591
|
-
const mergedConfig = {
|
|
608
|
+
const mergedConfig = withSchemaOverride({
|
|
592
609
|
...parentConfig,
|
|
593
610
|
...versionConfig,
|
|
594
|
-
};
|
|
611
|
+
});
|
|
595
612
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
596
613
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
597
614
|
}
|
|
@@ -603,11 +620,13 @@ custom_edit_url: null
|
|
|
603
620
|
.arguments("<id>")
|
|
604
621
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
605
622
|
.option("--all-versions", "Clean all versions.")
|
|
623
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
606
624
|
.action(async (id, instance) => {
|
|
607
625
|
var _a;
|
|
608
626
|
const options = instance.opts();
|
|
609
627
|
const pluginId = options.pluginId;
|
|
610
628
|
const allVersions = options.allVersions;
|
|
629
|
+
const schemasOnly = options.schemasOnly;
|
|
611
630
|
const pluginInstances = getPluginInstances(plugins);
|
|
612
631
|
let targetConfig;
|
|
613
632
|
if (pluginId) {
|
|
@@ -633,17 +652,17 @@ custom_edit_url: null
|
|
|
633
652
|
}
|
|
634
653
|
else {
|
|
635
654
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
636
|
-
await cleanApiDocs(targetConfig[key]);
|
|
655
|
+
await cleanApiDocs(targetConfig[key], schemasOnly);
|
|
637
656
|
if (allVersions) {
|
|
638
|
-
await cleanAllVersions(targetConfig[key]);
|
|
657
|
+
await cleanAllVersions(targetConfig[key], schemasOnly);
|
|
639
658
|
}
|
|
640
659
|
});
|
|
641
660
|
}
|
|
642
661
|
}
|
|
643
662
|
else {
|
|
644
|
-
await cleanApiDocs(targetConfig[id]);
|
|
663
|
+
await cleanApiDocs(targetConfig[id], schemasOnly);
|
|
645
664
|
if (allVersions) {
|
|
646
|
-
await cleanAllVersions(targetConfig[id]);
|
|
665
|
+
await cleanAllVersions(targetConfig[id], schemasOnly);
|
|
647
666
|
}
|
|
648
667
|
}
|
|
649
668
|
});
|
|
@@ -653,10 +672,12 @@ custom_edit_url: null
|
|
|
653
672
|
.usage("<id:version>")
|
|
654
673
|
.arguments("<id:version>")
|
|
655
674
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
675
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
656
676
|
.action(async (id, instance) => {
|
|
657
677
|
var _a;
|
|
658
678
|
const options = instance.opts();
|
|
659
679
|
const pluginId = options.pluginId;
|
|
680
|
+
const schemasOnly = options.schemasOnly;
|
|
660
681
|
const pluginInstances = getPluginInstances(plugins);
|
|
661
682
|
let targetConfig;
|
|
662
683
|
if (pluginId) {
|
|
@@ -685,14 +706,16 @@ custom_edit_url: null
|
|
|
685
706
|
chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key.");
|
|
686
707
|
}
|
|
687
708
|
else {
|
|
688
|
-
|
|
709
|
+
if (!schemasOnly) {
|
|
710
|
+
await cleanVersions(parentConfig.outputDir);
|
|
711
|
+
}
|
|
689
712
|
Object.keys(versions).forEach(async (key) => {
|
|
690
713
|
const versionConfig = versions[key];
|
|
691
714
|
const mergedConfig = {
|
|
692
715
|
...parentConfig,
|
|
693
716
|
...versionConfig,
|
|
694
717
|
};
|
|
695
|
-
await cleanApiDocs(mergedConfig);
|
|
718
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
696
719
|
});
|
|
697
720
|
}
|
|
698
721
|
}
|
|
@@ -702,7 +725,7 @@ custom_edit_url: null
|
|
|
702
725
|
...parentConfig,
|
|
703
726
|
...versionConfig,
|
|
704
727
|
};
|
|
705
|
-
await cleanApiDocs(mergedConfig);
|
|
728
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
706
729
|
}
|
|
707
730
|
});
|
|
708
731
|
},
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -108,6 +108,7 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
108
108
|
let items = [];
|
|
109
109
|
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
110
110
|
const infoId = (0, kebabCase_1.default)(infoIdSpaces);
|
|
111
|
+
const schemasOnly = (options === null || options === void 0 ? void 0 : options.schemasOnly) === true;
|
|
111
112
|
if (openapiData.info.description || openapiData.info.title) {
|
|
112
113
|
// Only create an info page if we have a description.
|
|
113
114
|
const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
|
|
@@ -378,13 +379,16 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
378
379
|
items.push(apiPage);
|
|
379
380
|
}
|
|
380
381
|
}
|
|
381
|
-
if (
|
|
382
|
+
if (schemasOnly ||
|
|
383
|
+
(options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
|
|
382
384
|
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 : {})
|
|
383
385
|
.flatMap(([_, s]) => s["x-tags"])
|
|
384
386
|
.filter((item) => !!item).length > 0) {
|
|
385
387
|
// Gather schemas
|
|
386
388
|
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 : {})) {
|
|
387
|
-
if (
|
|
389
|
+
if (schemasOnly ||
|
|
390
|
+
(options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
|
|
391
|
+
schemaObject["x-tags"]) {
|
|
388
392
|
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 : "";
|
|
389
393
|
const baseId = (0, kebabCase_1.default)(baseIdSpaces);
|
|
390
394
|
const schemaDescription = schemaObject.description;
|
|
@@ -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
|
});
|
package/lib/types.d.ts
CHANGED
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-
|
|
4
|
+
"version": "0.0.0-1076",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=14"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "c5c4370633dd11b143393c1bcda342b49816e15a"
|
|
69
69
|
}
|
package/src/index.ts
CHANGED
|
@@ -123,9 +123,12 @@ export default function pluginOpenAPIDocs(
|
|
|
123
123
|
markdownGenerators,
|
|
124
124
|
downloadUrl,
|
|
125
125
|
sidebarOptions,
|
|
126
|
+
schemasOnly,
|
|
126
127
|
disableCompression,
|
|
127
128
|
} = options;
|
|
128
129
|
|
|
130
|
+
const isSchemasOnly = schemasOnly === true;
|
|
131
|
+
|
|
129
132
|
// Remove trailing slash before proceeding
|
|
130
133
|
outputDir = outputDir.replace(/\/$/, "");
|
|
131
134
|
|
|
@@ -160,7 +163,7 @@ export default function pluginOpenAPIDocs(
|
|
|
160
163
|
}
|
|
161
164
|
|
|
162
165
|
// TODO: figure out better way to set default
|
|
163
|
-
if (Object.keys(sidebarOptions ?? {}).length > 0) {
|
|
166
|
+
if (!isSchemasOnly && Object.keys(sidebarOptions ?? {}).length > 0) {
|
|
164
167
|
const sidebarSlice = generateSidebarSlice(
|
|
165
168
|
sidebarOptions!,
|
|
166
169
|
options,
|
|
@@ -332,6 +335,9 @@ custom_edit_url: null
|
|
|
332
335
|
}
|
|
333
336
|
const markdown = pageGeneratorByType[item.type](item as any);
|
|
334
337
|
item.markdown = markdown;
|
|
338
|
+
if (isSchemasOnly && item.type !== "schema") {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
335
341
|
if (item.type === "api") {
|
|
336
342
|
// opportunity to compress JSON
|
|
337
343
|
// const serialize = (o: any) => {
|
|
@@ -485,29 +491,53 @@ custom_edit_url: null
|
|
|
485
491
|
}
|
|
486
492
|
}
|
|
487
493
|
|
|
488
|
-
async function cleanApiDocs(options: APIOptions) {
|
|
494
|
+
async function cleanApiDocs(options: APIOptions, schemasOnly = false) {
|
|
489
495
|
const { outputDir } = options;
|
|
490
496
|
const apiDir = posixPath(path.join(siteDir, outputDir));
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
apiMdxFiles.map((mdx) =>
|
|
500
|
-
fs.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
501
|
-
if (err) {
|
|
502
|
-
console.error(
|
|
503
|
-
chalk.red(`Cleanup failed for "${apiDir}/${mdx}"`),
|
|
504
|
-
chalk.yellow(err)
|
|
505
|
-
);
|
|
506
|
-
} else {
|
|
507
|
-
console.log(chalk.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
|
|
497
|
+
|
|
498
|
+
// When schemasOnly is true, only clean the schemas directory
|
|
499
|
+
if (!schemasOnly) {
|
|
500
|
+
const apiMdxFiles = await Globby(
|
|
501
|
+
["*.api.mdx", "*.info.mdx", "*.tag.mdx"],
|
|
502
|
+
{
|
|
503
|
+
cwd: path.resolve(apiDir),
|
|
504
|
+
deep: 1,
|
|
508
505
|
}
|
|
509
|
-
|
|
510
|
-
|
|
506
|
+
);
|
|
507
|
+
const sidebarFile = await Globby(["sidebar.js", "sidebar.ts"], {
|
|
508
|
+
cwd: path.resolve(apiDir),
|
|
509
|
+
deep: 1,
|
|
510
|
+
});
|
|
511
|
+
apiMdxFiles.map((mdx) =>
|
|
512
|
+
fs.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
513
|
+
if (err) {
|
|
514
|
+
console.error(
|
|
515
|
+
chalk.red(`Cleanup failed for "${apiDir}/${mdx}"`),
|
|
516
|
+
chalk.yellow(err)
|
|
517
|
+
);
|
|
518
|
+
} else {
|
|
519
|
+
console.log(
|
|
520
|
+
chalk.green(`Cleanup succeeded for "${apiDir}/${mdx}"`)
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
})
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
sidebarFile.map((sidebar) =>
|
|
527
|
+
fs.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
528
|
+
if (err) {
|
|
529
|
+
console.error(
|
|
530
|
+
chalk.red(`Cleanup failed for "${apiDir}/${sidebar}"`),
|
|
531
|
+
chalk.yellow(err)
|
|
532
|
+
);
|
|
533
|
+
} else {
|
|
534
|
+
console.log(
|
|
535
|
+
chalk.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`)
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
})
|
|
539
|
+
);
|
|
540
|
+
}
|
|
511
541
|
|
|
512
542
|
try {
|
|
513
543
|
fs.rmSync(`${apiDir}/schemas`, { recursive: true });
|
|
@@ -520,21 +550,6 @@ custom_edit_url: null
|
|
|
520
550
|
);
|
|
521
551
|
}
|
|
522
552
|
}
|
|
523
|
-
|
|
524
|
-
sidebarFile.map((sidebar) =>
|
|
525
|
-
fs.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
526
|
-
if (err) {
|
|
527
|
-
console.error(
|
|
528
|
-
chalk.red(`Cleanup failed for "${apiDir}/${sidebar}"`),
|
|
529
|
-
chalk.yellow(err)
|
|
530
|
-
);
|
|
531
|
-
} else {
|
|
532
|
-
console.log(
|
|
533
|
-
chalk.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`)
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
|
-
})
|
|
537
|
-
);
|
|
538
553
|
}
|
|
539
554
|
|
|
540
555
|
async function generateVersions(versions: object, outputDir: string) {
|
|
@@ -635,7 +650,7 @@ custom_edit_url: null
|
|
|
635
650
|
}
|
|
636
651
|
}
|
|
637
652
|
|
|
638
|
-
async function cleanAllVersions(options: APIOptions) {
|
|
653
|
+
async function cleanAllVersions(options: APIOptions, schemasOnly = false) {
|
|
639
654
|
const parentOptions = Object.assign({}, options);
|
|
640
655
|
|
|
641
656
|
const { versions } = parentOptions as any;
|
|
@@ -643,14 +658,16 @@ custom_edit_url: null
|
|
|
643
658
|
delete parentOptions.versions;
|
|
644
659
|
|
|
645
660
|
if (versions != null && Object.keys(versions).length > 0) {
|
|
646
|
-
|
|
661
|
+
if (!schemasOnly) {
|
|
662
|
+
await cleanVersions(parentOptions.outputDir);
|
|
663
|
+
}
|
|
647
664
|
Object.keys(versions).forEach(async (key) => {
|
|
648
665
|
const versionOptions = versions[key];
|
|
649
666
|
const mergedOptions = {
|
|
650
667
|
...parentOptions,
|
|
651
668
|
...versionOptions,
|
|
652
669
|
};
|
|
653
|
-
await cleanApiDocs(mergedOptions);
|
|
670
|
+
await cleanApiDocs(mergedOptions, schemasOnly);
|
|
654
671
|
});
|
|
655
672
|
}
|
|
656
673
|
}
|
|
@@ -668,10 +685,12 @@ custom_edit_url: null
|
|
|
668
685
|
.arguments("<id>")
|
|
669
686
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
670
687
|
.option("--all-versions", "Generate all versions.")
|
|
688
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
671
689
|
.action(async (id, instance) => {
|
|
672
690
|
const options = instance.opts();
|
|
673
691
|
const pluginId = options.pluginId;
|
|
674
692
|
const allVersions = options.allVersions;
|
|
693
|
+
const schemasOnly = options.schemasOnly;
|
|
675
694
|
const pluginInstances = getPluginInstances(plugins);
|
|
676
695
|
let targetConfig: any;
|
|
677
696
|
let targetDocsPluginId: any;
|
|
@@ -698,6 +717,9 @@ custom_edit_url: null
|
|
|
698
717
|
targetConfig = config;
|
|
699
718
|
}
|
|
700
719
|
|
|
720
|
+
const withSchemaOverride = (apiOptions: APIOptions): APIOptions =>
|
|
721
|
+
schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
722
|
+
|
|
701
723
|
if (id === "all") {
|
|
702
724
|
if (targetConfig[id]) {
|
|
703
725
|
console.error(
|
|
@@ -707,12 +729,10 @@ custom_edit_url: null
|
|
|
707
729
|
);
|
|
708
730
|
} else {
|
|
709
731
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
710
|
-
|
|
732
|
+
const apiOptions = withSchemaOverride(targetConfig[key]);
|
|
733
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
711
734
|
if (allVersions) {
|
|
712
|
-
await generateAllVersions(
|
|
713
|
-
targetConfig[key],
|
|
714
|
-
targetDocsPluginId
|
|
715
|
-
);
|
|
735
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
716
736
|
}
|
|
717
737
|
});
|
|
718
738
|
}
|
|
@@ -721,9 +741,10 @@ custom_edit_url: null
|
|
|
721
741
|
chalk.red(`ID '${id}' does not exist in OpenAPI docs config.`)
|
|
722
742
|
);
|
|
723
743
|
} else {
|
|
724
|
-
|
|
744
|
+
const apiOptions = withSchemaOverride(targetConfig[id]);
|
|
745
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
725
746
|
if (allVersions) {
|
|
726
|
-
await generateAllVersions(
|
|
747
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
727
748
|
}
|
|
728
749
|
}
|
|
729
750
|
});
|
|
@@ -736,9 +757,11 @@ custom_edit_url: null
|
|
|
736
757
|
.usage("<id:version>")
|
|
737
758
|
.arguments("<id:version>")
|
|
738
759
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
760
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
739
761
|
.action(async (id, instance) => {
|
|
740
762
|
const options = instance.opts();
|
|
741
763
|
const pluginId = options.pluginId;
|
|
764
|
+
const schemasOnly = options.schemasOnly;
|
|
742
765
|
const pluginInstances = getPluginInstances(plugins);
|
|
743
766
|
let targetConfig: any;
|
|
744
767
|
let targetDocsPluginId: any;
|
|
@@ -767,6 +790,9 @@ custom_edit_url: null
|
|
|
767
790
|
const [parentId, versionId] = id.split(":");
|
|
768
791
|
const parentConfig = Object.assign({}, targetConfig[parentId]);
|
|
769
792
|
|
|
793
|
+
const withSchemaOverride = (apiOptions: APIOptions): APIOptions =>
|
|
794
|
+
schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
795
|
+
|
|
770
796
|
const version = parentConfig.version as string;
|
|
771
797
|
const label = parentConfig.label as string;
|
|
772
798
|
const baseUrl = parentConfig.baseUrl as string;
|
|
@@ -796,10 +822,10 @@ custom_edit_url: null
|
|
|
796
822
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
797
823
|
Object.keys(versions).forEach(async (key) => {
|
|
798
824
|
const versionConfig = versions[key];
|
|
799
|
-
const mergedConfig = {
|
|
825
|
+
const mergedConfig = withSchemaOverride({
|
|
800
826
|
...parentConfig,
|
|
801
827
|
...versionConfig,
|
|
802
|
-
};
|
|
828
|
+
});
|
|
803
829
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
804
830
|
});
|
|
805
831
|
}
|
|
@@ -811,10 +837,10 @@ custom_edit_url: null
|
|
|
811
837
|
);
|
|
812
838
|
} else {
|
|
813
839
|
const versionConfig = versions[versionId];
|
|
814
|
-
const mergedConfig = {
|
|
840
|
+
const mergedConfig = withSchemaOverride({
|
|
815
841
|
...parentConfig,
|
|
816
842
|
...versionConfig,
|
|
817
|
-
};
|
|
843
|
+
});
|
|
818
844
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
819
845
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
820
846
|
}
|
|
@@ -829,10 +855,12 @@ custom_edit_url: null
|
|
|
829
855
|
.arguments("<id>")
|
|
830
856
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
831
857
|
.option("--all-versions", "Clean all versions.")
|
|
858
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
832
859
|
.action(async (id, instance) => {
|
|
833
860
|
const options = instance.opts();
|
|
834
861
|
const pluginId = options.pluginId;
|
|
835
862
|
const allVersions = options.allVersions;
|
|
863
|
+
const schemasOnly = options.schemasOnly;
|
|
836
864
|
const pluginInstances = getPluginInstances(plugins);
|
|
837
865
|
let targetConfig: any;
|
|
838
866
|
if (pluginId) {
|
|
@@ -865,16 +893,16 @@ custom_edit_url: null
|
|
|
865
893
|
);
|
|
866
894
|
} else {
|
|
867
895
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
868
|
-
await cleanApiDocs(targetConfig[key]);
|
|
896
|
+
await cleanApiDocs(targetConfig[key], schemasOnly);
|
|
869
897
|
if (allVersions) {
|
|
870
|
-
await cleanAllVersions(targetConfig[key]);
|
|
898
|
+
await cleanAllVersions(targetConfig[key], schemasOnly);
|
|
871
899
|
}
|
|
872
900
|
});
|
|
873
901
|
}
|
|
874
902
|
} else {
|
|
875
|
-
await cleanApiDocs(targetConfig[id]);
|
|
903
|
+
await cleanApiDocs(targetConfig[id], schemasOnly);
|
|
876
904
|
if (allVersions) {
|
|
877
|
-
await cleanAllVersions(targetConfig[id]);
|
|
905
|
+
await cleanAllVersions(targetConfig[id], schemasOnly);
|
|
878
906
|
}
|
|
879
907
|
}
|
|
880
908
|
});
|
|
@@ -887,9 +915,11 @@ custom_edit_url: null
|
|
|
887
915
|
.usage("<id:version>")
|
|
888
916
|
.arguments("<id:version>")
|
|
889
917
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
918
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
890
919
|
.action(async (id, instance) => {
|
|
891
920
|
const options = instance.opts();
|
|
892
921
|
const pluginId = options.pluginId;
|
|
922
|
+
const schemasOnly = options.schemasOnly;
|
|
893
923
|
const pluginInstances = getPluginInstances(plugins);
|
|
894
924
|
let targetConfig: any;
|
|
895
925
|
if (pluginId) {
|
|
@@ -925,14 +955,16 @@ custom_edit_url: null
|
|
|
925
955
|
"Can't use id 'all' for OpenAPI docs versions configuration key."
|
|
926
956
|
);
|
|
927
957
|
} else {
|
|
928
|
-
|
|
958
|
+
if (!schemasOnly) {
|
|
959
|
+
await cleanVersions(parentConfig.outputDir);
|
|
960
|
+
}
|
|
929
961
|
Object.keys(versions).forEach(async (key) => {
|
|
930
962
|
const versionConfig = versions[key];
|
|
931
963
|
const mergedConfig = {
|
|
932
964
|
...parentConfig,
|
|
933
965
|
...versionConfig,
|
|
934
966
|
};
|
|
935
|
-
await cleanApiDocs(mergedConfig);
|
|
967
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
936
968
|
});
|
|
937
969
|
}
|
|
938
970
|
} else {
|
|
@@ -941,7 +973,7 @@ custom_edit_url: null
|
|
|
941
973
|
...parentConfig,
|
|
942
974
|
...versionConfig,
|
|
943
975
|
};
|
|
944
|
-
await cleanApiDocs(mergedConfig);
|
|
976
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
945
977
|
}
|
|
946
978
|
});
|
|
947
979
|
},
|
|
@@ -11,6 +11,8 @@ import path from "path";
|
|
|
11
11
|
import { posixPath } from "@docusaurus/utils";
|
|
12
12
|
|
|
13
13
|
import { readOpenapiFiles } from ".";
|
|
14
|
+
import { processOpenapiFile } from "./openapi";
|
|
15
|
+
import type { APIOptions, SidebarOptions } from "../types";
|
|
14
16
|
|
|
15
17
|
// npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
|
|
16
18
|
|
|
@@ -37,4 +39,60 @@ describe("openapi", () => {
|
|
|
37
39
|
).toBeDefined();
|
|
38
40
|
});
|
|
39
41
|
});
|
|
42
|
+
|
|
43
|
+
describe("schemasOnly", () => {
|
|
44
|
+
it("includes schema metadata when showSchemas is disabled", async () => {
|
|
45
|
+
const openapiData = {
|
|
46
|
+
openapi: "3.0.0",
|
|
47
|
+
info: {
|
|
48
|
+
title: "Schema Only",
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
},
|
|
51
|
+
paths: {
|
|
52
|
+
"/ping": {
|
|
53
|
+
get: {
|
|
54
|
+
summary: "Ping",
|
|
55
|
+
responses: {
|
|
56
|
+
"200": {
|
|
57
|
+
description: "OK",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
components: {
|
|
64
|
+
schemas: {
|
|
65
|
+
WithoutTags: {
|
|
66
|
+
title: "Without Tags",
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
value: {
|
|
70
|
+
type: "string",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const options: APIOptions = {
|
|
79
|
+
specPath: "dummy", // required by the type but unused in this context
|
|
80
|
+
outputDir: "build",
|
|
81
|
+
showSchemas: false,
|
|
82
|
+
schemasOnly: true,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const sidebarOptions = {} as SidebarOptions;
|
|
86
|
+
|
|
87
|
+
const [items] = await processOpenapiFile(
|
|
88
|
+
openapiData as any,
|
|
89
|
+
options,
|
|
90
|
+
sidebarOptions
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const schemaItems = items.filter((item) => item.type === "schema");
|
|
94
|
+
expect(schemaItems).toHaveLength(1);
|
|
95
|
+
expect(schemaItems[0].id).toBe("without-tags");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
40
98
|
});
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -95,6 +95,7 @@ function createItems(
|
|
|
95
95
|
let items: PartialPage<ApiMetadata>[] = [];
|
|
96
96
|
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
97
97
|
const infoId = kebabCase(infoIdSpaces);
|
|
98
|
+
const schemasOnly = options?.schemasOnly === true;
|
|
98
99
|
|
|
99
100
|
if (openapiData.info.description || openapiData.info.title) {
|
|
100
101
|
// Only create an info page if we have a description.
|
|
@@ -434,6 +435,7 @@ function createItems(
|
|
|
434
435
|
}
|
|
435
436
|
|
|
436
437
|
if (
|
|
438
|
+
schemasOnly ||
|
|
437
439
|
options?.showSchemas === true ||
|
|
438
440
|
Object.entries(openapiData?.components?.schemas ?? {})
|
|
439
441
|
.flatMap(([_, s]) => s["x-tags"])
|
|
@@ -443,7 +445,11 @@ function createItems(
|
|
|
443
445
|
for (let [schema, schemaObject] of Object.entries(
|
|
444
446
|
openapiData?.components?.schemas ?? {}
|
|
445
447
|
)) {
|
|
446
|
-
if (
|
|
448
|
+
if (
|
|
449
|
+
schemasOnly ||
|
|
450
|
+
options?.showSchemas === true ||
|
|
451
|
+
schemaObject["x-tags"]
|
|
452
|
+
) {
|
|
447
453
|
const baseIdSpaces =
|
|
448
454
|
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
|
|
449
455
|
const baseId = kebabCase(baseIdSpaces);
|