docusaurus-plugin-openapi-docs 4.5.1 → 4.7.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.
Files changed (39) hide show
  1. package/README.md +110 -22
  2. package/lib/index.js +122 -50
  3. package/lib/markdown/createHeading.js +1 -1
  4. package/lib/markdown/createRequestHeader.js +5 -3
  5. package/lib/markdown/createSchema.js +2 -2
  6. package/lib/markdown/index.js +3 -2
  7. package/lib/markdown/schema.js +5 -0
  8. package/lib/markdown/utils.d.ts +38 -1
  9. package/lib/markdown/utils.js +100 -2
  10. package/lib/openapi/createSchemaExample.js +16 -2
  11. package/lib/openapi/createSchemaExample.test.d.ts +1 -0
  12. package/lib/openapi/createSchemaExample.test.js +48 -0
  13. package/lib/openapi/openapi.js +38 -17
  14. package/lib/openapi/openapi.test.js +48 -0
  15. package/lib/openapi/webhooks.test.d.ts +1 -0
  16. package/lib/openapi/webhooks.test.js +23 -0
  17. package/lib/options.js +4 -0
  18. package/lib/sidebars/index.js +12 -3
  19. package/package.json +16 -16
  20. package/src/index.ts +165 -62
  21. package/src/markdown/createHeading.ts +2 -2
  22. package/src/markdown/createRequestHeader.ts +9 -11
  23. package/src/markdown/createSchema.ts +4 -2
  24. package/src/markdown/index.ts +3 -2
  25. package/src/markdown/schema.ts +6 -0
  26. package/src/markdown/utils.ts +153 -3
  27. package/src/openapi/__fixtures__/webhook/openapi.yaml +17 -0
  28. package/src/openapi/createSchemaExample.test.ts +57 -0
  29. package/src/openapi/createSchemaExample.ts +26 -2
  30. package/src/openapi/openapi.test.ts +58 -0
  31. package/src/openapi/openapi.ts +35 -6
  32. package/src/openapi/webhooks.test.ts +30 -0
  33. package/src/options.ts +4 -0
  34. package/src/plugin-openapi.d.ts +1 -1
  35. package/src/sidebars/index.ts +15 -3
  36. package/src/{types.ts → types.d.ts} +12 -2
  37. package/lib/types.d.ts +0 -135
  38. package/lib/types.js +0 -8
  39. 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
