docusaurus-plugin-openapi-docs 1.0.1 → 1.0.4

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.
Files changed (66) hide show
  1. package/README.md +110 -21
  2. package/lib/index.d.ts +7 -1
  3. package/lib/index.js +257 -22
  4. package/lib/markdown/createAuthentication.d.ts +2 -0
  5. package/lib/markdown/createAuthentication.js +139 -0
  6. package/lib/markdown/createContactInfo.d.ts +2 -0
  7. package/lib/markdown/createContactInfo.js +49 -0
  8. package/lib/markdown/createLicense.d.ts +2 -0
  9. package/lib/markdown/createLicense.js +33 -0
  10. package/lib/markdown/createParamsDetails.js +2 -0
  11. package/lib/markdown/createSchemaDetails.js +6 -1
  12. package/lib/markdown/createStatusCodes.js +1 -1
  13. package/lib/markdown/createTermsOfService.d.ts +1 -0
  14. package/lib/markdown/createTermsOfService.js +32 -0
  15. package/lib/markdown/index.d.ts +3 -2
  16. package/lib/markdown/index.js +17 -3
  17. package/lib/openapi/createExample.js +59 -49
  18. package/lib/openapi/openapi.d.ts +5 -4
  19. package/lib/openapi/openapi.js +94 -50
  20. package/lib/openapi/openapi.test.js +0 -6
  21. package/lib/openapi/types.d.ts +5 -1
  22. package/lib/openapi/utils/loadAndBundleSpec.d.ts +3 -0
  23. package/lib/openapi/utils/loadAndBundleSpec.js +44 -0
  24. package/lib/openapi/utils/types.d.ts +306 -0
  25. package/lib/{markdown/createRequestBodyTable.js → openapi/utils/types.js} +0 -6
  26. package/lib/options.d.ts +0 -2
  27. package/lib/options.js +36 -7
  28. package/lib/sidebars/index.d.ts +2 -1
  29. package/lib/sidebars/index.js +91 -35
  30. package/lib/sidebars/utils.d.ts +2 -0
  31. package/lib/sidebars/utils.js +31 -0
  32. package/lib/types.d.ts +35 -11
  33. package/package.json +10 -9
  34. package/src/index.ts +332 -25
  35. package/src/markdown/createAuthentication.ts +160 -0
  36. package/src/markdown/createContactInfo.ts +52 -0
  37. package/src/markdown/createLicense.ts +34 -0
  38. package/src/markdown/createParamsDetails.ts +2 -0
  39. package/src/markdown/createSchemaDetails.ts +8 -2
  40. package/src/markdown/createStatusCodes.ts +1 -1
  41. package/src/markdown/createTermsOfService.ts +30 -0
  42. package/src/markdown/index.ts +23 -3
  43. package/src/openapi/createExample.ts +59 -50
  44. package/src/openapi/openapi.test.ts +0 -6
  45. package/src/openapi/openapi.ts +115 -53
  46. package/src/openapi/types.ts +5 -1
  47. package/src/openapi/utils/loadAndBundleSpec.ts +62 -0
  48. package/src/openapi/utils/types.ts +303 -0
  49. package/src/options.ts +41 -8
  50. package/src/{markdown/createRequestBodyTable.ts → postman-collection.d.ts} +2 -9
  51. package/src/sidebars/index.ts +116 -36
  52. package/src/sidebars/utils.ts +29 -0
  53. package/src/types.ts +36 -10
  54. package/lib/markdown/createFullWidthTable.d.ts +0 -2
  55. package/lib/markdown/createFullWidthTable.js +0 -18
  56. package/lib/markdown/createParamsTable.d.ts +0 -7
  57. package/lib/markdown/createParamsTable.js +0 -80
  58. package/lib/markdown/createRequestBodyTable.d.ts +0 -6
  59. package/lib/markdown/createSchemaTable.d.ts +0 -14
  60. package/lib/markdown/createSchemaTable.js +0 -217
  61. package/src/markdown/createFullWidthTable.ts +0 -16
  62. package/src/markdown/createParamsTable.ts +0 -102
  63. package/src/markdown/createSchemaTable.ts +0 -275
  64. package/src/openapi/__fixtures__/examples/yogurtstore/_category_.json +0 -4
  65. package/src/openapi/__fixtures__/examples/yogurtstore/froyo.yaml +0 -13
  66. 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,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",
