docusaurus-plugin-openapi-docs 0.0.0-360 → 0.0.0-365

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
@@ -78,6 +78,9 @@ api: {{{json}}}
78
78
  {{#api.method}}
79
79
  sidebar_class_name: "{{{api.method}}} api-method"
80
80
  {{/api.method}}
81
+ {{#infoPath}}
82
+ info_path: {{{infoPath}}}
83
+ {{/infoPath}}
81
84
  ---
82
85
 
83
86
  {{{markdown}}}
@@ -125,6 +128,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
125
128
  item.markdown = markdown;
126
129
  if (item.type === "api") {
127
130
  item.json = JSON.stringify(item.api);
131
+ if (item.infoId)
132
+ item.infoPath = `${outputDir}/${item.infoId}`;
128
133
  }
129
134
  const view = (0, mustache_1.render)(mdTemplate, item);
130
135
  const utils = (0, mustache_1.render)(infoMdTemplate, item);
@@ -0,0 +1,2 @@
1
+ import { SecuritySchemeObject } from "../openapi/types";
2
+ export declare function createAuthentication(securitySchemes: SecuritySchemeObject): string;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createAuthentication = void 0;
10
+ const createDescription_1 = require("./createDescription");
11
+ const utils_1 = require("./utils");
12
+ function createAuthentication(securitySchemes) {
13
+ if (!securitySchemes || !Object.keys(securitySchemes).length)
14
+ return "";
15
+ const createAuthenticationTable = (securityScheme) => {
16
+ const { bearerFormat, flows, name, scheme, type } = securityScheme;
17
+ const createSecuritySchemeTypeRow = () => (0, utils_1.create)("tr", {
18
+ children: [
19
+ (0, utils_1.create)("th", { children: "Security Scheme Type:" }),
20
+ (0, utils_1.create)("td", { children: type }),
21
+ ],
22
+ });
23
+ const createOAuthFlowRows = () => {
24
+ const flowRows = Object.entries(flows).map(([flowType, flowObj]) => {
25
+ const { authorizationUrl, tokenUrl, refreshUrl, scopes } = flowObj;
26
+ return (0, utils_1.create)("tr", {
27
+ children: [
28
+ (0, utils_1.create)("th", { children: `${flowType} OAuth Flow:` }),
29
+ (0, utils_1.create)("td", {
30
+ children: [
31
+ (0, utils_1.guard)(tokenUrl, () => (0, utils_1.create)("p", { children: `Token URL: ${tokenUrl}` })),
32
+ (0, utils_1.guard)(authorizationUrl, () => (0, utils_1.create)("p", {
33
+ children: `Authorization URL: ${authorizationUrl}`,
34
+ })),
35
+ (0, utils_1.guard)(refreshUrl, () => (0, utils_1.create)("p", { children: `Refresh URL: ${refreshUrl}` })),
36
+ (0, utils_1.create)("span", { children: "Scopes:" }),
37
+ (0, utils_1.create)("ul", {
38
+ children: Object.entries(scopes).map(([scope, description]) => (0, utils_1.create)("li", { children: `${scope}: ${description}` })),
39
+ }),
40
+ ],
41
+ }),
42
+ ],
43
+ });
44
+ });
45
+ return flowRows.join("");
46
+ };
47
+ switch (type) {
48
+ case "apiKey":
49
+ return (0, utils_1.create)("div", {
50
+ children: [
51
+ (0, utils_1.create)("table", {
52
+ children: (0, utils_1.create)("tbody", {
53
+ children: [
54
+ createSecuritySchemeTypeRow(),
55
+ (0, utils_1.create)("tr", {
56
+ children: [
57
+ (0, utils_1.create)("th", { children: "Header parameter name:" }),
58
+ (0, utils_1.create)("td", { children: name }),
59
+ ],
60
+ }),
61
+ ],
62
+ }),
63
+ }),
64
+ ],
65
+ });
66
+ case "http":
67
+ return (0, utils_1.create)("div", {
68
+ children: [
69
+ (0, utils_1.create)("table", {
70
+ children: (0, utils_1.create)("tbody", {
71
+ children: [
72
+ createSecuritySchemeTypeRow(),
73
+ (0, utils_1.create)("tr", {
74
+ children: [
75
+ (0, utils_1.create)("th", { children: "HTTP Authorization Scheme:" }),
76
+ (0, utils_1.create)("td", { children: scheme }),
77
+ ],
78
+ }),
79
+ (0, utils_1.create)("tr", {
80
+ children: [
81
+ (0, utils_1.create)("th", { children: "Bearer format:" }),
82
+ (0, utils_1.create)("td", { children: bearerFormat }),
83
+ ],
84
+ }),
85
+ ],
86
+ }),
87
+ }),
88
+ ],
89
+ });
90
+ case "oauth2":
91
+ return (0, utils_1.create)("div", {
92
+ children: [
93
+ (0, utils_1.create)("table", {
94
+ children: (0, utils_1.create)("tbody", {
95
+ children: [
96
+ createSecuritySchemeTypeRow(),
97
+ createOAuthFlowRows(),
98
+ ],
99
+ }),
100
+ }),
101
+ ],
102
+ });
103
+ default:
104
+ return "";
105
+ }
106
+ };
107
+ const formatTabLabel = (str) => {
108
+ const formattedLabel = str
109
+ .replace(/(_|-)/g, " ")
110
+ .trim()
111
+ .replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
112
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
113
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
114
+ const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
115
+ const isApiKey = formattedLabel.toLowerCase().includes("api");
116
+ return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
117
+ };
118
+ return (0, utils_1.create)("div", {
119
+ children: [
120
+ (0, utils_1.create)("h2", {
121
+ children: "Authentication",
122
+ id: "authentication",
123
+ style: { marginBottom: "1rem" },
124
+ }),
125
+ (0, utils_1.create)("Tabs", {
126
+ children: Object.entries(securitySchemes).map(([schemeType, schemeObj]) => (0, utils_1.create)("TabItem", {
127
+ label: formatTabLabel(schemeType),
128
+ value: `${schemeType}`,
129
+ children: [
130
+ (0, createDescription_1.createDescription)(schemeObj.description),
131
+ createAuthenticationTable(schemeObj),
132
+ ],
133
+ })),
134
+ }),
135
+ ],
136
+ style: { marginBottom: "2rem" },
137
+ });
138
+ }
139
+ exports.createAuthentication = createAuthentication;
@@ -1,4 +1,4 @@
1
1
  import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
2
2
  export declare function createApiPageMD({ title, api: { deprecated, "x-deprecated-description": deprecatedDescription, description, parameters, requestBody, responses, }, }: ApiPageMetadata): string;
3
- export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }: InfoPageMetadata): string;
3
+ export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, securitySchemes, }: InfoPageMetadata): string;
4
4
  export declare function createTagPageMD({ tag: { description } }: TagPageMetadata): string;