- [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/HEAD/LICENSE) [![npm latest package](https://img.shields.io/npm/v/docusaurus-plugin-openapi-docs/latest.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [![npm downloads](https://img.shields.io/npm/dm/docusaurus-plugin-openapi-docs.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [![npm canary package](https://img.shields.io/npm/v/docusaurus-plugin-openapi-docs/canary.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [![npm beta package](https://img.shields.io/npm/v/docusaurus-plugin-openapi-docs/beta.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs)
14
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/HEAD/LICENSE) [![npm latest package](https://img.shields.io/npm/v/docusaurus-plugin-openapi-docs/latest.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [![npm downloads](https://img.shields.io/npm/dm/docusaurus-plugin-openapi-docs.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs) [![npm canary package](https://img.shields.io/npm/v/docusaurus-plugin-openapi-docs/canary.svg)](https://www.npmjs.com/package/docusaurus-plugin-openapi-docs)
15
15
  <br/>
16
16
  [![build](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/actions/workflows/validate.yaml/badge.svg)](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/actions/workflows/validate.yaml) [![prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![Cypress.io](https://img.shields.io/badge/tested%20with-Cypress-04C38E.svg)](https://www.cypress.io/) [![jest](https://jestjs.io/img/jest-badge.svg)](https://github.com/facebook/jest) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](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.0.x (current) | `3.5.0 - 3.8.1` |
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.8.1 my-website --package-manager yarn
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,29 @@ 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
- | `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
171
- | `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. |
172
- | `label` | `string` | `null` | _Optional:_ Version label used when generating the versionselector dropdown menu. |
173
- | `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. |
174
- | `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. |
175
- | `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. |
176
- | `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. |
159
+ | Name | Type | Default | Description |
160
+ | -------------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
161
+ | `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
162
+ | `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. |
163
+ | `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. |
164
+ | `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
165
+ | `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. |
166
+ | `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. |
167
+ | `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. |
168
+ | `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) |
169
+ | `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. |
170
+ | `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. |
171
+ | `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security. |
172
+ | `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
173
+ | `version` | `string` | `null` | _Optional:_ Version assigned to a single or microspec 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. |
181
+ | `externalJsonProps` | `boolean` | `true` | _Optional:_ If set to `false`, disables externalization of large JSON props. By default, large JSON is written to external files for better build performance. |
177
182
 
178
183
  ### sidebarOptions
179
184
 
@@ -222,6 +227,71 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
222
227
  | --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
223
228
  | `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
229
 
230
+ ### Performance Optimization
231
+
232
+ By default, `externalJsonProps` is enabled to optimize Docusaurus build times. This externalizes large JSON objects to separate files, significantly improving build performance for large OpenAPI specs.
233
+
234
+ **How it works:**
235
+
236
+ - With `externalJsonProps: true` (default): Large JSON props are written to separate `.json` files and loaded via `require()`. This bypasses MDX AST processing entirely, allowing the bundler to handle JSON more efficiently.
237
+
238
+ - With `externalJsonProps: false`: Large JSON objects (responses, request bodies, parameters) are embedded directly in the MDX. The MDX compiler must parse these into an AST and serialize them back, which can be slow for deeply nested schemas.
239
+
240
+ **When to disable:**
241
+
242
+ You may set `externalJsonProps: false` if you have custom tooling that depends on parsing the MDX files directly:
243
+
244
+ ```typescript
245
+ petstore: {
246
+ specPath: "examples/petstore.yaml",
247
+ outputDir: "docs/petstore",
248
+ externalJsonProps: false, // Disable if needed for custom tooling
249
+ } satisfies OpenApiPlugin.Options,
250
+ ```
251
+
252
+ ## Theme Configuration Options
253
+
254
+ The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`:
255
+
256
+ | Name | Type | Default | Description |
257
+ | ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
258
+ | `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. |
259
+ | `authPersistance` | `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. |
260
+ | `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. |
261
+
262
+ Example:
263
+
264
+ ```typescript
265
+ // docusaurus.config.ts
266
+ {
267
+ themeConfig: {
268
+ api: {
269
+ proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config)
270
+ authPersistance: "localStorage",
271
+ requestTimeout: 60000, // 60 seconds
272
+ },
273
+ },
274
+ }
275
+ ```
276
+
277
+ ## Supported Vendor Extensions
278
+
279
+ 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.
280
+
281
+ | Extension | Purpose |
282
+ | ------------------------------------------ | --------------------------------------------------------------------- |
283
+ | `x-codeSamples` | Operation level code snippets displayed in the API Explorer. |
284
+ | `x-tagGroups` | Groups tags in the sidebar navigation. |
285
+ | `x-tags` | Assigns tags to schema objects so they appear with tagged operations. |
286
+ | `x-position` | Controls ordering of items in the sidebar. |
287
+ | `x-logo` / `x-dark-logo` | Provides logos for light and dark themes on the intro page. |
288
+ | `x-deprecated-description` | Custom text shown for deprecated operations. |
289
+ | `x-webhooks` | Defines webhook events. |
290
+ | `x-displayName` | Overrides tag display names. |
291
+ | `x-enumDescription` / `x-enumDescriptions` | Documents enum values. |
292
+
293
+ 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.
294
+
225
295
  ## CLI Usage
226
296
 
227
297
  ```bash
@@ -283,6 +353,16 @@ yarn docusaurus gen-api-docs all --all-versions
283
353
 
284
354
  > This will generate API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
285
355
 
356
+ To generate only schema MDX files—without updating the sidebar or requiring `showSchemas` in your plugin config—use the `--schemas-only` flag:
357
+
358
+ ```bash
359
+ yarn docusaurus gen-api-docs petstore --schemas-only
360
+ ```
361
+
362
+ > This command writes the schema pages to the configured output directory while leaving other generated docs untouched.
363
+
364
+ The `--schemas-only` flag is also available for `gen-api-docs:version`.
365
+
286
366
  ### Cleaning API Docs
287
367
 
288
368
  To clean/remove all API Docs, run the following command from the root directory of your project:
@@ -315,6 +395,14 @@ yarn docusaurus clean-api-docs all --all-versions
315
395
 
316
396
  > This will clean API docs for all versions of all the OpenAPI specification (OAS) files referenced in your `docusaurus-plugin-openapi-docs` config.
317
397
 
398
+ To clean only schema docs while leaving API, info, and tag docs untouched, use the `--schemas-only` flag:
399
+
400
+ ```bash
401
+ yarn docusaurus clean-api-docs petstore --schemas-only
402
+ ```
403
+
404
+ > The `--schemas-only` flag is also available for `clean-api-docs:version`.
405
+
318
406
  ### Versioning OpenAPI docs
319
407
 
320
408
  To generate _all_ versioned OpenAPI docs, run the following command from the root directory of your project:
package/lib/index.js CHANGED
@@ -20,6 +20,7 @@ const chalk_1 = __importDefault(require("chalk"));
20
20
  const json5_1 = __importDefault(require("json5"));
21
21
  const mustache_1 = require("mustache");
22
22
  const markdown_1 = require("./markdown");
23
+ const utils_2 = require("./markdown/utils");
23
24
  const openapi_1 = require("./openapi");
24
25
  const options_1 = require("./options");
25
26
  const sidebars_1 = __importDefault(require("./sidebars"));
@@ -78,7 +79,8 @@ function pluginOpenAPIDocs(context, options) {
78
79
  let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
79
80
  async function generateApiDocs(options, pluginId) {
80
81
  var _a, _b, _c, _d;
81
- let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, disableCompression, } = options;
82
+ let { specPath, outputDir, template, infoTemplate, tagTemplate, schemaTemplate, markdownGenerators, downloadUrl, sidebarOptions, schemasOnly, disableCompression, } = options;
83
+ const isSchemasOnly = schemasOnly === true;
82
84
  // Remove trailing slash before proceeding
83
85
  outputDir = outputDir.replace(/\/$/, "");
84
86
  // Override docPath if pluginId provided
@@ -103,7 +105,7 @@ function pluginOpenAPIDocs(context, options) {
103
105
  }
104
106
  }
105
107
  // TODO: figure out better way to set default
106
- if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
108
+ if (!isSchemasOnly && Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
107
109
  const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, options, loadedApi, tags, docPath, tagGroups);
108
110
  let sidebarSliceTemplate = `import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";\n\n`;
109
111
  sidebarSliceTemplate += `const sidebar: SidebarsConfig = {{{slice}}};\n\n`;
@@ -159,6 +161,9 @@ hide_send_button: true
159
161
  {{#frontMatter.show_extensions}}
160
162
  show_extensions: true
161
163
  {{/frontMatter.show_extensions}}
164
+ {{#frontMatter.mask_credentials_disabled}}
165
+ mask_credentials: false
166
+ {{/frontMatter.mask_credentials_disabled}}
162
167
  ---
163
168
 
164
169
  {{{markdown}}}
@@ -230,11 +235,24 @@ custom_edit_url: null
230
235
  schema: schemaPageGenerator,
231
236
  };
232
237
  loadedApi.map(async (item) => {
238
+ var _a, _b;
233
239
  if (downloadUrl) {
234
240
  item.downloadUrl = downloadUrl;
235
241
  }
236
- const markdown = pageGeneratorByType[item.type](item);
237
- item.markdown = markdown;
242
+ // Generate markdown, with externalization for API and schema pages
243
+ let externalFiles = [];
244
+ if (options.externalJsonProps &&
245
+ (item.type === "api" || item.type === "schema")) {
246
+ const result = (0, utils_2.runWithExternalization)(item.id, () => pageGeneratorByType[item.type](item));
247
+ item.markdown = result.result;
248
+ externalFiles = result.files;
249
+ }
250
+ else {
251
+ item.markdown = pageGeneratorByType[item.type](item);
252
+ }
253
+ if (isSchemasOnly && item.type !== "schema") {
254
+ return;
255
+ }
238
256
  if (item.type === "api") {
239
257
  // opportunity to compress JSON
240
258
  // const serialize = (o: any) => {
@@ -250,9 +268,14 @@ custom_edit_url: null
250
268
  .toString("base64"));
251
269
  let infoBasePath = `${outputDir}/${item.infoId}`;
252
270
  if (docRouteBasePath) {
253
- infoBasePath = `${docRouteBasePath}/${outputDir
254
- .split(docPath)[1]
255
- .replace(/^\/+/g, "")}/${item.infoId}`.replace(/^\/+/g, "");
271
+ // Safely extract path segment, handling cases where docPath may not be in outputDir
272
+ const outputSegment = docPath && outputDir.includes(docPath)
273
+ ? ((_b = (_a = outputDir.split(docPath)[1]) === null || _a === void 0 ? void 0 : _a.replace(/^\/+/g, "")) !== null && _b !== void 0 ? _b : "")
274
+ : outputDir
275
+ .slice(outputDir.indexOf("/", 1))
276
+ .replace(/^\/+/g, "");
277
+ infoBasePath =
278
+ `${docRouteBasePath}/${outputSegment}/${item.infoId}`.replace(/^\/+/g, "");
256
279
  }
257
280
  if (item.infoId)
258
281
  item.infoPath = infoBasePath;
@@ -268,6 +291,14 @@ custom_edit_url: null
268
291
  if (item.id.length === 0) {
269
292
  throw Error("Operation must have summary or operationId defined");
270
293
  }
294
+ // Write externalized JSON files
295
+ for (const jsonFile of externalFiles) {
296
+ const jsonPath = `${outputDir}/${jsonFile.filename}`;
297
+ if (!fs_1.default.existsSync(jsonPath)) {
298
+ fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
299
+ console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
300
+ }
301
+ }
271
302
  fs_1.default.writeFileSync(`${outputDir}/${item.id}.api.mdx`, view, "utf8");
272
303
  console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.api.mdx"`));
273
304
  }
@@ -318,6 +349,14 @@ custom_edit_url: null
318
349
  }
319
350
  // eslint-disable-next-line testing-library/render-result-naming-convention
320
351
  const schemaView = (0, mustache_1.render)(schemaMdTemplate, item);
352
+ // Write externalized JSON files in schemas directory
353
+ for (const jsonFile of externalFiles) {
354
+ const jsonPath = `${outputDir}/schemas/${jsonFile.filename}`;
355
+ if (!fs_1.default.existsSync(jsonPath)) {
356
+ fs_1.default.writeFileSync(jsonPath, jsonFile.content, "utf8");
357
+ console.log(chalk_1.default.green(`Successfully created "${jsonPath}"`));
358
+ }
359
+ }
321
360
  fs_1.default.writeFileSync(`${outputDir}/schemas/${item.id}.schema.mdx`, schemaView, "utf8");
322
361
  console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.schema.mdx"`));
323
362
  }
@@ -335,25 +374,50 @@ custom_edit_url: null
335
374
  throw e;
336
375
  }
337
376
  }
338
- async function cleanApiDocs(options) {
377
+ async function cleanApiDocs(options, schemasOnly = false) {
339
378
  const { outputDir } = options;
340
379
  const apiDir = (0, utils_1.posixPath)(path_1.default.join(siteDir, outputDir));
341
- const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
342
- cwd: path_1.default.resolve(apiDir),
343
- deep: 1,
344
- });
345
- const sidebarFile = await (0, utils_1.Globby)(["sidebar.js", "sidebar.ts"], {
346
- cwd: path_1.default.resolve(apiDir),
347
- deep: 1,
348
- });
349
- apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
350
- if (err) {
351
- console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${mdx}"`), chalk_1.default.yellow(err));
352
- }
353
- else {
354
- console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
355
- }
356
- }));
380
+ // When schemasOnly is true, only clean the schemas directory
381
+ if (!schemasOnly) {
382
+ const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx", "*.tag.mdx"], {
383
+ cwd: path_1.default.resolve(apiDir),
384
+ deep: 1,
385
+ });
386
+ const sidebarFile = await (0, utils_1.Globby)(["sidebar.js", "sidebar.ts"], {
387
+ cwd: path_1.default.resolve(apiDir),
388
+ deep: 1,
389
+ });
390
+ // Clean up externalized JSON files
391
+ const jsonFiles = await (0, utils_1.Globby)(["*.json", "!versions.json"], {
392
+ cwd: path_1.default.resolve(apiDir),
393
+ deep: 1,
394
+ });
395
+ apiMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/${mdx}`, (err) => {
396
+ if (err) {
397
+ console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${mdx}"`), chalk_1.default.yellow(err));
398
+ }
399
+ else {
400
+ console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
401
+ }
402
+ }));
403
+ sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
404
+ if (err) {
405
+ console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
406
+ }
407
+ else {
408
+ console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`));
409
+ }
410
+ }));
411
+ // Clean up externalized JSON files
412
+ jsonFiles.map((jsonFile) => fs_1.default.unlink(`${apiDir}/${jsonFile}`, (err) => {
413
+ if (err) {
414
+ console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${jsonFile}"`), chalk_1.default.yellow(err));
415
+ }
416
+ else {
417
+ console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${jsonFile}"`));
418
+ }
419
+ }));
420
+ }
357
421
  try {
358
422
  fs_1.default.rmSync(`${apiDir}/schemas`, { recursive: true });
359
423
  console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/schemas"`));
@@ -363,14 +427,6 @@ custom_edit_url: null
363
427
  console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/schemas"`), chalk_1.default.yellow(err));
364
428
  }