@@ -80,7 +86,7 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
80
86
  specPath: "examples/petstore.yaml", // Path to designated spec file
81
87
  outputDir: "api/petstore", // Output directory for generated .mdx docs
82
88
  sidebarOptions: {
83
- groupPathsBy: "tags",
89
+ groupPathsBy: "tag",
84
90
  },
85
91
  },
86
92
  burgers: {
@@ -97,27 +103,53 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
97
103
 
98
104
  > 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
105
 
100
- ### Plugin Configuration Options
106
+ ## Plugin Configuration Options
107
+
108
+ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following options:
109
+
110
+ | Name | Type | Default | Description |
111
+ | ------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
112
+ | `id` | `string` | `null` | A unique document id. |
113
+ | `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"). |
114
+
115
+ ### config
101
116
 
102
- `docusaurus-plugin-openapi-docs` can be configured with the following options:
117
+ `config` can be configured with the following options:
103
118
 
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
- | `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
109
- | `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
119
+ | Name | Type | Default | Description |
120
+ | ---------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
121
+ | `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
122
+ | `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
123
+ | `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
124
+ | `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
125
+ | `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
126
+ | `version` | `string` | `null` | _Optional:_ Version assigned to single or micro-spec API specified in `specPath`. |
127
+ | `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
128
+ | `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
129
+ | `versions` | `object` | `null` | _Optional:_ Set of options for versioning configuration. See below for a list of supported options. |
110
130
 
111
131
  `sidebarOptions` can be configured with the following options:
112
132
 
113
- | Name | Type | Default | Description |
114
- | -------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
115
- | `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by "tags". |
116
- | `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
117
- | `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
118
- | `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
133
+ | Name | Type | Default | Description |
134
+ | -------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
135
+ | `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by `tag`. |
136
+ | `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). |
137
+ | `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
138
+ | `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
139
+ | `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
119
140
 
120
- > Note: 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`.
141
+ > 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`.
142
+
143
+ `versions` can be configured with the following options:
144
+
145
+ | Name | Type | Default | Description |
146
+ | ---------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
147
+ | `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of micro OpenAPI specification files. |
148
+ | `ouputDir` | `string` | `null` | Desired output path for versioned, generated MDX files. |
149
+ | `label` | `string` | `null` | _Optional:_ Version label used when generating version selector dropdown menu. |
150
+ | `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
151
+
152
+ > All versions will automatically inherit `sidebarOptions` from the parent/base config.
121
153
 
122
154
  ## CLI Usage
123
155
 
@@ -138,9 +170,11 @@ Commands:
138
170
  write-translations [options] [siteDir] Extract required translations of your site.
139
171
  write-heading-ids [options] [siteDir] [files...] Generate heading ids in Markdown content.
140
172
  docs:version <version> Tag a new docs version
141
- gen-api-docs <id> Generates API Docs mdx and sidebars.
142
- clean-api-docs <id> Clears the Generated API Docs mdx and sidebars.
143
- docs:version:openapi <version> Tag a new docs version (openapi)
173
+ gen-api-docs <id> Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).
174
+ gen-api-docs:version <id:version> Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).
175
+ clean-api-docs <id> Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).
176
+ clean-api-docs:version <id:version> Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if
177
+ enabled).
144
178
  ```
145
179
 
146
180
  ### Generating OpenAPI Docs
@@ -189,6 +223,61 @@ yarn docusaurus clean-api-docs burgers
189
223
 
190
224
  > The example above will remove all API docs relative to `burgers`.
191
225
 
