docusaurus-plugin-openapi-docs 1.0.2 → 1.0.5
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 +106 -17
- package/lib/index.d.ts +7 -1
- package/lib/index.js +228 -18
- package/lib/markdown/createAuthentication.d.ts +2 -0
- package/lib/markdown/createAuthentication.js +139 -0
- package/lib/markdown/createParamsDetails.js +2 -0
- package/lib/markdown/createSchemaDetails.js +2 -0
- package/lib/markdown/index.d.ts +3 -2
- package/lib/markdown/index.js +10 -2
- package/lib/openapi/createExample.js +59 -49
- package/lib/openapi/openapi.d.ts +3 -3
- package/lib/openapi/openapi.js +71 -41
- package/lib/openapi/openapi.test.js +0 -6
- package/lib/openapi/utils/loadAndBundleSpec.d.ts +3 -0
- package/lib/openapi/utils/loadAndBundleSpec.js +44 -0
- package/lib/openapi/utils/types.d.ts +306 -0
- package/lib/openapi/utils/types.js +8 -0
- package/lib/options.d.ts +0 -2
- package/lib/options.js +36 -7
- package/lib/sidebars/index.d.ts +1 -1
- package/lib/sidebars/index.js +33 -30
- package/lib/sidebars/utils.d.ts +2 -0
- package/lib/sidebars/utils.js +31 -0
- package/lib/types.d.ts +34 -11
- package/package.json +10 -8
- package/src/index.ts +291 -20
- package/src/markdown/createAuthentication.ts +160 -0
- package/src/markdown/createParamsDetails.ts +2 -0
- package/src/markdown/createSchemaDetails.ts +2 -0
- package/src/markdown/index.ts +15 -2
- package/src/openapi/createExample.ts +59 -50
- package/src/openapi/openapi.test.ts +0 -6
- package/src/openapi/openapi.ts +85 -39
- package/src/openapi/utils/loadAndBundleSpec.ts +62 -0
- package/src/openapi/utils/types.ts +303 -0
- package/src/options.ts +41 -8
- package/src/sidebars/index.ts +40 -30
- package/src/sidebars/utils.ts +29 -0
- package/src/types.ts +35 -9
- package/src/openapi/__fixtures__/examples/yogurtstore/_category_.json +0 -4
- package/src/openapi/__fixtures__/examples/yogurtstore/froyo.yaml +0 -13
- package/src/openapi/__fixtures__/examples/yogurtstore/nested/nested.yaml +0 -13
package/README.md
CHANGED
|
@@ -20,6 +20,13 @@ OpenAPI plugin for generating API reference docs in Docusaurus v2.
|
|
|
20
20
|
|
|
21
21
|
The `docusaurus-plugin-openapi-docs` package extends the Docusaurus CLI with commands for generating MDX using the OpenAPI specification as the source. The resulting MDX is fully compatible with [plugin-content-docs](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs) and can be used to render beautiful reference API docs by setting `docItemComponent` to `@theme/ApiItem`, a custom component included in the `docusaurus-theme-openapi-docs` theme.
|
|
22
22
|
|
|
23
|
+
Key Features:
|
|
24
|
+
|
|
25
|
+
- **Compatible:** Works with Swagger 2.0 and OpenAPI 3.x.
|
|
26
|
+
- **Fast:** Convert large OpenAPI specs into MDX docs in seconds. 🔥
|
|
27
|
+
- **Stylish:** Based on the same [Infima styling framework](https://infima.dev/) that powers the Docusaurus UI.
|
|
28
|
+
- **Capable:** Supports single, multi and _even micro_ OpenAPI specs.
|
|
29
|
+
|
|
23
30
|
## Installation
|
|
24
31
|
|
|
25
32
|
Plugin:
|
|
@@ -71,16 +78,16 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
|
|
|
71
78
|
],
|
|
72
79
|
|
|
73
80
|
plugins: [
|
|
74
|
-
[
|
|
75
81
|
'docusaurus-plugin-openapi-docs',
|
|
76
82
|
{
|
|
77
83
|
id: "apiDocs",
|
|
84
|
+
docPluginId: "classic",
|
|
78
85
|
config: {
|
|
79
86
|
petstore: { // Note: petstore key is treated as the <id> and can be used to specify an API doc instance when using CLI commands
|
|
80
87
|
specPath: "examples/petstore.yaml", // Path to designated spec file
|
|
81
88
|
outputDir: "api/petstore", // Output directory for generated .mdx docs
|
|
82
89
|
sidebarOptions: {
|
|
83
|
-
groupPathsBy: "
|
|
90
|
+
groupPathsBy: "tag",
|
|
84
91
|
},
|
|
85
92
|
},
|
|
86
93
|
burgers: {
|
|
@@ -97,28 +104,53 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
|
|
|
97
104
|
|
|
98
105
|
> Note: You may optionally configure a dedicated `@docusaurus/plugin-content-docs` instance for use with `docusaurus-theme-openapi-docs` by setting `docItemComponent` to `@theme/ApiItem`.
|
|
99
106
|
|
|
100
|
-
|
|
107
|
+
## Plugin Configuration Options
|
|
108
|
+
|
|
109
|
+
The `docusaurus-plugin-openapi-docs` plugin can be configured with the following options:
|
|
110
|
+
|
|
111
|
+
| Name | Type | Default | Description |
|
|
112
|
+
| ------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| `id` | `string` | `null` | A unique document id. |
|
|
114
|
+
| `docPluginId` | `string` | `null` | The ID associated with the `plugin-content-docs` or `preset` instance used to render the OpenAPI docs (e.g. "your-plugin-id", "classic", "default"). |
|
|
115
|
+
|
|
116
|
+
### config
|
|
101
117
|
|
|
102
|
-
`
|
|
118
|
+
`config` can be configured with the following options:
|
|
103
119
|
|
|
104
|
-
| Name | Type | Default | Description
|
|
105
|
-
| ---------------- | -------- | ------- |
|
|
106
|
-
| `specPath` | `string` | `null` | Designated path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
|
|
107
|
-
| `ouputDir` | `string` | `null` | Desired output path for generated MDX files.
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
120
|
+
| Name | Type | Default | Description |
|
|
121
|
+
| ---------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
|
|
123
|
+
| `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
|
|
124
|
+
| `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
|
|
125
|
+
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
|
|
126
|
+
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
|
|
127
|
+
| `version` | `string` | `null` | _Optional:_ Version assigned to single or micro-spec API specified in `specPath`. |
|
|
128
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
|
|
129
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
|
|
130
|
+
| `versions` | `object` | `null` | _Optional:_ Set of options for versioning configuration. See below for a list of supported options. |
|
|
110
131
|
|
|
111
132
|
`sidebarOptions` can be configured with the following options:
|
|
112
133
|
|
|
113
134
|
| Name | Type | Default | Description |
|
|
114
135
|
| -------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
|
-
| `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by
|
|
116
|
-
| `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br
|
|
136
|
+
| `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by `tag`. |
|
|
137
|
+
| `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br/><br/>The supported options are as follows: <br/><br/> `tag`: Sets the category link config type to `generated-index` and uses the tag description as the link config description. <br/><br/>`info`: Sets the category link config type to `doc` and renders the `info` section as the category link (recommended only for multi/micro-spec scenarios). |
|
|
117
138
|
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
|
|
118
139
|
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
|
|
119
140
|
| `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
|
|
120
141
|
|
|
121
|
-
>
|
|
142
|
+
> You may optionally configure a `sidebarOptions`. In doing so, an individual `sidebar.js` slice with the configured options will be generated within the respective `outputDir`.
|
|
143
|
+
|
|
144
|
+
`versions` can be configured with the following options:
|
|
145
|
+
|
|
146
|
+
| Name | Type | Default | Description |
|
|
147
|
+
| ---------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
148
|
+
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of micro OpenAPI specification files. |
|
|
149
|
+
| `ouputDir` | `string` | `null` | Desired output path for versioned, generated MDX files. |
|
|
150
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
|
|
151
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
|
|
152
|
+
|
|
153
|
+
> All versions will automatically inherit `sidebarOptions` from the parent/base config.
|
|
122
154
|
|
|
123
155
|
## CLI Usage
|
|
124
156
|
|
|
@@ -139,9 +171,11 @@ Commands:
|
|
|
139
171
|
write-translations [options] [siteDir] Extract required translations of your site.
|
|
140
172
|
write-heading-ids [options] [siteDir] [files...] Generate heading ids in Markdown content.
|
|
141
173
|
docs:version <version> Tag a new docs version
|
|
142
|
-
gen-api-docs <id> Generates
|
|
143
|
-
|
|
144
|
-
docs
|
|
174
|
+
gen-api-docs <id> Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).
|
|
175
|
+
gen-api-docs:version <id:version> Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).
|
|
176
|
+
clean-api-docs <id> Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).
|
|
177
|
+
clean-api-docs:version <id:version> Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if
|
|
178
|
+
enabled).
|
|
145
179
|
```
|
|
146
180
|
|
|
147
181
|
### Generating OpenAPI Docs
|
|
@@ -190,6 +224,61 @@ yarn docusaurus clean-api-docs burgers
|
|
|
190
224
|
|
|
191
225
|
> The example above will remove all API docs relative to `burgers`.
|
|
192
226
|
|
|
227
|
+
### Versioning OpenAPI docs
|
|
228
|
+
|
|
229
|
+
To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
yarn docusaurus gen-api-docs:version <id>:all
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Example:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
yarn docusaurus gen-api-docs:version petstore:all
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
> This will generate API docs for all of the OpenAPI specification (OAS) files referenced in your `versions` config and will also generate a `versions.json` file.
|
|
242
|
+
|
|
243
|
+
> Substitue `all` with a specific version ID to generate/clean a specific version. Generating for `all` or a specific version ID will automatically update the `versions.json` file.
|
|
244
|
+
|
|
245
|
+
## Installing from Template
|
|
246
|
+
|
|
247
|
+
Run the following to bootstrap a Docsaurus v2 site (classic theme) with `docusaurus-openapi-docs`:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npx create-docusaurus@2.0.0-beta.21 my-website --package-manager yarn
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
> When prompted to select a template choose `Git repository`.
|
|
254
|
+
|
|
255
|
+
Template Repository URL:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
https://github.com/PaloAltoNetworks/docusaurus-template-openapi-docs.git
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
> When asked how the template repo should be cloned choose "copy" (unless you know better).
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
cd my-website
|
|
265
|
+
yarn
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Developer Quick Start
|
|
269
|
+
|
|
270
|
+
> Looking to make a contribution? Make sure to checkout out our contributing guide.
|
|
271
|
+
|
|
272
|
+
After [forking](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/fork) the main repository, run the following:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
git clone https://github.com/<your account>/docusaurus-openapi-docs.git
|
|
276
|
+
cd docusaurus-openapi-docs
|
|
277
|
+
yarn
|
|
278
|
+
yarn build-packages
|
|
279
|
+
yarn watch:demo
|
|
280
|
+
```
|
|
281
|
+
|
|
193
282
|
## Support
|
|
194
283
|
|
|
195
|
-
Please read [SUPPORT.md](SUPPORT.md) for details on how to get support for this project.
|
|
284
|
+
Please read [SUPPORT.md](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/main/SUPPORT.md) for details on how to get support for this project.
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { LoadContext, Plugin } from "@docusaurus/types";
|
|
2
2
|
import type { PluginOptions, LoadedContent } from "./types";
|
|
3
|
-
export
|
|
3
|
+
export declare function isURL(str: string): boolean;
|
|
4
|
+
export declare function getDocsData(dataArray: any[], filter: string): Object | undefined;
|
|
5
|
+
declare function pluginOpenAPIDocs(context: LoadContext, options: PluginOptions): Plugin<LoadedContent>;
|
|
6
|
+
declare namespace pluginOpenAPIDocs {
|
|
7
|
+
var validateOptions: ({ options, validate }: any) => any;
|
|
8
|
+
}
|
|
9
|
+
export default pluginOpenAPIDocs;
|
package/lib/index.js
CHANGED
|
@@ -9,6 +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
13
|
const fs_1 = __importDefault(require("fs"));
|
|
13
14
|
const path_1 = __importDefault(require("path"));
|
|
14
15
|
const utils_1 = require("@docusaurus/utils");
|
|
@@ -16,16 +17,60 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
16
17
|
const mustache_1 = require("mustache");
|
|
17
18
|
const markdown_1 = require("./markdown");
|
|
18
19
|
const openapi_1 = require("./openapi");
|
|
20
|
+
const options_1 = require("./options");
|
|
19
21
|
const sidebars_1 = __importDefault(require("./sidebars"));
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
function isURL(str) {
|
|
23
|
+
return /^(https?:)\/\//m.test(str);
|
|
24
|
+
}
|
|
25
|
+
exports.isURL = isURL;
|
|
26
|
+
function getDocsData(dataArray, filter) {
|
|
27
|
+
// eslint-disable-next-line array-callback-return
|
|
28
|
+
const filteredData = dataArray.filter((data) => {
|
|
29
|
+
if (data[0] === filter) {
|
|
30
|
+
return data[1];
|
|
31
|
+
}
|
|
32
|
+
// Search plugin-content-docs instances
|
|
33
|
+
if (data[0] === "@docusaurus/plugin-content-docs") {
|
|
34
|
+
const pluginId = data[1].id ? data[1].id : "default";
|
|
35
|
+
if (pluginId === filter) {
|
|
36
|
+
return data[1];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
})[0];
|
|
40
|
+
if (filteredData) {
|
|
41
|
+
// Search presets, e.g. "classic"
|
|
42
|
+
if (filteredData[0] === filter) {
|
|
43
|
+
return filteredData[1].docs;
|
|
44
|
+
}
|
|
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];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
exports.getDocsData = getDocsData;
|
|
56
|
+
function pluginOpenAPIDocs(context, options) {
|
|
57
|
+
const { config, docPluginId } = options;
|
|
58
|
+
const { siteDir, siteConfig } = context;
|
|
59
|
+
// Get routeBasePath and path from plugin-content-docs or preset
|
|
60
|
+
const presets = siteConfig.presets;
|
|
61
|
+
const plugins = siteConfig.plugins;
|
|
62
|
+
const presetsPlugins = presets.concat(plugins);
|
|
63
|
+
const docData = getDocsData(presetsPlugins, docPluginId);
|
|
64
|
+
const docRouteBasePath = docData ? docData.routeBasePath : undefined;
|
|
65
|
+
const docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
|
|
23
66
|
async function generateApiDocs(options) {
|
|
24
67
|
let { specPath, outputDir, template, sidebarOptions } = options;
|
|
25
|
-
const contentPath =
|
|
68
|
+
const contentPath = isURL(specPath)
|
|
69
|
+
? specPath
|
|
70
|
+
: path_1.default.resolve(siteDir, specPath);
|
|
26
71
|
try {
|
|
27
72
|
const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath, {});
|
|
28
|
-
const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles);
|
|
73
|
+
const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, sidebarOptions);
|
|
29
74
|
if (!fs_1.default.existsSync(outputDir)) {
|
|
30
75
|
try {
|
|
31
76
|
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
@@ -37,8 +82,7 @@ function pluginOpenAPI(context, options) {
|
|
|
37
82
|
}
|
|
38
83
|
// TODO: figure out better way to set default
|
|
39
84
|
if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
40
|
-
const sidebarSlice = (0, sidebars_1.default)(sidebarOptions,
|
|
41
|
-
options, loadedApi, tags);
|
|
85
|
+
const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath);
|
|
42
86
|
const sidebarSliceTemplate = template
|
|
43
87
|
? fs_1.default.readFileSync(template).toString()
|
|
44
88
|
: `module.exports = {{{slice}}};`;
|
|
@@ -78,6 +122,9 @@ api: {{{json}}}
|
|
|
78
122
|
{{#api.method}}
|
|
79
123
|
sidebar_class_name: "{{{api.method}}} api-method"
|
|
80
124
|
{{/api.method}}
|
|
125
|
+
{{#infoPath}}
|
|
126
|
+
info_path: {{{infoPath}}}
|
|
127
|
+
{{/infoPath}}
|
|
81
128
|
---
|
|
82
129
|
|
|
83
130
|
{{{markdown}}}
|
|
@@ -96,17 +143,48 @@ hide_title: true
|
|
|
96
143
|
import DocCardList from '@theme/DocCardList';
|
|
97
144
|
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
98
145
|
|
|
146
|
+
<DocCardList items={useCurrentSidebarCategory().items}/>
|
|
147
|
+
\`\`\`
|
|
148
|
+
`;
|
|
149
|
+
const tagMdTemplate = template
|
|
150
|
+
? fs_1.default.readFileSync(template).toString()
|
|
151
|
+
: `---
|
|
152
|
+
id: {{{id}}}
|
|
153
|
+
title: {{{description}}}
|
|
154
|
+
description: {{{description}}}
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
{{{markdown}}}
|
|
158
|
+
|
|
159
|
+
\`\`\`mdx-code-block
|
|
160
|
+
import DocCardList from '@theme/DocCardList';
|
|
161
|
+
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
162
|
+
|
|
99
163
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
|
100
164
|
\`\`\`
|
|
101
165
|
`;
|
|
102
166
|
loadedApi.map(async (item) => {
|
|
103
|
-
const markdown = item.type === "api"
|
|
167
|
+
const markdown = item.type === "api"
|
|
168
|
+
? (0, markdown_1.createApiPageMD)(item)
|
|
169
|
+
: item.type === "info"
|
|
170
|
+
? (0, markdown_1.createInfoPageMD)(item)
|
|
171
|
+
: (0, markdown_1.createTagPageMD)(item);
|
|
104
172
|
item.markdown = markdown;
|
|
105
173
|
if (item.type === "api") {
|
|
106
174
|
item.json = JSON.stringify(item.api);
|
|
175
|
+
let infoBasePath = `${outputDir}/${item.infoId}`;
|
|
176
|
+
if (docRouteBasePath) {
|
|
177
|
+
infoBasePath = `${docRouteBasePath}/${outputDir
|
|
178
|
+
.split(docPath)[1]
|
|
179
|
+
.replace(/^\/+/g, "")}/${item.infoId}`.replace(/^\/+/g, "");
|
|
180
|
+
}
|
|
181
|
+
if (item.infoId)
|
|
182
|
+
item.infoPath = infoBasePath;
|
|
107
183
|
}
|
|
108
184
|
const view = (0, mustache_1.render)(mdTemplate, item);
|
|
109
185
|
const utils = (0, mustache_1.render)(infoMdTemplate, item);
|
|
186
|
+
// eslint-disable-next-line testing-library/render-result-naming-convention
|
|
187
|
+
const tagUtils = (0, mustache_1.render)(tagMdTemplate, item);
|
|
110
188
|
if (item.type === "api") {
|
|
111
189
|
if (!fs_1.default.existsSync(`${outputDir}/${item.id}.api.mdx`)) {
|
|
112
190
|
try {
|
|
@@ -132,6 +210,17 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
132
210
|
}
|
|
133
211
|
}
|
|
134
212
|
}
|
|
213
|
+
if (item.type === "tag") {
|
|
214
|
+
if (!fs_1.default.existsSync(`${outputDir}/${item.id}.tag.mdx`)) {
|
|
215
|
+
try {
|
|
216
|
+
fs_1.default.writeFileSync(`${outputDir}/${item.id}.tag.mdx`, tagUtils, "utf8");
|
|
217
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.tag.mdx"`));
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
console.error(chalk_1.default.red(`Failed to write "${outputDir}/${item.id}.tag.mdx"`), chalk_1.default.yellow(err));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
135
224
|
return;
|
|
136
225
|
});
|
|
137
226
|
return;
|
|
@@ -144,11 +233,13 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
144
233
|
async function cleanApiDocs(options) {
|
|
145
234
|
const { outputDir } = options;
|
|
146
235
|
const apiDir = path_1.default.join(siteDir, outputDir);
|
|
147
|
-
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx"], {
|
|
236
|
+
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
|
|
148
237
|
cwd: path_1.default.resolve(apiDir),
|
|
238
|
+
deep: 1,
|
|
149
239
|
});
|
|
150
240
|
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js"], {
|
|
151
241
|
cwd: path_1.default.resolve(apiDir),
|
|
242
|
+
deep: 1,
|
|
152
243
|
});
|
|
153
244
|
apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
154
245
|
if (err) {
|
|
@@ -167,18 +258,48 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
167
258
|
}
|
|
168
259
|
}));
|
|
169
260
|
}
|
|
261
|
+
async function generateVersions(versions, outputDir) {
|
|
262
|
+
let versionsArray = [];
|
|
263
|
+
for (const [version, metadata] of Object.entries(versions)) {
|
|
264
|
+
versionsArray.push({
|
|
265
|
+
version: version,
|
|
266
|
+
label: metadata.label,
|
|
267
|
+
baseUrl: metadata.baseUrl,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const versionsJson = JSON.stringify(versionsArray, null, 2);
|
|
271
|
+
try {
|
|
272
|
+
fs_1.default.writeFileSync(`${outputDir}/versions.json`, versionsJson, "utf8");
|
|
273
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/versions.json"`));
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
console.error(chalk_1.default.red(`Failed to write "${outputDir}/versions.json"`), chalk_1.default.yellow(err));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async function cleanVersions(outputDir) {
|
|
280
|
+
if (fs_1.default.existsSync(`${outputDir}/versions.json`)) {
|
|
281
|
+
fs_1.default.unlink(`${outputDir}/versions.json`, (err) => {
|
|
282
|
+
if (err) {
|
|
283
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${outputDir}/versions.json"`), chalk_1.default.yellow(err));
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${outputDir}/versions.json"`));
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
170
291
|
return {
|
|
171
|
-
name: `docusaurus-plugin-openapi`,
|
|
292
|
+
name: `docusaurus-plugin-openapi-docs`,
|
|
172
293
|
extendCli(cli) {
|
|
173
294
|
cli
|
|
174
295
|
.command(`gen-api-docs`)
|
|
175
|
-
.description(`Generates
|
|
176
|
-
.usage("
|
|
296
|
+
.description(`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`)
|
|
297
|
+
.usage("<id>")
|
|
177
298
|
.arguments("<id>")
|
|
178
299
|
.action(async (id) => {
|
|
179
300
|
if (id === "all") {
|
|
180
301
|
if (config[id]) {
|
|
181
|
-
console.error(chalk_1.default.red("Can't use id 'all' for
|
|
302
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
182
303
|
}
|
|
183
304
|
else {
|
|
184
305
|
Object.keys(config).forEach(async function (key) {
|
|
@@ -187,21 +308,71 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
187
308
|
}
|
|
188
309
|
}
|
|
189
310
|
else if (!config[id]) {
|
|
190
|
-
console.error(chalk_1.default.red(`ID ${id} does not exist in
|
|
311
|
+
console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
|
|
191
312
|
}
|
|
192
313
|
else {
|
|
193
314
|
await generateApiDocs(config[id]);
|
|
194
315
|
}
|
|
195
316
|
});
|
|
317
|
+
cli
|
|
318
|
+
.command(`gen-api-docs:version`)
|
|
319
|
+
.description(`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`)
|
|
320
|
+
.usage("<id:version>")
|
|
321
|
+
.arguments("<id:version>")
|
|
322
|
+
.action(async (id) => {
|
|
323
|
+
const [parentId, versionId] = id.split(":");
|
|
324
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
325
|
+
const version = parentConfig.version;
|
|
326
|
+
const label = parentConfig.label;
|
|
327
|
+
const baseUrl = parentConfig.baseUrl;
|
|
328
|
+
let parentVersion = {};
|
|
329
|
+
parentVersion[version] = { label: label, baseUrl: baseUrl };
|
|
330
|
+
const { versions } = config[parentId];
|
|
331
|
+
const mergedVersions = Object.assign(parentVersion, versions);
|
|
332
|
+
// Prepare for merge
|
|
333
|
+
delete parentConfig.versions;
|
|
334
|
+
delete parentConfig.version;
|
|
335
|
+
delete parentConfig.label;
|
|
336
|
+
delete parentConfig.baseUrl;
|
|
337
|
+
// TODO: handle when no versions are defined by version command is passed
|
|
338
|
+
if (versionId === "all") {
|
|
339
|
+
if (versions[id]) {
|
|
340
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key."));
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
344
|
+
Object.keys(versions).forEach(async (key) => {
|
|
345
|
+
const versionConfig = versions[key];
|
|
346
|
+
const mergedConfig = {
|
|
347
|
+
...parentConfig,
|
|
348
|
+
...versionConfig,
|
|
349
|
+
};
|
|
350
|
+
await generateApiDocs(mergedConfig);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (!versions[versionId]) {
|
|
355
|
+
console.error(chalk_1.default.red(`Version ID '${versionId}' does not exist in OpenAPI docs versions config.`));
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const versionConfig = versions[versionId];
|
|
359
|
+
const mergedConfig = {
|
|
360
|
+
...parentConfig,
|
|
361
|
+
...versionConfig,
|
|
362
|
+
};
|
|
363
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
364
|
+
await generateApiDocs(mergedConfig);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
196
367
|
cli
|
|
197
368
|
.command(`clean-api-docs`)
|
|
198
|
-
.description(`Clears the
|
|
199
|
-
.usage("
|
|
369
|
+
.description(`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`)
|
|
370
|
+
.usage("<id>")
|
|
200
371
|
.arguments("<id>")
|
|
201
372
|
.action(async (id) => {
|
|
202
373
|
if (id === "all") {
|
|
203
374
|
if (config[id]) {
|
|
204
|
-
console.error(chalk_1.default.red("Can't use id 'all' for
|
|
375
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
205
376
|
}
|
|
206
377
|
else {
|
|
207
378
|
Object.keys(config).forEach(async function (key) {
|
|
@@ -213,7 +384,46 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
213
384
|
await cleanApiDocs(config[id]);
|
|
214
385
|
}
|
|
215
386
|
});
|
|
387
|
+
cli
|
|
388
|
+
.command(`clean-api-docs:version`)
|
|
389
|
+
.description(`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`)
|
|
390
|
+
.usage("<id:version>")
|
|
391
|
+
.arguments("<id:version>")
|
|
392
|
+
.action(async (id) => {
|
|
393
|
+
const [parentId, versionId] = id.split(":");
|
|
394
|
+
const { versions } = config[parentId];
|
|
395
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
396
|
+
delete parentConfig.versions;
|
|
397
|
+
if (versionId === "all") {
|
|
398
|
+
if (versions[id]) {
|
|
399
|
+
chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key.");
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
await cleanVersions(parentConfig.outputDir);
|
|
403
|
+
Object.keys(versions).forEach(async (key) => {
|
|
404
|
+
const versionConfig = versions[key];
|
|
405
|
+
const mergedConfig = {
|
|
406
|
+
...parentConfig,
|
|
407
|
+
...versionConfig,
|
|
408
|
+
};
|
|
409
|
+
await cleanApiDocs(mergedConfig);
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
const versionConfig = versions[versionId];
|
|
415
|
+
const mergedConfig = {
|
|
416
|
+
...parentConfig,
|
|
417
|
+
...versionConfig,
|
|
418
|
+
};
|
|
419
|
+
await cleanApiDocs(mergedConfig);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
216
422
|
},
|
|
217
423
|
};
|
|
218
424
|
}
|
|
219
|
-
exports.default =
|
|
425
|
+
exports.default = pluginOpenAPIDocs;
|
|
426
|
+
pluginOpenAPIDocs.validateOptions = ({ options, validate }) => {
|
|
427
|
+
const validatedOptions = validate(options_1.OptionsSchema, options);
|
|
428
|
+
return validatedOptions;
|
|
429
|
+
};
|