365
429
  }
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
430
  }
375
431
  async function generateVersions(versions, outputDir) {
376
432
  let versionsArray = [];
@@ -442,19 +498,21 @@ custom_edit_url: null
442
498
  });
443
499
  }
444
500
  }
445
- async function cleanAllVersions(options) {
501
+ async function cleanAllVersions(options, schemasOnly = false) {
446
502
  const parentOptions = Object.assign({}, options);
447
503
  const { versions } = parentOptions;
448
504
  delete parentOptions.versions;
449
505
  if (versions != null && Object.keys(versions).length > 0) {
450
- await cleanVersions(parentOptions.outputDir);
506
+ if (!schemasOnly) {
507
+ await cleanVersions(parentOptions.outputDir);
508
+ }
451
509
  Object.keys(versions).forEach(async (key) => {
452
510
  const versionOptions = versions[key];
453
511
  const mergedOptions = {
454
512
  ...parentOptions,
455
513
  ...versionOptions,
456
514
  };
457
- await cleanApiDocs(mergedOptions);
515
+ await cleanApiDocs(mergedOptions, schemasOnly);
458
516
  });
459
517
  }
460
518
  }
@@ -468,11 +526,13 @@ custom_edit_url: null
468
526
  .arguments("<id>")
469
527
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
470
528
  .option("--all-versions", "Generate all versions.")
529
+ .option("--schemas-only", "Generate only schema docs.")
471
530
  .action(async (id, instance) => {
472
531
  var _a;
473
532
  const options = instance.opts();
474
533
  const pluginId = options.pluginId;
475
534
  const allVersions = options.allVersions;
535
+ const schemasOnly = options.schemasOnly;
476
536
  const pluginInstances = getPluginInstances(plugins);
477
537
  let targetConfig;
478
538
  let targetDocsPluginId;
@@ -494,15 +554,17 @@ custom_edit_url: null
494
554
  }
495
555
  targetConfig = config;
496
556
  }
557
+ const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
497
558
  if (id === "all") {
498
559
  if (targetConfig[id]) {
499
560
  console.error(chalk_1.default.red("Can't use id 'all' for OpenAPI docs configuration key."));
500
561
  }
501
562
  else {
502
563
  Object.keys(targetConfig).forEach(async function (key) {
503
- await generateApiDocs(targetConfig[key], targetDocsPluginId);
564
+ const apiOptions = withSchemaOverride(targetConfig[key]);
565
+ await generateApiDocs(apiOptions, targetDocsPluginId);
504
566
  if (allVersions) {
505
- await generateAllVersions(targetConfig[key], targetDocsPluginId);
567
+ await generateAllVersions(apiOptions, targetDocsPluginId);
506
568
  }
507
569
  });
508
570
  }
@@ -511,9 +573,10 @@ custom_edit_url: null
511
573
  console.error(chalk_1.default.red(`ID '${id}' does not exist in OpenAPI docs config.`));
512
574
  }
513
575
  else {
514
- await generateApiDocs(targetConfig[id], targetDocsPluginId);
576
+ const apiOptions = withSchemaOverride(targetConfig[id]);
577
+ await generateApiDocs(apiOptions, targetDocsPluginId);
515
578
  if (allVersions) {
516
- await generateAllVersions(targetConfig[id], targetDocsPluginId);
579
+ await generateAllVersions(apiOptions, targetDocsPluginId);
517
580
  }
518
581
  }
519
582
  });