226
+ ### Versioning OpenAPI docs
227
+
228
+ To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
229
+
230
+ ```bash
231
+ yarn docusaurus gen-api-docs:version <id>:all
232
+ ```
233
+
234
+ Example:
235
+
236
+ ```bash
237
+ yarn docusaurus gen-api-docs:version petstore:all
238
+ ```
239
+
240
+ > 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.
241
+
242
+ > 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.
243
+
244
+ ## Installing from Template
245
+
246
+ Run the following to bootstrap a Docsaurus v2 site (classic theme) with `docusaurus-openapi-docs`:
247
+
248
+ ```bash
249
+ npx create-docusaurus@2.0.0-beta.21 my-website --package-manager yarn
250
+ ```
251
+
252
+ > When prompted to select a template choose `Git repository`.
253
+
254
+ Template Repository URL:
255
+
256
+ ```bash
257
+ https://github.com/PaloAltoNetworks/docusaurus-template-openapi-docs.git
258
+ ```
259
+
260
+ > When asked how the template repo should be cloned choose "copy" (unless you know better).
261
+
262
+ ```bash
263
+ cd my-website
264
+ yarn
265
+ ```
266
+
267
+ ## Developer Quick Start
268
+
269
+ > Looking to make a contribution? Make sure to checkout out our contributing guide.
270
+
271
+ After [forking](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/fork) the main repository, run the following:
272
+
273
+ ```bash
274
+ git clone https://github.com/<your account>/docusaurus-openapi-docs.git
275
+ cd docusaurus-openapi-docs
276
+ yarn
277
+ yarn build-packages
278
+ yarn watch:demo
279
+ ```
280
+
192
281
  ## Support
193
282
 
194
- Please read [SUPPORT.md](SUPPORT.md) for details on how to get support for this project.
283
+ 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 default function pluginOpenAPI(context: LoadContext, options: PluginOptions): Plugin<LoadedContent>;
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 pluginOpenAPI(context, options) {
21
- let { config } = options;
22
- let { siteDir } = context;
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 = path_1.default.resolve(siteDir, specPath);
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 = 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, // TODO: find a better way to handle null
41
- options, loadedApi);
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}}};`;
@@ -59,7 +103,12 @@ function pluginOpenAPI(context, options) {
59
103
  ? fs_1.default.readFileSync(template).toString()
60
104
  : `---
61
105
  id: {{{id}}}
