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 +5 -0
- package/lib/markdown/createAuthentication.d.ts +2 -0
- package/lib/markdown/createAuthentication.js +139 -0
- package/lib/markdown/index.d.ts +1 -1
- package/lib/markdown/index.js +5 -1
- package/lib/openapi/createExample.js +59 -49
- package/lib/openapi/openapi.js +13 -11
- package/lib/types.d.ts +5 -0
- package/package.json +8 -8
- package/src/index.ts +5 -0
- package/src/markdown/createAuthentication.ts +160 -0
- package/src/markdown/index.ts +10 -1
- package/src/openapi/createExample.ts +59 -50
- package/src/openapi/openapi.ts +3 -1
- package/src/types.ts +5 -0
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,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;
|
package/lib/markdown/index.d.ts
CHANGED
|
@@ -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;
|
package/lib/markdown/index.js
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
79
|
+
return obj;
|
|
73
80
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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 (
|
|
81
|
-
|
|
90
|
+
if (schema.enum) {
|
|
91
|
+
if (schema.default) {
|
|
92
|
+
return schema.default;
|
|
93
|
+
}
|
|
94
|
+
return normalizeArray(schema.enum)[0];
|
|
82
95
|
}
|
|
83
|
-
return
|
|
96
|
+
return primitive(schema);
|
|
84
97
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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 = {}) {
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -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: (
|
|
110
|
-
title: (
|
|
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 = (
|
|
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
|
-
(
|
|
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 = (
|
|
125
|
-
const 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 = (
|
|
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 = (
|
|
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: (
|
|
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-
|
|
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.
|
|
32
|
-
"@docusaurus/types": "2.0.0-beta.
|
|
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.
|
|
40
|
-
"@docusaurus/plugin-content-docs": "2.0.0-beta.
|
|
41
|
-
"@docusaurus/utils": "2.0.0-beta.
|
|
42
|
-
"@docusaurus/utils-validation": "2.0.0-beta.
|
|
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": "
|
|
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
|
+
}
|
package/src/markdown/index.ts
CHANGED
|
@@ -7,8 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import { escape } from "lodash";
|
|
9
9
|
|
|
10
|
-
import {
|
|
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
|
-
|
|
53
|
+
try {
|
|
54
|
+
let { type, example, allOf, properties, items } = schema;
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
if (example !== undefined) {
|
|
57
|
+
return example;
|
|
58
|
+
}
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
96
|
+
return obj;
|
|
92
97
|
}
|
|
93
|
-
return obj;
|
|
94
|
-
}
|
|
95
98
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if (type === "array") {
|
|
100
|
+
if (Array.isArray(items?.anyOf)) {
|
|
101
|
+
return items?.anyOf.map((item) => sampleFromSchema(item));
|
|
102
|
+
}
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
if (Array.isArray(items?.oneOf)) {
|
|
105
|
+
return items?.oneOf.map((item) => sampleFromSchema(item));
|
|
106
|
+
}
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
return [sampleFromSchema(items)];
|
|
109
|
+
}
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
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 = {}) {
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -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 {
|