@@ -8,6 +8,7 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.createTagPageMD = exports.createInfoPageMD = exports.createApiPageMD = void 0;
10
10
  const lodash_1 = require("lodash");
11
+ const createAuthentication_1 = require("./createAuthentication");
11
12
  const createContactInfo_1 = require("./createContactInfo");
12
13
  const createDeprecationNotice_1 = require("./createDeprecationNotice");
13
14
  const createDescription_1 = require("./createDescription");
@@ -36,11 +37,14 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
36
37
  ]);
37
38
  }
38
39
  exports.createApiPageMD = createApiPageMD;
39
- function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }) {
40
+ function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, securitySchemes, }) {
40
41
  return (0, utils_1.render)([
42
+ `import Tabs from "@theme/Tabs";\n`,
43
+ `import TabItem from "@theme/TabItem";\n`,
41
44
  (0, createVersionBadge_1.createVersionBadge)(version),
42
45
  `# ${(0, lodash_1.escape)(title)}\n\n`,
43
46
  (0, createDescription_1.createDescription)(description),
47
+ (0, createAuthentication_1.createAuthentication)(securitySchemes),
44
48
  (0, createContactInfo_1.createContactInfo)(contact),
45
49
  (0, createTermsOfService_1.createTermsOfService)(termsOfService),
46
50
  (0, createLicense_1.createLicense)(license),
@@ -5,8 +5,12 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  * ========================================================================== */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.sampleFromSchema = void 0;
13
+ const chalk_1 = __importDefault(require("chalk"));
10
14
  const primitives = {
11
15
  string: {
12
16
  default: () => "string",
@@ -31,64 +35,70 @@ const primitives = {
31
35
  array: {},
32
36
  };
33
37
  const sampleFromSchema = (schema = {}) => {
34
- let { type, example, allOf, properties, items } = schema;
35
- if (example !== undefined) {
36
- return example;
37
- }
38
- if (allOf) {
39
- // TODO: We are just assuming it will always be an object for now
40
- let obj = {
41
- type: "object",
42
- properties: {},
43
- required: [], // NOTE: We shouldn't need to worry about required
44
- };
45
- for (let item of allOf) {
46
- if (item.properties) {
47
- obj.properties = {
48
- ...obj.properties,
49
- ...item.properties,
50
- };
51
- }
52
- }
53
- return (0, exports.sampleFromSchema)(obj);
54
- }
55
- if (!type) {
56
- if (properties) {
57
- type = "object";
38
+ try {
39
+ let { type, example, allOf, properties, items } = schema;
40
+ if (example !== undefined) {
41
+ return example;
58
42
  }
59
- else if (items) {
60
- type = "array";
43
+ if (allOf) {
44
+ // TODO: We are just assuming it will always be an object for now
45
+ let obj = {
46
+ type: "object",
47
+ properties: {},
48
+ required: [], // NOTE: We shouldn't need to worry about required
49
+ };
50
+ for (let item of allOf) {
51
+ if (item.properties) {
52
+ obj.properties = {
53
+ ...obj.properties,
54
+ ...item.properties,
55
+ };
56
+ }
57
+ }
58
+ return (0, exports.sampleFromSchema)(obj);
61
59
  }
62
- else {
63
- return;
60
+ if (!type) {
61
+ if (properties) {
62
+ type = "object";
63
+ }
64
+ else if (items) {
65
+ type = "array";
66
+ }
67
+ else {
68
+ return;
69
+ }
64
70
  }
65
- }
66
- if (type === "object") {
67
- let obj = {};
68
- for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
69
- if (prop.deprecated) {
70
- continue;
71
+ if (type === "object") {
72
+ let obj = {};
73
+ for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
74
+ if (prop.deprecated) {
75
+ continue;
76
+ }
77
+ obj[name] = (0, exports.sampleFromSchema)(prop);
71
78
  }
72
- obj[name] = (0, exports.sampleFromSchema)(prop);
79
+ return obj;
73
80
  }
74
- return obj;
75
- }
76
- if (type === "array") {
77
- if (Array.isArray(items === null || items === void 0 ? void 0 : items.anyOf)) {
78
- return items === null || items === void 0 ? void 0 : items.anyOf.map((item) => (0, exports.sampleFromSchema)(item));
81
+ if (type === "array") {
82
+ if (Array.isArray(items === null || items === void 0 ? void 0 : items.anyOf)) {
83
+ return items === null || items === void 0 ? void 0 : items.anyOf.map((item) => (0, exports.sampleFromSchema)(item));
84
+ }
85
+ if (Array.isArray(items === null || items === void 0 ? void 0 : items.oneOf)) {
86
+ return items === null || items === void 0 ? void 0 : items.oneOf.map((item) => (0, exports.sampleFromSchema)(item));
87
+ }
88
+ return [(0, exports.sampleFromSchema)(items)];
79
89
  }
80
- if (Array.isArray(items === null || items === void 0 ? void 0 : items.oneOf)) {
81
- return items === null || items === void 0 ? void 0 : items.oneOf.map((item) => (0, exports.sampleFromSchema)(item));
90
+ if (schema.enum) {
91
+ if (schema.default) {
92
+ return schema.default;
93
+ }
94
+ return normalizeArray(schema.enum)[0];
82
95
  }
83
- return [(0, exports.sampleFromSchema)(items)];
96
+ return primitive(schema);
84
97
  }
85
- if (schema.enum) {
86
- if (schema.default) {
87
- return schema.default;
88
- }
89
- return normalizeArray(schema.enum)[0];
98
+ catch (err) {
99
+ console.error(chalk_1.default.yellow("WARNING: failed to create example from schema object:", err));
100
+ return;
90
101
  }
91
- return primitive(schema);
92
102
  };
93
103
  exports.sampleFromSchema = sampleFromSchema;
94
104
  function primitive(schema = {}) {
@@ -64,9 +64,10 @@ async function createPostmanCollection(openapiData) {
64
64
  return await jsonToCollection(data);
65
65
  }
66
66
  function createItems(openapiData, sidebarOptions) {
67
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
67
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
68
68
  // TODO: Find a better way to handle this
69
69
  let items = [];
70
+ const infoId = (0, lodash_1.kebabCase)(openapiData.info.title);
70
71
  if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
71
72
  // Only create an tag pages if categoryLinkSource set to tag.
72
73
  const tags = (_a = openapiData.tags) !== null && _a !== void 0 ? _a : [];
@@ -95,7 +96,6 @@ function createItems(openapiData, sidebarOptions) {
95
96
  }
96
97
  if (openapiData.info.description) {
97
98
  // Only create an info page if we have a description.
98
- const infoId = (0, lodash_1.kebabCase)(openapiData.info.title);
99
99
  const infoPage = {
100
100
  type: "info",
101
101
  id: infoId,
@@ -104,10 +104,11 @@ function createItems(openapiData, sidebarOptions) {
104
104
  description: openapiData.info.description,
105
105
  slug: "/" + infoId,
106
106
  frontMatter: {},
107
+ securitySchemes: (_b = openapiData.components) === null || _b === void 0 ? void 0 : _b.securitySchemes,
107
108
  info: {
108
109
  ...openapiData.info,
109
- tags: (_b = openapiData.tags) === null || _b === void 0 ? void 0 : _b.map((tagName) => { var _a; return getTagDisplayName(tagName.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
110
- title: (_c = openapiData.info.title) !== null && _c !== void 0 ? _c : "Introduction",
110
+ tags: (_c = openapiData.tags) === null || _c === void 0 ? void 0 : _c.map((tagName) => { var _a; return getTagDisplayName(tagName.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
111
+ title: (_d = openapiData.info.title) !== null && _d !== void 0 ? _d : "Introduction",
111
112
  },
112
113
  };
113
114
  items.push(infoPage);
@@ -115,16 +116,16 @@ function createItems(openapiData, sidebarOptions) {
115
116
  for (let [path, pathObject] of Object.entries(openapiData.paths)) {
116
117
  const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
117
118
  for (let [method, operationObject] of Object.entries({ ...rest })) {
118
- const title = (_e = (_d = operationObject.summary) !== null && _d !== void 0 ? _d : operationObject.operationId) !== null && _e !== void 0 ? _e : "Missing summary";
119
+ const title = (_f = (_e = operationObject.summary) !== null && _e !== void 0 ? _e : operationObject.operationId) !== null && _f !== void 0 ? _f : "Missing summary";
119
120
  if (operationObject.description === undefined) {
120
121
  operationObject.description =
121
- (_g = (_f = operationObject.summary) !== null && _f !== void 0 ? _f : operationObject.operationId) !== null && _g !== void 0 ? _g : "";
122
+ (_h = (_g = operationObject.summary) !== null && _g !== void 0 ? _g : operationObject.operationId) !== null && _h !== void 0 ? _h : "";
122
123
  }
123
124
  const baseId = (0, lodash_1.kebabCase)(title);
124
- const servers = (_j = (_h = operationObject.servers) !== null && _h !== void 0 ? _h : pathObject.servers) !== null && _j !== void 0 ? _j : openapiData.servers;
125
- const security = (_k = operationObject.security) !== null && _k !== void 0 ? _k : openapiData.security;
125
+ const servers = (_k = (_j = operationObject.servers) !== null && _j !== void 0 ? _j : pathObject.servers) !== null && _k !== void 0 ? _k : openapiData.servers;
126
+ const security = (_l = operationObject.security) !== null && _l !== void 0 ? _l : openapiData.security;
126
127
  // Add security schemes so we know how to handle security.
127
- const securitySchemes = (_l = openapiData.components) === null || _l === void 0 ? void 0 : _l.securitySchemes;
128
+ const securitySchemes = (_m = openapiData.components) === null || _m === void 0 ? void 0 : _m.securitySchemes;
128
129
  // Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
129
130
  if (securitySchemes) {
130
131
  for (let securityScheme of Object.values(securitySchemes)) {
@@ -134,7 +135,7 @@ function createItems(openapiData, sidebarOptions) {
134
135
  }
135
136
  }
136
137
  let jsonRequestBodyExample;
137
- const body = (_o = (_m = operationObject.requestBody) === null || _m === void 0 ? void 0 : _m.content) === null || _o === void 0 ? void 0 : _o["application/json"];
138
+ const body = (_p = (_o = operationObject.requestBody) === null || _o === void 0 ? void 0 : _o.content) === null || _p === void 0 ? void 0 : _p["application/json"];
138
139
  if (body === null || body === void 0 ? void 0 : body.schema) {
139
140
  jsonRequestBodyExample = (0, createExample_1.sampleFromSchema)(body.schema);
140
141
  }
@@ -143,6 +144,7 @@ function createItems(openapiData, sidebarOptions) {
143
144
  const apiPage = {
144
145
  type: "api",
145
146
  id: baseId,
147
+ infoId: infoId !== null && infoId !== void 0 ? infoId : "",
146
148
  unversionedId: baseId,
147
149
  title: title,
148
150
  description: description !== null && description !== void 0 ? description : "",
@@ -150,7 +152,7 @@ function createItems(openapiData, sidebarOptions) {
150
152
  frontMatter: {},
151
153
  api: {
152
154
  ...defaults,
153
- tags: (_p = operationObject.tags) === null || _p === void 0 ? void 0 : _p.map((tagName) => { var _a; return getTagDisplayName(tagName, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
155
+ tags: (_q = operationObject.tags) === null || _q === void 0 ? void 0 : _q.map((tagName) => { var _a; return getTagDisplayName(tagName, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
154
156
  method,
155
157
  path,
156
158
  servers,
package/lib/types.d.ts CHANGED
@@ -23,6 +23,8 @@ export interface ApiMetadataBase {
23
23
  next?: ApiNavLink;
24
24
  id: string;
25
25
  unversionedId: string;
26
+ infoId?: string;
27
+ infoPath?: string;
26
28
  title: string;
27
29
  description: string;
28
30
  source: string;
@@ -52,6 +54,9 @@ export interface InfoPageMetadata extends ApiMetadataBase {
52
54
  type: "info";
53
55
  info: ApiInfo;
54
56
  markdown?: string;
57
+ securitySchemes?: {
58
+ [key: string]: SecuritySchemeObject;
59
+ };
55
60
  }
56
61
  export interface TagPageMetadata extends ApiMetadataBase {
57
62
  type: "tag";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-plugin-openapi-docs",
3
3
  "description": "OpenAPI plugin for Docusaurus.",
4
- "version": "0.0.0-360",
4
+ "version": "0.0.0-365",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,18 +28,18 @@
28
28
  "watch": "tsc --watch"
29
29
  },
30
30
  "devDependencies": {
31
- "@docusaurus/module-type-aliases": "2.0.0-beta.18",
32
- "@docusaurus/types": "2.0.0-beta.18",
31
+ "@docusaurus/module-type-aliases": "2.0.0-beta.21",
32
+ "@docusaurus/types": "2.0.0-beta.21",
33
33
  "@types/fs-extra": "^9.0.13",
34
34
  "@types/json-schema": "^7.0.9",
35
35
  "@types/lodash": "^4.14.176",
36
36
  "utility-types": "^3.10.0"
37
37
  },
38
38
  "dependencies": {
39
- "@docusaurus/mdx-loader": "2.0.0-beta.18",
40
- "@docusaurus/plugin-content-docs": "2.0.0-beta.18",
41
- "@docusaurus/utils": "2.0.0-beta.18",
42
- "@docusaurus/utils-validation": "2.0.0-beta.18",
39
+ "@docusaurus/mdx-loader": "2.0.0-beta.21",
40
+ "@docusaurus/plugin-content-docs": "2.0.0-beta.21",
41
+ "@docusaurus/utils": "2.0.0-beta.21",
42
+ "@docusaurus/utils-validation": "2.0.0-beta.21",
43
43
  "@paloaltonetworks/openapi-to-postmanv2": "3.1.0-hotfix.1",
44
44
  "@paloaltonetworks/postman-collection": "^4.1.0",
45
45
  "@types/js-yaml": "^4.0.5",
@@ -60,5 +60,5 @@
60
60
  "engines": {
61
61
  "node": ">=14"
62
62
  },
63
- "gitHead": "68ef835e7fa974cbf00ea0ccab6945b3c7ef2ba7"
63
+ "gitHead": "f9390cc5f7f74c629f45bb374c26dac169deb797"
64
64
  }
package/src/index.ts CHANGED
@@ -103,6 +103,9 @@ api: {{{json}}}
103
103
  {{#api.method}}
104
104
  sidebar_class_name: "{{{api.method}}} api-method"
105
105
  {{/api.method}}
106
+ {{#infoPath}}
107
+ info_path: {{{infoPath}}}
108
+ {{/infoPath}}
106
109
  ---
107
110
 
108
111
  {{{markdown}}}
@@ -154,7 +157,9 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
154
157
  item.markdown = markdown;
155
158
  if (item.type === "api") {
156
159
  item.json = JSON.stringify(item.api);
160
+ if (item.infoId) item.infoPath = `${outputDir}/${item.infoId}`;
157
161
  }
162
+
158
163
  const view = render(mdTemplate, item);
159
164
  const utils = render(infoMdTemplate, item);
160
165
  // eslint-disable-next-line testing-library/render-result-naming-convention
@@ -0,0 +1,160 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ import { OAuthFlowObject, SecuritySchemeObject } from "../openapi/types";
9
+ import { createDescription } from "./createDescription";
10
+ import { create, guard } from "./utils";
11
+
12
+ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
13
+ if (!securitySchemes || !Object.keys(securitySchemes).length) return "";
14
+
15
+ const createAuthenticationTable = (securityScheme: any) => {
16
+ const { bearerFormat, flows, name, scheme, type } = securityScheme;
17
+
18
+ const createSecuritySchemeTypeRow = () =>
19
+ create("tr", {
20
+ children: [
21
+ create("th", { children: "Security Scheme Type:" }),
22
+ create("td", { children: type }),
23
+ ],
24
+ });
25
+
26
+ const createOAuthFlowRows = () => {
27
+ const flowRows = Object.entries(flows).map(([flowType, flowObj]) => {
28
+ const { authorizationUrl, tokenUrl, refreshUrl, scopes } =
29
+ flowObj as OAuthFlowObject;
30
+
31
+ return create("tr", {
32
+ children: [
33
+ create("th", { children: `${flowType} OAuth Flow:` }),
34
+ create("td", {
35
+ children: [
36
+ guard(tokenUrl, () =>
37
+ create("p", { children: `Token URL: ${tokenUrl}` })
38
+ ),
39
+ guard(authorizationUrl, () =>
40
+ create("p", {
41
+ children: `Authorization URL: ${authorizationUrl}`,
42
+ })
43
+ ),
44
+ guard(refreshUrl, () =>
45
+ create("p", { children: `Refresh URL: ${refreshUrl}` })
46
+ ),
47
+ create("span", { children: "Scopes:" }),
48
+ create("ul", {
49
+ children: Object.entries(scopes).map(([scope, description]) =>
50
+ create("li", { children: `${scope}: ${description}` })
51
+ ),
52
+ }),
53
+ ],
54
+ }),
55
+ ],
56
+ });
57
+ });
58
+
59
+ return flowRows.join("");
60
+ };
61
+
62
+ switch (type) {
63
+ case "apiKey":
64
+ return create("div", {
65
+ children: [
66
+ create("table", {
67
+ children: create("tbody", {
68
+ children: [
69
+ createSecuritySchemeTypeRow(),
70
+ create("tr", {
71
+ children: [
72
+ create("th", { children: "Header parameter name:" }),
73
+ create("td", { children: name }),
74
+ ],
75
+ }),
76
+ ],
77
+ }),
78
+ }),
79
+ ],
80
+ });
81
+ case "http":
82
+ return create("div", {
83
+ children: [
84
+ create("table", {
85
+ children: create("tbody", {
86
+ children: [
87
+ createSecuritySchemeTypeRow(),
88
+ create("tr", {
89
+ children: [
90
+ create("th", { children: "HTTP Authorization Scheme:" }),
91
+ create("td", { children: scheme }),
92
+ ],
93
+ }),
94
+ create("tr", {
95
+ children: [
96
+ create("th", { children: "Bearer format:" }),
97
+ create("td", { children: bearerFormat }),
98
+ ],
99
+ }),
100
+ ],
101
+ }),
102
+ }),
103
+ ],
104
+ });
105
+ case "oauth2":
106
+ return create("div", {
107
+ children: [
108
+ create("table", {
109
+ children: create("tbody", {
110
+ children: [
111
+ createSecuritySchemeTypeRow(),
112
+ createOAuthFlowRows(),
113
+ ],
114
+ }),
115
+ }),
116
+ ],
117
+ });
118
+ default:
119
+ return "";
120
+ }
121
+ };
122
+
123
+ const formatTabLabel = (str: string) => {
124
+ const formattedLabel = str
125
+ .replace(/(_|-)/g, " ")
126
+ .trim()
127
+ .replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
128
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
129
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
130
+
131
+ const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
132
+ const isApiKey = formattedLabel.toLowerCase().includes("api");
133
+
134
+ return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
135
+ };
136
+
137
+ return create("div", {
138
+ children: [
139
+ create("h2", {
140
+ children: "Authentication",
141
+ id: "authentication",
142
+ style: { marginBottom: "1rem" },
143
+ }),
144
+ create("Tabs", {
145
+ children: Object.entries(securitySchemes).map(
146
+ ([schemeType, schemeObj]) =>
147
+ create("TabItem", {
148
+ label: formatTabLabel(schemeType),
149
+ value: `${schemeType}`,
150
+ children: [
151
+ createDescription(schemeObj.description),
152
+ createAuthenticationTable(schemeObj),
153
+ ],
154
+ })
155
+ ),
156
+ }),
157
+ ],
158
+ style: { marginBottom: "2rem" },
159
+ });
160
+ }
@@ -7,8 +7,13 @@
7
7
 
8
8
  import { escape } from "lodash";
9
9
 
10
- import { ContactObject, LicenseObject } from "../openapi/types";
10
+ import {
11
+ ContactObject,
12
+ LicenseObject,
13
+ SecuritySchemeObject,
14
+ } from "../openapi/types";
11
15
  import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
16
+ import { createAuthentication } from "./createAuthentication";
12
17
  import { createContactInfo } from "./createContactInfo";
13
18
  import { createDeprecationNotice } from "./createDeprecationNotice";
14
19
  import { createDescription } from "./createDescription";
@@ -50,11 +55,15 @@ export function createApiPageMD({
50
55
 
51
56
  export function createInfoPageMD({
52
57
  info: { title, version, description, contact, license, termsOfService },
58
+ securitySchemes,
53
59
  }: InfoPageMetadata) {
54
60
  return render([
61
+ `import Tabs from "@theme/Tabs";\n`,
62
+ `import TabItem from "@theme/TabItem";\n`,
55
63
  createVersionBadge(version),
56
64
  `# ${escape(title)}\n\n`,
57
65
  createDescription(description),
66
+ createAuthentication(securitySchemes as unknown as SecuritySchemeObject),
58
67
  createContactInfo(contact as ContactObject),
59
68
  createTermsOfService(termsOfService),
60
69
  createLicense(license as LicenseObject),
@@ -5,6 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
+ import chalk from "chalk";
9
+
8
10
  import { SchemaObject } from "./types";
9
11
 
10
12
  interface OASTypeToTypeMap {
@@ -48,71 +50,78 @@ const primitives: Primitives = {
48
50
  };
49
51
 
50
52
  export const sampleFromSchema = (schema: SchemaObject = {}): any => {
51
- let { type, example, allOf, properties, items } = schema;
53
+ try {
54
+ let { type, example, allOf, properties, items } = schema;
52
55
 
53
- if (example !== undefined) {
54
- return example;
55
- }
56
+ if (example !== undefined) {
57
+ return example;
58
+ }
56
59
 
57
- if (allOf) {
58
- // TODO: We are just assuming it will always be an object for now
59
- let obj: SchemaObject = {
60
- type: "object",
61
- properties: {},
62
- required: [], // NOTE: We shouldn't need to worry about required
63
- };
64
- for (let item of allOf) {
65
- if (item.properties) {
66
- obj.properties = {
67
- ...obj.properties,
68
- ...item.properties,
69
- };
60
+ if (allOf) {
61
+ // TODO: We are just assuming it will always be an object for now
62
+ let obj: SchemaObject = {
63
+ type: "object",
64
+ properties: {},
65
+ required: [], // NOTE: We shouldn't need to worry about required
66
+ };
67
+ for (let item of allOf) {
68
+ if (item.properties) {
69
+ obj.properties = {
70
+ ...obj.properties,
71
+ ...item.properties,
72
+ };
73
+ }
70
74
  }
75
+ return sampleFromSchema(obj);
71
76
  }
72
- return sampleFromSchema(obj);
73
- }
74
77
 
75
- if (!type) {
76
- if (properties) {
77
- type = "object";
78
- } else if (items) {
79
- type = "array";
80
- } else {
81
- return;
78
+ if (!type) {
79
+ if (properties) {
80
+ type = "object";
81
+ } else if (items) {
82
+ type = "array";
83
+ } else {
84
+ return;
85
+ }
82
86
  }
83
- }
84
87
 
85
- if (type === "object") {
86
- let obj: any = {};
87
- for (let [name, prop] of Object.entries(properties ?? {})) {
88
- if (prop.deprecated) {
89
- continue;
88
+ if (type === "object") {
89
+ let obj: any = {};
90
+ for (let [name, prop] of Object.entries(properties ?? {})) {
91
+ if (prop.deprecated) {
92
+ continue;
93
+ }
94
+ obj[name] = sampleFromSchema(prop);
90
95
  }
91
- obj[name] = sampleFromSchema(prop);
96
+ return obj;
92
97
  }
93
- return obj;
94
- }
95
98
 
96
- if (type === "array") {
97
- if (Array.isArray(items?.anyOf)) {
98
- return items?.anyOf.map((item) => sampleFromSchema(item));
99
- }
99
+ if (type === "array") {
100
+ if (Array.isArray(items?.anyOf)) {
101
+ return items?.anyOf.map((item) => sampleFromSchema(item));
102
+ }
100
103
 
101
- if (Array.isArray(items?.oneOf)) {
102
- return items?.oneOf.map((item) => sampleFromSchema(item));
103
- }
104
+ if (Array.isArray(items?.oneOf)) {
105
+ return items?.oneOf.map((item) => sampleFromSchema(item));
106
+ }
104
107
 
105
- return [sampleFromSchema(items)];
106
- }
108
+ return [sampleFromSchema(items)];
109
+ }
107
110
 
108
- if (schema.enum) {
109
- if (schema.default) {
110
- return schema.default;
111
+ if (schema.enum) {
112
+ if (schema.default) {
113
+ return schema.default;
114
+ }
115
+ return normalizeArray(schema.enum)[0];
111
116
  }
112
- return normalizeArray(schema.enum)[0];
113
- }
114
117
 
115
- return primitive(schema);
118
+ return primitive(schema);
119
+ } catch (err) {
120
+ console.error(
121
+ chalk.yellow("WARNING: failed to create example from schema object:", err)
122
+ );
123
+ return;
124
+ }
116
125
  };
117
126
 
118
127
  function primitive(schema: SchemaObject = {}) {
@@ -87,6 +87,7 @@ function createItems(
87
87
  ): ApiMetadata[] {
88
88
  // TODO: Find a better way to handle this
89
89
  let items: PartialPage<ApiMetadata>[] = [];
90
+ const infoId = kebabCase(openapiData.info.title);
90
91
 
91
92
  if (sidebarOptions?.categoryLinkSource === "tag") {
92
93
  // Only create an tag pages if categoryLinkSource set to tag.
@@ -119,7 +120,6 @@ function createItems(
119
120
 
120
121
  if (openapiData.info.description) {
121
122
  // Only create an info page if we have a description.
122
- const infoId = kebabCase(openapiData.info.title);
123
123
  const infoPage: PartialPage<InfoPageMetadata> = {
124
124
  type: "info",
125
125
  id: infoId,
@@ -128,6 +128,7 @@ function createItems(
128
128
  description: openapiData.info.description,
129
129
  slug: "/" + infoId,
130
130
  frontMatter: {},
131
+ securitySchemes: openapiData.components?.securitySchemes,
131
132
  info: {
132
133
  ...openapiData.info,
133
134
  tags: openapiData.tags?.map((tagName) =>
@@ -183,6 +184,7 @@ function createItems(
183
184
  const apiPage: PartialPage<ApiPageMetadata> = {
184
185
  type: "api",
185
186
  id: baseId,
187
+ infoId: infoId ?? "",
186
188
  unversionedId: baseId,
187
189
  title: title,
188
190
  description: description ?? "",
package/src/types.ts CHANGED
@@ -48,6 +48,8 @@ export interface ApiMetadataBase {
48
48
  //
49
49
  id: string; // TODO legacy versioned id => try to remove
50
50
  unversionedId: string; // TODO new unversioned id => try to rename to "id"
51
+ infoId?: string;
52
+ infoPath?: string;
51
53
  title: string;
52
54
  description: string;
53
55
  source: string; // @site aliased source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
@@ -80,6 +82,9 @@ export interface InfoPageMetadata extends ApiMetadataBase {
80
82
  type: "info";
81
83
  info: ApiInfo;
82
84
  markdown?: string;
85
+ securitySchemes?: {
86
+ [key: string]: SecuritySchemeObject;
87
+ };
83
88
  }
84
89
 
85
90
  export interface TagPageMetadata extends ApiMetadataBase {