@@ -523,10 +586,12 @@ custom_edit_url: null
523
586
  .usage("<id:version>")
524
587
  .arguments("<id:version>")
525
588
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
589
+ .option("--schemas-only", "Generate only schema docs.")
526
590
  .action(async (id, instance) => {
527
591
  var _a;
528
592
  const options = instance.opts();
529
593
  const pluginId = options.pluginId;
594
+ const schemasOnly = options.schemasOnly;
530
595
  const pluginInstances = getPluginInstances(plugins);
531
596
  let targetConfig;
532
597
  let targetDocsPluginId;
@@ -550,6 +615,7 @@ custom_edit_url: null
550
615
  }
551
616
  const [parentId, versionId] = id.split(":");
552
617
  const parentConfig = Object.assign({}, targetConfig[parentId]);
618
+ const withSchemaOverride = (apiOptions) => schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
553
619
  const version = parentConfig.version;
554
620
  const label = parentConfig.label;
555
621
  const baseUrl = parentConfig.baseUrl;
@@ -572,10 +638,10 @@ custom_edit_url: null
572
638
  await generateVersions(mergedVersions, parentConfig.outputDir);
573
639
  Object.keys(versions).forEach(async (key) => {
574
640
  const versionConfig = versions[key];
575
- const mergedConfig = {
641
+ const mergedConfig = withSchemaOverride({
576
642
  ...parentConfig,
577
643
  ...versionConfig,
578
- };
644
+ });
579
645
  await generateApiDocs(mergedConfig, targetDocsPluginId);
580
646
  });
581
647
  }
