docusaurus-plugin-openapi-docs 2.1.3 → 3.0.0-beta.10

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/lib/index.js CHANGED
@@ -15,6 +15,7 @@ const path_1 = __importDefault(require("path"));
15
15
  const zlib_1 = __importDefault(require("zlib"));
16
16
  const utils_1 = require("@docusaurus/utils");
17
17
  const chalk_1 = __importDefault(require("chalk"));
18
+ const json5_1 = __importDefault(require("json5"));
18
19
  const mustache_1 = require("mustache");
19
20
  const markdown_1 = require("./markdown");
20
21
  const openapi_1 = require("./openapi");
@@ -105,17 +106,19 @@ function pluginOpenAPIDocs(context, options) {
105
106
  // TODO: figure out better way to set default
106
107
  if (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
- const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
109
+ let sidebarSliceTemplate = `import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";\n\n`;
110
+ sidebarSliceTemplate += `const sidebar: SidebarsConfig = {{{slice}}};\n\n`;
111
+ sidebarSliceTemplate += `export default sidebar.apisidebar;\n`;
109
112
  const view = (0, mustache_1.render)(sidebarSliceTemplate, {
110
- slice: JSON.stringify(sidebarSlice),
113
+ slice: json5_1.default.stringify({ apisidebar: sidebarSlice }, { space: 2, quote: '"' }),
111
114
  });
112
- if (!fs_1.default.existsSync(`${outputDir}/sidebar.js`)) {
115
+ if (!fs_1.default.existsSync(`${outputDir}/sidebar.ts`)) {
113
116
  try {
114
- fs_1.default.writeFileSync(`${outputDir}/sidebar.js`, view, "utf8");
115
- console.log(chalk_1.default.green(`Successfully created "${outputDir}/sidebar.js"`));
117
+ fs_1.default.writeFileSync(`${outputDir}/sidebar.ts`, view, "utf8");
118
+ console.log(chalk_1.default.green(`Successfully created "${outputDir}/sidebar.ts"`));
116
119
  }
117
120
  catch (err) {
118
- console.error(chalk_1.default.red(`Failed to write "${outputDir}/sidebar.js"`), chalk_1.default.yellow(err));
121
+ console.error(chalk_1.default.red(`Failed to write "${outputDir}/sidebar.ts"`), chalk_1.default.yellow(err));
119
122
  }
120
123
  }
121
124
  }
@@ -375,7 +378,7 @@ custom_edit_url: null
375
378
  }
376
379
  const versionsJson = JSON.stringify(versionsArray, null, 2);
377
380
  try {
378
- fs_1.default.writeFileSync(`${outputDir}/versions.json`, versionsJson, "utf8");
381
+ fs_1.default.writeFileSync(`${outputDir}/versions.json`, versionsJson + "\n", "utf8");
379
382
  console.log(chalk_1.default.green(`Successfully created "${outputDir}/versions.json"`));
380
383
  }
381
384
  catch (err) {
@@ -399,7 +402,7 @@ custom_edit_url: null
399
402
  extendCli(cli) {
400
403
  cli
401
404
  .command(`gen-api-docs`)
402
- .description(`Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`)
405
+ .description(`Generates OpenAPI docs in MDX file format and sidebar.ts (if enabled).`)
403
406
  .usage("<id>")
404
407
  .arguments("<id>")
405
408
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
@@ -447,7 +450,7 @@ custom_edit_url: null
447
450
  });
448
451
  cli
449
452
  .command(`gen-api-docs:version`)
450
- .description(`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`)
453
+ .description(`Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.ts (if enabled).`)
451
454
  .usage("<id:version>")
452
455
  .arguments("<id:version>")
453
456
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
@@ -522,7 +525,7 @@ custom_edit_url: null
522
525
  });
523
526
  cli
524
527
  .command(`clean-api-docs`)
525
- .description(`Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`)
528
+ .description(`Clears the generated OpenAPI docs MDX files and sidebar.ts (if enabled).`)
526
529
  .usage("<id>")
527
530
  .arguments("<id>")
528
531
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
@@ -565,7 +568,7 @@ custom_edit_url: null
565
568
  });
566
569
  cli
567
570
  .command(`clean-api-docs:version`)
568
- .description(`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`)
571
+ .description(`Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.ts (if enabled).`)
569
572
  .usage("<id:version>")
570
573
  .arguments("<id:version>")
571
574
  .option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
@@ -148,11 +148,12 @@ function createAuthentication(securitySchemes) {
148
148
  };
