docusaurus-plugin-openapi-docs 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/lib/index.js +32 -7
- package/lib/markdown/createContactInfo.d.ts +2 -0
- package/lib/markdown/createContactInfo.js +49 -0
- package/lib/markdown/createLicense.d.ts +2 -0
- package/lib/markdown/createLicense.js +33 -0
- package/lib/markdown/createSchemaDetails.js +4 -1
- package/lib/markdown/createStatusCodes.js +1 -1
- package/lib/markdown/createTermsOfService.d.ts +1 -0
- package/lib/markdown/createTermsOfService.js +32 -0
- package/lib/markdown/index.d.ts +1 -1
- package/lib/markdown/index.js +8 -2
- package/lib/openapi/openapi.d.ts +4 -3
- package/lib/openapi/openapi.js +35 -21
- package/lib/openapi/types.d.ts +5 -1
- package/lib/sidebars/index.d.ts +2 -1
- package/lib/sidebars/index.js +72 -19
- package/lib/types.d.ts +2 -1
- package/package.json +2 -3
- package/src/index.ts +44 -8
- package/src/markdown/createContactInfo.ts +52 -0
- package/src/markdown/createLicense.ts +34 -0
- package/src/markdown/createSchemaDetails.ts +6 -2
- package/src/markdown/createStatusCodes.ts +1 -1
- package/src/markdown/createTermsOfService.ts +30 -0
- package/src/markdown/index.ts +9 -2
- package/src/openapi/openapi.ts +32 -16
- package/src/openapi/types.ts +5 -1
- package/src/{markdown/createRequestBodyTable.ts → postman-collection.d.ts} +2 -9
- package/src/sidebars/index.ts +90 -20
- package/src/types.ts +2 -2
- package/lib/markdown/createFullWidthTable.d.ts +0 -2
- package/lib/markdown/createFullWidthTable.js +0 -18
- package/lib/markdown/createParamsTable.d.ts +0 -7
- package/lib/markdown/createParamsTable.js +0 -80
- package/lib/markdown/createRequestBodyTable.d.ts +0 -6
- package/lib/markdown/createRequestBodyTable.js +0 -14
- package/lib/markdown/createSchemaTable.d.ts +0 -14
- package/lib/markdown/createSchemaTable.js +0 -217
- package/src/markdown/createFullWidthTable.ts +0 -16
- package/src/markdown/createParamsTable.ts +0 -102
- package/src/markdown/createSchemaTable.ts +0 -275
package/README.md
CHANGED
|
@@ -110,12 +110,13 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
|
|
|
110
110
|
|
|
111
111
|
`sidebarOptions` can be configured with the following options:
|
|
112
112
|
|
|
113
|
-
| Name | Type | Default | Description
|
|
114
|
-
| -------------------- | --------- | ------- |
|
|
115
|
-
| `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by "tags".
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
113
|
+
| Name | Type | Default | Description |
|
|
114
|
+
| -------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
|
+
| `groupPathsBy` | `string` | `null` | Organize and group sidebar slice by specified option. Note: Currently, `groupPathsBy` only contains support for grouping by "tags". |
|
|
116
|
+
| `categoryLinkSource` | `string` | `null` | Defines what source to use for rendering category link pages when grouping paths by tag. <br/></br>The supported options are as follows: <br/></br> `tag`: Sets the category link config type to `generated-index` and uses the tag description as the link config description. <br/><br/>`info`: Sets the category link config type to `doc` and renders the `info` section as the category link (recommended only for multi/micro-spec scenarios). |
|
|
117
|
+
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. |
|
|
118
|
+
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. |
|
|
119
|
+
| `customProps` | `object` | `null` | Additional props for customizing a sidebar item. |
|
|
119
120
|
|
|
120
121
|
> Note: You may optionally configure a `sidebarOptions`. In doing so, an individual `sidebar.js` slice with the configured options will be generated within the respective `outputDir`.
|
|
121
122
|
|
package/lib/index.js
CHANGED
|
@@ -25,7 +25,7 @@ function pluginOpenAPI(context, options) {
|
|
|
25
25
|
const contentPath = path_1.default.resolve(siteDir, specPath);
|
|
26
26
|
try {
|
|
27
27
|
const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath, {});
|
|
28
|
-
const loadedApi = await (0, openapi_1.processOpenapiFiles)(openapiFiles);
|
|
28
|
+
const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles);
|
|
29
29
|
if (!fs_1.default.existsSync(outputDir)) {
|
|
30
30
|
try {
|
|
31
31
|
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
@@ -38,7 +38,7 @@ function pluginOpenAPI(context, options) {
|
|
|
38
38
|
// TODO: figure out better way to set default
|
|
39
39
|
if (Object.keys(sidebarOptions !== null && sidebarOptions !== void 0 ? sidebarOptions : {}).length > 0) {
|
|
40
40
|
const sidebarSlice = (0, sidebars_1.default)(sidebarOptions, // TODO: find a better way to handle null
|
|
41
|
-
options, loadedApi);
|
|
41
|
+
options, loadedApi, tags);
|
|
42
42
|
const sidebarSliceTemplate = template
|
|
43
43
|
? fs_1.default.readFileSync(template).toString()
|
|
44
44
|
: `module.exports = {{{slice}}};`;
|
|
@@ -59,7 +59,12 @@ function pluginOpenAPI(context, options) {
|
|
|
59
59
|
? fs_1.default.readFileSync(template).toString()
|
|
60
60
|
: `---
|
|
61
61
|
id: {{{id}}}
|
|
62
|
+
{{^api}}
|
|
63
|
+
sidebar_label: Introduction
|
|
64
|
+
{{/api}}
|
|
65
|
+
{{#api}}
|
|
62
66
|
sidebar_label: {{{title}}}
|
|
67
|
+
{{/api}}
|
|
63
68
|
{{^api}}
|
|
64
69
|
sidebar_position: 0
|
|
65
70
|
{{/api}}
|
|
@@ -76,6 +81,23 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
76
81
|
---
|
|
77
82
|
|
|
78
83
|
{{{markdown}}}
|
|
84
|
+
`;
|
|
85
|
+
const infoMdTemplate = template
|
|
86
|
+
? fs_1.default.readFileSync(template).toString()
|
|
87
|
+
: `---
|
|
88
|
+
id: {{{id}}}
|
|
89
|
+
sidebar_label: {{{title}}}
|
|
90
|
+
hide_title: true
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
{{{markdown}}}
|
|
94
|
+
|
|
95
|
+
\`\`\`mdx-code-block
|
|
96
|
+
import DocCardList from '@theme/DocCardList';
|
|
97
|
+
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
98
|
+
|
|
99
|
+
<DocCardList items={useCurrentSidebarCategory().items}/>
|
|
100
|
+
\`\`\`
|
|
79
101
|
`;
|
|
80
102
|
loadedApi.map(async (item) => {
|
|
81
103
|
const markdown = item.type === "api" ? (0, markdown_1.createApiPageMD)(item) : (0, markdown_1.createInfoPageMD)(item);
|
|
@@ -84,6 +106,7 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
84
106
|
item.json = JSON.stringify(item.api);
|
|
85
107
|
}
|
|
86
108
|
const view = (0, mustache_1.render)(mdTemplate, item);
|
|
109
|
+
const utils = (0, mustache_1.render)(infoMdTemplate, item);
|
|
87
110
|
if (item.type === "api") {
|
|
88
111
|
if (!fs_1.default.existsSync(`${outputDir}/${item.id}.api.mdx`)) {
|
|
89
112
|
try {
|
|
@@ -97,13 +120,15 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
97
120
|
}
|
|
98
121
|
// TODO: determine if we actually want/need this
|
|
99
122
|
if (item.type === "info") {
|
|
100
|
-
if (!fs_1.default.existsSync(`${outputDir}
|
|
123
|
+
if (!fs_1.default.existsSync(`${outputDir}/${item.id}.info.mdx`)) {
|
|
101
124
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
125
|
+
(sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "info" // Only use utils template if set to "info"
|
|
126
|
+
? fs_1.default.writeFileSync(`${outputDir}/${item.id}.info.mdx`, utils, "utf8")
|
|
127
|
+
: fs_1.default.writeFileSync(`${outputDir}/${item.id}.info.mdx`, view, "utf8");
|
|
128
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.info.mdx"`));
|
|
104
129
|
}
|
|
105
130
|
catch (err) {
|
|
106
|
-
console.error(chalk_1.default.red(`Failed to write "${outputDir}
|
|
131
|
+
console.error(chalk_1.default.red(`Failed to write "${outputDir}/${item.id}.info.mdx"`), chalk_1.default.yellow(err));
|
|
107
132
|
}
|
|
108
133
|
}
|
|
109
134
|
}
|
|
@@ -119,7 +144,7 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
119
144
|
async function cleanApiDocs(options) {
|
|
120
145
|
const { outputDir } = options;
|
|
121
146
|
const apiDir = path_1.default.join(siteDir, outputDir);
|
|
122
|
-
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx"], {
|
|
147
|
+
const apiMdxFiles = await (0, utils_1.Globby)(["*.api.mdx", "*.info.mdx"], {
|
|
123
148
|
cwd: path_1.default.resolve(apiDir),
|
|
124
149
|
});
|
|
125
150
|
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js"], {
|
|
@@ -0,0 +1,49 @@
|
|
|
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.createContactInfo = void 0;
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
function createContactInfo(contact) {
|
|
12
|
+
if (!contact || !Object.keys(contact).length)
|
|
13
|
+
return "";
|
|
14
|
+
const { name, url, email } = contact;
|
|
15
|
+
return (0, utils_1.create)("div", {
|
|
16
|
+
style: {
|
|
17
|
+
display: "flex",
|
|
18
|
+
flexDirection: "column",
|
|
19
|
+
marginBottom: "var(--ifm-paragraph-margin-bottom)",
|
|
20
|
+
},
|
|
21
|
+
children: [
|
|
22
|
+
(0, utils_1.create)("h3", {
|
|
23
|
+
style: {
|
|
24
|
+
marginBottom: "0.25rem",
|
|
25
|
+
},
|
|
26
|
+
children: "Contact",
|
|
27
|
+
}),
|
|
28
|
+
(0, utils_1.create)("span", {
|
|
29
|
+
children: [
|
|
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
|
+
})),
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
(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
|
+
],
|
|
45
|
+
})),
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
exports.createContactInfo = createContactInfo;
|
|
@@ -0,0 +1,33 @@
|
|
|
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.createLicense = void 0;
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
function createLicense(license) {
|
|
12
|
+
if (!license || !Object.keys(license).length)
|
|
13
|
+
return "";
|
|
14
|
+
const { name, url } = license;
|
|
15
|
+
return (0, utils_1.create)("div", {
|
|
16
|
+
style: {
|
|
17
|
+
marginBottom: "var(--ifm-paragraph-margin-bottom)",
|
|
18
|
+
},
|
|
19
|
+
children: [
|
|
20
|
+
(0, utils_1.create)("h3", {
|
|
21
|
+
style: {
|
|
22
|
+
marginBottom: "0.25rem",
|
|
23
|
+
},
|
|
24
|
+
children: "License",
|
|
25
|
+
}),
|
|
26
|
+
(0, utils_1.guard)(url, () => (0, utils_1.create)("a", {
|
|
27
|
+
href: url,
|
|
28
|
+
children: name !== null && name !== void 0 ? name : url,
|
|
29
|
+
})),
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.createLicense = createLicense;
|
|
@@ -185,7 +185,10 @@ function createRowsRoot({ schema }) {
|
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
187
|
function createSchemaDetails({ title, body, ...rest }) {
|
|
188
|
-
if (body === undefined ||
|
|
188
|
+
if (body === undefined ||
|
|
189
|
+
body.content === undefined ||
|
|
190
|
+
Object.keys(body).length === 0 ||
|
|
191
|
+
Object.keys(body.content).length === 0) {
|
|
189
192
|
return undefined;
|
|
190
193
|
}
|
|
191
194
|
// TODO:
|
|
@@ -20,7 +20,7 @@ function createStatusCodes({ responses }) {
|
|
|
20
20
|
}
|
|
21
21
|
return (0, utils_1.create)("div", {
|
|
22
22
|
children: [
|
|
23
|
-
(0, utils_1.create)("
|
|
23
|
+
(0, utils_1.create)("ApiTabs", {
|
|
24
24
|
children: codes.map((code) => {
|
|
25
25
|
return (0, utils_1.create)("TabItem", {
|
|
26
26
|
label: code,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createTermsOfService(termsOfService: string | undefined): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
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.createTermsOfService = void 0;
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
function createTermsOfService(termsOfService) {
|
|
12
|
+
if (!termsOfService)
|
|
13
|
+
return "";
|
|
14
|
+
return (0, utils_1.create)("div", {
|
|
15
|
+
style: {
|
|
16
|
+
marginBottom: "var(--ifm-paragraph-margin-bottom)",
|
|
17
|
+
},
|
|
18
|
+
children: [
|
|
19
|
+
(0, utils_1.create)("h3", {
|
|
20
|
+
style: {
|
|
21
|
+
marginBottom: "0.25rem",
|
|
22
|
+
},
|
|
23
|
+
children: "Terms of Service",
|
|
24
|
+
}),
|
|
25
|
+
(0, utils_1.create)("a", {
|
|
26
|
+
href: `${termsOfService}`,
|
|
27
|
+
children: termsOfService,
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.createTermsOfService = createTermsOfService;
|
package/lib/markdown/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ApiPageMetadata, InfoPageMetadata } 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 }, }: InfoPageMetadata): string;
|
|
3
|
+
export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }: InfoPageMetadata): string;
|
package/lib/markdown/index.js
CHANGED
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.createInfoPageMD = exports.createApiPageMD = void 0;
|
|
10
10
|
const lodash_1 = require("lodash");
|
|
11
|
+
const createContactInfo_1 = require("./createContactInfo");
|
|
11
12
|
const createDeprecationNotice_1 = require("./createDeprecationNotice");
|
|
12
13
|
const createDescription_1 = require("./createDescription");
|
|
14
|
+
const createLicense_1 = require("./createLicense");
|
|
13
15
|
const createParamsDetails_1 = require("./createParamsDetails");
|
|
14
16
|
const createRequestBodyDetails_1 = require("./createRequestBodyDetails");
|
|
15
17
|
const createStatusCodes_1 = require("./createStatusCodes");
|
|
18
|
+
const createTermsOfService_1 = require("./createTermsOfService");
|
|
16
19
|
const createVersionBadge_1 = require("./createVersionBadge");
|
|
17
20
|
const utils_1 = require("./utils");
|
|
18
21
|
function createApiPageMD({ title, api: { deprecated, "x-deprecated-description": deprecatedDescription, description, parameters, requestBody, responses, }, }) {
|
|
19
22
|
return (0, utils_1.render)([
|
|
20
23
|
`import ParamsItem from "@theme/ParamsItem";\n`,
|
|
21
24
|
`import SchemaItem from "@theme/SchemaItem"\n`,
|
|
22
|
-
`import
|
|
25
|
+
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
23
26
|
`import TabItem from "@theme/TabItem";\n\n`,
|
|
24
27
|
`## ${(0, lodash_1.escape)(title)}\n\n`,
|
|
25
28
|
(0, createDeprecationNotice_1.createDeprecationNotice)({ deprecated, description: deprecatedDescription }),
|
|
@@ -33,11 +36,14 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
|
|
|
33
36
|
]);
|
|
34
37
|
}
|
|
35
38
|
exports.createApiPageMD = createApiPageMD;
|
|
36
|
-
function createInfoPageMD({ info: { title, version, description }, }) {
|
|
39
|
+
function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }) {
|
|
37
40
|
return (0, utils_1.render)([
|
|
38
41
|
(0, createVersionBadge_1.createVersionBadge)(version),
|
|
39
42
|
`# ${(0, lodash_1.escape)(title)}\n\n`,
|
|
40
43
|
(0, createDescription_1.createDescription)(description),
|
|
44
|
+
(0, createContactInfo_1.createContactInfo)(contact),
|
|
45
|
+
(0, createTermsOfService_1.createTermsOfService)(termsOfService),
|
|
46
|
+
(0, createLicense_1.createLicense)(license),
|
|
41
47
|
]);
|
|
42
48
|
}
|
|
43
49
|
exports.createInfoPageMD = createInfoPageMD;
|
package/lib/openapi/openapi.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ApiMetadata } from "../types";
|
|
2
|
-
import { OpenApiObjectWithRef } from "./types";
|
|
2
|
+
import { OpenApiObjectWithRef, TagObject } from "./types";
|
|
3
3
|
interface OpenApiFiles {
|
|
4
4
|
source: string;
|
|
5
5
|
sourceDirName: string;
|
|
6
6
|
data: OpenApiObjectWithRef;
|
|
7
7
|
}
|
|
8
8
|
export declare function readOpenapiFiles(openapiPath: string, _options: {}): Promise<OpenApiFiles[]>;
|
|
9
|
-
export declare function processOpenapiFiles(files: OpenApiFiles[]): Promise<ApiMetadata[]>;
|
|
10
|
-
export declare function processOpenapiFile(openapiDataWithRefs: OpenApiObjectWithRef): Promise<ApiMetadata[]>;
|
|
9
|
+
export declare function processOpenapiFiles(files: OpenApiFiles[]): Promise<[ApiMetadata[], TagObject[]]>;
|
|
10
|
+
export declare function processOpenapiFile(openapiDataWithRefs: OpenApiObjectWithRef): Promise<[ApiMetadata[], TagObject[]]>;
|
|
11
|
+
export declare function getTagDisplayName(tagName: string, tags: TagObject[]): string;
|
|
11
12
|
export {};
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -9,11 +9,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.processOpenapiFile = exports.processOpenapiFiles = exports.readOpenapiFiles = void 0;
|
|
12
|
+
exports.getTagDisplayName = exports.processOpenapiFile = exports.processOpenapiFiles = exports.readOpenapiFiles = void 0;
|
|
13
13
|
const path_1 = __importDefault(require("path"));
|
|
14
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
15
|
const openapi_to_postmanv2_1 = __importDefault(require("@paloaltonetworks/openapi-to-postmanv2"));
|
|
16
|
-
// @ts-ignore
|
|
17
16
|
const postman_collection_1 = __importDefault(require("@paloaltonetworks/postman-collection"));
|
|
18
17
|
const chalk_1 = __importDefault(require("chalk"));
|
|
19
18
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
@@ -65,22 +64,24 @@ async function createPostmanCollection(openapiData) {
|
|
|
65
64
|
return await jsonToCollection(data);
|
|
66
65
|
}
|
|
67
66
|
function createItems(openapiData) {
|
|
68
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
67
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
69
68
|
// TODO: Find a better way to handle this
|
|
70
69
|
let items = [];
|
|
71
70
|
// Only create an info page if we have a description.
|
|
72
71
|
if (openapiData.info.description) {
|
|
72
|
+
const infoId = (0, lodash_1.kebabCase)(openapiData.info.title);
|
|
73
73
|
const infoPage = {
|
|
74
74
|
type: "info",
|
|
75
|
-
id:
|
|
76
|
-
unversionedId:
|
|
77
|
-
title:
|
|
75
|
+
id: infoId,
|
|
76
|
+
unversionedId: infoId,
|
|
77
|
+
title: openapiData.info.title,
|
|
78
78
|
description: openapiData.info.description,
|
|
79
|
-
slug: "/
|
|
79
|
+
slug: "/" + infoId,
|
|
80
80
|
frontMatter: {},
|
|
81
81
|
info: {
|
|
82
82
|
...openapiData.info,
|
|
83
|
-
|
|
83
|
+
tags: (_a = openapiData.tags) === null || _a === void 0 ? void 0 : _a.map((tagName) => { var _a; return getTagDisplayName(tagName.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
|
|
84
|
+
title: (_b = openapiData.info.title) !== null && _b !== void 0 ? _b : "Introduction",
|
|
84
85
|
},
|
|
85
86
|
};
|
|
86
87
|
items.push(infoPage);
|
|
@@ -88,16 +89,16 @@ function createItems(openapiData) {
|
|
|
88
89
|
for (let [path, pathObject] of Object.entries(openapiData.paths)) {
|
|
89
90
|
const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
|
|
90
91
|
for (let [method, operationObject] of Object.entries({ ...rest })) {
|
|
91
|
-
const title = (
|
|
92
|
+
const title = (_d = (_c = operationObject.summary) !== null && _c !== void 0 ? _c : operationObject.operationId) !== null && _d !== void 0 ? _d : "Missing summary";
|
|
92
93
|
if (operationObject.description === undefined) {
|
|
93
94
|
operationObject.description =
|
|
94
|
-
(
|
|
95
|
+
(_f = (_e = operationObject.summary) !== null && _e !== void 0 ? _e : operationObject.operationId) !== null && _f !== void 0 ? _f : "";
|
|
95
96
|
}
|
|
96
97
|
const baseId = (0, lodash_1.kebabCase)(title);
|
|
97
|
-
const servers = (
|
|
98
|
-
const security = (
|
|
98
|
+
const servers = (_h = (_g = operationObject.servers) !== null && _g !== void 0 ? _g : pathObject.servers) !== null && _h !== void 0 ? _h : openapiData.servers;
|
|
99
|
+
const security = (_j = operationObject.security) !== null && _j !== void 0 ? _j : openapiData.security;
|
|
99
100
|
// Add security schemes so we know how to handle security.
|
|
100
|
-
const securitySchemes = (
|
|
101
|
+
const securitySchemes = (_k = openapiData.components) === null || _k === void 0 ? void 0 : _k.securitySchemes;
|
|
101
102
|
// Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
|
|
102
103
|
if (securitySchemes) {
|
|
103
104
|
for (let securityScheme of Object.values(securitySchemes)) {
|
|
@@ -107,7 +108,7 @@ function createItems(openapiData) {
|
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
let jsonRequestBodyExample;
|
|
110
|
-
const body = (
|
|
111
|
+
const body = (_m = (_l = operationObject.requestBody) === null || _l === void 0 ? void 0 : _l.content) === null || _m === void 0 ? void 0 : _m["application/json"];
|
|
111
112
|
if (body === null || body === void 0 ? void 0 : body.schema) {
|
|
112
113
|
jsonRequestBodyExample = (0, createExample_1.sampleFromSchema)(body.schema);
|
|
113
114
|
}
|
|
@@ -123,7 +124,7 @@ function createItems(openapiData) {
|
|
|
123
124
|
frontMatter: {},
|
|
124
125
|
api: {
|
|
125
126
|
...defaults,
|
|
126
|
-
tags: (
|
|
127
|
+
tags: (_o = operationObject.tags) === null || _o === void 0 ? void 0 : _o.map((tagName) => { var _a; return getTagDisplayName(tagName, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
|
|
127
128
|
method,
|
|
128
129
|
path,
|
|
129
130
|
servers,
|
|
@@ -142,7 +143,6 @@ function createItems(openapiData) {
|
|
|
142
143
|
* Attach Postman Request objects to the corresponding ApiItems.
|
|
143
144
|
*/
|
|
144
145
|
function bindCollectionToApiItems(items, postmanCollection) {
|
|
145
|
-
// @ts-ignore
|
|
146
146
|
postmanCollection.forEachItem((item) => {
|
|
147
147
|
const method = item.request.method.toLowerCase();
|
|
148
148
|
const path = item.request.url
|
|
@@ -194,14 +194,23 @@ async function readOpenapiFiles(openapiPath, _options) {
|
|
|
194
194
|
exports.readOpenapiFiles = readOpenapiFiles;
|
|
195
195
|
async function processOpenapiFiles(files) {
|
|
196
196
|
const promises = files.map(async (file) => {
|
|
197
|
-
const
|
|
198
|
-
|
|
197
|
+
const processedFile = await processOpenapiFile(file.data);
|
|
198
|
+
const itemsObjectsArray = processedFile[0].map((item) => ({
|
|
199
199
|
...item,
|
|
200
200
|
}));
|
|
201
|
+
const tags = processedFile[1];
|
|
202
|
+
return [itemsObjectsArray, tags];
|
|
201
203
|
});
|
|
202
204
|
const metadata = await Promise.all(promises);
|
|
203
|
-
const items = metadata
|
|
204
|
-
|
|
205
|
+
const items = metadata
|
|
206
|
+
.map(function (x) {
|
|
207
|
+
return x[0];
|
|
208
|
+
})
|
|
209
|
+
.flat();
|
|
210
|
+
const tags = metadata.map(function (x) {
|
|
211
|
+
return x[1];
|
|
212
|
+
});
|
|
213
|
+
return [items, tags];
|
|
205
214
|
}
|
|
206
215
|
exports.processOpenapiFiles = processOpenapiFiles;
|
|
207
216
|
async function processOpenapiFile(openapiDataWithRefs) {
|
|
@@ -209,7 +218,11 @@ async function processOpenapiFile(openapiDataWithRefs) {
|
|
|
209
218
|
const postmanCollection = await createPostmanCollection(openapiData);
|
|
210
219
|
const items = createItems(openapiData);
|
|
211
220
|
bindCollectionToApiItems(items, postmanCollection);
|
|
212
|
-
|
|
221
|
+
let tags = [];
|
|
222
|
+
if (openapiData.tags !== undefined) {
|
|
223
|
+
tags = openapiData.tags;
|
|
224
|
+
}
|
|
225
|
+
return [items, tags];
|
|
213
226
|
}
|
|
214
227
|
exports.processOpenapiFile = processOpenapiFile;
|
|
215
228
|
// order for picking items as a display name of tags
|
|
@@ -231,3 +244,4 @@ function getTagDisplayName(tagName, tags) {
|
|
|
231
244
|
// always default to the tagName
|
|
232
245
|
return tagName;
|
|
233
246
|
}
|
|
247
|
+
exports.getTagDisplayName = getTagDisplayName;
|
package/lib/openapi/types.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface InfoObject {
|
|
|
29
29
|
contact?: ContactObject;
|
|
30
30
|
license?: LicenseObject;
|
|
31
31
|
version: string;
|
|
32
|
+
tags?: String[];
|
|
32
33
|
}
|
|
33
34
|
export interface ContactObject {
|
|
34
35
|
name?: string;
|
|
@@ -151,6 +152,7 @@ export interface ParameterObject {
|
|
|
151
152
|
example?: any;
|
|
152
153
|
examples?: Map<ExampleObject>;
|
|
153
154
|
content?: Map<MediaTypeObject>;
|
|
155
|
+
param?: Object;
|
|
154
156
|
}
|
|
155
157
|
export interface ParameterObjectWithRef {
|
|
156
158
|
name: string;
|
|
@@ -236,7 +238,7 @@ export interface LinkObject {
|
|
|
236
238
|
export declare type HeaderObject = Omit<ParameterObject, "name" | "in">;
|
|
237
239
|
export declare type HeaderObjectWithRef = Omit<ParameterObjectWithRef, "name" | "in">;
|
|
238
240
|
export interface TagObject {
|
|
239
|
-
name
|
|
241
|
+
name?: string;
|
|
240
242
|
description?: string;
|
|
241
243
|
externalDocs?: ExternalDocumentationObject;
|
|
242
244
|
"x-displayName"?: string;
|
|
@@ -304,6 +306,8 @@ export interface HttpSecuritySchemeObject {
|
|
|
304
306
|
description?: string;
|
|
305
307
|
scheme: string;
|
|
306
308
|
bearerFormat?: string;
|
|
309
|
+
name?: string;
|
|
310
|
+
in?: string;
|
|
307
311
|
}
|
|
308
312
|
export interface Oauth2SecuritySchemeObject {
|
|
309
313
|
type: "oauth2";
|
package/lib/sidebars/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ProcessedSidebar } from "@docusaurus/plugin-content-docs/src/sidebars/types";
|
|
2
|
+
import { TagObject } from "../openapi/types";
|
|
2
3
|
import type { SidebarOptions, APIOptions, ApiMetadata } from "../types";
|
|
3
|
-
export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[]): ProcessedSidebar;
|
|
4
|
+
export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[], tags: TagObject[]): ProcessedSidebar;
|
package/lib/sidebars/index.js
CHANGED
|
@@ -10,25 +10,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const clsx_1 = __importDefault(require("clsx"));
|
|
13
|
+
const lodash_1 = require("lodash");
|
|
13
14
|
const uniq_1 = __importDefault(require("lodash/uniq"));
|
|
14
15
|
function isApiItem(item) {
|
|
15
16
|
return item.type === "api";
|
|
16
17
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// type: "link" as const,
|
|
22
|
-
// label: item.title,
|
|
23
|
-
// href: item.permalink,
|
|
24
|
-
// docId: item.id,
|
|
25
|
-
// };
|
|
26
|
-
// });
|
|
18
|
+
function isInfoItem(item) {
|
|
19
|
+
return item.type === "info";
|
|
20
|
+
}
|
|
21
|
+
function groupByTags(items, sidebarOptions, options, tags) {
|
|
27
22
|
const { outputDir } = options;
|
|
28
|
-
const { sidebarCollapsed, sidebarCollapsible, customProps } = sidebarOptions;
|
|
23
|
+
const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
|
|
29
24
|
const apiItems = items.filter(isApiItem);
|
|
25
|
+
const infoItems = items.filter(isInfoItem);
|
|
26
|
+
const intros = infoItems.map((item) => {
|
|
27
|
+
return {
|
|
28
|
+
id: item.id,
|
|
29
|
+
title: item.title,
|
|
30
|
+
description: item.description,
|
|
31
|
+
tags: item.info.tags,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
30
34
|
// TODO: make sure we only take the first tag
|
|
31
|
-
const
|
|
35
|
+
const apiTags = (0, uniq_1.default)(apiItems
|
|
32
36
|
.flatMap((item) => item.api.tags)
|
|
33
37
|
.filter((item) => !!item));
|
|
34
38
|
// TODO: optimize this or make it a function
|
|
@@ -51,11 +55,56 @@ function groupByTags(items, sidebarOptions, options) {
|
|
|
51
55
|
}, item.api.method),
|
|
52
56
|
};
|
|
53
57
|
}
|
|
54
|
-
|
|
58
|
+
let rootIntroDoc = undefined;
|
|
59
|
+
if (infoItems.length === 1) {
|
|
60
|
+
const infoItem = infoItems[0];
|
|
61
|
+
const id = infoItem.id;
|
|
62
|
+
rootIntroDoc = {
|
|
63
|
+
type: "doc",
|
|
64
|
+
id: `${basePath}/${id}`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const tagged = apiTags
|
|
55
68
|
.map((tag) => {
|
|
69
|
+
// Map info object to tag
|
|
70
|
+
const infoObject = intros.find((i) => i.tags.includes(tag));
|
|
71
|
+
const tagObject = tags.flat().find((t) => {
|
|
72
|
+
var _a;
|
|
73
|
+
return (_a = (tag === t.name || tag === t["x-displayName"])) !== null && _a !== void 0 ? _a : {
|
|
74
|
+
name: tag,
|
|
75
|
+
description: `${tag} Index`,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
// TODO: perhaps move this into a getLinkConfig() function
|
|
79
|
+
let linkConfig = undefined;
|
|
80
|
+
if (infoObject !== undefined && categoryLinkSource === "info") {
|
|
81
|
+
linkConfig = {
|
|
82
|
+
type: "doc",
|
|
83
|
+
id: `${basePath}/${infoObject.id}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// TODO: perhaps move this into a getLinkConfig() function
|
|
87
|
+
if (tagObject !== undefined && categoryLinkSource === "tag") {
|
|
88
|
+
const linkDescription = tagObject === null || tagObject === void 0 ? void 0 : tagObject.description;
|
|
89
|
+
linkConfig = {
|
|
90
|
+
type: "generated-index",
|
|
91
|
+
title: tag,
|
|
92
|
+
description: linkDescription,
|
|
93
|
+
slug: "/category/" + (0, lodash_1.kebabCase)(tag),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Default behavior
|
|
97
|
+
if (categoryLinkSource === undefined) {
|
|
98
|
+
linkConfig = {
|
|
99
|
+
type: "generated-index",
|
|
100
|
+
title: tag,
|
|
101
|
+
slug: "/category/" + (0, lodash_1.kebabCase)(tag),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
56
104
|
return {
|
|
57
105
|
type: "category",
|
|
58
106
|
label: tag,
|
|
107
|
+
link: linkConfig,
|
|
59
108
|
collapsible: sidebarCollapsible,
|
|
60
109
|
collapsed: sidebarCollapsed,
|
|
61
110
|
items: apiItems
|
|
@@ -64,25 +113,29 @@ function groupByTags(items, sidebarOptions, options) {
|
|
|
64
113
|
};
|
|
65
114
|
})
|
|
66
115
|
.filter((item) => item.items.length > 0); // Filter out any categories with no items.
|
|
116
|
+
// TODO: determine how we want to handle these
|
|
67
117
|
// const untagged = [
|
|
68
|
-
// // TODO: determine if needed and how
|
|
69
118
|
// {
|
|
70
119
|
// type: "category" as const,
|
|
71
120
|
// label: "UNTAGGED",
|
|
72
|
-
//
|
|
73
|
-
//
|
|
121
|
+
// collapsible: sidebarCollapsible,
|
|
122
|
+
// collapsed: sidebarCollapsed,
|
|
74
123
|
// items: apiItems
|
|
75
|
-
// //@ts-ignore
|
|
76
124
|
// .filter(({ api }) => api.tags === undefined || api.tags.length === 0)
|
|
77
125
|
// .map(createDocItem),
|
|
78
126
|
// },
|
|
79
127
|
// ];
|
|
128
|
+
// Shift root intro doc to top of sidebar
|
|
129
|
+
// TODO: Add input validation for categoryLinkSource options
|
|
130
|
+
if (rootIntroDoc && categoryLinkSource !== "info") {
|
|
131
|
+
tagged.unshift(rootIntroDoc);
|
|
132
|
+
}
|
|
80
133
|
return [...tagged];
|
|
81
134
|
}
|
|
82
|
-
function generateSidebarSlice(sidebarOptions, options, api) {
|
|
135
|
+
function generateSidebarSlice(sidebarOptions, options, api, tags) {
|
|
83
136
|
let sidebarSlice = [];
|
|
84
137
|
if (sidebarOptions.groupPathsBy === "tags") {
|
|
85
|
-
sidebarSlice = groupByTags(api, sidebarOptions, options);
|
|
138
|
+
sidebarSlice = groupByTags(api, sidebarOptions, options, tags);
|
|
86
139
|
}
|
|
87
140
|
return sidebarSlice;
|
|
88
141
|
}
|