@@ -585,10 +651,10 @@ custom_edit_url: null
585
651
  }
586
652
  else {
587
653
  const versionConfig = versions[versionId];
588
- const mergedConfig = {
654
+ const mergedConfig = withSchemaOverride({
589
655
  ...parentConfig,
590
656
  ...versionConfig,
591
- };
657
+ });
592
658
  await generateVersions(mergedVersions, parentConfig.outputDir);
593
659
  await generateApiDocs(mergedConfig, targetDocsPluginId);
594
660
  }
@@ -600,11 +666,13 @@ custom_edit_url: null
600
666
  .arguments("<id>")
601
667
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
602
668
  .option("--all-versions", "Clean all versions.")
669
+ .option("--schemas-only", "Clean only schema docs.")
603
670
  .action(async (id, instance) => {
604
671
  var _a;
605
672
  const options = instance.opts();
606
673
  const pluginId = options.pluginId;
607
674
  const allVersions = options.allVersions;
675
+ const schemasOnly = options.schemasOnly;
608
676
  const pluginInstances = getPluginInstances(plugins);
609
677
  let targetConfig;
610
678
  if (pluginId) {
@@ -630,17 +698,17 @@ custom_edit_url: null
630
698
  }
631
699
  else {
632
700
  Object.keys(targetConfig).forEach(async function (key) {
633
- await cleanApiDocs(targetConfig[key]);
701
+ await cleanApiDocs(targetConfig[key], schemasOnly);
634
702
  if (allVersions) {
635
- await cleanAllVersions(targetConfig[key]);
703
+ await cleanAllVersions(targetConfig[key], schemasOnly);
636
704
  }
637
705
  });
638
706
  }
639
707
  }
640
708
  else {
641
- await cleanApiDocs(targetConfig[id]);
709
+ await cleanApiDocs(targetConfig[id], schemasOnly);
642
710
  if (allVersions) {
643
- await cleanAllVersions(targetConfig[id]);
711
+ await cleanAllVersions(targetConfig[id], schemasOnly);
644
712
  }
645
713
  }
646
714
  });
