docusaurus-plugin-openapi-docs 4.5.0 → 4.6.0
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 +87 -22
- package/lib/index.js +80 -48
- package/lib/markdown/createHeading.js +1 -1
- package/lib/markdown/createRequestHeader.js +5 -3
- package/lib/markdown/createSchema.js +2 -2
- package/lib/markdown/index.js +3 -2
- package/lib/openapi/createSchemaExample.js +16 -2
- package/lib/openapi/createSchemaExample.test.d.ts +1 -0
- package/lib/openapi/createSchemaExample.test.js +48 -0
- package/lib/openapi/openapi.js +38 -17
- package/lib/openapi/openapi.test.js +48 -0
- package/lib/openapi/webhooks.test.d.ts +1 -0
- package/lib/openapi/webhooks.test.js +23 -0
- package/lib/options.js +3 -0
- package/lib/sidebars/index.js +12 -3
- package/lib/types.d.ts +5 -2
- package/package.json +16 -16
- package/src/index.ts +104 -60
- package/src/markdown/createHeading.ts +2 -2
- package/src/markdown/createRequestHeader.ts +9 -11
- package/src/markdown/createSchema.ts +4 -2
- package/src/markdown/index.ts +3 -2
- package/src/openapi/__fixtures__/webhook/openapi.yaml +17 -0
- package/src/openapi/createSchemaExample.test.ts +57 -0
- package/src/openapi/createSchemaExample.ts +26 -2
- package/src/openapi/openapi.test.ts +58 -0
- package/src/openapi/openapi.ts +35 -6
- package/src/openapi/webhooks.test.ts +30 -0
- package/src/options.ts +3 -0
- package/src/plugin-openapi.d.ts +1 -1
- package/src/sidebars/index.ts +15 -3
- package/src/types.ts +5 -2
- package/src/plugin-content-docs-types.d.ts +0 -42
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ OpenAPI plugin for generating API reference docs in Docusaurus v3.
|
|
|
11
11
|
<img src="https://img.shields.io/badge/dynamic/json?style=for-the-badge&logo=meta&color=blueviolet&label=Docusaurus&query=dependencies%5B%22%40docusaurus%2Fcore%22%5D&url=https%3A%2F%2Fraw.githubusercontent.com%2FPaloAltoNetworks%2Fdocusaurus-openapi-docs%2Fmain%2Fdemo%2Fpackage.json" />
|
|
12
12
|
<br/><br/>
|
|
13
13
|
|
|
14
|
-
[](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/HEAD/LICENSE) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs)
|
|
14
|
+
[](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/HEAD/LICENSE) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs)
|
|
15
15
|
<br/>
|
|
16
16
|
[](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/actions/workflows/validate.yaml) [](https://github.com/prettier/prettier) [](https://www.cypress.io/) [](https://github.com/facebook/jest) [](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/HEAD/CONTRIBUTING.md#pull-requests)
|
|
17
17
|
<br />
|
|
@@ -41,7 +41,7 @@ Key Features:
|
|
|
41
41
|
|
|
42
42
|
| Docusaurus OpenAPI Docs | Docusaurus |
|
|
43
43
|
| ----------------------- | --------------- |
|
|
44
|
-
| 4.
|
|
44
|
+
| 4.x.x (current) | `3.5.0 - 3.9.2` |
|
|
45
45
|
| 3.0.x (end-of-support) | `3.0.1 - 3.4.0` |
|
|
46
46
|
| 2.2.3 (legacy) | `2.4.1 - 2.4.3` |
|
|
47
47
|
| 1.7.3 (end-of-support) | `2.0.1 - 2.2.0` |
|
|
@@ -51,7 +51,7 @@ Key Features:
|
|
|
51
51
|
Run the following to bootstrap a Docusaurus v3 site (classic theme) with `docusaurus-openapi-docs`:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
npx create-docusaurus@3.
|
|
54
|
+
npx create-docusaurus@3.9.2 my-website --package-manager yarn
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
> When prompted to select a template choose `Git repository`.
|
|
@@ -127,6 +127,7 @@ import type * as OpenApiPlugin from "docusaurus-plugin-openapi-docs";
|
|
|
127
127
|
petstore: {
|
|
128
128
|
specPath: "examples/petstore.yaml",
|
|
129
129
|
outputDir: "docs/petstore",
|
|
130
|
+
maskCredentials: false, // Disable credential masking in code snippets
|
|
130
131
|
sidebarOptions: {
|
|
131
132
|
groupPathsBy: "tag",
|
|
132
133
|
},
|
|
@@ -155,25 +156,28 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
155
156
|
|
|
156
157
|
`config` can be configured with the following options:
|
|
157
158
|
|
|
158
|
-
| Name | Type | Default | Description
|
|
159
|
-
| -------------------- | --------- | ------- |
|
|
160
|
-
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files.
|
|
161
|
-
| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files.
|
|
162
|
-
| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser.
|
|
163
|
-
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template.
|
|
164
|
-
| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only.
|
|
165
|
-
| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only.
|
|
166
|
-
| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only.
|
|
167
|
-
| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc)
|
|
168
|
-
| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel.
|
|
169
|
-
| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions.
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
159
|
+
| Name | Type | Default | Description |
|
|
160
|
+
| -------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
+
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
|
|
162
|
+
| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. |
|
|
163
|
+
| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. |
|
|
164
|
+
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
|
|
165
|
+
| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. |
|
|
166
|
+
| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. |
|
|
167
|
+
| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. |
|
|
168
|
+
| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) |
|
|
169
|
+
| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. |
|
|
170
|
+
| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. |
|
|
171
|
+
| `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security. |
|
|
172
|
+
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
|
|
173
|
+
| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. |
|
|
174
|
+
| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. |
|
|
175
|
+
| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. |
|
|
176
|
+
| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. |
|
|
177
|
+
| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. |
|
|
178
|
+
| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. |
|
|
179
|
+
| `showInfoPage` | `boolean` | `true` | _Optional:_ If set to `false`, disables generation of the info page (overview page with API title and description). |
|
|
180
|
+
| `schemasOnly` | `boolean` | `false` | _Optional:_ If set to `true`, generates only schema pages (no API endpoint pages). Also available as `--schemas-only` CLI flag. |
|
|
177
181
|
|
|
178
182
|
### sidebarOptions
|
|
179
183
|
|
|
@@ -222,6 +226,49 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
222
226
|
| --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
223
227
|
| `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.<br/><br/>**Function type:** `(item: ApiPageMetadata \| SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` |
|
|
224
228
|
|
|
229
|
+
## Theme Configuration Options
|
|
230
|
+
|
|
231
|
+
The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`:
|
|
232
|
+
|
|
233
|
+
| Name | Type | Default | Description |
|
|
234
|
+
| ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| `proxy` | `string` | `null` | _Optional:_ Site-wide proxy URL to prepend to base URL when performing API requests. Can be overridden per-spec via plugin config. |
|
|
236
|
+
| `authPersistance` | `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. |
|
|
237
|
+
| `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. |
|
|
238
|
+
|
|
239
|
+
Example:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
// docusaurus.config.ts
|
|
243
|
+
{
|
|
244
|
+
themeConfig: {
|
|
245
|
+
api: {
|
|
246
|
+
proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config)
|
|
247
|
+
authPersistance: "localStorage",
|
|
248
|
+
requestTimeout: 60000, // 60 seconds
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Supported Vendor Extensions
|
|
255
|
+
|
|
256
|
+
The plugin extracts a number of vendor extensions from the OpenAPI spec to enrich the generated docs. The theme renders some of these values as part of the UI.
|
|
257
|
+
|
|
258
|
+
| Extension | Purpose |
|
|
259
|
+
| ------------------------------------------ | --------------------------------------------------------------------- |
|
|
260
|
+
| `x-codeSamples` | Operation level code snippets displayed in the API Explorer. |
|
|
261
|
+
| `x-tagGroups` | Groups tags in the sidebar navigation. |
|
|
262
|
+
| `x-tags` | Assigns tags to schema objects so they appear with tagged operations. |
|
|
263
|
+
| `x-position` | Controls ordering of items in the sidebar. |
|
|
264
|
+
| `x-logo` / `x-dark-logo` | Provides logos for light and dark themes on the intro page. |
|
|
265
|
+
| `x-deprecated-description` | Custom text shown for deprecated operations. |
|
|
266
|
+
| `x-webhooks` | Defines webhook events. |
|
|
267
|
+
| `x-displayName` | Overrides tag display names. |
|
|
268
|
+
| `x-enumDescription` / `x-enumDescriptions` | Documents enum values. |
|
|
269
|
+
|
|
270
|
+
Other ReDoc specific extensions such as `x-circular-ref`, `x-code-samples` (deprecated), `x-examples`, `x-ignoredHeaderParameters`, `x-nullable`, `x-servers`, `x-traitTag`, `x-additionalPropertiesName`, and `x-explicitMappingOnly` are ignored when extracting custom data.
|
|
271
|
+
|
|
225
272
|
## CLI Usage
|
|
226
273
|
|
|
227
274
|
```bash
|
|
@@ -283,6 +330,16 @@ yarn docusaurus gen-api-docs all --all-versions
|
|
|
283
330
|
|
|
284
331
|
> This will generate API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
|
|
285
332
|
|
|
333
|
+
To generate only schema MDX files—without updating the sidebar or requiring `showSchemas` in your plugin config—use the `--schemas-only` flag:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
yarn docusaurus gen-api-docs petstore --schemas-only
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
> This command writes the schema pages to the configured output directory while leaving other generated docs untouched.
|
|
340
|
+
|
|
341
|
+
The `--schemas-only` flag is also available for `gen-api-docs:version`.
|
|
342
|
+
|
|
286
343
|
### Cleaning API Docs
|
|
287
344
|
|
|
288
345
|
To clean/remove all API Docs, run the following command from the root directory of your project:
|
|
@@ -315,6 +372,14 @@ yarn docusaurus clean-api-docs all --all-versions
|
|
|
315
372
|
|
|
316
373
|
> This will clean API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
|
|
317
374
|
|
|
375
|
+
To clean only schema docs while leaving API, info, and tag docs untouched, use the `--schemas-only` flag:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
yarn docusaurus clean-api-docs petstore --schemas-only
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
> The `--schemas-only` flag is also available for `clean-api-docs:version`.
|
|
382
|
+
|
|
318
383
|
### Versioning OpenAPI docs
|
|
319
384
|
|
|
320
385
|
To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
|
package/lib/index.js
CHANGED
|
@@ -78,7 +78,8 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
78
78
|
let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
|
|
79
79
|
async function generateApiDocs(options, pluginId) {
|
|
80
80
|
var _a, _b, _c, _d;
|
|
81
|
-
let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, disableCompression, } = options;
|
|
81
|
+
let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, schemasOnly, disableCompression, } = options;
|
|
82
|
+
const isSchemasOnly = schemasOnly === true;
|
|
82
83
|
// Remove trailing slash before proceeding
|
|
83
84
|
outputDir = outputDir.replace(/\/$/, "");
|
|
84
85
|
// Override docPath if pluginId provided
|
|
@@ -103,7 +104,7 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
// TODO: figure out better way to set default
|
|
106
|
-
if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
107
|
+
if (!isSchemasOnly && Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
107
108
|
const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath, tagGroups);
|
|
108
109
|
let sidebarSliceTemplate = `import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";\n\n`;
|
|
109
110
|
sidebarSliceTemplate += `const sidebar: SidebarsConfig = {{{slice}}};\n\n`;
|
|
@@ -159,6 +160,9 @@ hide_send_button: true
|
|
|
159
160
|
{{#frontMatter.show_extensions}}
|
|
160
161
|
show_extensions: true
|
|
161
162
|
{{/frontMatter.show_extensions}}
|
|
163
|
+
{{#frontMatter.mask_credentials_disabled}}
|
|
164
|
+
mask_credentials: false
|
|
165
|
+
{{/frontMatter.mask_credentials_disabled}}
|
|
162
166
|
---
|
|
163
167
|
|
|
164
168
|
{{{markdown}}}
|
|
@@ -230,11 +234,15 @@ custom_edit_url: null
|
|
|
230
234
|
schema: schemaPageGenerator,
|
|
231
235
|
};
|
|
232
236
|
loadedApi.map(async (item) => {
|
|
237
|
+
var _a, _b;
|
|
233
238
|
if (downloadUrl) {
|
|
234
239
|
item.downloadUrl = downloadUrl;
|
|
235
240
|
}
|
|
236
241
|
const markdown = pageGeneratorByType[item.type](item);
|
|
237
242
|
item.markdown = markdown;
|
|
243
|
+
if (isSchemasOnly && item.type !== "schema") {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
238
246
|
if (item.type === "api") {
|
|
239
247
|
// opportunity to compress JSON
|
|
240
248
|
// const serialize = (o: any) => {
|
|
@@ -250,9 +258,14 @@ custom_edit_url: null
|
|
|
250
258
|
.toString("base64"));
|
|
251
259
|
let infoBasePath = `${outputDir}/${item.infoId}`;
|
|
252
260
|
if (docRouteBasePath) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
.replace(/^\/+/g, "")
|
|
261
|
+
// Safely extract path segment, handling cases where docPath may not be in outputDir
|
|
262
|
+
const outputSegment = docPath && outputDir.includes(docPath)
|
|
263
|
+
? ((_b = (_a = outputDir.split(docPath)[1]) === null || _a === void 0 ? void 0 : _a.replace(/^\/+/g, "")) !== null && _b !== void 0 ? _b : "")
|
|
264
|
+
: outputDir
|
|
265
|
+
.slice(outputDir.indexOf("/", 1))
|
|
266
|
+
.replace(/^\/+/g, "");
|
|
267
|
+
infoBasePath =
|
|
268
|
+
`${docRouteBasePath}/${outputSegment}/${item.infoId}`.replace(/^\/+/g, "");
|
|
256
269
|
}
|
|
257
270
|
if (item.infoId)
|
|
258
271
|
item.infoPath = infoBasePath;
|
|
@@ -335,25 +348,36 @@ custom_edit_url: null
|
|
|
335
348
|
throw e;
|
|
336
349
|
}
|
|
337
350
|
}
|
|
338
|
-
async function cleanApiDocs(options) {
|
|
351
|
+
async function cleanApiDocs(options, schemasOnly = false) {
|
|
339
352
|
const { outputDir } = options;
|
|
340
353
|
const apiDir = (0, utils_1.posixPath)(path_1.default.join(siteDir, outputDir));
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
354
|
+
// When schemasOnly is true, only clean the schemas directory
|
|
355
|
+
if (!schemasOnly) {
|
|
356
|
+
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
|
|
357
|
+
cwd: path_1.default.resolve(apiDir),
|
|
358
|
+
deep: 1,
|
|
359
|
+
});
|
|
360
|
+
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js", "sidebar.ts"], {
|
|
361
|
+
cwd: path_1.default.resolve(apiDir),
|
|
362
|
+
deep: 1,
|
|
363
|
+
});
|
|
364
|
+
apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
365
|
+
if (err) {
|
|
366
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${mdx}"`), chalk_1.default.yellow(err));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
|
|
370
|
+
}
|
|
371
|
+
}));
|
|
372
|
+
sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
373
|
+
if (err) {
|
|
374
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`));
|
|
378
|
+
}
|
|
379
|
+
}));
|
|
380
|
+
}
|
|
357
381
|
try {
|
|
358
382
|
fs_1.default.rmSync(`${apiDir}/schemas`, { recursive: true });
|
|
359
383
|
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/schemas"`));
|
|
@@ -363,14 +387,6 @@ custom_edit_url: null
|
|
|
363
387
|
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/schemas"`), chalk_1.default.yellow(err));
|
|
364
388
|
}
|
|
365
389
|
}
|
|
366
|
-
sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
367
|
-
if (err) {
|
|
368
|
-
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`));
|
|
372
|
-
}
|
|
373
|
-
}));
|
|
374
390
|
}
|
|
375
391
|
async function generateVersions(versions, outputDir) {
|
|
376
392
|
let versionsArray = [];
|
|
@@ -442,19 +458,21 @@ custom_edit_url: null
|
|
|
442
458
|
});
|
|
443
459
|
}
|
|
444
460
|
}
|
|
445
|
-
async function cleanAllVersions(options) {
|
|
461
|
+
async function cleanAllVersions(options, schemasOnly = false) {
|
|
446
462
|
const parentOptions = Object.assign({}, options);
|
|
447
463
|
const { versions } = parentOptions;
|
|
448
464
|
delete parentOptions.versions;
|
|
449
465
|
if (versions != null && Object.keys(versions).length > 0) {
|
|
450
|
-
|
|
466
|
+
if (!schemasOnly) {
|
|
467
|
+
await cleanVersions(parentOptions.outputDir);
|
|
468
|
+
}
|
|
451
469
|
Object.keys(versions).forEach(async (key) => {
|
|
452
470
|
const versionOptions = versions[key];
|
|
453
471
|
const mergedOptions = {
|
|
454
472
|
...parentOptions,
|
|
455
473
|
...versionOptions,
|
|
456
474
|
};
|
|
457
|
-
await cleanApiDocs(mergedOptions);
|
|
475
|
+
await cleanApiDocs(mergedOptions, schemasOnly);
|
|
458
476
|
});
|
|
459
477
|
}
|
|
460
478
|
}
|
|
@@ -468,11 +486,13 @@ custom_edit_url: null
|
|
|
468
486
|
.arguments("<id>")
|
|
469
487
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
470
488
|
.option("--all-versions", "Generate all versions.")
|
|
489
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
471
490
|
.action(async (id, instance) => {
|
|
472
491
|
var _a;
|
|
473
492
|
const options = instance.opts();
|
|
474
493
|
const pluginId = options.pluginId;
|
|
475
494
|
const allVersions = options.allVersions;
|
|
495
|
+
const schemasOnly = options.schemasOnly;
|
|
476
496
|
const pluginInstances = getPluginInstances(plugins);
|
|
477
497
|
let targetConfig;
|
|
478
498
|
let targetDocsPluginId;
|
|
@@ -494,15 +514,17 @@ custom_edit_url: null
|
|
|
494
514
|
}
|
|
495
515
|
targetConfig = config;
|
|
496
516
|
}
|
|
517
|
+
const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
497
518
|
if (id === "all") {
|
|
498
519
|
if (targetConfig[id]) {
|
|
499
520
|
console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
|
|
500
521
|
}
|
|
501
522
|
else {
|
|
502
523
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
503
|
-
|
|
524
|
+
const apiOptions = withSchemaOverride(targetConfig[key]);
|
|
525
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
504
526
|
if (allVersions) {
|
|
505
|
-
await generateAllVersions(
|
|
527
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
506
528
|
}
|
|
507
529
|
});
|
|
508
530
|
}
|
|
@@ -511,9 +533,10 @@ custom_edit_url: null
|
|
|
511
533
|
console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
|
|
512
534
|
}
|
|
513
535
|
else {
|
|
514
|
-
|
|
536
|
+
const apiOptions = withSchemaOverride(targetConfig[id]);
|
|
537
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
515
538
|
if (allVersions) {
|
|
516
|
-
await generateAllVersions(
|
|
539
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
517
540
|
}
|
|
518
541
|
}
|
|
519
542
|
});
|
|
@@ -523,10 +546,12 @@ custom_edit_url: null
|
|
|
523
546
|
.usage("<id:version>")
|
|
524
547
|
.arguments("<id:version>")
|
|
525
548
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
549
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
526
550
|
.action(async (id, instance) => {
|
|
527
551
|
var _a;
|
|
528
552
|
const options = instance.opts();
|
|
529
553
|
const pluginId = options.pluginId;
|
|
554
|
+
const schemasOnly = options.schemasOnly;
|
|
530
555
|
const pluginInstances = getPluginInstances(plugins);
|
|
531
556
|
let targetConfig;
|
|
532
557
|
let targetDocsPluginId;
|
|
@@ -550,6 +575,7 @@ custom_edit_url: null
|
|
|
550
575
|
}
|
|
551
576
|
const [parentId, versionId] = id.split(":");
|
|
552
577
|
const parentConfig = Object.assign({}, targetConfig[parentId]);
|
|
578
|
+
const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
553
579
|
const version = parentConfig.version;
|
|
554
580
|
const label = parentConfig.label;
|
|
555
581
|
const baseUrl = parentConfig.baseUrl;
|
|
@@ -572,10 +598,10 @@ custom_edit_url: null
|
|
|
572
598
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
573
599
|
Object.keys(versions).forEach(async (key) => {
|
|
574
600
|
const versionConfig = versions[key];
|
|
575
|
-
const mergedConfig = {
|
|
601
|
+
const mergedConfig = withSchemaOverride({
|
|
576
602
|
...parentConfig,
|
|
577
603
|
...versionConfig,
|
|
578
|
-
};
|
|
604
|
+
});
|
|
579
605
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
580
606
|
});
|
|
581
607
|
}
|
|
@@ -585,10 +611,10 @@ custom_edit_url: null
|
|
|
585
611
|
}
|
|
586
612
|
else {
|
|
587
613
|
const versionConfig = versions[versionId];
|
|
588
|
-
const mergedConfig = {
|
|
614
|
+
const mergedConfig = withSchemaOverride({
|
|
589
615
|
...parentConfig,
|
|
590
616
|
...versionConfig,
|
|
591
|
-
};
|
|
617
|
+
});
|
|
592
618
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
593
619
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
594
620
|
}
|
|
@@ -600,11 +626,13 @@ custom_edit_url: null
|
|
|
600
626
|
.arguments("<id>")
|
|
601
627
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
602
628
|
.option("--all-versions", "Clean all versions.")
|
|
629
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
603
630
|
.action(async (id, instance) => {
|
|
604
631
|
var _a;
|
|
605
632
|
const options = instance.opts();
|
|
606
633
|
const pluginId = options.pluginId;
|
|
607
634
|
const allVersions = options.allVersions;
|
|
635
|
+
const schemasOnly = options.schemasOnly;
|
|
608
636
|
const pluginInstances = getPluginInstances(plugins);
|
|
609
637
|
let targetConfig;
|
|
610
638
|
if (pluginId) {
|
|
@@ -630,17 +658,17 @@ custom_edit_url: null
|
|
|
630
658
|
}
|
|
631
659
|
else {
|
|
632
660
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
633
|
-
await cleanApiDocs(targetConfig[key]);
|
|
661
|
+
await cleanApiDocs(targetConfig[key], schemasOnly);
|
|
634
662
|
if (allVersions) {
|
|
635
|
-
await cleanAllVersions(targetConfig[key]);
|
|
663
|
+
await cleanAllVersions(targetConfig[key], schemasOnly);
|
|
636
664
|
}
|
|
637
665
|
});
|
|
638
666
|
}
|
|
639
667
|
}
|
|
640
668
|
else {
|
|
641
|
-
await cleanApiDocs(targetConfig[id]);
|
|
669
|
+
await cleanApiDocs(targetConfig[id], schemasOnly);
|
|
642
670
|
if (allVersions) {
|
|
643
|
-
await cleanAllVersions(targetConfig[id]);
|
|
671
|
+
await cleanAllVersions(targetConfig[id], schemasOnly);
|
|
644
672
|
}
|
|
645
673
|
}
|
|
646
674
|
});
|
|
@@ -650,10 +678,12 @@ custom_edit_url: null
|
|
|
650
678
|
.usage("<id:version>")
|
|
651
679
|
.arguments("<id:version>")
|
|
652
680
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
681
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
653
682
|
.action(async (id, instance) => {
|
|
654
683
|
var _a;
|
|
655
684
|
const options = instance.opts();
|
|
656
685
|
const pluginId = options.pluginId;
|
|
686
|
+
const schemasOnly = options.schemasOnly;
|
|
657
687
|
const pluginInstances = getPluginInstances(plugins);
|
|
658
688
|
let targetConfig;
|
|
659
689
|
if (pluginId) {
|
|
@@ -682,14 +712,16 @@ custom_edit_url: null
|
|
|
682
712
|
chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key.");
|
|
683
713
|
}
|
|
684
714
|
else {
|
|
685
|
-
|
|
715
|
+
if (!schemasOnly) {
|
|
716
|
+
await cleanVersions(parentConfig.outputDir);
|
|
717
|
+
}
|
|
686
718
|
Object.keys(versions).forEach(async (key) => {
|
|
687
719
|
const versionConfig = versions[key];
|
|
688
720
|
const mergedConfig = {
|
|
689
721
|
...parentConfig,
|
|
690
722
|
...versionConfig,
|
|
691
723
|
};
|
|
692
|
-
await cleanApiDocs(mergedConfig);
|
|
724
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
693
725
|
});
|
|
694
726
|
}
|
|
695
727
|
}
|
|
@@ -699,7 +731,7 @@ custom_edit_url: null
|
|
|
699
731
|
...parentConfig,
|
|
700
732
|
...versionConfig,
|
|
701
733
|
};
|
|
702
|
-
await cleanApiDocs(mergedConfig);
|
|
734
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
703
735
|
}
|
|
704
736
|
});
|
|
705
737
|
},
|
|
@@ -11,11 +11,13 @@ const utils_1 = require("./utils");
|
|
|
11
11
|
function createRequestHeader(header) {
|
|
12
12
|
return [
|
|
13
13
|
(0, utils_1.create)("Heading", {
|
|
14
|
-
children: header,
|
|
15
14
|
id: header.replace(" ", "-").toLowerCase(),
|
|
16
15
|
as: "h2",
|
|
17
16
|
className: "openapi-tabs__heading",
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
children: [
|
|
18
|
+
`<Translate id="theme.openapi.request.title">${header}</Translate>`,
|
|
19
|
+
],
|
|
20
|
+
}),
|
|
21
|
+
"\n\n",
|
|
20
22
|
];
|
|
21
23
|
}
|
|
@@ -316,7 +316,7 @@ function createDetailsNode(name, schemaName, schema, required, nullable) {
|
|
|
316
316
|
: required === true, () => [
|
|
317
317
|
(0, utils_1.create)("span", {
|
|
318
318
|
className: "openapi-schema__required",
|
|
319
|
-
children: "required",
|
|
319
|
+
children: "<Translate id='theme.openapi.schemaItem.required'>required</Translate>",
|
|
320
320
|
}),
|
|
321
321
|
]),
|
|
322
322
|
(0, utils_1.guard)(schema.deprecated, () => [
|
|
@@ -454,7 +454,7 @@ function createPropertyDiscriminator(name, schemaName, schema, discriminator, re
|
|
|
454
454
|
(0, utils_1.guard)(required, () => [
|
|
455
455
|
(0, utils_1.create)("span", {
|
|
456
456
|
className: "openapi-schema__required",
|
|
457
|
-
children: "required",
|
|
457
|
+
children: "<Translate id='theme.openapi.schemaItem.required'>required</Translate>",
|
|
458
458
|
}),
|
|
459
459
|
]),
|
|
460
460
|
],
|
package/lib/markdown/index.js
CHANGED
|
@@ -37,7 +37,8 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
|
|
|
37
37
|
`import StatusCodes from "@theme/StatusCodes";\n`,
|
|
38
38
|
`import OperationTabs from "@theme/OperationTabs";\n`,
|
|
39
39
|
`import TabItem from "@theme/TabItem";\n`,
|
|
40
|
-
`import Heading from "@theme/Heading";\n
|
|
40
|
+
`import Heading from "@theme/Heading";\n`,
|
|
41
|
+
`import Translate from "@docusaurus/Translate";\n\n`,
|
|
41
42
|
(0, createHeading_1.createHeading)(title),
|
|
42
43
|
(0, createMethodEndpoint_1.createMethodEndpoint)(method, path),
|
|
43
44
|
infoPath && (0, createAuthorization_1.createAuthorization)(infoPath),
|
|
@@ -82,7 +83,7 @@ function createSchemaPageMD({ schema }) {
|
|
|
82
83
|
return (0, utils_1.render)([
|
|
83
84
|
`import Schema from "@theme/Schema";\n`,
|
|
84
85
|
`import Heading from "@theme/Heading";\n\n`,
|
|
85
|
-
(0, createHeading_1.createHeading)(title
|
|
86
|
+
(0, createHeading_1.createHeading)(title),
|
|
86
87
|
(0, createDescription_1.createDescription)(description),
|
|
87
88
|
(0, utils_1.create)("Schema", {
|
|
88
89
|
schema: schema,
|
|
@@ -58,7 +58,14 @@ function sampleFromProp(name, prop, obj, context) {
|
|
|
58
58
|
return obj;
|
|
59
59
|
}
|
|
60
60
|
// TODO: handle discriminators
|
|
61
|
-
|
|
61
|
+
// Check for explicit example/examples first (OAS 3.1 support)
|
|
62
|
+
if (prop.example !== undefined) {
|
|
63
|
+
obj[name] = prop.example;
|
|
64
|
+
}
|
|
65
|
+
else if (prop.examples !== undefined && prop.examples.length > 0) {
|
|
66
|
+
obj[name] = prop.examples[0];
|
|
67
|
+
}
|
|
68
|
+
else if (prop.oneOf) {
|
|
62
69
|
obj[name] = (0, exports.sampleFromSchema)(prop.oneOf[0], context);
|
|
63
70
|
}
|
|
64
71
|
else if (prop.anyOf) {
|
|
@@ -77,10 +84,14 @@ const sampleFromSchema = (schema = {}, context) => {
|
|
|
77
84
|
try {
|
|
78
85
|
// deep copy schema before processing
|
|
79
86
|
let schemaCopy = JSON.parse(JSON.stringify(schema));
|
|
80
|
-
let { type, example, allOf, properties, items, oneOf, anyOf } = schemaCopy;
|
|
87
|
+
let { type, example, examples, allOf, properties, items, oneOf, anyOf, const: constant, } = schemaCopy;
|
|
81
88
|
if (example !== undefined) {
|
|
82
89
|
return example;
|
|
83
90
|
}
|
|
91
|
+
// OAS 3.1 / JSON Schema: examples is an array
|
|
92
|
+
if (examples !== undefined && examples.length > 0) {
|
|
93
|
+
return examples[0];
|
|
94
|
+
}
|
|
84
95
|
if (oneOf) {
|
|
85
96
|
if (properties) {
|
|
86
97
|
const combinedSchemas = (0, merge_1.default)(schemaCopy, oneOf[0]);
|
|
@@ -169,6 +180,9 @@ const sampleFromSchema = (schema = {}, context) => {
|
|
|
169
180
|
if (shouldExcludeProperty(schemaCopy, context)) {
|
|
170
181
|
return undefined;
|
|
171
182
|
}
|
|
183
|
+
if (constant) {
|
|
184
|
+
return constant;
|
|
185
|
+
}
|
|
172
186
|
return primitive(schemaCopy);
|
|
173
187
|
}
|
|
174
188
|
catch (err) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|