docusaurus-plugin-openapi-docs 4.5.1 → 4.7.0
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 +110 -22
- package/lib/index.js +122 -50
- package/lib/markdown/createHeading.js +1 -1
- package/lib/markdown/createRequestHeader.js +5 -3
- package/lib/markdown/createSchema.js +2 -2
- package/lib/markdown/index.js +3 -2
- package/lib/markdown/schema.js +5 -0
- package/lib/markdown/utils.d.ts +38 -1
- package/lib/markdown/utils.js +100 -2
- package/lib/openapi/createSchemaExample.js +16 -2
- package/lib/openapi/createSchemaExample.test.d.ts +1 -0
- package/lib/openapi/createSchemaExample.test.js +48 -0
- package/lib/openapi/openapi.js +38 -17
- package/lib/openapi/openapi.test.js +48 -0
- package/lib/openapi/webhooks.test.d.ts +1 -0
- package/lib/openapi/webhooks.test.js +23 -0
- package/lib/options.js +4 -0
- package/lib/sidebars/index.js +12 -3
- package/package.json +16 -16
- package/src/index.ts +165 -62
- package/src/markdown/createHeading.ts +2 -2
- package/src/markdown/createRequestHeader.ts +9 -11
- package/src/markdown/createSchema.ts +4 -2
- package/src/markdown/index.ts +3 -2
- package/src/markdown/schema.ts +6 -0
- package/src/markdown/utils.ts +153 -3
- package/src/openapi/__fixtures__/webhook/openapi.yaml +17 -0
- package/src/openapi/createSchemaExample.test.ts +57 -0
- package/src/openapi/createSchemaExample.ts +26 -2
- package/src/openapi/openapi.test.ts +58 -0
- package/src/openapi/openapi.ts +35 -6
- package/src/openapi/webhooks.test.ts +30 -0
- package/src/options.ts +4 -0
- package/src/plugin-openapi.d.ts +1 -1
- package/src/sidebars/index.ts +15 -3
- package/src/{types.ts → types.d.ts} +12 -2
- package/lib/types.d.ts +0 -135
- package/lib/types.js +0 -8
- package/src/plugin-content-docs-types.d.ts +0 -42
package/lib/markdown/index.js
CHANGED
|
@@ -37,7 +37,8 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
|
|
|
37
37
|
`import StatusCodes from "@theme/StatusCodes";\n`,
|
|
38
38
|
`import OperationTabs from "@theme/OperationTabs";\n`,
|
|
39
39
|
`import TabItem from "@theme/TabItem";\n`,
|
|
40
|
-
`import Heading from "@theme/Heading";\n
|
|
40
|
+
`import Heading from "@theme/Heading";\n`,
|
|
41
|
+
`import Translate from "@docusaurus/Translate";\n\n`,
|
|
41
42
|
(0, createHeading_1.createHeading)(title),
|
|
42
43
|
(0, createMethodEndpoint_1.createMethodEndpoint)(method, path),
|
|
43
44
|
infoPath && (0, createAuthorization_1.createAuthorization)(infoPath),
|
|
@@ -82,7 +83,7 @@ function createSchemaPageMD({ schema }) {
|
|
|
82
83
|
return (0, utils_1.render)([
|
|
83
84
|
`import Schema from "@theme/Schema";\n`,
|
|
84
85
|
`import Heading from "@theme/Heading";\n\n`,
|
|
85
|
-
(0, createHeading_1.createHeading)(title
|
|
86
|
+
(0, createHeading_1.createHeading)(title),
|
|
86
87
|
(0, createDescription_1.createDescription)(description),
|
|
87
88
|
(0, utils_1.create)("Schema", {
|
|
88
89
|
schema: schema,
|
package/lib/markdown/schema.js
CHANGED
|
@@ -10,6 +10,11 @@ exports.getSchemaName = getSchemaName;
|
|
|
10
10
|
exports.getQualifierMessage = getQualifierMessage;
|
|
11
11
|
function prettyName(schema, circular) {
|
|
12
12
|
var _a, _b, _c, _d, _e;
|
|
13
|
+
// Handle enum-only schemas (valid in JSON Schema)
|
|
14
|
+
// When enum is present without explicit type, treat as string
|
|
15
|
+
if (schema.enum && !schema.type) {
|
|
16
|
+
return "string";
|
|
17
|
+
}
|
|
13
18
|
if (schema.format) {
|
|
14
19
|
if (schema.type) {
|
|
15
20
|
return `${schema.type}<${schema.format}>`;
|
package/lib/markdown/utils.d.ts
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an external JSON file to be written alongside the MDX.
|
|
3
|
+
*/
|
|
4
|
+
export interface ExternalFile {
|
|
5
|
+
/** The filename for the JSON file (relative to outputDir) */
|
|
6
|
+
filename: string;
|
|
7
|
+
/** The JSON content to write */
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of running MDX generation with externalization.
|
|
12
|
+
*/
|
|
13
|
+
export interface ExternalizationResult<T> {
|
|
14
|
+
/** The result of the generation function */
|
|
15
|
+
result: T;
|
|
16
|
+
/** External JSON files to write */
|
|
17
|
+
files: ExternalFile[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs a function with externalization enabled.
|
|
21
|
+
* Any calls to create() within the function will externalize eligible component props.
|
|
22
|
+
*
|
|
23
|
+
* @param baseFilename - Base filename for the MDX file (without extension)
|
|
24
|
+
* @param fn - Function to run with externalization enabled
|
|
25
|
+
* @returns The function result and any external files that were collected
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const { result: mdx, files } = runWithExternalization("add-pet", () => {
|
|
29
|
+
* return createApiPageMD(item);
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export declare function runWithExternalization<T>(baseFilename: string, fn: () => T): ExternalizationResult<T>;
|
|
1
33
|
/**
|
|
2
34
|
* Children in the plugin does not accept DOM elements, when compared with Children in the theme.
|
|
3
|
-
* It is designed for rendering HTML
|
|
35
|
+
* It is designed for rendering HTML as strings.
|
|
4
36
|
*/
|
|
5
37
|
export type Children = string | undefined | (string | string[] | undefined)[];
|
|
6
38
|
export type Props = Record<string, any> & {
|
|
@@ -9,6 +41,11 @@ export type Props = Record<string, any> & {
|
|
|
9
41
|
export type Options = {
|
|
10
42
|
inline?: boolean;
|
|
11
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Creates a JSX component string with the given tag, props, and options.
|
|
46
|
+
* When called within runWithExternalization(), props for eligible
|
|
47
|
+
* components are externalized to a single JSON file and spread.
|
|
48
|
+
*/
|
|
12
49
|
export declare function create(tag: string, props: Props, options?: Options): string;
|
|
13
50
|
export declare function guard<T>(value: T | undefined, cb: (value: T) => Children): string;
|
|
14
51
|
export declare function render(children: Children): string;
|
package/lib/markdown/utils.js
CHANGED
|
@@ -7,15 +7,82 @@
|
|
|
7
7
|
* ========================================================================== */
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.codeBlock = exports.curlyBrackets = exports.codeFence = exports.greaterThan = exports.lessThan = void 0;
|
|
10
|
+
exports.runWithExternalization = runWithExternalization;
|
|
10
11
|
exports.create = create;
|
|
11
12
|
exports.guard = guard;
|
|
12
13
|
exports.render = render;
|
|
13
14
|
exports.clean = clean;
|
|
15
|
+
/**
|
|
16
|
+
* Module-level externalization context.
|
|
17
|
+
* Note: AsyncLocalStorage would be cleaner but isn't available in browser bundles.
|
|
18
|
+
*/
|
|
19
|
+
let externalizationContext = null;
|
|
20
|
+
/**
|
|
21
|
+
* Components whose props should be externalized to separate JSON files.
|
|
22
|
+
* These are the components that typically receive large JSON objects.
|
|
23
|
+
*/
|
|
24
|
+
const EXTERNALIZABLE_COMPONENTS = new Set([
|
|
25
|
+
"StatusCodes",
|
|
26
|
+
"ParamsDetails",
|
|
27
|
+
"RequestSchema",
|
|
28
|
+
"Schema",
|
|
29
|
+
"SchemaItem",
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* Runs a function with externalization enabled.
|
|
33
|
+
* Any calls to create() within the function will externalize eligible component props.
|
|
34
|
+
*
|
|
35
|
+
* @param baseFilename - Base filename for the MDX file (without extension)
|
|
36
|
+
* @param fn - Function to run with externalization enabled
|
|
37
|
+
* @returns The function result and any external files that were collected
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const { result: mdx, files } = runWithExternalization("add-pet", () => {
|
|
41
|
+
* return createApiPageMD(item);
|
|
42
|
+
* });
|
|
43
|
+
*/
|
|
44
|
+
function runWithExternalization(baseFilename, fn) {
|
|
45
|
+
// Set up context
|
|
46
|
+
externalizationContext = {
|
|
47
|
+
baseFilename,
|
|
48
|
+
componentCounters: {},
|
|
49
|
+
files: [],
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
const result = fn();
|
|
53
|
+
const files = externalizationContext.files;
|
|
54
|
+
return { result, files };
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
// Always clear context
|
|
58
|
+
externalizationContext = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a JSX component string with the given tag, props, and options.
|
|
63
|
+
* When called within runWithExternalization(), props for eligible
|
|
64
|
+
* components are externalized to a single JSON file and spread.
|
|
65
|
+
*/
|
|
14
66
|
function create(tag, props, options = {}) {
|
|
15
67
|
const { children, ...rest } = props;
|
|
16
68
|
let propString = "";
|
|
17
|
-
|
|
18
|
-
|
|
69
|
+
// Check if this component's props should be externalized
|
|
70
|
+
if (shouldExternalizeComponent(tag, rest)) {
|
|
71
|
+
const filename = generateExternalFilename(tag);
|
|
72
|
+
const content = JSON.stringify(rest);
|
|
73
|
+
// Add to external files
|
|
74
|
+
externalizationContext.files.push({
|
|
75
|
+
filename,
|
|
76
|
+
content,
|
|
77
|
+
});
|
|
78
|
+
// Use spread syntax with require
|
|
79
|
+
propString = `\n {...require("./${filename}")}`;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Inline props as usual
|
|
83
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
84
|
+
propString += `\n ${key}={${JSON.stringify(value)}}`;
|
|
85
|
+
}
|
|
19
86
|
}
|
|
20
87
|
let indentedChildren = render(children).replace(/^/gm, " ");
|
|
21
88
|
if (options.inline) {
|
|
@@ -26,6 +93,37 @@ function create(tag, props, options = {}) {
|
|
|
26
93
|
indentedChildren += indentedChildren ? "\n" : "";
|
|
27
94
|
return `<${tag}${propString}>\n${indentedChildren}</${tag}>`;
|
|
28
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Determines if a component's props should be externalized.
|
|
98
|
+
*/
|
|
99
|
+
function shouldExternalizeComponent(tag, props) {
|
|
100
|
+
// No context means externalization is not enabled
|
|
101
|
+
if (!externalizationContext) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (!EXTERNALIZABLE_COMPONENTS.has(tag)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
// Don't externalize if props are empty or only contain undefined/null
|
|
108
|
+
const hasContent = Object.values(props).some((v) => v !== undefined && v !== null);
|
|
109
|
+
if (!hasContent) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generates a unique filename for an externalized component's props.
|
|
116
|
+
*/
|
|
117
|
+
function generateExternalFilename(componentName) {
|
|
118
|
+
var _a;
|
|
119
|
+
if (!externalizationContext) {
|
|
120
|
+
throw new Error("Externalization context not set");
|
|
121
|
+
}
|
|
122
|
+
const count = ((_a = externalizationContext.componentCounters[componentName]) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
123
|
+
externalizationContext.componentCounters[componentName] = count;
|
|
124
|
+
const suffix = count > 1 ? `.${count}` : "";
|
|
125
|
+
return `${externalizationContext.baseFilename}.${componentName}${suffix}.json`;
|
|
126
|
+
}
|
|
29
127
|
function guard(value, cb) {
|
|
30
128
|
if (!!value || value === 0) {
|
|
31
129
|
const children = cb(value);
|
|
@@ -58,7 +58,14 @@ function sampleFromProp(name, prop, obj, context) {
|
|
|
58
58
|
return obj;
|
|
59
59
|
}
|
|
60
60
|
// TODO: handle discriminators
|
|
61
|
-
|
|
61
|
+
// Check for explicit example/examples first (OAS 3.1 support)
|
|
62
|
+
if (prop.example !== undefined) {
|
|
63
|
+
obj[name] = prop.example;
|
|
64
|
+
}
|
|
65
|
+
else if (prop.examples !== undefined && prop.examples.length > 0) {
|
|
66
|
+
obj[name] = prop.examples[0];
|
|
67
|
+
}
|
|
68
|
+
else if (prop.oneOf) {
|
|
62
69
|
obj[name] = (0, exports.sampleFromSchema)(prop.oneOf[0], context);
|
|
63
70
|
}
|
|
64
71
|
else if (prop.anyOf) {
|
|
@@ -77,10 +84,14 @@ const sampleFromSchema = (schema = {}, context) => {
|
|
|
77
84
|
try {
|
|
78
85
|
// deep copy schema before processing
|
|
79
86
|
let schemaCopy = JSON.parse(JSON.stringify(schema));
|
|
80
|
-
let { type, example, allOf, properties, items, oneOf, anyOf } = schemaCopy;
|
|
87
|
+
let { type, example, examples, allOf, properties, items, oneOf, anyOf, const: constant, } = schemaCopy;
|
|
81
88
|
if (example !== undefined) {
|
|
82
89
|
return example;
|
|
83
90
|
}
|
|
91
|
+
// OAS 3.1 / JSON Schema: examples is an array
|
|
92
|
+
if (examples !== undefined && examples.length > 0) {
|
|
93
|
+
return examples[0];
|
|
94
|
+
}
|
|
84
95
|
if (oneOf) {
|
|
85
96
|
if (properties) {
|
|
86
97
|
const combinedSchemas = (0, merge_1.default)(schemaCopy, oneOf[0]);
|
|
@@ -169,6 +180,9 @@ const sampleFromSchema = (schema = {}, context) => {
|
|
|
169
180
|
if (shouldExcludeProperty(schemaCopy, context)) {
|
|
170
181
|
return undefined;
|
|
171
182
|
}
|
|
183
|
+
if (constant) {
|
|
184
|
+
return constant;
|
|
185
|
+
}
|
|
172
186
|
return primitive(schemaCopy);
|
|
173
187
|
}
|
|
174
188
|
catch (err) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
const createSchemaExample_1 = require("./createSchemaExample");
|
|
10
|
+
describe("sampleFromSchema", () => {
|
|
11
|
+
describe("const support", () => {
|
|
12
|
+
it("should return default string value when const is not present", () => {
|
|
13
|
+
const schema = {
|
|
14
|
+
type: "string",
|
|
15
|
+
};
|
|
16
|
+
const context = { type: "request" };
|
|
17
|
+
const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
|
|
18
|
+
expect(result).toBe("string");
|
|
19
|
+
});
|
|
20
|
+
it("should return const value when const is present", () => {
|
|
21
|
+
const schema = {
|
|
22
|
+
type: "string",
|
|
23
|
+
const: "example",
|
|
24
|
+
};
|
|
25
|
+
const context = { type: "request" };
|
|
26
|
+
const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
|
|
27
|
+
expect(result).toBe("example");
|
|
28
|
+
});
|
|
29
|
+
it("should handle anyOf with const values", () => {
|
|
30
|
+
const schema = {
|
|
31
|
+
type: "string",
|
|
32
|
+
anyOf: [
|
|
33
|
+
{
|
|
34
|
+
type: "string",
|
|
35
|
+
const: "dog",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "string",
|
|
39
|
+
const: "cat",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
const context = { type: "request" };
|
|
44
|
+
const result = (0, createSchemaExample_1.sampleFromSchema)(schema, context);
|
|
45
|
+
expect(result).toBe("dog");
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -65,11 +65,16 @@ const loadAndResolveSpec_1 = require("./utils/loadAndResolveSpec");
|
|
|
65
65
|
*/
|
|
66
66
|
function jsonToCollection(data) {
|
|
67
67
|
return new Promise((resolve, reject) => {
|
|
68
|
+
var _a, _b;
|
|
68
69
|
let schemaPack = new openapi_to_postmanv2_1.default.SchemaPack({ type: "json", data }, { schemaFaker: false });
|
|
69
70
|
schemaPack.computedOptions.schemaFaker = false;
|
|
71
|
+
// Make sure the schema was properly validated or reject with error
|
|
72
|
+
if (!((_a = schemaPack.validationResult) === null || _a === void 0 ? void 0 : _a.result)) {
|
|
73
|
+
return reject((_b = schemaPack.validationResult) === null || _b === void 0 ? void 0 : _b.reason);
|
|
74
|
+
}
|
|
70
75
|
schemaPack.convert((_err, conversionResult) => {
|
|
71
|
-
if (!conversionResult.result) {
|
|
72
|
-
return reject(conversionResult.reason);
|
|
76
|
+
if (_err || !conversionResult.result) {
|
|
77
|
+
return reject(_err || conversionResult.reason);
|
|
73
78
|
}
|
|
74
79
|
return resolve(new sdk.Collection(conversionResult.output[0].data));
|
|
75
80
|
});
|
|
@@ -98,13 +103,15 @@ async function createPostmanCollection(openapiData) {
|
|
|
98
103
|
return await jsonToCollection(data);
|
|
99
104
|
}
|
|
100
105
|
function createItems(openapiData, options, sidebarOptions) {
|
|
101
|
-
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, _3, _4, _5, _6, _7;
|
|
106
|
+
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, _3, _4, _5, _6, _7, _8;
|
|
102
107
|
// TODO: Find a better way to handle this
|
|
103
108
|
let items = [];
|
|
104
109
|
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
105
110
|
const infoId = (0, kebabCase_1.default)(infoIdSpaces);
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
const schemasOnly = (options === null || options === void 0 ? void 0 : options.schemasOnly) === true;
|
|
112
|
+
// Only create an info page if we have a description/title AND showInfoPage is not false
|
|
113
|
+
if ((openapiData.info.description || openapiData.info.title) &&
|
|
114
|
+
(options === null || options === void 0 ? void 0 : options.showInfoPage) !== false) {
|
|
108
115
|
const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
|
|
109
116
|
let splitDescription;
|
|
110
117
|
if (infoDescription) {
|
|
@@ -231,6 +238,9 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
231
238
|
...((options === null || options === void 0 ? void 0 : options.showExtensions) && {
|
|
232
239
|
show_extensions: options.showExtensions,
|
|
233
240
|
}),
|
|
241
|
+
...((options === null || options === void 0 ? void 0 : options.maskCredentials) === false && {
|
|
242
|
+
mask_credentials_disabled: true,
|
|
243
|
+
}),
|
|
234
244
|
},
|
|
235
245
|
api: {
|
|
236
246
|
...defaults,
|
|
@@ -251,10 +261,15 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
251
261
|
}
|
|
252
262
|
// Gather x-webhooks endpoints
|
|
253
263
|
for (let [path, pathObject] of Object.entries((_q = (_p = openapiData["x-webhooks"]) !== null && _p !== void 0 ? _p : openapiData["webhooks"]) !== null && _q !== void 0 ? _q : {})) {
|
|
264
|
+
const eventName = path;
|
|
254
265
|
path = "webhook";
|
|
255
266
|
const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
|
|
256
267
|
for (let [method, operationObject] of Object.entries({ ...rest })) {
|
|
257
268
|
method = "event";
|
|
269
|
+
if (operationObject.summary === undefined &&
|
|
270
|
+
operationObject.operationId === undefined) {
|
|
271
|
+
operationObject.summary = eventName;
|
|
272
|
+
}
|
|
258
273
|
const title = (_s = (_r = operationObject.summary) !== null && _r !== void 0 ? _r : operationObject.operationId) !== null && _s !== void 0 ? _s : "Missing summary";
|
|
259
274
|
if (operationObject.description === undefined) {
|
|
260
275
|
operationObject.description =
|
|
@@ -262,7 +277,7 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
262
277
|
}
|
|
263
278
|
const baseId = operationObject.operationId
|
|
264
279
|
? (0, kebabCase_1.default)(operationObject.operationId)
|
|
265
|
-
: (0, kebabCase_1.default)(operationObject.summary);
|
|
280
|
+
: (0, kebabCase_1.default)((_v = operationObject.summary) !== null && _v !== void 0 ? _v : eventName);
|
|
266
281
|
const extensions = [];
|
|
267
282
|
const commonExtensions = ["x-codeSamples"];
|
|
268
283
|
for (const [key, value] of Object.entries(operationObject)) {
|
|
@@ -270,10 +285,10 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
270
285
|
extensions.push({ key, value });
|
|
271
286
|
}
|
|
272
287
|
}
|
|
273
|
-
const servers = (
|
|
274
|
-
const security = (
|
|
288
|
+
const servers = (_x = (_w = operationObject.servers) !== null && _w !== void 0 ? _w : pathObject.servers) !== null && _x !== void 0 ? _x : openapiData.servers;
|
|
289
|
+
const security = (_y = operationObject.security) !== null && _y !== void 0 ? _y : openapiData.security;
|
|
275
290
|
// Add security schemes so we know how to handle security.
|
|
276
|
-
const securitySchemes = (
|
|
291
|
+
const securitySchemes = (_z = openapiData.components) === null || _z === void 0 ? void 0 : _z.securitySchemes;
|
|
277
292
|
// Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
|
|
278
293
|
if (securitySchemes) {
|
|
279
294
|
for (let securityScheme of Object.values(securitySchemes)) {
|
|
@@ -283,7 +298,7 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
283
298
|
}
|
|
284
299
|
}
|
|
285
300
|
let jsonRequestBodyExample;
|
|
286
|
-
const content = (
|
|
301
|
+
const content = (_0 = operationObject.requestBody) === null || _0 === void 0 ? void 0 : _0.content;
|
|
287
302
|
let body;
|
|
288
303
|
for (let key in content) {
|
|
289
304
|
if (key.toLowerCase() === "application/json" ||
|
|
@@ -296,7 +311,7 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
296
311
|
jsonRequestBodyExample = (0, createRequestExample_1.sampleRequestFromSchema)(body.schema);
|
|
297
312
|
}
|
|
298
313
|
// Handle vendor JSON media types
|
|
299
|
-
const bodyContent = (
|
|
314
|
+
const bodyContent = (_1 = operationObject.requestBody) === null || _1 === void 0 ? void 0 : _1.content;
|
|
300
315
|
if (bodyContent) {
|
|
301
316
|
const firstBodyContentKey = Object.keys(bodyContent)[0];
|
|
302
317
|
if (firstBodyContentKey.endsWith("+json")) {
|
|
@@ -345,6 +360,9 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
345
360
|
...((options === null || options === void 0 ? void 0 : options.showExtensions) && {
|
|
346
361
|
show_extensions: options.showExtensions,
|
|
347
362
|
}),
|
|
363
|
+
...((options === null || options === void 0 ? void 0 : options.maskCredentials) === false && {
|
|
364
|
+
mask_credentials_disabled: true,
|
|
365
|
+
}),
|
|
348
366
|
},
|
|
349
367
|
api: {
|
|
350
368
|
...defaults,
|
|
@@ -362,14 +380,17 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
362
380
|
items.push(apiPage);
|
|
363
381
|
}
|
|
364
382
|
}
|
|
365
|
-
if (
|
|
366
|
-
|
|
383
|
+
if (schemasOnly ||
|
|
384
|
+
(options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
|
|
385
|
+
Object.entries((_3 = (_2 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _2 === void 0 ? void 0 : _2.schemas) !== null && _3 !== void 0 ? _3 : {})
|
|
367
386
|
.flatMap(([_, s]) => s["x-tags"])
|
|
368
387
|
.filter((item) => !!item).length > 0) {
|
|
369
388
|
// Gather schemas
|
|
370
|
-
for (let [schema, schemaObject] of Object.entries((
|
|
371
|
-
if (
|
|
372
|
-
|
|
389
|
+
for (let [schema, schemaObject] of Object.entries((_5 = (_4 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _4 === void 0 ? void 0 : _4.schemas) !== null && _5 !== void 0 ? _5 : {})) {
|
|
390
|
+
if (schemasOnly ||
|
|
391
|
+
(options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
|
|
392
|
+
schemaObject["x-tags"]) {
|
|
393
|
+
const baseIdSpaces = (_7 = (_6 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _6 === void 0 ? void 0 : _6.replace(" ", "-").toLowerCase()) !== null && _7 !== void 0 ? _7 : "";
|
|
373
394
|
const baseId = (0, kebabCase_1.default)(baseIdSpaces);
|
|
374
395
|
const schemaDescription = schemaObject.description;
|
|
375
396
|
let splitDescription;
|
|
@@ -403,7 +424,7 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
403
424
|
}
|
|
404
425
|
if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
|
|
405
426
|
// Get global tags
|
|
406
|
-
const tags = (
|
|
427
|
+
const tags = (_8 = openapiData.tags) !== null && _8 !== void 0 ? _8 : [];
|
|
407
428
|
// Get operation tags
|
|
408
429
|
const apiItems = items.filter((item) => {
|
|
409
430
|
return item.type === "api";
|
|
@@ -13,6 +13,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
13
13
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
14
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
15
|
const _1 = require(".");
|
|
16
|
+
const openapi_1 = require("./openapi");
|
|
16
17
|
// npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
|
|
17
18
|
describe("openapi", () => {
|
|
18
19
|
describe("readOpenapiFiles", () => {
|
|
@@ -30,4 +31,51 @@ describe("openapi", () => {
|
|
|
30
31
|
expect((_b = (_a = yaml === null || yaml === void 0 ? void 0 : yaml.data.components) === null || _a === void 0 ? void 0 : _a.schemas) === null || _b === void 0 ? void 0 : _b.HelloString["x-tags"]).toBeDefined();
|
|
31
32
|
});
|
|
32
33
|
});
|
|
34
|
+
describe("schemasOnly", () => {
|
|
35
|
+
it("includes schema metadata when showSchemas is disabled", async () => {
|
|
36
|
+
const openapiData = {
|
|
37
|
+
openapi: "3.0.0",
|
|
38
|
+
info: {
|
|
39
|
+
title: "Schema Only",
|
|
40
|
+
version: "1.0.0",
|
|
41
|
+
},
|
|
42
|
+
paths: {
|
|
43
|
+
"/ping": {
|
|
44
|
+
get: {
|
|
45
|
+
summary: "Ping",
|
|
46
|
+
responses: {
|
|
47
|
+
"200": {
|
|
48
|
+
description: "OK",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
components: {
|
|
55
|
+
schemas: {
|
|
56
|
+
WithoutTags: {
|
|
57
|
+
title: "Without Tags",
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: {
|
|
60
|
+
value: {
|
|
61
|
+
type: "string",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
const options = {
|
|
69
|
+
specPath: "dummy", // required by the type but unused in this context
|
|
70
|
+
outputDir: "build",
|
|
71
|
+
showSchemas: false,
|
|
72
|
+
schemasOnly: true,
|
|
73
|
+
};
|
|
74
|
+
const sidebarOptions = {};
|
|
75
|
+
const [items] = await (0, openapi_1.processOpenapiFile)(openapiData, options, sidebarOptions);
|
|
76
|
+
const schemaItems = items.filter((item) => item.type === "schema");
|
|
77
|
+
expect(schemaItems).toHaveLength(1);
|
|
78
|
+
expect(schemaItems[0].id).toBe("without-tags");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
33
81
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
14
|
+
const utils_1 = require("@docusaurus/utils");
|
|
15
|
+
const _1 = require(".");
|
|
16
|
+
describe("webhooks", () => {
|
|
17
|
+
it("uses event name when summary and operationId are missing", async () => {
|
|
18
|
+
const files = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/webhook/openapi.yaml")));
|
|
19
|
+
const [items] = await (0, _1.processOpenapiFiles)(files, { specPath: "", outputDir: "" }, {});
|
|
20
|
+
const webhookItem = items.find((item) => item.type === "api");
|
|
21
|
+
expect(webhookItem === null || webhookItem === void 0 ? void 0 : webhookItem.id).toBe("order-created");
|
|
22
|
+
});
|
|
23
|
+
});
|
package/lib/options.js
CHANGED
|
@@ -44,7 +44,11 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
|
|
|
44
44
|
sidebarOptions: sidebarOptions,
|
|
45
45
|
markdownGenerators: markdownGenerators,
|
|
46
46
|
showSchemas: utils_validation_1.Joi.boolean(),
|
|
47
|
+
showInfoPage: utils_validation_1.Joi.boolean(),
|
|
48
|
+
schemasOnly: utils_validation_1.Joi.boolean(),
|
|
47
49
|
disableCompression: utils_validation_1.Joi.boolean(),
|
|
50
|
+
maskCredentials: utils_validation_1.Joi.boolean(),
|
|
51
|
+
externalJsonProps: utils_validation_1.Joi.boolean().default(true),
|
|
48
52
|
version: utils_validation_1.Joi.string().when("versions", {
|
|
49
53
|
is: utils_validation_1.Joi.exist(),
|
|
50
54
|
then: utils_validation_1.Joi.required(),
|
package/lib/sidebars/index.js
CHANGED
|
@@ -81,9 +81,18 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
|
81
81
|
if (sidebarOptions.groupPathsBy !== "tagGroup") {
|
|
82
82
|
apiTags = (0, uniq_1.default)(apiTags.concat(operationTags, schemaTags));
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
// Extract base path from outputDir, handling cases where docPath may not be in outputDir
|
|
85
|
+
const getBasePathFromOutput = (output, doc) => {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
if (doc && output.includes(doc)) {
|
|
88
|
+
return (_b = (_a = output.split(doc)[1]) === null || _a === void 0 ? void 0 : _a.replace(/^\/+/g, "")) !== null && _b !== void 0 ? _b : "";
|
|
89
|
+
}
|
|
90
|
+
const slashIndex = output.indexOf("/", 1);
|
|
91
|
+
return slashIndex === -1
|
|
92
|
+
? ""
|
|
93
|
+
: output.slice(slashIndex).replace(/^\/+/g, "");
|
|
94
|
+
};
|
|
95
|
+
const basePath = getBasePathFromOutput(outputDir, docPath);
|
|
87
96
|
const createDocItemFnContext = {
|
|
88
97
|
sidebarOptions,
|
|
89
98
|
basePath,
|
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": "4.
|
|
4
|
+
"version": "4.7.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -32,29 +32,29 @@
|
|
|
32
32
|
"@docusaurus/types": "^3.5.0",
|
|
33
33
|
"@docusaurus/utils": "^3.5.0",
|
|
34
34
|
"@docusaurus/utils-validation": "^3.5.0",
|
|
35
|
-
"@types/fs-extra": "^
|
|
36
|
-
"@types/json-pointer": "^1.0.
|
|
37
|
-
"@types/json-schema": "^7.0.
|
|
38
|
-
"@types/lodash": "^4.
|
|
39
|
-
"@types/mustache": "^4.
|
|
40
|
-
"eslint-plugin-prettier": "^5.
|
|
35
|
+
"@types/fs-extra": "^11.0.4",
|
|
36
|
+
"@types/json-pointer": "^1.0.34",
|
|
37
|
+
"@types/json-schema": "^7.0.15",
|
|
38
|
+
"@types/lodash": "^4.17.20",
|
|
39
|
+
"@types/mustache": "^4.2.6",
|
|
40
|
+
"eslint-plugin-prettier": "^5.5.1"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@apidevtools/json-schema-ref-parser": "^11.5.4",
|
|
44
|
-
"@redocly/openapi-core": "^1.
|
|
44
|
+
"@redocly/openapi-core": "^1.34.3",
|
|
45
45
|
"allof-merge": "^0.6.6",
|
|
46
46
|
"chalk": "^4.1.2",
|
|
47
|
-
"clsx": "^
|
|
48
|
-
"fs-extra": "^
|
|
47
|
+
"clsx": "^2.1.1",
|
|
48
|
+
"fs-extra": "^11.3.0",
|
|
49
49
|
"json-pointer": "^0.6.2",
|
|
50
50
|
"json5": "^2.2.3",
|
|
51
|
-
"lodash": "^4.17.
|
|
51
|
+
"lodash": "^4.17.21",
|
|
52
52
|
"mustache": "^4.2.0",
|
|
53
|
-
"openapi-to-postmanv2": "^
|
|
54
|
-
"postman-collection": "^
|
|
55
|
-
"slugify": "^1.6.
|
|
53
|
+
"openapi-to-postmanv2": "^5.0.0",
|
|
54
|
+
"postman-collection": "^5.0.2",
|
|
55
|
+
"slugify": "^1.6.6",
|
|
56
56
|
"swagger2openapi": "^7.0.8",
|
|
57
|
-
"xml-formatter": "^
|
|
57
|
+
"xml-formatter": "^3.6.6"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@docusaurus/plugin-content-docs": "^3.5.0",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=14"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "f5829b8e478b0ee76344ba31edd67efdfea18990"
|
|
69
69
|
}
|