docusaurus-plugin-openapi-docs 1.4.7 → 1.5.1-hotfix1
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 +1 -0
- package/lib/index.js +6 -2
- package/lib/markdown/createDescription.js +4 -2
- package/lib/markdown/createRequestSchema.js +3 -1
- package/lib/markdown/createResponseSchema.js +2 -0
- package/lib/markdown/index.js +1 -1
- package/lib/markdown/utils.d.ts +1 -0
- package/lib/markdown/utils.js +4 -3
- package/lib/openapi/createRequestExample.js +6 -4
- package/lib/openapi/createResponseExample.js +7 -4
- package/lib/openapi/openapi.d.ts +3 -3
- package/lib/openapi/openapi.js +102 -9
- package/lib/openapi/openapi.test.js +1 -1
- package/lib/openapi/types.d.ts +1 -0
- package/lib/openapi/utils/loadAndResolveSpec.js +8 -2
- package/lib/options.js +1 -0
- package/lib/types.d.ts +1 -0
- package/package.json +3 -4
- package/src/index.ts +6 -1
- package/src/markdown/createDescription.ts +5 -3
- package/src/markdown/createRequestSchema.ts +3 -1
- package/src/markdown/createResponseSchema.ts +2 -0
- package/src/markdown/index.ts +1 -1
- package/src/markdown/utils.ts +3 -2
- package/src/openapi/createRequestExample.ts +10 -4
- package/src/openapi/createResponseExample.ts +13 -4
- package/src/openapi/openapi.test.ts +1 -2
- package/src/openapi/openapi.ts +129 -5
- package/src/openapi/types.ts +1 -0
- package/src/openapi/utils/loadAndResolveSpec.ts +8 -2
- package/src/options.ts +1 -0
- package/src/types.ts +1 -0
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -121,6 +121,7 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
121
121
|
| ---------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
122
122
|
| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
|
|
123
123
|
| `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
|
|
124
|
+
| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. |
|
|
124
125
|
| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
|
|
125
126
|
| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) |
|
|
126
127
|
| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
|
package/lib/index.js
CHANGED
|
@@ -87,8 +87,8 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
87
87
|
? specPath
|
|
88
88
|
: path_1.default.resolve(siteDir, specPath);
|
|
89
89
|
try {
|
|
90
|
-
const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath
|
|
91
|
-
const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, sidebarOptions);
|
|
90
|
+
const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath);
|
|
91
|
+
const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, options, sidebarOptions);
|
|
92
92
|
if (!fs_1.default.existsSync(outputDir)) {
|
|
93
93
|
try {
|
|
94
94
|
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
@@ -143,6 +143,10 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
143
143
|
{{#infoPath}}
|
|
144
144
|
info_path: {{{infoPath}}}
|
|
145
145
|
{{/infoPath}}
|
|
146
|
+
custom_edit_url: null
|
|
147
|
+
{{#frontMatter.proxy}}
|
|
148
|
+
proxy: {{{frontMatter.proxy}}}
|
|
149
|
+
{{/frontMatter.proxy}}
|
|
146
150
|
---
|
|
147
151
|
|
|
148
152
|
{{{markdown}}}
|
|
@@ -13,7 +13,9 @@ function createDescription(description) {
|
|
|
13
13
|
return "";
|
|
14
14
|
}
|
|
15
15
|
return `\n\n${description
|
|
16
|
-
.replace(utils_1.
|
|
17
|
-
.replace(utils_1.
|
|
16
|
+
.replace(utils_1.greaterThan, "\\>")
|
|
17
|
+
.replace(utils_1.codeFence, function (match) {
|
|
18
|
+
return match.replace(/\\>/g, ">");
|
|
19
|
+
})}\n\n`;
|
|
18
20
|
}
|
|
19
21
|
exports.createDescription = createDescription;
|
|
@@ -28,8 +28,8 @@ function mergeAllOf(allOf) {
|
|
|
28
28
|
"x-examples": function () {
|
|
29
29
|
return true;
|
|
30
30
|
},
|
|
31
|
-
ignoreAdditionalProperties: true,
|
|
32
31
|
},
|
|
32
|
+
ignoreAdditionalProperties: true,
|
|
33
33
|
});
|
|
34
34
|
const required = allOf.reduce((acc, cur) => {
|
|
35
35
|
if (Array.isArray(cur.required)) {
|
|
@@ -480,6 +480,7 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
480
480
|
collapsible: false,
|
|
481
481
|
name,
|
|
482
482
|
required: Array.isArray(required) ? required.includes(name) : required,
|
|
483
|
+
deprecated: mergedSchemas.deprecated,
|
|
483
484
|
schemaDescription: mergedSchemas.description,
|
|
484
485
|
schemaName: schemaName,
|
|
485
486
|
qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
|
|
@@ -507,6 +508,7 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
507
508
|
collapsible: false,
|
|
508
509
|
name,
|
|
509
510
|
required: Array.isArray(required) ? required.includes(name) : required,
|
|
511
|
+
deprecated: schema.deprecated,
|
|
510
512
|
schemaDescription: schema.description,
|
|
511
513
|
schemaName: schemaName,
|
|
512
514
|
qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
|
|
@@ -479,6 +479,7 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
479
479
|
collapsible: false,
|
|
480
480
|
name,
|
|
481
481
|
required: false,
|
|
482
|
+
deprecated: mergedSchemas.deprecated,
|
|
482
483
|
schemaDescription: mergedSchemas.description,
|
|
483
484
|
schemaName: schemaName,
|
|
484
485
|
qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
|
|
@@ -506,6 +507,7 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
506
507
|
collapsible: false,
|
|
507
508
|
name,
|
|
508
509
|
required: false,
|
|
510
|
+
deprecated: schema.deprecated,
|
|
509
511
|
schemaDescription: schema.description,
|
|
510
512
|
schemaName: schemaName,
|
|
511
513
|
qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
|
package/lib/markdown/index.js
CHANGED
|
@@ -26,7 +26,7 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
|
|
|
26
26
|
`import MimeTabs from "@theme/MimeTabs";\n`,
|
|
27
27
|
`import ParamsItem from "@theme/ParamsItem";\n`,
|
|
28
28
|
`import ResponseSamples from "@theme/ResponseSamples";\n`,
|
|
29
|
-
`import SchemaItem from "@theme/SchemaItem"
|
|
29
|
+
`import SchemaItem from "@theme/SchemaItem";\n`,
|
|
30
30
|
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
31
31
|
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
32
32
|
`import TabItem from "@theme/TabItem";\n\n`,
|
package/lib/markdown/utils.d.ts
CHANGED
package/lib/markdown/utils.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
* ========================================================================== */
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.greaterThan = exports.lessThan = exports.render = exports.guard = exports.create = void 0;
|
|
9
|
+
exports.codeFence = exports.greaterThan = exports.lessThan = exports.render = exports.guard = exports.create = void 0;
|
|
10
10
|
function create(tag, props) {
|
|
11
11
|
const { children, ...rest } = props;
|
|
12
12
|
let propString = "";
|
|
@@ -35,5 +35,6 @@ function render(children) {
|
|
|
35
35
|
}
|
|
36
36
|
exports.render = render;
|
|
37
37
|
// Regex to selectively URL-encode '>' and '<' chars
|
|
38
|
-
exports.lessThan = /<(?!(=|button|\s?\/button|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|a|\s?\/a|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|div|\s?\/div|center|\s?\/center))/
|
|
39
|
-
exports.greaterThan = /(?<!(button|details|summary|hr|br|span|strong|small|table|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|a|tag|li|ol|ul|img|div|center|\/|\s|"|'))
|
|
38
|
+
exports.lessThan = /<(?!(=|button|\s?\/button|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|a|\s?\/a|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|div|\s?\/div|center|\s?\/center))/gu;
|
|
39
|
+
exports.greaterThan = /(?<!(button|details|summary|hr|br|span|strong|small|table|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|a|tag|li|ol|ul|img|div|center|\/|\s|"|'))>/gu;
|
|
40
|
+
exports.codeFence = /`{1,3}[\s\S]*?`{1,3}/g;
|
|
@@ -76,7 +76,7 @@ const sampleRequestFromSchema = (schema = {}) => {
|
|
|
76
76
|
const { mergedSchemas } = (0, createRequestSchema_1.mergeAllOf)(allOf);
|
|
77
77
|
if (mergedSchemas.properties) {
|
|
78
78
|
for (const [key, value] of Object.entries(mergedSchemas.properties)) {
|
|
79
|
-
if (value.readOnly && value.readOnly === true) {
|
|
79
|
+
if ((value.readOnly && value.readOnly === true) || value.deprecated) {
|
|
80
80
|
delete mergedSchemas.properties[key];
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -99,14 +99,16 @@ const sampleRequestFromSchema = (schema = {}) => {
|
|
|
99
99
|
for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
|
|
100
100
|
if (prop.properties) {
|
|
101
101
|
for (const [key, value] of Object.entries(prop.properties)) {
|
|
102
|
-
if (value.readOnly && value.readOnly === true)
|
|
102
|
+
if ((value.readOnly && value.readOnly === true) ||
|
|
103
|
+
value.deprecated) {
|
|
103
104
|
delete prop.properties[key];
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
if (prop.items && prop.items.properties) {
|
|
108
109
|
for (const [key, value] of Object.entries(prop.items.properties)) {
|
|
109
|
-
if (value.readOnly && value.readOnly === true)
|
|
110
|
+
if ((value.readOnly && value.readOnly === true) ||
|
|
111
|
+
value.deprecated) {
|
|
110
112
|
delete prop.items.properties[key];
|
|
111
113
|
}
|
|
112
114
|
}
|
|
@@ -137,7 +139,7 @@ const sampleRequestFromSchema = (schema = {}) => {
|
|
|
137
139
|
}
|
|
138
140
|
return normalizeArray(schema.enum)[0];
|
|
139
141
|
}
|
|
140
|
-
if (schema.readOnly && schema.readOnly === true) {
|
|
142
|
+
if ((schema.readOnly && schema.readOnly === true) || schema.deprecated) {
|
|
141
143
|
return undefined;
|
|
142
144
|
}
|
|
143
145
|
return primitive(schema);
|
|
@@ -68,7 +68,8 @@ const sampleResponseFromSchema = (schema = {}) => {
|
|
|
68
68
|
const { mergedSchemas } = (0, createResponseSchema_1.mergeAllOf)(allOf);
|
|
69
69
|
if (mergedSchemas.properties) {
|
|
70
70
|
for (const [key, value] of Object.entries(mergedSchemas.properties)) {
|
|
71
|
-
if (value.writeOnly && value.writeOnly === true)
|
|
71
|
+
if ((value.writeOnly && value.writeOnly === true) ||
|
|
72
|
+
value.deprecated) {
|
|
72
73
|
delete mergedSchemas.properties[key];
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -99,14 +100,16 @@ const sampleResponseFromSchema = (schema = {}) => {
|
|
|
99
100
|
for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
|
|
100
101
|
if (prop.properties) {
|
|
101
102
|
for (const [key, value] of Object.entries(prop.properties)) {
|
|
102
|
-
if (value.writeOnly && value.writeOnly === true)
|
|
103
|
+
if ((value.writeOnly && value.writeOnly === true) ||
|
|
104
|
+
value.deprecated) {
|
|
103
105
|
delete prop.properties[key];
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
if (prop.items && prop.items.properties) {
|
|
108
110
|
for (const [key, value] of Object.entries(prop.items.properties)) {
|
|
109
|
-
if (value.writeOnly && value.writeOnly === true)
|
|
111
|
+
if ((value.writeOnly && value.writeOnly === true) ||
|
|
112
|
+
value.deprecated) {
|
|
110
113
|
delete prop.items.properties[key];
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -137,7 +140,7 @@ const sampleResponseFromSchema = (schema = {}) => {
|
|
|
137
140
|
}
|
|
138
141
|
return normalizeArray(schema.enum)[0];
|
|
139
142
|
}
|
|
140
|
-
if (schema.writeOnly && schema.writeOnly === true) {
|
|
143
|
+
if ((schema.writeOnly && schema.writeOnly === true) || schema.deprecated) {
|
|
141
144
|
return undefined;
|
|
142
145
|
}
|
|
143
146
|
return primitive(schema);
|
package/lib/openapi/openapi.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ interface OpenApiFiles {
|
|
|
5
5
|
sourceDirName: string;
|
|
6
6
|
data: OpenApiObject;
|
|
7
7
|
}
|
|
8
|
-
export declare function readOpenapiFiles(openapiPath: string
|
|
9
|
-
export declare function processOpenapiFiles(files: OpenApiFiles[], sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[][]]>;
|
|
10
|
-
export declare function processOpenapiFile(openapiData: OpenApiObject, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[]]>;
|
|
8
|
+
export declare function readOpenapiFiles(openapiPath: string): Promise<OpenApiFiles[]>;
|
|
9
|
+
export declare function processOpenapiFiles(files: OpenApiFiles[], options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[][]]>;
|
|
10
|
+
export declare function processOpenapiFile(openapiData: OpenApiObject, options: APIOptions, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[]]>;
|
|
11
11
|
export declare function getTagDisplayName(tagName: string, tags: TagObject[]): string;
|
|
12
12
|
export {};
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -60,11 +60,12 @@ async function createPostmanCollection(openapiData) {
|
|
|
60
60
|
}
|
|
61
61
|
return await jsonToCollection(data);
|
|
62
62
|
}
|
|
63
|
-
function createItems(openapiData, sidebarOptions) {
|
|
64
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
63
|
+
function createItems(openapiData, options, sidebarOptions) {
|
|
64
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
65
65
|
// TODO: Find a better way to handle this
|
|
66
66
|
let items = [];
|
|
67
|
-
const
|
|
67
|
+
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
68
|
+
const infoId = (0, kebabCase_1.default)(infoIdSpaces);
|
|
68
69
|
if (openapiData.info.description) {
|
|
69
70
|
// Only create an info page if we have a description.
|
|
70
71
|
const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
|
|
@@ -171,6 +172,98 @@ function createItems(openapiData, sidebarOptions) {
|
|
|
171
172
|
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
172
173
|
.replace(/\s+$/, "")
|
|
173
174
|
: "",
|
|
175
|
+
...((options === null || options === void 0 ? void 0 : options.proxy) && { proxy: options.proxy }),
|
|
176
|
+
},
|
|
177
|
+
api: {
|
|
178
|
+
...defaults,
|
|
179
|
+
tags: operationObject.tags,
|
|
180
|
+
method,
|
|
181
|
+
path,
|
|
182
|
+
servers,
|
|
183
|
+
security,
|
|
184
|
+
securitySchemes,
|
|
185
|
+
jsonRequestBodyExample,
|
|
186
|
+
info: openapiData.info,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
items.push(apiPage);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Gather x-webhooks endpoints
|
|
193
|
+
for (let [path, pathObject] of Object.entries((_q = openapiData["x-webhooks"]) !== null && _q !== void 0 ? _q : {})) {
|
|
194
|
+
path = "webhook";
|
|
195
|
+
const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
|
|
196
|
+
for (let [method, operationObject] of Object.entries({ ...rest })) {
|
|
197
|
+
method = "event";
|
|
198
|
+
const title = (_s = (_r = operationObject.summary) !== null && _r !== void 0 ? _r : operationObject.operationId) !== null && _s !== void 0 ? _s : "Missing summary";
|
|
199
|
+
if (operationObject.description === undefined) {
|
|
200
|
+
operationObject.description =
|
|
201
|
+
(_u = (_t = operationObject.summary) !== null && _t !== void 0 ? _t : operationObject.operationId) !== null && _u !== void 0 ? _u : "";
|
|
202
|
+
}
|
|
203
|
+
const baseId = operationObject.operationId
|
|
204
|
+
? (0, kebabCase_1.default)(operationObject.operationId)
|
|
205
|
+
: (0, kebabCase_1.default)(operationObject.summary);
|
|
206
|
+
const servers = (_w = (_v = operationObject.servers) !== null && _v !== void 0 ? _v : pathObject.servers) !== null && _w !== void 0 ? _w : openapiData.servers;
|
|
207
|
+
const security = (_x = operationObject.security) !== null && _x !== void 0 ? _x : openapiData.security;
|
|
208
|
+
// Add security schemes so we know how to handle security.
|
|
209
|
+
const securitySchemes = (_y = openapiData.components) === null || _y === void 0 ? void 0 : _y.securitySchemes;
|
|
210
|
+
// Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
|
|
211
|
+
if (securitySchemes) {
|
|
212
|
+
for (let securityScheme of Object.values(securitySchemes)) {
|
|
213
|
+
if (securityScheme.type === "http") {
|
|
214
|
+
securityScheme.scheme = securityScheme.scheme.toLowerCase();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
let jsonRequestBodyExample;
|
|
219
|
+
const body = (_0 = (_z = operationObject.requestBody) === null || _z === void 0 ? void 0 : _z.content) === null || _0 === void 0 ? void 0 : _0["application/json"];
|
|
220
|
+
if (body === null || body === void 0 ? void 0 : body.schema) {
|
|
221
|
+
jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(body.schema);
|
|
222
|
+
}
|
|
223
|
+
// Handle vendor JSON media types
|
|
224
|
+
const bodyContent = (_1 = operationObject.requestBody) === null || _1 === void 0 ? void 0 : _1.content;
|
|
225
|
+
if (bodyContent) {
|
|
226
|
+
const firstBodyContentKey = Object.keys(bodyContent)[0];
|
|
227
|
+
if (firstBodyContentKey.endsWith("+json")) {
|
|
228
|
+
const firstBody = bodyContent[firstBodyContentKey];
|
|
229
|
+
if (firstBody === null || firstBody === void 0 ? void 0 : firstBody.schema) {
|
|
230
|
+
jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(firstBody.schema);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// TODO: Don't include summary temporarilly
|
|
235
|
+
const { summary, ...defaults } = operationObject;
|
|
236
|
+
// Merge common parameters with operation parameters
|
|
237
|
+
// Operation params take precendence over common params
|
|
238
|
+
if (parameters !== undefined) {
|
|
239
|
+
if (operationObject.parameters !== undefined) {
|
|
240
|
+
defaults.parameters = (0, unionBy_1.default)(operationObject.parameters, parameters, "name");
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
defaults.parameters = parameters;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const opDescription = operationObject.description;
|
|
247
|
+
let splitDescription;
|
|
248
|
+
if (opDescription) {
|
|
249
|
+
splitDescription = opDescription.match(/[^\r\n]+/g);
|
|
250
|
+
}
|
|
251
|
+
const apiPage = {
|
|
252
|
+
type: "api",
|
|
253
|
+
id: baseId,
|
|
254
|
+
infoId: infoId !== null && infoId !== void 0 ? infoId : "",
|
|
255
|
+
unversionedId: baseId,
|
|
256
|
+
title: title ? title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'") : "",
|
|
257
|
+
description: operationObject.description
|
|
258
|
+
? operationObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
259
|
+
: "",
|
|
260
|
+
frontMatter: {
|
|
261
|
+
description: splitDescription
|
|
262
|
+
? splitDescription[0]
|
|
263
|
+
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
264
|
+
.replace(/\s+$/, "")
|
|
265
|
+
: "",
|
|
266
|
+
...((options === null || options === void 0 ? void 0 : options.proxy) && { proxy: options.proxy }),
|
|
174
267
|
},
|
|
175
268
|
api: {
|
|
176
269
|
...defaults,
|
|
@@ -189,7 +282,7 @@ function createItems(openapiData, sidebarOptions) {
|
|
|
189
282
|
}
|
|
190
283
|
if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
|
|
191
284
|
// Get global tags
|
|
192
|
-
const tags = (
|
|
285
|
+
const tags = (_2 = openapiData.tags) !== null && _2 !== void 0 ? _2 : [];
|
|
193
286
|
// Get operation tags
|
|
194
287
|
const apiItems = items.filter((item) => {
|
|
195
288
|
return item.type === "api";
|
|
@@ -248,7 +341,7 @@ function bindCollectionToApiItems(items, postmanCollection) {
|
|
|
248
341
|
}
|
|
249
342
|
});
|
|
250
343
|
}
|
|
251
|
-
async function readOpenapiFiles(openapiPath
|
|
344
|
+
async function readOpenapiFiles(openapiPath) {
|
|
252
345
|
if (!(0, index_1.isURL)(openapiPath)) {
|
|
253
346
|
const stat = await fs_extra_1.default.lstat(openapiPath);
|
|
254
347
|
if (stat.isDirectory()) {
|
|
@@ -281,10 +374,10 @@ async function readOpenapiFiles(openapiPath, options) {
|
|
|
281
374
|
];
|
|
282
375
|
}
|
|
283
376
|
exports.readOpenapiFiles = readOpenapiFiles;
|
|
284
|
-
async function processOpenapiFiles(files, sidebarOptions) {
|
|
377
|
+
async function processOpenapiFiles(files, options, sidebarOptions) {
|
|
285
378
|
const promises = files.map(async (file) => {
|
|
286
379
|
if (file.data !== undefined) {
|
|
287
|
-
const processedFile = await processOpenapiFile(file.data, sidebarOptions);
|
|
380
|
+
const processedFile = await processOpenapiFile(file.data, options, sidebarOptions);
|
|
288
381
|
const itemsObjectsArray = processedFile[0].map((item) => ({
|
|
289
382
|
...item,
|
|
290
383
|
}));
|
|
@@ -315,9 +408,9 @@ async function processOpenapiFiles(files, sidebarOptions) {
|
|
|
315
408
|
return [items, tags];
|
|
316
409
|
}
|
|
317
410
|
exports.processOpenapiFiles = processOpenapiFiles;
|
|
318
|
-
async function processOpenapiFile(openapiData, sidebarOptions) {
|
|
411
|
+
async function processOpenapiFile(openapiData, options, sidebarOptions) {
|
|
319
412
|
const postmanCollection = await createPostmanCollection(openapiData);
|
|
320
|
-
const items = createItems(openapiData, sidebarOptions);
|
|
413
|
+
const items = createItems(openapiData, options, sidebarOptions);
|
|
321
414
|
bindCollectionToApiItems(items, postmanCollection);
|
|
322
415
|
let tags = [];
|
|
323
416
|
if (openapiData.tags !== undefined) {
|
|
@@ -16,7 +16,7 @@ const _1 = require(".");
|
|
|
16
16
|
describe("openapi", () => {
|
|
17
17
|
describe("readOpenapiFiles", () => {
|
|
18
18
|
it("readOpenapiFiles", async () => {
|
|
19
|
-
const results = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/examples"))
|
|
19
|
+
const results = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/examples")));
|
|
20
20
|
const categoryMeta = results.find((x) => x.source.endsWith("_category_.json"));
|
|
21
21
|
expect(categoryMeta).toBeFalsy();
|
|
22
22
|
// console.log(results);
|
package/lib/openapi/types.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.loadAndResolveSpec = exports.convertSwagger2OpenAPI = void 0;
|
|
13
|
-
const json_schema_ref_parser_1 = __importDefault(require("@
|
|
13
|
+
const json_schema_ref_parser_1 = __importDefault(require("@paloaltonetworks/json-schema-ref-parser"));
|
|
14
14
|
const openapi_core_1 = require("@redocly/openapi-core");
|
|
15
15
|
const chalk_1 = __importDefault(require("chalk"));
|
|
16
16
|
// @ts-ignore
|
|
@@ -58,7 +58,13 @@ function serializer(replacer, cycleReplacer) {
|
|
|
58
58
|
}
|
|
59
59
|
function convertSwagger2OpenAPI(spec) {
|
|
60
60
|
console.warn("[ReDoc Compatibility mode]: Converting OpenAPI 2.0 to OpenAPI 3.0");
|
|
61
|
-
return new Promise((resolve, reject) => (0, swagger2openapi_1.convertObj)(spec, {
|
|
61
|
+
return new Promise((resolve, reject) => (0, swagger2openapi_1.convertObj)(spec, {
|
|
62
|
+
patch: true,
|
|
63
|
+
warnOnly: true,
|
|
64
|
+
text: "{}",
|
|
65
|
+
anchors: true,
|
|
66
|
+
resolveInternal: true,
|
|
67
|
+
}, (err, res) => {
|
|
62
68
|
// TODO: log any warnings
|
|
63
69
|
if (err) {
|
|
64
70
|
return reject(err);
|
package/lib/options.js
CHANGED
|
@@ -21,6 +21,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
|
|
|
21
21
|
config: utils_validation_1.Joi.object()
|
|
22
22
|
.pattern(/^/, utils_validation_1.Joi.object({
|
|
23
23
|
specPath: utils_validation_1.Joi.string().required(),
|
|
24
|
+
proxy: utils_validation_1.Joi.string(),
|
|
24
25
|
outputDir: utils_validation_1.Joi.string().required(),
|
|
25
26
|
template: utils_validation_1.Joi.string(),
|
|
26
27
|
downloadUrl: utils_validation_1.Joi.string(),
|
package/lib/types.d.ts
CHANGED
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": "1.
|
|
4
|
+
"version": "1.5.1-hotfix1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"utility-types": "^3.10.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@
|
|
42
|
+
"@paloaltonetworks/json-schema-ref-parser": "0.0.0-dev-hotfix1",
|
|
43
43
|
"@docusaurus/mdx-loader": "^2.0.1",
|
|
44
44
|
"@docusaurus/plugin-content-docs": "^2.0.1",
|
|
45
45
|
"@docusaurus/utils": "^2.0.1",
|
|
@@ -67,6 +67,5 @@
|
|
|
67
67
|
},
|
|
68
68
|
"engines": {
|
|
69
69
|
"node": ">=14"
|
|
70
|
-
}
|
|
71
|
-
"gitHead": "c4908dd9886556981677c8ff900450252abe6bf3"
|
|
70
|
+
}
|
|
72
71
|
}
|
package/src/index.ts
CHANGED
|
@@ -106,9 +106,10 @@ export default function pluginOpenAPIDocs(
|
|
|
106
106
|
: path.resolve(siteDir, specPath);
|
|
107
107
|
|
|
108
108
|
try {
|
|
109
|
-
const openapiFiles = await readOpenapiFiles(contentPath
|
|
109
|
+
const openapiFiles = await readOpenapiFiles(contentPath);
|
|
110
110
|
const [loadedApi, tags] = await processOpenapiFiles(
|
|
111
111
|
openapiFiles,
|
|
112
|
+
options,
|
|
112
113
|
sidebarOptions!
|
|
113
114
|
);
|
|
114
115
|
if (!fs.existsSync(outputDir)) {
|
|
@@ -182,6 +183,10 @@ sidebar_class_name: "{{{api.method}}} api-method"
|
|
|
182
183
|
{{#infoPath}}
|
|
183
184
|
info_path: {{{infoPath}}}
|
|
184
185
|
{{/infoPath}}
|
|
186
|
+
custom_edit_url: null
|
|
187
|
+
{{#frontMatter.proxy}}
|
|
188
|
+
proxy: {{{frontMatter.proxy}}}
|
|
189
|
+
{{/frontMatter.proxy}}
|
|
185
190
|
---
|
|
186
191
|
|
|
187
192
|
{{{markdown}}}
|
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import { greaterThan,
|
|
8
|
+
import { greaterThan, codeFence } from "./utils";
|
|
9
9
|
|
|
10
10
|
export function createDescription(description: string | undefined) {
|
|
11
11
|
if (!description) {
|
|
12
12
|
return "";
|
|
13
13
|
}
|
|
14
14
|
return `\n\n${description
|
|
15
|
-
.replace(
|
|
16
|
-
.replace(
|
|
15
|
+
.replace(greaterThan, "\\>")
|
|
16
|
+
.replace(codeFence, function (match) {
|
|
17
|
+
return match.replace(/\\>/g, ">");
|
|
18
|
+
})}\n\n`;
|
|
17
19
|
}
|
|
@@ -29,8 +29,8 @@ export function mergeAllOf(allOf: SchemaObject[]) {
|
|
|
29
29
|
"x-examples": function () {
|
|
30
30
|
return true;
|
|
31
31
|
},
|
|
32
|
-
ignoreAdditionalProperties: true,
|
|
33
32
|
},
|
|
33
|
+
ignoreAdditionalProperties: true,
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
const required = allOf.reduce((acc, cur) => {
|
|
@@ -597,6 +597,7 @@ function createEdges({
|
|
|
597
597
|
collapsible: false,
|
|
598
598
|
name,
|
|
599
599
|
required: Array.isArray(required) ? required.includes(name) : required,
|
|
600
|
+
deprecated: mergedSchemas.deprecated,
|
|
600
601
|
schemaDescription: mergedSchemas.description,
|
|
601
602
|
schemaName: schemaName,
|
|
602
603
|
qualifierMessage: getQualifierMessage(schema),
|
|
@@ -630,6 +631,7 @@ function createEdges({
|
|
|
630
631
|
collapsible: false,
|
|
631
632
|
name,
|
|
632
633
|
required: Array.isArray(required) ? required.includes(name) : required,
|
|
634
|
+
deprecated: schema.deprecated,
|
|
633
635
|
schemaDescription: schema.description,
|
|
634
636
|
schemaName: schemaName,
|
|
635
637
|
qualifierMessage: getQualifierMessage(schema),
|
|
@@ -597,6 +597,7 @@ function createEdges({
|
|
|
597
597
|
collapsible: false,
|
|
598
598
|
name,
|
|
599
599
|
required: false,
|
|
600
|
+
deprecated: mergedSchemas.deprecated,
|
|
600
601
|
schemaDescription: mergedSchemas.description,
|
|
601
602
|
schemaName: schemaName,
|
|
602
603
|
qualifierMessage: getQualifierMessage(schema),
|
|
@@ -630,6 +631,7 @@ function createEdges({
|
|
|
630
631
|
collapsible: false,
|
|
631
632
|
name,
|
|
632
633
|
required: false,
|
|
634
|
+
deprecated: schema.deprecated,
|
|
633
635
|
schemaDescription: schema.description,
|
|
634
636
|
schemaName: schemaName,
|
|
635
637
|
qualifierMessage: getQualifierMessage(schema),
|
package/src/markdown/index.ts
CHANGED
|
@@ -53,7 +53,7 @@ export function createApiPageMD({
|
|
|
53
53
|
`import MimeTabs from "@theme/MimeTabs";\n`,
|
|
54
54
|
`import ParamsItem from "@theme/ParamsItem";\n`,
|
|
55
55
|
`import ResponseSamples from "@theme/ResponseSamples";\n`,
|
|
56
|
-
`import SchemaItem from "@theme/SchemaItem"
|
|
56
|
+
`import SchemaItem from "@theme/SchemaItem";\n`,
|
|
57
57
|
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
58
58
|
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
59
59
|
`import TabItem from "@theme/TabItem";\n\n`,
|
package/src/markdown/utils.ts
CHANGED
|
@@ -43,6 +43,7 @@ export function render(children: Children): string {
|
|
|
43
43
|
|
|
44
44
|
// Regex to selectively URL-encode '>' and '<' chars
|
|
45
45
|
export const lessThan =
|
|
46
|
-
/<(?!(=|button|\s?\/button|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|a|\s?\/a|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|div|\s?\/div|center|\s?\/center))/
|
|
46
|
+
/<(?!(=|button|\s?\/button|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|a|\s?\/a|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|div|\s?\/div|center|\s?\/center))/gu;
|
|
47
47
|
export const greaterThan =
|
|
48
|
-
/(?<!(button|details|summary|hr|br|span|strong|small|table|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|a|tag|li|ol|ul|img|div|center|\/|\s|"|'))
|
|
48
|
+
/(?<!(button|details|summary|hr|br|span|strong|small|table|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|a|tag|li|ol|ul|img|div|center|\/|\s|"|'))>/gu;
|
|
49
|
+
export const codeFence = /`{1,3}[\s\S]*?`{1,3}/g;
|
|
@@ -98,7 +98,7 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
98
98
|
mergeAllOf(allOf);
|
|
99
99
|
if (mergedSchemas.properties) {
|
|
100
100
|
for (const [key, value] of Object.entries(mergedSchemas.properties)) {
|
|
101
|
-
if (value.readOnly && value.readOnly === true) {
|
|
101
|
+
if ((value.readOnly && value.readOnly === true) || value.deprecated) {
|
|
102
102
|
delete mergedSchemas.properties[key];
|
|
103
103
|
}
|
|
104
104
|
}
|
|
@@ -121,7 +121,10 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
121
121
|
for (let [name, prop] of Object.entries(properties ?? {})) {
|
|
122
122
|
if (prop.properties) {
|
|
123
123
|
for (const [key, value] of Object.entries(prop.properties)) {
|
|
124
|
-
if (
|
|
124
|
+
if (
|
|
125
|
+
(value.readOnly && value.readOnly === true) ||
|
|
126
|
+
value.deprecated
|
|
127
|
+
) {
|
|
125
128
|
delete prop.properties[key];
|
|
126
129
|
}
|
|
127
130
|
}
|
|
@@ -129,7 +132,10 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
129
132
|
|
|
130
133
|
if (prop.items && prop.items.properties) {
|
|
131
134
|
for (const [key, value] of Object.entries(prop.items.properties)) {
|
|
132
|
-
if (
|
|
135
|
+
if (
|
|
136
|
+
(value.readOnly && value.readOnly === true) ||
|
|
137
|
+
value.deprecated
|
|
138
|
+
) {
|
|
133
139
|
delete prop.items.properties[key];
|
|
134
140
|
}
|
|
135
141
|
}
|
|
@@ -168,7 +174,7 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
168
174
|
return normalizeArray(schema.enum)[0];
|
|
169
175
|
}
|
|
170
176
|
|
|
171
|
-
if (schema.readOnly && schema.readOnly === true) {
|
|
177
|
+
if ((schema.readOnly && schema.readOnly === true) || schema.deprecated) {
|
|
172
178
|
return undefined;
|
|
173
179
|
}
|
|
174
180
|
|
|
@@ -88,7 +88,10 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
88
88
|
mergeAllOf(allOf);
|
|
89
89
|
if (mergedSchemas.properties) {
|
|
90
90
|
for (const [key, value] of Object.entries(mergedSchemas.properties)) {
|
|
91
|
-
if (
|
|
91
|
+
if (
|
|
92
|
+
(value.writeOnly && value.writeOnly === true) ||
|
|
93
|
+
value.deprecated
|
|
94
|
+
) {
|
|
92
95
|
delete mergedSchemas.properties[key];
|
|
93
96
|
}
|
|
94
97
|
}
|
|
@@ -121,7 +124,10 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
121
124
|
for (let [name, prop] of Object.entries(properties ?? {})) {
|
|
122
125
|
if (prop.properties) {
|
|
123
126
|
for (const [key, value] of Object.entries(prop.properties)) {
|
|
124
|
-
if (
|
|
127
|
+
if (
|
|
128
|
+
(value.writeOnly && value.writeOnly === true) ||
|
|
129
|
+
value.deprecated
|
|
130
|
+
) {
|
|
125
131
|
delete prop.properties[key];
|
|
126
132
|
}
|
|
127
133
|
}
|
|
@@ -129,7 +135,10 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
129
135
|
|
|
130
136
|
if (prop.items && prop.items.properties) {
|
|
131
137
|
for (const [key, value] of Object.entries(prop.items.properties)) {
|
|
132
|
-
if (
|
|
138
|
+
if (
|
|
139
|
+
(value.writeOnly && value.writeOnly === true) ||
|
|
140
|
+
value.deprecated
|
|
141
|
+
) {
|
|
133
142
|
delete prop.items.properties[key];
|
|
134
143
|
}
|
|
135
144
|
}
|
|
@@ -168,7 +177,7 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
|
|
|
168
177
|
return normalizeArray(schema.enum)[0];
|
|
169
178
|
}
|
|
170
179
|
|
|
171
|
-
if (schema.writeOnly && schema.writeOnly === true) {
|
|
180
|
+
if ((schema.writeOnly && schema.writeOnly === true) || schema.deprecated) {
|
|
172
181
|
return undefined;
|
|
173
182
|
}
|
|
174
183
|
|
|
@@ -17,8 +17,7 @@ describe("openapi", () => {
|
|
|
17
17
|
describe("readOpenapiFiles", () => {
|
|
18
18
|
it("readOpenapiFiles", async () => {
|
|
19
19
|
const results = await readOpenapiFiles(
|
|
20
|
-
posixPath(path.join(__dirname, "__fixtures__/examples"))
|
|
21
|
-
{ specPath: "./", outputDir: "./" }
|
|
20
|
+
posixPath(path.join(__dirname, "__fixtures__/examples"))
|
|
22
21
|
);
|
|
23
22
|
const categoryMeta = results.find((x) =>
|
|
24
23
|
x.source.endsWith("_category_.json")
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -80,11 +80,13 @@ type PartialPage<T> = Omit<T, "permalink" | "source" | "sourceDirName">;
|
|
|
80
80
|
|
|
81
81
|
function createItems(
|
|
82
82
|
openapiData: OpenApiObject,
|
|
83
|
+
options: APIOptions,
|
|
83
84
|
sidebarOptions: SidebarOptions
|
|
84
85
|
): ApiMetadata[] {
|
|
85
86
|
// TODO: Find a better way to handle this
|
|
86
87
|
let items: PartialPage<ApiMetadata>[] = [];
|
|
87
|
-
const
|
|
88
|
+
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
89
|
+
const infoId = kebabCase(infoIdSpaces);
|
|
88
90
|
|
|
89
91
|
if (openapiData.info.description) {
|
|
90
92
|
// Only create an info page if we have a description.
|
|
@@ -218,6 +220,7 @@ function createItems(
|
|
|
218
220
|
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
219
221
|
.replace(/\s+$/, "")
|
|
220
222
|
: "",
|
|
223
|
+
...(options?.proxy && { proxy: options.proxy }),
|
|
221
224
|
},
|
|
222
225
|
api: {
|
|
223
226
|
...defaults,
|
|
@@ -236,6 +239,122 @@ function createItems(
|
|
|
236
239
|
}
|
|
237
240
|
}
|
|
238
241
|
|
|
242
|
+
// Gather x-webhooks endpoints
|
|
243
|
+
for (let [path, pathObject] of Object.entries(
|
|
244
|
+
openapiData["x-webhooks"] ?? {}
|
|
245
|
+
)) {
|
|
246
|
+
path = "webhook";
|
|
247
|
+
const { $ref, description, parameters, servers, summary, ...rest } =
|
|
248
|
+
pathObject;
|
|
249
|
+
for (let [method, operationObject] of Object.entries({ ...rest })) {
|
|
250
|
+
method = "event";
|
|
251
|
+
const title =
|
|
252
|
+
operationObject.summary ??
|
|
253
|
+
operationObject.operationId ??
|
|
254
|
+
"Missing summary";
|
|
255
|
+
if (operationObject.description === undefined) {
|
|
256
|
+
operationObject.description =
|
|
257
|
+
operationObject.summary ?? operationObject.operationId ?? "";
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const baseId = operationObject.operationId
|
|
261
|
+
? kebabCase(operationObject.operationId)
|
|
262
|
+
: kebabCase(operationObject.summary);
|
|
263
|
+
|
|
264
|
+
const servers =
|
|
265
|
+
operationObject.servers ?? pathObject.servers ?? openapiData.servers;
|
|
266
|
+
|
|
267
|
+
const security = operationObject.security ?? openapiData.security;
|
|
268
|
+
|
|
269
|
+
// Add security schemes so we know how to handle security.
|
|
270
|
+
const securitySchemes = openapiData.components?.securitySchemes;
|
|
271
|
+
|
|
272
|
+
// Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
|
|
273
|
+
if (securitySchemes) {
|
|
274
|
+
for (let securityScheme of Object.values(securitySchemes)) {
|
|
275
|
+
if (securityScheme.type === "http") {
|
|
276
|
+
securityScheme.scheme = securityScheme.scheme.toLowerCase();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let jsonRequestBodyExample;
|
|
282
|
+
const body = operationObject.requestBody?.content?.["application/json"];
|
|
283
|
+
if (body?.schema) {
|
|
284
|
+
jsonRequestBodyExample = sampleRequestFromSchema(body.schema);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Handle vendor JSON media types
|
|
288
|
+
const bodyContent = operationObject.requestBody?.content;
|
|
289
|
+
if (bodyContent) {
|
|
290
|
+
const firstBodyContentKey = Object.keys(bodyContent)[0];
|
|
291
|
+
if (firstBodyContentKey.endsWith("+json")) {
|
|
292
|
+
const firstBody = bodyContent[firstBodyContentKey];
|
|
293
|
+
if (firstBody?.schema) {
|
|
294
|
+
jsonRequestBodyExample = sampleRequestFromSchema(firstBody.schema);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// TODO: Don't include summary temporarilly
|
|
300
|
+
const { summary, ...defaults } = operationObject;
|
|
301
|
+
|
|
302
|
+
// Merge common parameters with operation parameters
|
|
303
|
+
// Operation params take precendence over common params
|
|
304
|
+
if (parameters !== undefined) {
|
|
305
|
+
if (operationObject.parameters !== undefined) {
|
|
306
|
+
defaults.parameters = unionBy(
|
|
307
|
+
operationObject.parameters,
|
|
308
|
+
parameters,
|
|
309
|
+
"name"
|
|
310
|
+
);
|
|
311
|
+
} else {
|
|
312
|
+
defaults.parameters = parameters;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const opDescription = operationObject.description;
|
|
317
|
+
let splitDescription: any;
|
|
318
|
+
if (opDescription) {
|
|
319
|
+
splitDescription = opDescription.match(/[^\r\n]+/g);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const apiPage: PartialPage<ApiPageMetadata> = {
|
|
323
|
+
type: "api",
|
|
324
|
+
id: baseId,
|
|
325
|
+
infoId: infoId ?? "",
|
|
326
|
+
unversionedId: baseId,
|
|
327
|
+
title: title ? title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'") : "",
|
|
328
|
+
description: operationObject.description
|
|
329
|
+
? operationObject.description.replace(
|
|
330
|
+
/((?:^|[^\\])(?:\\{2})*)"/g,
|
|
331
|
+
"$1'"
|
|
332
|
+
)
|
|
333
|
+
: "",
|
|
334
|
+
frontMatter: {
|
|
335
|
+
description: splitDescription
|
|
336
|
+
? splitDescription[0]
|
|
337
|
+
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
338
|
+
.replace(/\s+$/, "")
|
|
339
|
+
: "",
|
|
340
|
+
...(options?.proxy && { proxy: options.proxy }),
|
|
341
|
+
},
|
|
342
|
+
api: {
|
|
343
|
+
...defaults,
|
|
344
|
+
tags: operationObject.tags,
|
|
345
|
+
method,
|
|
346
|
+
path,
|
|
347
|
+
servers,
|
|
348
|
+
security,
|
|
349
|
+
securitySchemes,
|
|
350
|
+
jsonRequestBodyExample,
|
|
351
|
+
info: openapiData.info,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
items.push(apiPage);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
239
358
|
if (sidebarOptions?.categoryLinkSource === "tag") {
|
|
240
359
|
// Get global tags
|
|
241
360
|
const tags: TagObject[] = openapiData.tags ?? [];
|
|
@@ -318,8 +437,7 @@ interface OpenApiFiles {
|
|
|
318
437
|
}
|
|
319
438
|
|
|
320
439
|
export async function readOpenapiFiles(
|
|
321
|
-
openapiPath: string
|
|
322
|
-
options: APIOptions
|
|
440
|
+
openapiPath: string
|
|
323
441
|
): Promise<OpenApiFiles[]> {
|
|
324
442
|
if (!isURL(openapiPath)) {
|
|
325
443
|
const stat = await fs.lstat(openapiPath);
|
|
@@ -361,11 +479,16 @@ export async function readOpenapiFiles(
|
|
|
361
479
|
|
|
362
480
|
export async function processOpenapiFiles(
|
|
363
481
|
files: OpenApiFiles[],
|
|
482
|
+
options: APIOptions,
|
|
364
483
|
sidebarOptions: SidebarOptions
|
|
365
484
|
): Promise<[ApiMetadata[], TagObject[][]]> {
|
|
366
485
|
const promises = files.map(async (file) => {
|
|
367
486
|
if (file.data !== undefined) {
|
|
368
|
-
const processedFile = await processOpenapiFile(
|
|
487
|
+
const processedFile = await processOpenapiFile(
|
|
488
|
+
file.data,
|
|
489
|
+
options,
|
|
490
|
+
sidebarOptions
|
|
491
|
+
);
|
|
369
492
|
const itemsObjectsArray = processedFile[0].map((item) => ({
|
|
370
493
|
...item,
|
|
371
494
|
}));
|
|
@@ -402,10 +525,11 @@ export async function processOpenapiFiles(
|
|
|
402
525
|
|
|
403
526
|
export async function processOpenapiFile(
|
|
404
527
|
openapiData: OpenApiObject,
|
|
528
|
+
options: APIOptions,
|
|
405
529
|
sidebarOptions: SidebarOptions
|
|
406
530
|
): Promise<[ApiMetadata[], TagObject[]]> {
|
|
407
531
|
const postmanCollection = await createPostmanCollection(openapiData);
|
|
408
|
-
const items = createItems(openapiData, sidebarOptions);
|
|
532
|
+
const items = createItems(openapiData, options, sidebarOptions);
|
|
409
533
|
|
|
410
534
|
bindCollectionToApiItems(items, postmanCollection);
|
|
411
535
|
|
package/src/openapi/types.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import $RefParser from "@
|
|
8
|
+
import $RefParser from "@paloaltonetworks/json-schema-ref-parser";
|
|
9
9
|
import { bundle, Config } from "@redocly/openapi-core";
|
|
10
10
|
import type { Source, Document } from "@redocly/openapi-core";
|
|
11
11
|
import { ResolvedConfig } from "@redocly/openapi-core/lib/config";
|
|
@@ -66,7 +66,13 @@ export function convertSwagger2OpenAPI(spec: object) {
|
|
|
66
66
|
return new Promise((resolve, reject) =>
|
|
67
67
|
convertObj(
|
|
68
68
|
spec,
|
|
69
|
-
{
|
|
69
|
+
{
|
|
70
|
+
patch: true,
|
|
71
|
+
warnOnly: true,
|
|
72
|
+
text: "{}",
|
|
73
|
+
anchors: true,
|
|
74
|
+
resolveInternal: true,
|
|
75
|
+
},
|
|
70
76
|
(err: any, res: any) => {
|
|
71
77
|
// TODO: log any warnings
|
|
72
78
|
if (err) {
|
package/src/options.ts
CHANGED
package/src/types.ts
CHANGED
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 Palo Alto Networks
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|