149
149
  return (0, utils_1.create)("div", {
150
150
  children: [
151
- (0, utils_1.create)("h2", {
151
+ (0, utils_1.create)("Heading", {
152
152
  children: "Authentication",
153
153
  id: "authentication",
154
- style: { marginBottom: "1rem" },
155
- }),
154
+ as: "h2",
155
+ className: "openapi-tabs__heading",
156
+ }, { inline: true }),
156
157
  (0, utils_1.create)("SchemaTabs", {
157
158
  className: "openapi-tabs__security-schemes",
158
159
  children: Object.entries(securitySchemes).map(([schemeKey, schemeObj]) => (0, utils_1.create)("TabItem", {
@@ -25,10 +25,12 @@ function createCallbacks({ callbacks }) {
25
25
  (0, utils_1.create)("div", {
26
26
  className: "openapi__divider",
27
27
  }),
28
- (0, utils_1.create)("h2", {
28
+ (0, utils_1.create)("Heading", {
29
29
  children: "Callbacks",
30
30
  id: "callbacks",
31
- }),
31
+ as: "h2",
32
+ className: "openapi-tabs__heading",
33
+ }, { inline: true }),
32
34
  (0, utils_1.create)("OperationTabs", {
33
35
  className: "openapi-tabs__operation",
34
36
  children: callbacksNames.flatMap((name) => {
@@ -28,20 +28,11 @@ function createContactInfo(contact) {
28
28
  (0, utils_1.create)("span", {
29
29
  children: [
30
30
  (0, utils_1.guard)(name, () => `${name}: `),
31
- (0, utils_1.guard)(email, () => (0, utils_1.create)("a", {
32
- href: `mailto:${email}`,
33
- children: `${email}`,
34
- })),
31
+ (0, utils_1.guard)(email, () => `[${email}](mailto:${email})`),
35
32
  ],
36
33
  }),
37
34
  (0, utils_1.guard)(url, () => (0, utils_1.create)("span", {
38
- children: [
39
- "URL: ",
40
- (0, utils_1.create)("a", {
41
- href: `${url}`,
42
- children: `${url}`,
43
- }),
44
- ],
35
+ children: ["URL: ", `[${url}](mailto:${url})`],
45
36
  })),
46
37
  ],
47
38
  });
@@ -12,8 +12,11 @@ function createAdmonition({ children }) {
12
12
  return `:::caution deprecated\n\n${(0, utils_1.render)(children)}\n\n:::`;
13
13
  }
14
14
  function createDeprecationNotice({ deprecated, description, }) {
15
- return (0, utils_1.guard)(deprecated, () => createAdmonition({
16
- children: description !== null && description !== void 0 ? description : "This endpoint has been deprecated and may be replaced or removed in future versions of the API.",
17
- }));
15
+ return (0, utils_1.guard)(deprecated, () => {
16
+ var _a;
17
+ return createAdmonition({
18
+ children: (_a = (0, utils_1.clean)(description)) !== null && _a !== void 0 ? _a : "This endpoint has been deprecated and may be replaced or removed in future versions of the API.",
19
+ });
20
+ });
18
21
  }
19
22
  exports.createDeprecationNotice = createDeprecationNotice;
@@ -9,13 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.createDescription = void 0;
10
10
  const utils_1 = require("./utils");
11
11
  function createDescription(description) {
12
- if (!description) {
13
- return "";
14
- }
15
- return `\n\n${description
16
- .replace(utils_1.greaterThan, "\\>")
17
- .replace(utils_1.codeFence, function (match) {
18
- return match.replace(/\\>/g, ">");
19
- })}\n\n`;
12
+ return `\n\n${(0, utils_1.clean)(description)}\n\n`;
20
13
  }
21
14
  exports.createDescription = createDescription;
@@ -10,10 +10,11 @@ exports.createHeading = void 0;
10
10
  const utils_1 = require("./utils");
11
11
  function createHeading(heading) {
12
12
  return [
13
- (0, utils_1.create)("h1", {
13
+ (0, utils_1.create)("Heading", {
14
+ children: (0, utils_1.clean)(heading),
15
+ as: "h1",
14
16
  className: "openapi__heading",
15
- children: `${heading}`,
16
- }),
17
+ }, { inline: true }),
17
18
  `\n\n`,
18
19
  ];
19
20
  }
@@ -1 +1 @@
1
- export declare function createRequestHeader(header: string): string;
1
+ export declare function createRequestHeader(header: string): string[];
@@ -7,7 +7,16 @@
7
7
  * ========================================================================== */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.createRequestHeader = void 0;
10
+ const utils_1 = require("./utils");
10
11
  function createRequestHeader(header) {
11
- return `## ${header}\n\n`;
12
+ return [
13
+ (0, utils_1.create)("Heading", {
14
+ children: header,
15
+ id: header.replace(" ", "-").toLowerCase(),
16
+ as: "h2",
17
+ className: "openapi-tabs__heading",
18
+ }, { inline: true }),
19
+ `\n\n`,
20
+ ];
12
21
  }
13
22
  exports.createRequestHeader = createRequestHeader;
@@ -32,7 +32,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
32
32
  const prettier = __importStar(require("prettier"));
33
33
  const createSchema_1 = require("./createSchema");
34
34
  describe("createNodes", () => {
35
- it("should create readable MODs for oneOf primitive properties", () => {
35
+ it("should create readable MODs for oneOf primitive properties", async () => {
36
36
  const schema = {
37
37
  type: "object",
38
38
  properties: {
@@ -68,6 +68,6 @@ describe("createNodes", () => {
68
68
  },
69
69
  },
70
70
  };
71
- expect((0, createSchema_1.createNodes)(schema, "request").map((md) => prettier.format(md, { parser: "babel" }))).toMatchSnapshot();
71
+ expect(await Promise.all((0, createSchema_1.createNodes)(schema, "request").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
72
72
  });
73
73
  });
@@ -13,7 +13,7 @@ function createVersionBadge(version) {
13
13
  (0, utils_1.create)("span", {
14
14
  className: "theme-doc-version-badge badge badge--secondary",
15
15
  children: `Version: ${escape(version)}`,
16
- }),
16
+ }, { inline: true }),
17
17
  `\n\n`,
18
18
  ]);
19
19
  }
@@ -39,9 +39,10 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
39
39
  `import SchemaItem from "@theme/SchemaItem";\n`,
40
40
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
41
41
  `import Markdown from "@theme/Markdown";\n`,
42
+ `import Heading from "@theme/Heading";\n`,
42
43
  `import OperationTabs from "@theme/OperationTabs";\n`,
43
44
  `import TabItem from "@theme/TabItem";\n\n`,
44
- (0, createHeading_1.createHeading)(title.replace(utils_1.lessThan, "&lt;").replace(utils_1.greaterThan, "&gt;")),
45
+ (0, createHeading_1.createHeading)(title),
45
46
  (0, createMethodEndpoint_1.createMethodEndpoint)(method, path),
46
47
  infoPath && (0, createAuthorization_1.createAuthorization)(infoPath),
47
48
  frontMatter.show_extensions
@@ -66,12 +67,13 @@ exports.createApiPageMD = createApiPageMD;
66
67
  function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService, logo, darkLogo, }, securitySchemes, downloadUrl, }) {
67
68
  return (0, utils_1.render)([
68
69
  `import ApiLogo from "@theme/ApiLogo";\n`,
70
+ `import Heading from "@theme/Heading";\n`,
69
71
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
70
72
  `import TabItem from "@theme/TabItem";\n`,
71
73
  `import Export from "@theme/ApiExplorer/Export";\n\n`,
72
74
  (0, createVersionBadge_1.createVersionBadge)(version),
73
75
  (0, createDownload_1.createDownload)(downloadUrl),
74
- (0, createHeading_1.createHeading)(title.replace(utils_1.lessThan, "&lt;").replace(utils_1.greaterThan, "&gt;")),
76
+ (0, createHeading_1.createHeading)(title),
75
77
  (0, createLogo_1.createLogo)(logo, darkLogo),
76
78
  (0, createDescription_1.createDescription)(description),
77
79
  (0, createAuthentication_1.createAuthentication)(securitySchemes),
@@ -91,6 +93,7 @@ function createSchemaPageMD({ schema }) {
91
93
  `import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
92
94
  `import SchemaItem from "@theme/SchemaItem";\n`,
93
95
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
96
+ `import Heading from "@theme/Heading";\n`,
94
97
  `import TabItem from "@theme/TabItem";\n\n`,
95
98
  (0, createHeading_1.createHeading)(title.replace(utils_1.lessThan, "&lt;").replace(utils_1.greaterThan, "&gt;")),
96
99
  (0, createDescription_1.createDescription)(description),
@@ -2,9 +2,15 @@ export type Children = string | undefined | (string | string[] | undefined)[];
2
2
  export type Props = Record<string, any> & {
3
3
  children?: Children;
4
4
  };
5
- export declare function create(tag: string, props: Props): string;
5
+ export type Options = {
6
+ inline?: boolean;
7
+ };
8
+ export declare function create(tag: string, props: Props, options?: Options): string;
6
9
  export declare function guard<T>(value: T | undefined, cb: (value: T) => Children): string;
7
10
  export declare function render(children: Children): string;
8
11
  export declare const lessThan: RegExp;
9
12
  export declare const greaterThan: RegExp;
10
13
  export declare const codeFence: RegExp;
14
+ export declare const curlyBrackets: RegExp;
15
+ export declare const codeBlock: RegExp;
16
+ export declare function clean(value: string | undefined): string;
@@ -6,14 +6,21 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  * ========================================================================== */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.codeFence = exports.greaterThan = exports.lessThan = exports.render = exports.guard = exports.create = void 0;
10
- function create(tag, props) {
9
+ exports.clean = exports.codeBlock = exports.curlyBrackets = exports.codeFence = exports.greaterThan = exports.lessThan = exports.render = exports.guard = exports.create = void 0;
10
+ function create(tag, props, options = {}) {
11
11
  const { children, ...rest } = props;
12
12
  let propString = "";
13
13
  for (const [key, value] of Object.entries(rest)) {
14
- propString += ` ${key}={${JSON.stringify(value)}}`;
14
+ propString += `\n ${key}={${JSON.stringify(value)}}`;
15
15
  }
16
- return `<${tag}${propString}>${render(children)}</${tag}>`;
16
+ let indentedChildren = render(children).replace(/^/gm, " ");
17
+ if (options.inline) {
18
+ propString += `\n children={${JSON.stringify(children)}}`;
19
+ indentedChildren = "";
20
+ }
21
+ propString += propString ? "\n" : "";
22
+ indentedChildren += indentedChildren ? "\n" : "";
23
+ return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
17
24
  }
18
25
  exports.create = create;
19
26
  function guard(value, cb) {
@@ -35,6 +42,27 @@ function render(children) {
35
42
  }
36
43
  exports.render = render;
37
44
  // Regex to selectively URL-encode '>' and '<' chars
38
- exports.lessThan = /<(?!(=|button|\s?\/button|code|\s?\/code|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|thead|\s?\/thead|tbody|\s?\/tbody|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|bold|\s?\/bold|a|\s?\/a|table|\s?\/table|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|svg|\s?\/svg|div|\s?\/div|center|\s?\/center))/gu;
45
+ exports.lessThan = /<=?(?!(=|button|\s?\/button|code|\s?\/code|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|thead|\s?\/thead|tbody|\s?\/tbody|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|bold|\s?\/bold|a|\s?\/a|table|\s?\/table|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|svg|\s?\/svg|div|\s?\/div|center|\s?\/center))/gu;
39
46
  exports.greaterThan = /(?<!(button|code|details|summary|hr|br|span|strong|small|table|thead|tbody|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|bold|a|li|ol|ul|img|svg|div|center|\/|\s|"|'))>/gu;
40
47
  exports.codeFence = /`{1,3}[\s\S]*?`{1,3}/g;
48
+ exports.curlyBrackets = /([{|}])/g;
49
+ exports.codeBlock = /(^```.*[\s\S]*?```$|`[^`].+?`)/gm;
50
+ function clean(value) {
51
+ if (!value) {
52
+ return "";
53
+ }
54
+ let sections = value.split(exports.codeBlock);
55
+ for (let sectionIndex in sections) {
56
+ if (!sections[sectionIndex].startsWith("`")) {
57
+ sections[sectionIndex] = sections[sectionIndex]
58
+ .replace(exports.lessThan, "&lt;")
59
+ .replace(exports.greaterThan, "&gt;")
60
+ .replace(exports.codeFence, function (match) {
61
+ return match.replace(/\\>/g, ">");
62
+ })
63
+ .replace(exports.curlyBrackets, "\\$1");
64
+ }
65
+ }
66
+ return sections.join("");
67
+ }
68
+ exports.clean = clean;
@@ -534,7 +534,7 @@ exports.setSecuritySchemePrefix = setSecuritySchemePrefix;
534
534
  const shortenHTTPVerb = (verb) => ({
535
535
  delete: "del",
536
536
  options: "opts",
537
- }[verb] || verb);
537
+ })[verb] || verb;
538
538
  exports.shortenHTTPVerb = shortenHTTPVerb;
539
539
  function isRedocExtension(key) {
540
540
  const redocExtensions = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-plugin-openapi-docs",
3
3
  "description": "OpenAPI plugin for Docusaurus.",
4
- "version": "2.1.3",
4
+ "version": "3.0.0-beta.10",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,18 +28,19 @@
28
28
  "watch": "tsc --watch"
29
29
  },
30
30
  "devDependencies": {
31
- "@docusaurus/types": ">=2.4.1 <=2.4.3",
31
+ "@docusaurus/types": "^3.0.1",
32
32
  "@types/fs-extra": "^9.0.13",
33
33
  "@types/json-pointer": "^1.0.31",
34
34
  "@types/json-schema": "^7.0.9",
35
35
  "@types/lodash": "^4.14.176",
36
- "@types/mustache": "^4.1.2"
36
+ "@types/mustache": "^4.1.2",
37
+ "eslint-plugin-prettier": "^5.0.1"
37
38
  },
38
39
  "dependencies": {
39
40
  "@apidevtools/json-schema-ref-parser": "^11.5.4",
40
- "@docusaurus/plugin-content-docs": ">=2.4.1 <=2.4.3",
41
- "@docusaurus/utils": ">=2.4.1 <=2.4.3",
42
- "@docusaurus/utils-validation": ">=2.4.1 <=2.4.3",
41
+ "@docusaurus/plugin-content-docs": "^3.0.1",
42
+ "@docusaurus/utils": "^3.0.1",
43
+ "@docusaurus/utils-validation": "^3.0.1",
43
44
  "@paloaltonetworks/openapi-to-postmanv2": "3.1.0-hotfix.1",
44
45
  "@paloaltonetworks/postman-collection": "^4.1.0",
45
46
  "@redocly/openapi-core": "^1.10.5",
@@ -48,6 +49,7 @@
48
49
  "fs-extra": "^9.0.1",
49
50
  "json-pointer": "^0.6.2",
50
51
  "json-schema-merge-allof": "^0.8.1",
52
+ "json5": "^2.2.3",
51
53
  "lodash": "^4.17.20",
52
54
  "mustache": "^4.2.0",
53
55
  "slugify": "^1.6.5",
@@ -60,5 +62,5 @@
60
62
  "engines": {
61
63
  "node": ">=14"
62
64
  },
63
- "gitHead": "3bca23ffd3bc51c3d7f4ebb3916e2ece8c823961"
65
+ "gitHead": "82d70be14358052625d00e637b1eeba52a14b706"
64
66
  }
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ import zlib from "zlib";
12
12
  import type { LoadContext, Plugin } from "@docusaurus/types";
13
13
  import { Globby, posixPath } from "@docusaurus/utils";
14
14
  import chalk from "chalk";
15
+ import JSON5 from "json5";
15
16
  import { render } from "mustache";
16
17
 
17
18
  import {
@@ -159,21 +160,26 @@ export default function pluginOpenAPIDocs(
159
160
  tagGroups
160
161
  );
161
162
 
162
- const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
163
+ let sidebarSliceTemplate = `import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";\n\n`;
164
+ sidebarSliceTemplate += `const sidebar: SidebarsConfig = {{{slice}}};\n\n`;
165
+ sidebarSliceTemplate += `export default sidebar.apisidebar;\n`;
163
166
 
164
167
  const view = render(sidebarSliceTemplate, {
165
- slice: JSON.stringify(sidebarSlice),
168
+ slice: JSON5.stringify(
169
+ { apisidebar: sidebarSlice },
170
+ { space: 2, quote: '"' }
171
+ ),
166
172
  });
167
173
 
168
- if (!fs.existsSync(`${outputDir}/sidebar.js`)) {
174
+ if (!fs.existsSync(`${outputDir}/sidebar.ts`)) {
169
175
  try {
170
- fs.writeFileSync(`${outputDir}/sidebar.js`, view, "utf8");
176
+ fs.writeFileSync(`${outputDir}/sidebar.ts`, view, "utf8");
171
177
  console.log(
172
- chalk.green(`Successfully created "${outputDir}/sidebar.js"`)
178
+ chalk.green(`Successfully created "${outputDir}/sidebar.ts"`)
173
179
  );
174
180
  } catch (err) {
175
181
  console.error(
176
- chalk.red(`Failed to write "${outputDir}/sidebar.js"`),
182
+ chalk.red(`Failed to write "${outputDir}/sidebar.ts"`),
177
183
  chalk.yellow(err)
178
184
  );
179
185
  }
@@ -528,7 +534,11 @@ custom_edit_url: null
528
534
 
529
535
  const versionsJson = JSON.stringify(versionsArray, null, 2);
530
536
  try {
531
- fs.writeFileSync(`${outputDir}/versions.json`, versionsJson, "utf8");
537
+ fs.writeFileSync(
538
+ `${outputDir}/versions.json`,
539
+ versionsJson + "\n",
540
+ "utf8"
541
+ );
532
542
  console.log(
533
543
  chalk.green(`Successfully created "${outputDir}/versions.json"`)
534
544
  );
@@ -564,7 +574,7 @@ custom_edit_url: null
564
574
  cli
565
575
  .command(`gen-api-docs`)
566
576
  .description(
567
- `Generates OpenAPI docs in MDX file format and sidebar.js (if enabled).`
577
+ `Generates OpenAPI docs in MDX file format and sidebar.ts (if enabled).`
568
578
  )
569
579
  .usage("<id>")
570
580
  .arguments("<id>")
@@ -622,7 +632,7 @@ custom_edit_url: null
622
632
  cli
623
633
  .command(`gen-api-docs:version`)
624
634
  .description(
625
- `Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.js (if enabled).`
635
+ `Generates versioned OpenAPI docs in MDX file format, versions.js and sidebar.ts (if enabled).`
626
636
  )
627
637
  .usage("<id:version>")
628
638
  .arguments("<id:version>")
@@ -713,7 +723,7 @@ custom_edit_url: null
713
723
  cli
714
724
  .command(`clean-api-docs`)
715
725
  .description(
716
- `Clears the generated OpenAPI docs MDX files and sidebar.js (if enabled).`
726
+ `Clears the generated OpenAPI docs MDX files and sidebar.ts (if enabled).`
717
727
  )
718
728
  .usage("<id>")
719
729
  .arguments("<id>")
@@ -764,7 +774,7 @@ custom_edit_url: null
764
774
  cli
765
775
  .command(`clean-api-docs:version`)
766
776
  .description(
767
- `Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.js (if enabled).`
777
+ `Clears the versioned, generated OpenAPI docs MDX files, versions.json and sidebar.ts (if enabled).`
768
778
  )
769
779
  .usage("<id:version>")
770
780
  .arguments("<id:version>")
@@ -6,7 +6,7 @@ Array [
6
6
  <details style={{}} className={\\"openapi-markdown__details\\"}>
7
7
  <summary style={{}}>
8
8
  <strong>oneOfProperty</strong>
9
- <span style={{ opacity: \\"0.6\\" }}> object</span>
9
+ <span style={{ opacity: \\"0.6\\" }}>object</span>
10
10
  </summary>
11
11
  <div style={{ marginLeft: \\"1rem\\" }}></div>
12
12
  <div>
@@ -167,11 +167,16 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
167
167
 
168
168
  return create("div", {
169
169
  children: [
170
- create("h2", {
171
- children: "Authentication",
172
- id: "authentication",
173
- style: { marginBottom: "1rem" },
174
- }),
170
+ create(
171
+ "Heading",
172
+ {
173
+ children: "Authentication",
174
+ id: "authentication",
175
+ as: "h2",
176
+ className: "openapi-tabs__heading",
177
+ },
178
+ { inline: true }
179
+ ),
175
180
  create("SchemaTabs", {
176
181
  className: "openapi-tabs__security-schemes",
177
182
  children: Object.entries(securitySchemes).map(
@@ -43,10 +43,16 @@ export function createCallbacks({ callbacks }: Props) {
43
43
  create("div", {
44
44
  className: "openapi__divider",
45
45
  }),
46
- create("h2", {
47
- children: "Callbacks",
48
- id: "callbacks",
49
- }),
46
+ create(
47
+ "Heading",
48
+ {
49
+ children: "Callbacks",
50
+ id: "callbacks",
51
+ as: "h2",
52
+ className: "openapi-tabs__heading",
53
+ },
54
+ { inline: true }
55
+ ),
50
56
  create("OperationTabs", {
51
57
  className: "openapi-tabs__operation",
52
58
  children: callbacksNames.flatMap((name) => {
@@ -28,23 +28,12 @@ export function createContactInfo(contact: ContactObject) {
28
28
  create("span", {
29
29
  children: [
30
30
  guard(name, () => `${name}: `),
31
- guard(email, () =>
32
- create("a", {
33
- href: `mailto:${email}`,
34
- children: `${email}`,
35
- })
36
- ),
31
+ guard(email, () => `[${email}](mailto:${email})`),
37
32
  ],
38
33
  }),
39
34
  guard(url, () =>
40
35
  create("span", {
41
- children: [
42
- "URL: ",
43
- create("a", {
44
- href: `${url}`,
45
- children: `${url}`,
46
- }),
47
- ],
36
+ children: ["URL: ", `[${url}](mailto:${url})`],
48
37
  })
49
38
  ),
50
39
  ],
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { guard, Props, render } from "./utils";
8
+ import { clean, guard, Props, render } from "./utils";
9
9
 
10
10
  function createAdmonition({ children }: Props) {
11
11
  return `:::caution deprecated\n\n${render(children)}\n\n:::`;
@@ -23,7 +23,7 @@ export function createDeprecationNotice({
23
23
  return guard(deprecated, () =>
24
24
  createAdmonition({
25
25
  children:
26
- description ??
26
+ clean(description) ??
27
27
  "This endpoint has been deprecated and may be replaced or removed in future versions of the API.",
28
28
  })
29
29
  );
@@ -5,15 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { greaterThan, codeFence } from "./utils";
8
+ import { clean } from "./utils";
9
9
 
10
10
  export function createDescription(description: string | undefined) {
11
- if (!description) {
12
- return "";
13
- }
14
- return `\n\n${description
15
- .replace(greaterThan, "\\>")
16
- .replace(codeFence, function (match) {
17
- return match.replace(/\\>/g, ">");
18
- })}\n\n`;
11
+ return `\n\n${clean(description)}\n\n`;
19
12
  }
@@ -5,14 +5,19 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { create } from "./utils";
8
+ import { clean, create } from "./utils";
9
9
 
10
10
  export function createHeading(heading: string) {
11
11
  return [
12
- create("h1", {
13
- className: "openapi__heading",
14
- children: `${heading}`,
15
- }),
12
+ create(
13
+ "Heading",
14
+ {
15
+ children: clean(heading),
16
+ as: "h1",
17
+ className: "openapi__heading",
18
+ },
19
+ { inline: true }
20
+ ),
16
21
  `\n\n`,
17
22
  ];
18
23
  }
@@ -5,6 +5,20 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
+ import { create } from "./utils";
9
+
8
10
  export function createRequestHeader(header: string) {
9
- return `## ${header}\n\n`;
11
+ return [
12
+ create(
13
+ "Heading",
14
+ {
15
+ children: header,
16
+ id: header.replace(" ", "-").toLowerCase(),
17
+ as: "h2",
18
+ className: "openapi-tabs__heading",
19
+ },
20
+ { inline: true }
21
+ ),
22
+ `\n\n`,
23
+ ];
10
24
  }
@@ -11,7 +11,7 @@ import { createNodes } from "./createSchema";
11
11
  import { SchemaObject } from "../openapi/types";
12
12
 
13
13
  describe("createNodes", () => {
14
- it("should create readable MODs for oneOf primitive properties", () => {
14
+ it("should create readable MODs for oneOf primitive properties", async () => {
15
15
  const schema: SchemaObject = {
16
16
  type: "object",
17
17
  properties: {
@@ -48,8 +48,10 @@ describe("createNodes", () => {
48
48
  },
49
49
  };
50
50
  expect(
51
- createNodes(schema, "request").map((md: any) =>
52
- prettier.format(md, { parser: "babel" })
51
+ await Promise.all(
52
+ createNodes(schema, "request").map(
53
+ async (md: any) => await prettier.format(md, { parser: "babel" })
54
+ )
53
55
  )
54
56
  ).toMatchSnapshot();
55
57
  });
@@ -9,10 +9,14 @@ import { create, guard } from "./utils";
9
9
 
10
10
  export function createVersionBadge(version: string | undefined) {
11
11
  return guard(version, (version) => [
12
- create("span", {
13
- className: "theme-doc-version-badge badge badge--secondary",
14
- children: `Version: ${escape(version)}`,
15
- }),
12
+ create(
13
+ "span",
14
+ {
15
+ className: "theme-doc-version-badge badge badge--secondary",
16
+ children: `Version: ${escape(version)}`,
17
+ },
18
+ { inline: true }
19
+ ),
16
20
  `\n\n`,
17
21
  ]);
18
22
  }
@@ -77,9 +77,10 @@ export function createApiPageMD({
77
77
  `import SchemaItem from "@theme/SchemaItem";\n`,
78
78
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
79
79
  `import Markdown from "@theme/Markdown";\n`,
80
+ `import Heading from "@theme/Heading";\n`,
80
81
  `import OperationTabs from "@theme/OperationTabs";\n`,
81
82
  `import TabItem from "@theme/TabItem";\n\n`,
82
- createHeading(title.replace(lessThan, "&lt;").replace(greaterThan, "&gt;")),
83
+ createHeading(title),
83
84
  createMethodEndpoint(method, path),
84
85
  infoPath && createAuthorization(infoPath),
85
86
  frontMatter.show_extensions
@@ -117,13 +118,14 @@ export function createInfoPageMD({
117
118
  }: InfoPageMetadata) {
118
119
  return render([
119
120
  `import ApiLogo from "@theme/ApiLogo";\n`,
121
+ `import Heading from "@theme/Heading";\n`,
120
122
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
121
123
  `import TabItem from "@theme/TabItem";\n`,
122
124
  `import Export from "@theme/ApiExplorer/Export";\n\n`,
123
125
 
124
126
  createVersionBadge(version),
125
127
  createDownload(downloadUrl),
126
- createHeading(title.replace(lessThan, "&lt;").replace(greaterThan, "&gt;")),
128
+ createHeading(title),
127
129
  createLogo(logo, darkLogo),
128
130
  createDescription(description),
129
131
  createAuthentication(securitySchemes as unknown as SecuritySchemeObject),
@@ -143,6 +145,7 @@ export function createSchemaPageMD({ schema }: SchemaPageMetadata) {
143
145
  `import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
144
146
  `import SchemaItem from "@theme/SchemaItem";\n`,
145
147
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
148
+ `import Heading from "@theme/Heading";\n`,
146
149
  `import TabItem from "@theme/TabItem";\n\n`,
147
150
  createHeading(title.replace(lessThan, "&lt;").replace(greaterThan, "&gt;")),
148
151
  createDescription(description),
@@ -9,15 +9,29 @@ export type Children = string | undefined | (string | string[] | undefined)[];
9
9
 
10
10
  export type Props = Record<string, any> & { children?: Children };
11
11
 
12
- export function create(tag: string, props: Props): string {
12
+ export type Options = { inline?: boolean };
13
+
14
+ export function create(
15
+ tag: string,
16
+ props: Props,
17
+ options: Options = {}
18
+ ): string {
13
19
  const { children, ...rest } = props;
14
20
 
15
21
  let propString = "";
16
22
  for (const [key, value] of Object.entries(rest)) {
17
- propString += ` ${key}={${JSON.stringify(value)}}`;
23
+ propString += `\n ${key}={${JSON.stringify(value)}}`;
18
24
  }
25
+ let indentedChildren = render(children).replace(/^/gm, " ");
19
26
 
20
- return `<${tag}${propString}>${render(children)}</${tag}>`;
27
+ if (options.inline) {
28
+ propString += `\n children={${JSON.stringify(children)}}`;
29
+ indentedChildren = "";
30
+ }
31
+
32
+ propString += propString ? "\n" : "";
33
+ indentedChildren += indentedChildren ? "\n" : "";
34
+ return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
21
35
  }
22
36
 
23
37
  export function guard<T>(
@@ -43,7 +57,29 @@ export function render(children: Children): string {
43
57
 
44
58
  // Regex to selectively URL-encode '>' and '<' chars
45
59
  export const lessThan =
46
- /<(?!(=|button|\s?\/button|code|\s?\/code|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|thead|\s?\/thead|tbody|\s?\/tbody|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|bold|\s?\/bold|a|\s?\/a|table|\s?\/table|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|svg|\s?\/svg|div|\s?\/div|center|\s?\/center))/gu;
60
+ /<=?(?!(=|button|\s?\/button|code|\s?\/code|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|thead|\s?\/thead|tbody|\s?\/tbody|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|bold|\s?\/bold|a|\s?\/a|table|\s?\/table|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|svg|\s?\/svg|div|\s?\/div|center|\s?\/center))/gu;
47
61
  export const greaterThan =
48
62
  /(?<!(button|code|details|summary|hr|br|span|strong|small|table|thead|tbody|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|bold|a|li|ol|ul|img|svg|div|center|\/|\s|"|'))>/gu;
49
63
  export const codeFence = /`{1,3}[\s\S]*?`{1,3}/g;
64
+ export const curlyBrackets = /([{|}])/g;
65
+ export const codeBlock = /(^```.*[\s\S]*?```$|`[^`].+?`)/gm;
66
+
67
+ export function clean(value: string | undefined): string {
68
+ if (!value) {
69
+ return "";
70
+ }
71
+
72
+ let sections = value.split(codeBlock);
73
+ for (let sectionIndex in sections) {
74
+ if (!sections[sectionIndex].startsWith("`")) {
75
+ sections[sectionIndex] = sections[sectionIndex]
76
+ .replace(lessThan, "&lt;")
77
+ .replace(greaterThan, "&gt;")
78
+ .replace(codeFence, function (match) {
79
+ return match.replace(/\\>/g, ">");
80
+ })
81
+ .replace(curlyBrackets, "\\$1");
82
+ }
83
+ }
84
+ return sections.join("");
85
+ }
@@ -326,8 +326,8 @@ export class OpenAPIParser {
326
326
  const receiverItems = isBoolean(receiver.items)
327
327
  ? { items: receiver.items }
328
328
  : receiver.items
329
- ? (Object.assign({}, receiver.items) as OpenAPISchema)
330
- : {};
329
+ ? (Object.assign({}, receiver.items) as OpenAPISchema)
330
+ : {};
331
331
  const subSchemaItems = isBoolean(items)
332
332
  ? { items }
333
333
  : (Object.assign({}, items) as OpenAPISchema);
@@ -689,7 +689,7 @@ export const shortenHTTPVerb = (verb) =>
689
689
  ({
690
690
  delete: "del",
691
691
  options: "opts",
692
- }[verb] || verb);
692
+ })[verb] || verb;
693
693
 
694
694
  export function isRedocExtension(key: string): boolean {
695
695
  const redocExtensions = {