@@ -650,10 +718,12 @@ custom_edit_url: null
650
718
  .usage("<id:version>")
651
719
  .arguments("<id:version>")
652
720
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
721
+ .option("--schemas-only", "Clean only schema docs.")
653
722
  .action(async (id, instance) => {
654
723
  var _a;
655
724
  const options = instance.opts();
656
725
  const pluginId = options.pluginId;
726
+ const schemasOnly = options.schemasOnly;
657
727
  const pluginInstances = getPluginInstances(plugins);
658
728
  let targetConfig;
659
729
  if (pluginId) {
@@ -682,14 +752,16 @@ custom_edit_url: null
682
752
  chalk_1.default.red("Can't use id 'all' for OpenAPI docs versions configuration key.");
683
753
  }
684
754
  else {
685
- await cleanVersions(parentConfig.outputDir);
755
+ if (!schemasOnly) {
756
+ await cleanVersions(parentConfig.outputDir);
757
+ }
686
758
  Object.keys(versions).forEach(async (key) => {
687
759
  const versionConfig = versions[key];
688
760
  const mergedConfig = {
689
761
  ...parentConfig,
690
762
  ...versionConfig,
691
763
  };
692
- await cleanApiDocs(mergedConfig);
764
+ await cleanApiDocs(mergedConfig, schemasOnly);
693
765
  });
694
766
  }
695
767
  }
@@ -699,7 +771,7 @@ custom_edit_url: null
699
771
  ...parentConfig,
700
772
  ...versionConfig,
701
773
  };
702
- await cleanApiDocs(mergedConfig);
774
+ await cleanApiDocs(mergedConfig, schemasOnly);
703
775
  }
704
776
  });
705
777
  },
@@ -11,7 +11,7 @@ const utils_1 = require("./utils");
11
11
  function createHeading(heading) {
12
12
  return [
13
13
  (0, utils_1.create)("Heading", {
14
- children: (0, utils_1.clean)(heading),
14
+ children: heading,
15
15
  as: "h1",
16
16
  className: "openapi__heading",
17
17
  }, { inline: true }),
@@ -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
- }, { inline: true }),
19
- `\n\n`,
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
  ],