docusaurus-plugin-openapi-docs 0.0.0-375 → 0.0.0-379
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 +85 -7
- package/lib/index.js +124 -7
- package/lib/markdown/index.js +1 -1
- package/lib/options.js +18 -0
- package/lib/sidebars/utils.d.ts +2 -0
- package/lib/sidebars/utils.js +31 -0
- package/lib/types.d.ts +12 -0
- package/package.json +2 -2
- package/src/index.ts +163 -9
- package/src/markdown/index.ts +1 -1
- package/src/options.ts +21 -0
- package/src/sidebars/utils.ts +29 -0
- package/src/types.ts +13 -0
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,7 +78,6 @@ 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",
|
|
@@ -107,18 +113,33 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
|
|
|
107
113
|
| `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
|
|
108
114
|
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
|
|
109
115
|
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
|
|
116
|
+
| `version` | `string` | `null` | _Optional:_ Version assigned to single or micro-spec API specified in `specPath`. |
|
|
117
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
|
|
118
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
|
|
119
|
+
| `versions` | `object` | `null` | _Optional:_ Set of options for versioning configuration. See below for a list of supported options. |
|
|
110
120
|
|
|
111
121
|
`sidebarOptions` can be configured with the following options:
|
|
112
122
|
|
|
113
123
|
| Name | Type | Default | Description |
|
|
114
124
|
| -------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
125
|
| `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by `tag`. |
|
|
116
|
-
| `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br
|
|
126
|
+
| `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
127
|
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
|
|
118
128
|
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
|
|
119
129
|
| `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
|
|
120
130
|
|
|
121
|
-
>
|
|
131
|
+
> 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`.
|
|
132
|
+
|
|
133
|
+
`versions` can be configured with the following options:
|
|
134
|
+
|
|
135
|
+
| Name | Type | Default | Description |
|
|
136
|
+
| ---------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
137
|
+
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of micro OpenAPI specification files. |
|
|
138
|
+
| `ouputDir` | `string` | `null` | Desired output path for versioned, generated MDX files. |
|
|
139
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
|
|
140
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
|
|
141
|
+
|
|
142
|
+
> All versions will automatically inherit `sidebarOptions` from the parent/base config.
|
|
122
143
|
|
|
123
144
|
## CLI Usage
|
|
124
145
|
|
|
@@ -139,9 +160,11 @@ Commands:
|
|
|
139
160
|
write-translations [options] [siteDir] Extract required translations of your site.
|
|
140
161
|
write-heading-ids [options] [siteDir] [files...] Generate heading ids in Markdown content.
|
|
141
162
|
docs:version <version> Tag a new docs version
|
|
142
|
-
gen-api-docs <id> Generates
|
|
143
|
-
|
|
144
|
-
docs
|
|
163
|
+
gen-api-docs <id> Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).
|
|
164
|
+
gen-api-docs:version <id:version> Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).
|
|
165
|
+
clean-api-docs <id> Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).
|
|
166
|
+
clean-api-docs:version <id:version> Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if
|
|
167
|
+
enabled).
|
|
145
168
|
```
|
|
146
169
|
|
|
147
170
|
### Generating OpenAPI Docs
|
|
@@ -190,6 +213,61 @@ yarn docusaurus clean-api-docs burgers
|
|
|
190
213
|
|
|
191
214
|
> The example above will remove all API docs relative to `burgers`.
|
|
192
215
|
|
|
216
|
+
### Versioning OpenAPI docs
|
|
217
|
+
|
|
218
|
+
To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
yarn docusaurus gen-api-docs:version <id>:all
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Example:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
yarn docusaurus gen-api-docs:version petstore:all
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
> 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.
|
|
231
|
+
|
|
232
|
+
> 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.
|
|
233
|
+
|
|
234
|
+
## Installing from Template
|
|
235
|
+
|
|
236
|
+
Run the following to bootstrap a Docsaurus v2 site (classic theme) with `docusaurus-openapi-docs`:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
npx create-docusaurus@2.0.0-beta.21 my-website --package-manager yarn
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
> When prompted to select a template choose `Git repository`.
|
|
243
|
+
|
|
244
|
+
Template Repository URL:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
https://github.com/PaloAltoNetworks/docusaurus-template-openapi-docs.git
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
> When asked how the template repo should be cloned choose "copy" (unless you know better).
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
cd my-website
|
|
254
|
+
yarn
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Developer Quick Start
|
|
258
|
+
|
|
259
|
+
> Looking to make a contribution? Make sure to checkout out our contributing guide.
|
|
260
|
+
|
|
261
|
+
After [forking](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/fork) the main repository, run the following:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
git clone https://github.com/<your account>/docusaurus-openapi-docs.git
|
|
265
|
+
cd docusaurus-openapi-docs
|
|
266
|
+
yarn
|
|
267
|
+
yarn build-packages
|
|
268
|
+
yarn watch:demo
|
|
269
|
+
```
|
|
270
|
+
|
|
193
271
|
## Support
|
|
194
272
|
|
|
195
|
-
Please read [SUPPORT.md](SUPPORT.md) for details on how to get support for this project.
|
|
273
|
+
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.js
CHANGED
|
@@ -192,9 +192,11 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
192
192
|
const apiDir = path_1.default.join(siteDir, outputDir);
|
|
193
193
|
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
|
|
194
194
|
cwd: path_1.default.resolve(apiDir),
|
|
195
|
+
deep: 1,
|
|
195
196
|
});
|
|
196
197
|
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js"], {
|
|
197
198
|
cwd: path_1.default.resolve(apiDir),
|
|
199
|
+
deep: 1,
|
|
198
200
|
});
|
|
199
201
|
apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
200
202
|
if (err) {
|
|
@@ -213,18 +215,48 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
213
215
|
}
|
|
214
216
|
}));
|
|
215
217
|
}
|
|
218
|
+
async function generateVersions(versions, outputDir) {
|
|
219
|
+
let versionsArray = [];
|
|
220
|
+
for (const [version, metadata] of Object.entries(versions)) {
|
|
221
|
+
versionsArray.push({
|
|
222
|
+
version: version,
|
|
223
|
+
label: metadata.label,
|
|
224
|
+
baseUrl: metadata.baseUrl,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const versionsJson = JSON.stringify(versionsArray, null, 2);
|
|
228
|
+
try {
|
|
229
|
+
fs_1.default.writeFileSync(`${outputDir}/versions.json`, versionsJson, "utf8");
|
|
230
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/versions.json"`));
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
console.error(chalk_1.default.red(`Failed to write "${outputDir}/versions.json"`), chalk_1.default.yellow(err));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async function cleanVersions(outputDir) {
|
|
237
|
+
if (fs_1.default.existsSync(`${outputDir}/versions.json`)) {
|
|
238
|
+
fs_1.default.unlink(`${outputDir}/versions.json`, (err) => {
|
|
239
|
+
if (err) {
|
|
240
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${outputDir}/versions.json"`), chalk_1.default.yellow(err));
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${outputDir}/versions.json"`));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
216
248
|
return {
|
|
217
249
|
name: `docusaurus-plugin-openapi-docs`,
|
|
218
250
|
extendCli(cli) {
|
|
219
251
|
cli
|
|
220
252
|
.command(`gen-api-docs`)
|
|
221
|
-
.description(`Generates
|
|
222
|
-
.usage("
|
|
253
|
+
.description(`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`)
|
|
254
|
+
.usage("<id>")
|
|
223
255
|
.arguments("<id>")
|
|
224
256
|
.action(async (id) => {
|
|
225
257
|
if (id === "all") {
|
|
226
258
|
if (config[id]) {
|
|
227
|
-
console.error(chalk_1.default.red("Can't use id 'all' for
|
|
259
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
228
260
|
}
|
|
229
261
|
else {
|
|
230
262
|
Object.keys(config).forEach(async function (key) {
|
|
@@ -233,21 +265,71 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
233
265
|
}
|
|
234
266
|
}
|
|
235
267
|
else if (!config[id]) {
|
|
236
|
-
console.error(chalk_1.default.red(`ID ${id} does not exist in
|
|
268
|
+
console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
|
|
237
269
|
}
|
|
238
270
|
else {
|
|
239
271
|
await generateApiDocs(config[id]);
|
|
240
272
|
}
|
|
241
273
|
});
|
|
274
|
+
cli
|
|
275
|
+
.command(`gen-api-docs:version`)
|
|
276
|
+
.description(`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`)
|
|
277
|
+
.usage("<id:version>")
|
|
278
|
+
.arguments("<id:version>")
|
|
279
|
+
.action(async (id) => {
|
|
280
|
+
const [parentId, versionId] = id.split(":");
|
|
281
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
282
|
+
const version = parentConfig.version;
|
|
283
|
+
const label = parentConfig.label;
|
|
284
|
+
const baseUrl = parentConfig.baseUrl;
|
|
285
|
+
let parentVersion = {};
|
|
286
|
+
parentVersion[version] = { label: label, baseUrl: baseUrl };
|
|
287
|
+
const { versions } = config[parentId];
|
|
288
|
+
const mergedVersions = Object.assign(parentVersion, versions);
|
|
289
|
+
// Prepare for merge
|
|
290
|
+
delete parentConfig.versions;
|
|
291
|
+
delete parentConfig.version;
|
|
292
|
+
delete parentConfig.label;
|
|
293
|
+
delete parentConfig.baseUrl;
|
|
294
|
+
// TODO: handle when no versions are defined by version command is passed
|
|
295
|
+
if (versionId === "all") {
|
|
296
|
+
if (versions[id]) {
|
|
297
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key."));
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
301
|
+
Object.keys(versions).forEach(async (key) => {
|
|
302
|
+
const versionConfig = versions[key];
|
|
303
|
+
const mergedConfig = {
|
|
304
|
+
...parentConfig,
|
|
305
|
+
...versionConfig,
|
|
306
|
+
};
|
|
307
|
+
await generateApiDocs(mergedConfig);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else if (!versions[versionId]) {
|
|
312
|
+
console.error(chalk_1.default.red(`Version ID '${versionId}' does not exist in OpenAPI docs versions config.`));
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
const versionConfig = versions[versionId];
|
|
316
|
+
const mergedConfig = {
|
|
317
|
+
...parentConfig,
|
|
318
|
+
...versionConfig,
|
|
319
|
+
};
|
|
320
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
321
|
+
await generateApiDocs(mergedConfig);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
242
324
|
cli
|
|
243
325
|
.command(`clean-api-docs`)
|
|
244
|
-
.description(`Clears the
|
|
245
|
-
.usage("
|
|
326
|
+
.description(`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`)
|
|
327
|
+
.usage("<id>")
|
|
246
328
|
.arguments("<id>")
|
|
247
329
|
.action(async (id) => {
|
|
248
330
|
if (id === "all") {
|
|
249
331
|
if (config[id]) {
|
|
250
|
-
console.error(chalk_1.default.red("Can't use id 'all' for
|
|
332
|
+
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
251
333
|
}
|
|
252
334
|
else {
|
|
253
335
|
Object.keys(config).forEach(async function (key) {
|
|
@@ -259,6 +341,41 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
259
341
|
await cleanApiDocs(config[id]);
|
|
260
342
|
}
|
|
261
343
|
});
|
|
344
|
+
cli
|
|
345
|
+
.command(`clean-api-docs:version`)
|
|
346
|
+
.description(`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`)
|
|
347
|
+
.usage("<id:version>")
|
|
348
|
+
.arguments("<id:version>")
|
|
349
|
+
.action(async (id) => {
|
|
350
|
+
const [parentId, versionId] = id.split(":");
|
|
351
|
+
const { versions } = config[parentId];
|
|
352
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
353
|
+
delete parentConfig.versions;
|
|
354
|
+
if (versionId === "all") {
|
|
355
|
+
if (versions[id]) {
|
|
356
|
+
chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key.");
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
await cleanVersions(parentConfig.outputDir);
|
|
360
|
+
Object.keys(versions).forEach(async (key) => {
|
|
361
|
+
const versionConfig = versions[key];
|
|
362
|
+
const mergedConfig = {
|
|
363
|
+
...parentConfig,
|
|
364
|
+
...versionConfig,
|
|
365
|
+
};
|
|
366
|
+
await cleanApiDocs(mergedConfig);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
const versionConfig = versions[versionId];
|
|
372
|
+
const mergedConfig = {
|
|
373
|
+
...parentConfig,
|
|
374
|
+
...versionConfig,
|
|
375
|
+
};
|
|
376
|
+
await cleanApiDocs(mergedConfig);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
262
379
|
},
|
|
263
380
|
};
|
|
264
381
|
}
|
package/lib/markdown/index.js
CHANGED
|
@@ -40,7 +40,7 @@ exports.createApiPageMD = createApiPageMD;
|
|
|
40
40
|
function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, securitySchemes, }) {
|
|
41
41
|
return (0, utils_1.render)([
|
|
42
42
|
`import Tabs from "@theme/Tabs";\n`,
|
|
43
|
-
`import TabItem from "@theme/TabItem";\n`,
|
|
43
|
+
`import TabItem from "@theme/TabItem";\n\n`,
|
|
44
44
|
(0, createVersionBadge_1.createVersionBadge)(version),
|
|
45
45
|
`# ${(0, lodash_1.escape)(title)}\n\n`,
|
|
46
46
|
(0, createDescription_1.createDescription)(description),
|
package/lib/options.js
CHANGED
|
@@ -24,6 +24,24 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
|
|
|
24
24
|
outputDir: utils_validation_1.Joi.string().required(),
|
|
25
25
|
template: utils_validation_1.Joi.string(),
|
|
26
26
|
sidebarOptions: sidebarOptions,
|
|
27
|
+
version: utils_validation_1.Joi.string().when("versions", {
|
|
28
|
+
is: utils_validation_1.Joi.exist(),
|
|
29
|
+
then: utils_validation_1.Joi.required(),
|
|
30
|
+
}),
|
|
31
|
+
label: utils_validation_1.Joi.string().when("versions", {
|
|
32
|
+
is: utils_validation_1.Joi.exist(),
|
|
33
|
+
then: utils_validation_1.Joi.required(),
|
|
34
|
+
}),
|
|
35
|
+
baseUrl: utils_validation_1.Joi.string().when("versions", {
|
|
36
|
+
is: utils_validation_1.Joi.exist(),
|
|
37
|
+
then: utils_validation_1.Joi.required(),
|
|
38
|
+
}),
|
|
39
|
+
versions: utils_validation_1.Joi.object().pattern(/^/, utils_validation_1.Joi.object({
|
|
40
|
+
specPath: utils_validation_1.Joi.string().required(),
|
|
41
|
+
outputDir: utils_validation_1.Joi.string().required(),
|
|
42
|
+
label: utils_validation_1.Joi.string().required(),
|
|
43
|
+
baseUrl: utils_validation_1.Joi.string().required(),
|
|
44
|
+
})),
|
|
27
45
|
}))
|
|
28
46
|
.required(),
|
|
29
47
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.versionCrumb = exports.versionSelector = void 0;
|
|
10
|
+
const mustache_1 = require("mustache");
|
|
11
|
+
function versionSelector(versions) {
|
|
12
|
+
const template = `<div class="dropdown dropdown--hoverable dropdown--right">
|
|
13
|
+
<button class="button button--block button--sm button--secondary"><span>Select API Version</span></button>
|
|
14
|
+
<ul class="dropdown__menu">
|
|
15
|
+
{{#.}}<li><a class="dropdown__link" href="{{{baseUrl}}}">{{{label}}}</a></li>{{/.}}
|
|
16
|
+
</ul>
|
|
17
|
+
</div>
|
|
18
|
+
`;
|
|
19
|
+
const view = (0, mustache_1.render)(template, versions);
|
|
20
|
+
return view;
|
|
21
|
+
}
|
|
22
|
+
exports.versionSelector = versionSelector;
|
|
23
|
+
function versionCrumb(version) {
|
|
24
|
+
const template = `<ul style="display: flex;" class="breadcrumbs breadcrumbs--sm">
|
|
25
|
+
<li style="margin-left: auto; margin-right: 0;" class="breadcrumbs__item breadcrumbs__item--active">
|
|
26
|
+
<a class="breadcrumbs__link"><span>{{{.}}}</span></a></li></ul>
|
|
27
|
+
`;
|
|
28
|
+
const view = (0, mustache_1.render)(template, version);
|
|
29
|
+
return view;
|
|
30
|
+
}
|
|
31
|
+
exports.versionCrumb = versionCrumb;
|
package/lib/types.d.ts
CHANGED
|
@@ -12,6 +12,18 @@ export interface APIOptions {
|
|
|
12
12
|
outputDir: string;
|
|
13
13
|
template?: string;
|
|
14
14
|
sidebarOptions?: SidebarOptions;
|
|
15
|
+
version?: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
versions?: {
|
|
19
|
+
[key: string]: APIVersionOptions;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface APIVersionOptions {
|
|
23
|
+
specPath: string;
|
|
24
|
+
outputDir: string;
|
|
25
|
+
label: string;
|
|
26
|
+
baseUrl: string;
|
|
15
27
|
}
|
|
16
28
|
export interface LoadedContent {
|
|
17
29
|
loadedApi: ApiMetadata[];
|
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-379",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=14"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "87e5b6e59b66aae31c2f163060b030b232a45d39"
|
|
66
66
|
}
|
package/src/index.ts
CHANGED
|
@@ -255,9 +255,11 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
255
255
|
const apiDir = path.join(siteDir, outputDir);
|
|
256
256
|
const apiMdxFiles = await Globby(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
|
|
257
257
|
cwd: path.resolve(apiDir),
|
|
258
|
+
deep: 1,
|
|
258
259
|
});
|
|
259
260
|
const sidebarFile = await Globby(["sidebar.js"], {
|
|
260
261
|
cwd: path.resolve(apiDir),
|
|
262
|
+
deep: 1,
|
|
261
263
|
});
|
|
262
264
|
apiMdxFiles.map((mdx) =>
|
|
263
265
|
fs.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
@@ -288,21 +290,66 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
288
290
|
);
|
|
289
291
|
}
|
|
290
292
|
|
|
293
|
+
async function generateVersions(versions: object, outputDir: string) {
|
|
294
|
+
let versionsArray = [] as object[];
|
|
295
|
+
for (const [version, metadata] of Object.entries(versions)) {
|
|
296
|
+
versionsArray.push({
|
|
297
|
+
version: version,
|
|
298
|
+
label: metadata.label,
|
|
299
|
+
baseUrl: metadata.baseUrl,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const versionsJson = JSON.stringify(versionsArray, null, 2);
|
|
304
|
+
try {
|
|
305
|
+
fs.writeFileSync(`${outputDir}/versions.json`, versionsJson, "utf8");
|
|
306
|
+
console.log(
|
|
307
|
+
chalk.green(`Successfully created "${outputDir}/versions.json"`)
|
|
308
|
+
);
|
|
309
|
+
} catch (err) {
|
|
310
|
+
console.error(
|
|
311
|
+
chalk.red(`Failed to write "${outputDir}/versions.json"`),
|
|
312
|
+
chalk.yellow(err)
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function cleanVersions(outputDir: string) {
|
|
318
|
+
if (fs.existsSync(`${outputDir}/versions.json`)) {
|
|
319
|
+
fs.unlink(`${outputDir}/versions.json`, (err) => {
|
|
320
|
+
if (err) {
|
|
321
|
+
console.error(
|
|
322
|
+
chalk.red(`Cleanup failed for "${outputDir}/versions.json"`),
|
|
323
|
+
chalk.yellow(err)
|
|
324
|
+
);
|
|
325
|
+
} else {
|
|
326
|
+
console.log(
|
|
327
|
+
chalk.green(`Cleanup succeeded for "${outputDir}/versions.json"`)
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
291
334
|
return {
|
|
292
335
|
name: `docusaurus-plugin-openapi-docs`,
|
|
293
336
|
|
|
294
337
|
extendCli(cli): void {
|
|
295
338
|
cli
|
|
296
339
|
.command(`gen-api-docs`)
|
|
297
|
-
.description(
|
|
298
|
-
|
|
299
|
-
"[options] <id key value in plugin config within docusaurus.config.js>"
|
|
340
|
+
.description(
|
|
341
|
+
`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`
|
|
300
342
|
)
|
|
343
|
+
.usage("<id>")
|
|
301
344
|
.arguments("<id>")
|
|
302
345
|
.action(async (id) => {
|
|
303
346
|
if (id === "all") {
|
|
304
347
|
if (config[id]) {
|
|
305
|
-
console.error(
|
|
348
|
+
console.error(
|
|
349
|
+
chalk.red(
|
|
350
|
+
"Can't use id 'all' for OpenAPI docs configuration key."
|
|
351
|
+
)
|
|
352
|
+
);
|
|
306
353
|
} else {
|
|
307
354
|
Object.keys(config).forEach(async function (key) {
|
|
308
355
|
await generateApiDocs(config[key]);
|
|
@@ -310,24 +357,91 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
310
357
|
}
|
|
311
358
|
} else if (!config[id]) {
|
|
312
359
|
console.error(
|
|
313
|
-
chalk.red(`ID ${id} does not exist in
|
|
360
|
+
chalk.red(`ID '${id}' does not exist in OpenAPI docs config.`)
|
|
314
361
|
);
|
|
315
362
|
} else {
|
|
316
363
|
await generateApiDocs(config[id]);
|
|
317
364
|
}
|
|
318
365
|
});
|
|
319
366
|
|
|
367
|
+
cli
|
|
368
|
+
.command(`gen-api-docs:version`)
|
|
369
|
+
.description(
|
|
370
|
+
`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`
|
|
371
|
+
)
|
|
372
|
+
.usage("<id:version>")
|
|
373
|
+
.arguments("<id:version>")
|
|
374
|
+
.action(async (id) => {
|
|
375
|
+
const [parentId, versionId] = id.split(":");
|
|
376
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
377
|
+
|
|
378
|
+
const version = parentConfig.version as string;
|
|
379
|
+
const label = parentConfig.label as string;
|
|
380
|
+
const baseUrl = parentConfig.baseUrl as string;
|
|
381
|
+
|
|
382
|
+
let parentVersion = {} as any;
|
|
383
|
+
parentVersion[version] = { label: label, baseUrl: baseUrl };
|
|
384
|
+
|
|
385
|
+
const { versions } = config[parentId] as any;
|
|
386
|
+
const mergedVersions = Object.assign(parentVersion, versions);
|
|
387
|
+
|
|
388
|
+
// Prepare for merge
|
|
389
|
+
delete parentConfig.versions;
|
|
390
|
+
delete parentConfig.version;
|
|
391
|
+
delete parentConfig.label;
|
|
392
|
+
delete parentConfig.baseUrl;
|
|
393
|
+
|
|
394
|
+
// TODO: handle when no versions are defined by version command is passed
|
|
395
|
+
if (versionId === "all") {
|
|
396
|
+
if (versions[id]) {
|
|
397
|
+
console.error(
|
|
398
|
+
chalk.red(
|
|
399
|
+
"Can't use id 'all' for OpenAPI docs versions configuration key."
|
|
400
|
+
)
|
|
401
|
+
);
|
|
402
|
+
} else {
|
|
403
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
404
|
+
Object.keys(versions).forEach(async (key) => {
|
|
405
|
+
const versionConfig = versions[key];
|
|
406
|
+
const mergedConfig = {
|
|
407
|
+
...parentConfig,
|
|
408
|
+
...versionConfig,
|
|
409
|
+
};
|
|
410
|
+
await generateApiDocs(mergedConfig);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
} else if (!versions[versionId]) {
|
|
414
|
+
console.error(
|
|
415
|
+
chalk.red(
|
|
416
|
+
`Version ID '${versionId}' does not exist in OpenAPI docs versions config.`
|
|
417
|
+
)
|
|
418
|
+
);
|
|
419
|
+
} else {
|
|
420
|
+
const versionConfig = versions[versionId];
|
|
421
|
+
const mergedConfig = {
|
|
422
|
+
...parentConfig,
|
|
423
|
+
...versionConfig,
|
|
424
|
+
};
|
|
425
|
+
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
426
|
+
await generateApiDocs(mergedConfig);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
320
430
|
cli
|
|
321
431
|
.command(`clean-api-docs`)
|
|
322
|
-
.description(
|
|
323
|
-
|
|
324
|
-
"[options] <id key value in plugin config within docusaurus.config.js>"
|
|
432
|
+
.description(
|
|
433
|
+
`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`
|
|
325
434
|
)
|
|
435
|
+
.usage("<id>")
|
|
326
436
|
.arguments("<id>")
|
|
327
437
|
.action(async (id) => {
|
|
328
438
|
if (id === "all") {
|
|
329
439
|
if (config[id]) {
|
|
330
|
-
console.error(
|
|
440
|
+
console.error(
|
|
441
|
+
chalk.red(
|
|
442
|
+
"Can't use id 'all' for OpenAPI docs configuration key."
|
|
443
|
+
)
|
|
444
|
+
);
|
|
331
445
|
} else {
|
|
332
446
|
Object.keys(config).forEach(async function (key) {
|
|
333
447
|
await cleanApiDocs(config[key]);
|
|
@@ -337,6 +451,46 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
337
451
|
await cleanApiDocs(config[id]);
|
|
338
452
|
}
|
|
339
453
|
});
|
|
454
|
+
|
|
455
|
+
cli
|
|
456
|
+
.command(`clean-api-docs:version`)
|
|
457
|
+
.description(
|
|
458
|
+
`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`
|
|
459
|
+
)
|
|
460
|
+
.usage("<id:version>")
|
|
461
|
+
.arguments("<id:version>")
|
|
462
|
+
.action(async (id) => {
|
|
463
|
+
const [parentId, versionId] = id.split(":");
|
|
464
|
+
const { versions } = config[parentId] as any;
|
|
465
|
+
|
|
466
|
+
const parentConfig = Object.assign({}, config[parentId]);
|
|
467
|
+
delete parentConfig.versions;
|
|
468
|
+
|
|
469
|
+
if (versionId === "all") {
|
|
470
|
+
if (versions[id]) {
|
|
471
|
+
chalk.red(
|
|
472
|
+
"Can't use id 'all' for OpenAPI docs versions configuration key."
|
|
473
|
+
);
|
|
474
|
+
} else {
|
|
475
|
+
await cleanVersions(parentConfig.outputDir);
|
|
476
|
+
Object.keys(versions).forEach(async (key) => {
|
|
477
|
+
const versionConfig = versions[key];
|
|
478
|
+
const mergedConfig = {
|
|
479
|
+
...parentConfig,
|
|
480
|
+
...versionConfig,
|
|
481
|
+
};
|
|
482
|
+
await cleanApiDocs(mergedConfig);
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
} else {
|
|
486
|
+
const versionConfig = versions[versionId];
|
|
487
|
+
const mergedConfig = {
|
|
488
|
+
...parentConfig,
|
|
489
|
+
...versionConfig,
|
|
490
|
+
};
|
|
491
|
+
await cleanApiDocs(mergedConfig);
|
|
492
|
+
}
|
|
493
|
+
});
|
|
340
494
|
},
|
|
341
495
|
};
|
|
342
496
|
}
|
package/src/markdown/index.ts
CHANGED
|
@@ -59,7 +59,7 @@ export function createInfoPageMD({
|
|
|
59
59
|
}: InfoPageMetadata) {
|
|
60
60
|
return render([
|
|
61
61
|
`import Tabs from "@theme/Tabs";\n`,
|
|
62
|
-
`import TabItem from "@theme/TabItem";\n`,
|
|
62
|
+
`import TabItem from "@theme/TabItem";\n\n`,
|
|
63
63
|
createVersionBadge(version),
|
|
64
64
|
`# ${escape(title)}\n\n`,
|
|
65
65
|
createDescription(description),
|
package/src/options.ts
CHANGED
|
@@ -26,6 +26,27 @@ export const OptionsSchema = Joi.object({
|
|
|
26
26
|
outputDir: Joi.string().required(),
|
|
27
27
|
template: Joi.string(),
|
|
28
28
|
sidebarOptions: sidebarOptions,
|
|
29
|
+
version: Joi.string().when("versions", {
|
|
30
|
+
is: Joi.exist(),
|
|
31
|
+
then: Joi.required(),
|
|
32
|
+
}),
|
|
33
|
+
label: Joi.string().when("versions", {
|
|
34
|
+
is: Joi.exist(),
|
|
35
|
+
then: Joi.required(),
|
|
36
|
+
}),
|
|
37
|
+
baseUrl: Joi.string().when("versions", {
|
|
38
|
+
is: Joi.exist(),
|
|
39
|
+
then: Joi.required(),
|
|
40
|
+
}),
|
|
41
|
+
versions: Joi.object().pattern(
|
|
42
|
+
/^/,
|
|
43
|
+
Joi.object({
|
|
44
|
+
specPath: Joi.string().required(),
|
|
45
|
+
outputDir: Joi.string().required(),
|
|
46
|
+
label: Joi.string().required(),
|
|
47
|
+
baseUrl: Joi.string().required(),
|
|
48
|
+
})
|
|
49
|
+
),
|
|
29
50
|
})
|
|
30
51
|
)
|
|
31
52
|
.required(),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import { render } from "mustache";
|
|
9
|
+
|
|
10
|
+
export function versionSelector(versions: object[]) {
|
|
11
|
+
const template = `<div class="dropdown dropdown--hoverable dropdown--right">
|
|
12
|
+
<button class="button button--block button--sm button--secondary"><span>Select API Version</span></button>
|
|
13
|
+
<ul class="dropdown__menu">
|
|
14
|
+
{{#.}}<li><a class="dropdown__link" href="{{{baseUrl}}}">{{{label}}}</a></li>{{/.}}
|
|
15
|
+
</ul>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
const view = render(template, versions);
|
|
19
|
+
return view;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function versionCrumb(version: string) {
|
|
23
|
+
const template = `<ul style="display: flex;" class="breadcrumbs breadcrumbs--sm">
|
|
24
|
+
<li style="margin-left: auto; margin-right: 0;" class="breadcrumbs__item breadcrumbs__item--active">
|
|
25
|
+
<a class="breadcrumbs__link"><span>{{{.}}}</span></a></li></ul>
|
|
26
|
+
`;
|
|
27
|
+
const view = render(template, version);
|
|
28
|
+
return view;
|
|
29
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -32,6 +32,19 @@ export interface APIOptions {
|
|
|
32
32
|
outputDir: string;
|
|
33
33
|
template?: string;
|
|
34
34
|
sidebarOptions?: SidebarOptions;
|
|
35
|
+
version?: string;
|
|
36
|
+
label?: string;
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
versions?: {
|
|
39
|
+
[key: string]: APIVersionOptions;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface APIVersionOptions {
|
|
44
|
+
specPath: string;
|
|
45
|
+
outputDir: string;
|
|
46
|
+
label: string;
|
|
47
|
+
baseUrl: string;
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
export interface LoadedContent {
|