106
+ {{^api}}
107
+ sidebar_label: Introduction
108
+ {{/api}}
109
+ {{#api}}
62
110
  sidebar_label: {{{title}}}
111
+ {{/api}}
63
112
  {{^api}}
64
113
  sidebar_position: 0
65
114
  {{/api}}
@@ -73,17 +122,69 @@ api: {{{json}}}
73
122
  {{#api.method}}
74
123
  sidebar_class_name: "{{{api.method}}} api-method"
75
124
  {{/api.method}}
125
+ {{#infoPath}}
126
+ info_path: {{{infoPath}}}
127
+ {{/infoPath}}
76
128
  ---
77
129
 
78
130
  {{{markdown}}}
131
+ `;
132
+ const infoMdTemplate = template
133
+ ? fs_1.default.readFileSync(template).toString()
134
+ : `---
135
+ id: {{{id}}}
136
+ sidebar_label: {{{title}}}
137
+ hide_title: true
138
+ ---
139
+
140
+ {{{markdown}}}
141
+
142
+ \`\`\`mdx-code-block
143
+ import DocCardList from '@theme/DocCardList';
144
+ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
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
+
163
+ <DocCardList items={useCurrentSidebarCategory().items}/>
164
+ \`\`\`
79
165
  `;
80
166
  loadedApi.map(async (item) => {
81
- const markdown = item.type === "api" ? (0, markdown_1.createApiPageMD)(item) : (0, markdown_1.createInfoPageMD)(item);
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);
82
172
  item.markdown = markdown;
83
173
  if (item.type === "api") {
84
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;
85
183
  }
86
184
  const view = (0, mustache_1.render)(mdTemplate, item);
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);
87
188
  if (item.type === "api") {
88
189
  if (!fs_1.default.existsSync(`${outputDir}/${item.id}.api.mdx`)) {
89
190
  try {
@@ -97,13 +198,26 @@ sidebar_class_name: "{{{api.method}}} api-method"
97
198
  }
98
199
  // TODO: determine if we actually want/need this
99
200
  if (item.type === "info") {
100
- if (!fs_1.default.existsSync(`${outputDir}/index.api.mdx`)) {
201
+ if (!fs_1.default.existsSync(`${outputDir}/${item.id}.info.mdx`)) {
202
+ try {
203
+ (sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "info" // Only use utils template if set to "info"
204
+ ? fs_1.default.writeFileSync(`${outputDir}/${item.id}.info.mdx`, utils, "utf8")
205
+ : fs_1.default.writeFileSync(`${outputDir}/${item.id}.info.mdx`, view, "utf8");
206
+ console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.info.mdx"`));
207
+ }
208
+ catch (err) {
209
+ console.error(chalk_1.default.red(`Failed to write "${outputDir}/${item.id}.info.mdx"`), chalk_1.default.yellow(err));
210
+ }
211
+ }
212
+ }
213
+ if (item.type === "tag") {
214
+ if (!fs_1.default.existsSync(`${outputDir}/${item.id}.tag.mdx`)) {
101
215
  try {
102
- fs_1.default.writeFileSync(`${outputDir}/index.api.mdx`, view, "utf8");
103
- console.log(chalk_1.default.green(`Successfully created "${outputDir}/index.api.mdx"`));
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"`));
104
218
  }
105
219
  catch (err) {
106
- console.error(chalk_1.default.red(`Failed to write "${outputDir}/index.api.mdx"`), chalk_1.default.yellow(err));
220
+ console.error(chalk_1.default.red(`Failed to write "${outputDir}/${item.id}.tag.mdx"`), chalk_1.default.yellow(err));
107
221
  }
108
222
  }
109
223
  }
@@ -119,11 +233,13 @@ sidebar_class_name: "{{{api.method}}} api-method"
119
233
  async function cleanApiDocs(options) {
120
234
  const { outputDir } = options;
121
235
  const apiDir = path_1.default.join(siteDir, outputDir);
122
- const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx"], {
236
+ const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
123
237
  cwd: path_1.default.resolve(apiDir),
238
+ deep: 1,
124
239
  });
125
240
  const sidebarFile = await (0, utils_1.Globby)(["sidebar.js"], {
126
241
  cwd: path_1.default.resolve(apiDir),
242
+ deep: 1,
127
243
  });
128
244
  apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
129
245
  if (err) {
@@ -142,18 +258,48 @@ sidebar_class_name: "{{{api.method}}} api-method"
142
258
  }
143
259
  }));
144
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
+ }
145
291
  return {
146
- name: `docusaurus-plugin-openapi`,
292
+ name: `docusaurus-plugin-openapi-docs`,
147
293
  extendCli(cli) {
148
294
  cli
149
295
  .command(`gen-api-docs`)
150
- .description(`Generates API Docs mdx and sidebars.`)
151
- .usage("[options] <id key value in plugin config within docusaurus.config.js>")
296
+ .description(`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`)
297
+ .usage("<id>")
152
298
  .arguments("<id>")
153
299
  .action(async (id) => {
154
300
  if (id === "all") {
155
301
  if (config[id]) {
156
- console.error(chalk_1.default.red("Can't use id 'all' for API Doc."));
302
+ console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
157
303
  }
158
304
  else {
159
305
  Object.keys(config).forEach(async function (key) {
@@ -162,21 +308,71 @@ sidebar_class_name: "{{{api.method}}} api-method"
162
308
  }
163
309
  }
164
310
  else if (!config[id]) {
165
- console.error(chalk_1.default.red(`ID ${id} does not exist in openapi-plugin config`));
311
+ console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
166
312
  }
167
313
  else {
168
314
  await generateApiDocs(config[id]);
169
315
  }
170
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
+ });
171
367
  cli
172
368
  .command(`clean-api-docs`)
173
- .description(`Clears the Generated API Docs mdx and sidebars.`)
174
- .usage("[options] <id key value in plugin config within docusaurus.config.js>")
369
+ .description(`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`)
370
+ .usage("<id>")
175
371
  .arguments("<id>")
176
372
  .action(async (id) => {
177
373
  if (id === "all") {
178
374
  if (config[id]) {
179
- console.error(chalk_1.default.red("Can't use id 'all' for API Doc."));
375
+ console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
180
376
  }
181
377
  else {
182
378
  Object.keys(config).forEach(async function (key) {
@@ -188,7 +384,46 @@ sidebar_class_name: "{{{api.method}}} api-method"
188
384
  await cleanApiDocs(config[id]);
189
385
  }
190
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
+ });
191
422
  },
192
423
  };
193
424
  }
194
- exports.default = pluginOpenAPI;
425
+ exports.default = pluginOpenAPIDocs;
426
+ pluginOpenAPIDocs.validateOptions = ({ options, validate }) => {
427
+ const validatedOptions = validate(options_1.OptionsSchema, options);
428
+ return validatedOptions;
429
+ };
@@ -0,0 +1,2 @@
1
+ import { SecuritySchemeObject } from "../openapi/types";
2
+ export declare function createAuthentication(securitySchemes: SecuritySchemeObject): string;