docusaurus-theme-openapi-docs 4.2.0 → 4.3.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/lib/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
- package/lib/theme/ApiExplorer/Authorization/index.js +3 -0
- package/lib/theme/ApiExplorer/Body/index.js +11 -2
- package/lib/theme/Markdown/Details/_Details.scss +5 -2
- package/lib/theme/Markdown/index.js +160 -18
- package/lib/theme/ParamsItem/index.js +7 -48
- package/lib/theme/RequestSchema/index.js +11 -3
- package/lib/theme/ResponseExamples/index.d.ts +9 -39
- package/lib/theme/ResponseExamples/index.js +3 -99
- package/lib/theme/ResponseHeaders/index.d.ts +13 -0
- package/lib/theme/ResponseHeaders/index.js +39 -0
- package/lib/theme/ResponseSchema/index.js +4 -2
- package/lib/theme/Schema/index.js +29 -21
- package/lib/theme/SchemaItem/index.js +7 -41
- package/lib/theme/StatusCodes/index.js +10 -7
- package/package.json +10 -6
- package/src/theme/ApiExplorer/ApiCodeBlock/Line/_Line.scss +0 -12
- package/src/theme/ApiExplorer/Authorization/index.tsx +3 -0
- package/src/theme/ApiExplorer/Body/index.tsx +3 -2
- package/src/theme/Markdown/Details/_Details.scss +5 -2
- package/src/theme/Markdown/index.js +160 -18
- package/src/theme/ParamsItem/index.tsx +6 -36
- package/src/theme/RequestSchema/index.tsx +3 -3
- package/src/theme/ResponseExamples/index.tsx +24 -122
- package/src/theme/ResponseHeaders/index.tsx +49 -0
- package/src/theme/ResponseSchema/index.tsx +2 -2
- package/src/theme/Schema/index.tsx +29 -22
- package/src/theme/SchemaItem/index.tsx +11 -35
- package/src/theme/StatusCodes/index.tsx +3 -3
|
@@ -58,13 +58,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
58
58
|
const react_1 = __importStar(require("react"));
|
|
59
59
|
const BrowserOnly_1 = __importDefault(require("@docusaurus/BrowserOnly"));
|
|
60
60
|
const Details_1 = __importDefault(require("@theme/Details"));
|
|
61
|
+
const Markdown_1 = __importDefault(require("@theme/Markdown"));
|
|
61
62
|
const MimeTabs_1 = __importDefault(require("@theme/MimeTabs")); // Assume these components exist
|
|
62
63
|
const ResponseExamples_1 = require("@theme/ResponseExamples");
|
|
63
64
|
const Schema_1 = __importDefault(require("@theme/Schema"));
|
|
64
65
|
const SchemaTabs_1 = __importDefault(require("@theme/SchemaTabs"));
|
|
65
66
|
const SkeletonLoader_1 = __importDefault(require("@theme/SkeletonLoader"));
|
|
66
67
|
const TabItem_1 = __importDefault(require("@theme/TabItem"));
|
|
67
|
-
const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
|
|
68
68
|
const ResponseSchemaComponent = ({ title, body, style }) => {
|
|
69
69
|
if (
|
|
70
70
|
body === undefined ||
|
|
@@ -143,7 +143,9 @@ const ResponseSchemaComponent = ({ title, body, style }) => {
|
|
|
143
143
|
{
|
|
144
144
|
style: { marginTop: "1rem", marginBottom: "1rem" },
|
|
145
145
|
},
|
|
146
|
-
|
|
146
|
+
react_1.default.createElement(
|
|
147
|
+
Markdown_1.default,
|
|
148
|
+
null,
|
|
147
149
|
body.description
|
|
148
150
|
)
|
|
149
151
|
)
|
|
@@ -17,17 +17,15 @@ const Details_1 = __importDefault(require("@theme/Details"));
|
|
|
17
17
|
const DiscriminatorTabs_1 = __importDefault(
|
|
18
18
|
require("@theme/DiscriminatorTabs")
|
|
19
19
|
);
|
|
20
|
+
const Markdown_1 = __importDefault(require("@theme/Markdown"));
|
|
20
21
|
const SchemaItem_1 = __importDefault(require("@theme/SchemaItem"));
|
|
21
22
|
const SchemaTabs_1 = __importDefault(require("@theme/SchemaTabs"));
|
|
22
23
|
const TabItem_1 = __importDefault(require("@theme/TabItem"));
|
|
23
24
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
24
25
|
const allof_merge_1 = require("allof-merge");
|
|
25
26
|
const clsx_1 = __importDefault(require("clsx"));
|
|
26
|
-
const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
|
|
27
27
|
const schema_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/schema");
|
|
28
28
|
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
|
|
29
|
-
const react_markdown_1 = __importDefault(require("react-markdown"));
|
|
30
|
-
const rehype_raw_1 = __importDefault(require("rehype-raw"));
|
|
31
29
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
32
30
|
// const jsonSchemaMergeAllOf = require("json-schema-merge-allof");
|
|
33
31
|
const mergeAllOf = (allOf) => {
|
|
@@ -38,14 +36,11 @@ const mergeAllOf = (allOf) => {
|
|
|
38
36
|
return mergedSchemas;
|
|
39
37
|
};
|
|
40
38
|
// Renders string as markdown, useful for descriptions and qualifiers
|
|
41
|
-
const
|
|
39
|
+
const MarkdownWrapper = ({ text }) => {
|
|
42
40
|
return react_1.default.createElement(
|
|
43
41
|
"div",
|
|
44
42
|
{ style: { marginTop: ".5rem", marginBottom: ".5rem" } },
|
|
45
|
-
react_1.default.createElement(
|
|
46
|
-
children: (0, createDescription_1.createDescription)(text),
|
|
47
|
-
rehypePlugins: [rehype_raw_1.default],
|
|
48
|
-
})
|
|
43
|
+
react_1.default.createElement(Markdown_1.default, null, text)
|
|
49
44
|
);
|
|
50
45
|
};
|
|
51
46
|
const Summary = ({ name, schemaName, schema, required }) => {
|
|
@@ -276,11 +271,11 @@ const PropertyDiscriminator = ({
|
|
|
276
271
|
"div",
|
|
277
272
|
{ style: { marginLeft: "1rem" } },
|
|
278
273
|
schema.description &&
|
|
279
|
-
react_1.default.createElement(
|
|
274
|
+
react_1.default.createElement(MarkdownWrapper, {
|
|
280
275
|
text: schema.description,
|
|
281
276
|
}),
|
|
282
277
|
(0, schema_1.getQualifierMessage)(discriminator) &&
|
|
283
|
-
react_1.default.createElement(
|
|
278
|
+
react_1.default.createElement(MarkdownWrapper, {
|
|
284
279
|
text: (0, schema_1.getQualifierMessage)(discriminator),
|
|
285
280
|
})
|
|
286
281
|
),
|
|
@@ -321,7 +316,10 @@ const PropertyDiscriminator = ({
|
|
|
321
316
|
const DiscriminatorNode = ({ discriminator, schema, schemaType }) => {
|
|
322
317
|
let discriminatedSchemas = {};
|
|
323
318
|
let inferredMapping = {};
|
|
324
|
-
|
|
319
|
+
// default to empty object if no parent-level properties exist
|
|
320
|
+
const discriminatorProperty = schema.properties
|
|
321
|
+
? schema.properties[discriminator.propertyName]
|
|
322
|
+
: {};
|
|
325
323
|
if (schema.allOf) {
|
|
326
324
|
const mergedSchemas = mergeAllOf(schema);
|
|
327
325
|
if (mergedSchemas.oneOf || mergedSchemas.anyOf) {
|
|
@@ -347,15 +345,23 @@ const DiscriminatorNode = ({ discriminator, schema, schemaType }) => {
|
|
|
347
345
|
}
|
|
348
346
|
const subProperties = subSchema.properties || mergedSubSchema.properties;
|
|
349
347
|
if (subProperties[discriminator.propertyName]) {
|
|
350
|
-
schema.properties
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
348
|
+
if (schema.properties) {
|
|
349
|
+
schema.properties[discriminator.propertyName] = {
|
|
350
|
+
...schema.properties[discriminator.propertyName],
|
|
351
|
+
...subProperties[discriminator.propertyName],
|
|
352
|
+
};
|
|
353
|
+
if (subSchema.required && !schema.required) {
|
|
354
|
+
schema.required = subSchema.required;
|
|
355
|
+
}
|
|
356
|
+
// Avoid duplicating property
|
|
357
|
+
delete subProperties[discriminator.propertyName];
|
|
358
|
+
} else {
|
|
359
|
+
schema.properties = {};
|
|
360
|
+
schema.properties[discriminator.propertyName] =
|
|
361
|
+
subProperties[discriminator.propertyName];
|
|
362
|
+
// Avoid duplicating property
|
|
363
|
+
delete subProperties[discriminator.propertyName];
|
|
356
364
|
}
|
|
357
|
-
// Avoid duplicating property
|
|
358
|
-
delete subProperties[discriminator.propertyName];
|
|
359
365
|
}
|
|
360
366
|
});
|
|
361
367
|
const name = discriminator.propertyName;
|
|
@@ -460,9 +466,11 @@ const SchemaNodeDetails = ({
|
|
|
460
466
|
"div",
|
|
461
467
|
{ style: { marginLeft: "1rem" } },
|
|
462
468
|
schema.description &&
|
|
463
|
-
react_1.default.createElement(
|
|
469
|
+
react_1.default.createElement(MarkdownWrapper, {
|
|
470
|
+
text: schema.description,
|
|
471
|
+
}),
|
|
464
472
|
(0, schema_1.getQualifierMessage)(schema) &&
|
|
465
|
-
react_1.default.createElement(
|
|
473
|
+
react_1.default.createElement(MarkdownWrapper, {
|
|
466
474
|
text: (0, schema_1.getQualifierMessage)(schema),
|
|
467
475
|
}),
|
|
468
476
|
react_1.default.createElement(SchemaNode, {
|
|
@@ -12,12 +12,8 @@ var __importDefault =
|
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
const react_1 = __importDefault(require("react"));
|
|
15
|
-
const
|
|
15
|
+
const Markdown_1 = __importDefault(require("@theme/Markdown"));
|
|
16
16
|
const clsx_1 = __importDefault(require("clsx"));
|
|
17
|
-
const react_markdown_1 = __importDefault(require("react-markdown"));
|
|
18
|
-
const rehype_raw_1 = __importDefault(require("rehype-raw"));
|
|
19
|
-
const remark_gfm_1 = __importDefault(require("remark-gfm"));
|
|
20
|
-
const createDescription_1 = require("../../markdown/createDescription");
|
|
21
17
|
const utils_1 = require("../../markdown/utils");
|
|
22
18
|
const transformEnumDescriptions = (enumDescriptions) => {
|
|
23
19
|
if (enumDescriptions) {
|
|
@@ -91,11 +87,7 @@ function SchemaItem(props) {
|
|
|
91
87
|
return react_1.default.createElement(
|
|
92
88
|
"div",
|
|
93
89
|
{ style: { marginTop: ".5rem" } },
|
|
94
|
-
react_1.default.createElement(
|
|
95
|
-
remarkPlugins: [remark_gfm_1.default],
|
|
96
|
-
rehypePlugins: [rehype_raw_1.default],
|
|
97
|
-
children: value,
|
|
98
|
-
})
|
|
90
|
+
react_1.default.createElement(Markdown_1.default, null, value)
|
|
99
91
|
);
|
|
100
92
|
}
|
|
101
93
|
);
|
|
@@ -103,43 +95,18 @@ function SchemaItem(props) {
|
|
|
103
95
|
schemaDescription,
|
|
104
96
|
(description) =>
|
|
105
97
|
react_1.default.createElement(
|
|
106
|
-
|
|
98
|
+
react_1.default.Fragment,
|
|
107
99
|
null,
|
|
108
|
-
react_1.default.createElement(
|
|
109
|
-
children: (0, createDescription_1.createDescription)(description),
|
|
110
|
-
components: {
|
|
111
|
-
pre: "div",
|
|
112
|
-
code({ node, inline, className, children, ...props }) {
|
|
113
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
114
|
-
if (inline)
|
|
115
|
-
return react_1.default.createElement("code", null, children);
|
|
116
|
-
return !inline && match
|
|
117
|
-
? react_1.default.createElement(
|
|
118
|
-
CodeBlock_1.default,
|
|
119
|
-
{ className: className },
|
|
120
|
-
children
|
|
121
|
-
)
|
|
122
|
-
: react_1.default.createElement(
|
|
123
|
-
CodeBlock_1.default,
|
|
124
|
-
null,
|
|
125
|
-
children
|
|
126
|
-
);
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
rehypePlugins: [rehype_raw_1.default],
|
|
130
|
-
})
|
|
100
|
+
react_1.default.createElement(Markdown_1.default, null, description)
|
|
131
101
|
)
|
|
132
102
|
);
|
|
133
103
|
const renderQualifierMessage = (0, utils_1.guard)(
|
|
134
104
|
qualifierMessage,
|
|
135
105
|
(message) =>
|
|
136
106
|
react_1.default.createElement(
|
|
137
|
-
|
|
107
|
+
react_1.default.Fragment,
|
|
138
108
|
null,
|
|
139
|
-
react_1.default.createElement(
|
|
140
|
-
children: (0, createDescription_1.createDescription)(message),
|
|
141
|
-
rehypePlugins: [rehype_raw_1.default],
|
|
142
|
-
})
|
|
109
|
+
react_1.default.createElement(Markdown_1.default, null, message)
|
|
143
110
|
)
|
|
144
111
|
);
|
|
145
112
|
function renderDefaultValue() {
|
|
@@ -218,8 +185,7 @@ function SchemaItem(props) {
|
|
|
218
185
|
react_1.default.createElement(
|
|
219
186
|
"span",
|
|
220
187
|
{ className: "openapi-schema__name" },
|
|
221
|
-
" "
|
|
222
|
-
schemaName
|
|
188
|
+
Array.isArray(schemaName) ? schemaName.join(" | ") : schemaName
|
|
223
189
|
),
|
|
224
190
|
(nullable || required || deprecated) &&
|
|
225
191
|
react_1.default.createElement("span", {
|
|
@@ -14,10 +14,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
const react_1 = __importDefault(require("react"));
|
|
15
15
|
const ApiTabs_1 = __importDefault(require("@theme/ApiTabs"));
|
|
16
16
|
const Details_1 = __importDefault(require("@theme/Details"));
|
|
17
|
-
const
|
|
17
|
+
const Markdown_1 = __importDefault(require("@theme/Markdown"));
|
|
18
|
+
const ResponseHeaders_1 = __importDefault(require("@theme/ResponseHeaders"));
|
|
18
19
|
const ResponseSchema_1 = __importDefault(require("@theme/ResponseSchema"));
|
|
19
20
|
const TabItem_1 = __importDefault(require("@theme/TabItem"));
|
|
20
|
-
const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
|
|
21
21
|
const StatusCodes = ({ label, id, responses }) => {
|
|
22
22
|
if (!responses) return null;
|
|
23
23
|
const codes = Object.keys(responses);
|
|
@@ -40,7 +40,11 @@ const StatusCodes = ({ label, id, responses }) => {
|
|
|
40
40
|
react_1.default.createElement(
|
|
41
41
|
"div",
|
|
42
42
|
{ style: { marginTop: ".5rem", marginBottom: ".5rem" } },
|
|
43
|
-
|
|
43
|
+
react_1.default.createElement(
|
|
44
|
+
Markdown_1.default,
|
|
45
|
+
null,
|
|
46
|
+
response.description
|
|
47
|
+
)
|
|
44
48
|
)
|
|
45
49
|
),
|
|
46
50
|
responseHeaders &&
|
|
@@ -61,10 +65,9 @@ const StatusCodes = ({ label, id, responses }) => {
|
|
|
61
65
|
)
|
|
62
66
|
),
|
|
63
67
|
},
|
|
64
|
-
react_1.default.createElement(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
68
|
+
react_1.default.createElement(ResponseHeaders_1.default, {
|
|
69
|
+
responseHeaders: responseHeaders,
|
|
70
|
+
})
|
|
68
71
|
),
|
|
69
72
|
react_1.default.createElement(ResponseSchema_1.default, {
|
|
70
73
|
title: "Schema",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-theme-openapi-docs",
|
|
3
3
|
"description": "OpenAPI theme for Docusaurus.",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.3.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -28,26 +28,26 @@
|
|
|
28
28
|
"watch": "concurrently --names \"lib,lib-next,tsc\" --kill-others \"yarn babel:lib --watch\" \"yarn babel:lib-next --watch\" \"yarn tsc --watch\""
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
+
"@docusaurus/theme-common": "^3.5.0",
|
|
31
32
|
"@docusaurus/types": "^3.5.0",
|
|
32
33
|
"@types/crypto-js": "^4.1.0",
|
|
33
34
|
"@types/file-saver": "^2.0.5",
|
|
34
35
|
"@types/lodash": "^4.14.176",
|
|
35
36
|
"concurrently": "^5.2.0",
|
|
37
|
+
"docusaurus-plugin-openapi-docs": "^4.3.0",
|
|
38
|
+
"docusaurus-plugin-sass": "^0.2.3",
|
|
36
39
|
"eslint-plugin-prettier": "^5.0.1"
|
|
37
40
|
},
|
|
38
41
|
"dependencies": {
|
|
39
|
-
"@docusaurus/theme-common": "^3.5.0",
|
|
40
42
|
"@hookform/error-message": "^2.0.1",
|
|
41
43
|
"@reduxjs/toolkit": "^1.7.1",
|
|
42
44
|
"allof-merge": "^0.6.6",
|
|
43
45
|
"clsx": "^1.1.1",
|
|
44
46
|
"copy-text-to-clipboard": "^3.1.0",
|
|
45
47
|
"crypto-js": "^4.1.1",
|
|
46
|
-
"docusaurus-plugin-openapi-docs": "^4.2.0",
|
|
47
|
-
"docusaurus-plugin-sass": "^0.2.3",
|
|
48
48
|
"file-saver": "^2.0.5",
|
|
49
49
|
"lodash": "^4.17.20",
|
|
50
|
-
"node-polyfill-webpack-plugin": "^
|
|
50
|
+
"node-polyfill-webpack-plugin": "^3.0.0",
|
|
51
51
|
"postman-code-generators": "^1.10.1",
|
|
52
52
|
"postman-collection": "^4.4.0",
|
|
53
53
|
"prism-react-renderer": "^2.3.0",
|
|
@@ -61,15 +61,19 @@
|
|
|
61
61
|
"remark-gfm": "3.0.1",
|
|
62
62
|
"sass": "^1.80.4",
|
|
63
63
|
"sass-loader": "^16.0.2",
|
|
64
|
+
"unist-util-visit": "^5.0.0",
|
|
64
65
|
"webpack": "^5.61.0",
|
|
65
66
|
"xml-formatter": "^2.6.1"
|
|
66
67
|
},
|
|
67
68
|
"peerDependencies": {
|
|
69
|
+
"@docusaurus/theme-common": "^3.5.0",
|
|
70
|
+
"docusaurus-plugin-openapi-docs": "^4.0.0",
|
|
71
|
+
"docusaurus-plugin-sass": "^0.2.3",
|
|
68
72
|
"react": "^16.8.4 || ^17.0.0 || ^18.0.0",
|
|
69
73
|
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0"
|
|
70
74
|
},
|
|
71
75
|
"engines": {
|
|
72
76
|
"node": ">=14"
|
|
73
77
|
},
|
|
74
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "e16e2f912a3da02444d1755b6d350deadd62185f"
|
|
75
79
|
}
|
|
@@ -8,13 +8,6 @@ the background in custom CSS file due bug https://github.com/facebook/docusaurus
|
|
|
8
8
|
--docusaurus-highlighted-code-line-bg: rgb(100 100 100);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.theme-code-block-highlighted-line {
|
|
12
|
-
background-color: var(--docusaurus-highlighted-code-line-bg);
|
|
13
|
-
display: block;
|
|
14
|
-
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
|
15
|
-
padding: 0 var(--ifm-pre-padding);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
11
|
.openapi-explorer__code-block-code-line {
|
|
19
12
|
display: table-row;
|
|
20
13
|
counter-increment: line-count;
|
|
@@ -36,11 +29,6 @@ the background in custom CSS file due bug https://github.com/facebook/docusaurus
|
|
|
36
29
|
opacity: 0.4;
|
|
37
30
|
}
|
|
38
31
|
|
|
39
|
-
:global(.theme-code-block-highlighted-line)
|
|
40
|
-
.openapi-explorer__code-block-code-line-number::before {
|
|
41
|
-
opacity: 0.8;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
32
|
.openapi-explorer__code-block-code-line-number {
|
|
45
33
|
padding-right: var(--ifm-pre-padding);
|
|
46
34
|
}
|
|
@@ -48,6 +48,7 @@ function Authorization() {
|
|
|
48
48
|
<FormItem label="Bearer Token" key={a.key + "-bearer"}>
|
|
49
49
|
<FormTextInput
|
|
50
50
|
placeholder="Bearer Token"
|
|
51
|
+
password
|
|
51
52
|
value={data[a.key].token ?? ""}
|
|
52
53
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
53
54
|
const value = e.target.value;
|
|
@@ -69,6 +70,7 @@ function Authorization() {
|
|
|
69
70
|
<FormItem label="Bearer Token" key={a.key + "-oauth2"}>
|
|
70
71
|
<FormTextInput
|
|
71
72
|
placeholder="Bearer Token"
|
|
73
|
+
password
|
|
72
74
|
value={data[a.key].token ?? ""}
|
|
73
75
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
74
76
|
const value = e.target.value;
|
|
@@ -130,6 +132,7 @@ function Authorization() {
|
|
|
130
132
|
<FormItem label={`${a.key}`} key={a.key + "-apikey"}>
|
|
131
133
|
<FormTextInput
|
|
132
134
|
placeholder={`${a.key}`}
|
|
135
|
+
password
|
|
133
136
|
value={data[a.key].apiKey ?? ""}
|
|
134
137
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
135
138
|
const value = e.target.value;
|
|
@@ -14,6 +14,7 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
|
14
14
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
15
15
|
import LiveApp from "@theme/ApiExplorer/LiveEditor";
|
|
16
16
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
17
|
+
import Markdown from "@theme/Markdown";
|
|
17
18
|
import SchemaTabs from "@theme/SchemaTabs";
|
|
18
19
|
import TabItem from "@theme/TabItem";
|
|
19
20
|
import { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
@@ -303,7 +304,7 @@ function Body({
|
|
|
303
304
|
</TabItem>
|
|
304
305
|
{/* @ts-ignore */}
|
|
305
306
|
<TabItem label="Example" value="example">
|
|
306
|
-
{example.summary && <
|
|
307
|
+
{example.summary && <Markdown>{example.summary}</Markdown>}
|
|
307
308
|
{exampleBody && (
|
|
308
309
|
<LiveApp
|
|
309
310
|
action={dispatch}
|
|
@@ -341,7 +342,7 @@ function Body({
|
|
|
341
342
|
value={example.label}
|
|
342
343
|
key={example.label}
|
|
343
344
|
>
|
|
344
|
-
{example.summary && <
|
|
345
|
+
{example.summary && <Markdown>{example.summary}</Markdown>}
|
|
345
346
|
{example.body && (
|
|
346
347
|
<LiveApp action={dispatch} language={language}>
|
|
347
348
|
{example.body}
|
|
@@ -23,10 +23,13 @@
|
|
|
23
23
|
|
|
24
24
|
/* Top-Level Details Caret Styling */
|
|
25
25
|
.openapi-left-panel__container > .openapi-markdown__details > summary::before,
|
|
26
|
-
.openapi-markdown__details.mime > summary::before
|
|
27
|
-
.openapi-markdown__details.response > summary::before {
|
|
26
|
+
.openapi-markdown__details.mime > summary::before {
|
|
28
27
|
top: 0.1rem;
|
|
29
28
|
}
|
|
29
|
+
|
|
30
|
+
.openapi-markdown__details.response > summary::before {
|
|
31
|
+
top: 0.25rem; /* TODO: figure out why this is necessary */
|
|
32
|
+
}
|
|
30
33
|
/* End of Top-Level Details Caret Styling */
|
|
31
34
|
|
|
32
35
|
.openapi-markdown__details {
|
|
@@ -7,30 +7,172 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
|
+
import Admonition from "@theme/Admonition";
|
|
10
11
|
import CodeBlock from "@theme/CodeBlock";
|
|
11
12
|
import ReactMarkdown from "react-markdown";
|
|
12
13
|
import rehypeRaw from "rehype-raw";
|
|
14
|
+
import remarkGfm from "remark-gfm";
|
|
15
|
+
|
|
16
|
+
function remarkAdmonition() {
|
|
17
|
+
return (tree) => {
|
|
18
|
+
const openingTagRegex = /^:::(\w+)(?:\[(.*?)\])?\s*$/;
|
|
19
|
+
const closingTagRegex = /^:::\s*$/;
|
|
20
|
+
const textOnlyAdmonition = /^:::(\w+)(?:\[(.*?)\])?\s*([\s\S]*?)\s*:::$/;
|
|
21
|
+
|
|
22
|
+
const nodes = [];
|
|
23
|
+
let bufferedChildren = [];
|
|
24
|
+
|
|
25
|
+
let insideAdmonition = false;
|
|
26
|
+
let type = null;
|
|
27
|
+
let title = null;
|
|
28
|
+
|
|
29
|
+
tree.children.forEach((node) => {
|
|
30
|
+
if (
|
|
31
|
+
node.type === "paragraph" &&
|
|
32
|
+
node.children.length === 1 &&
|
|
33
|
+
node.children[0].type === "text"
|
|
34
|
+
) {
|
|
35
|
+
const text = node.children[0].value.trim();
|
|
36
|
+
const openingMatch = text.match(openingTagRegex);
|
|
37
|
+
const closingMatch = text.match(closingTagRegex);
|
|
38
|
+
const textOnlyAdmonitionMatch = text.match(textOnlyAdmonition);
|
|
39
|
+
|
|
40
|
+
if (textOnlyAdmonitionMatch) {
|
|
41
|
+
const type = textOnlyAdmonitionMatch[1];
|
|
42
|
+
const title = textOnlyAdmonitionMatch[2]
|
|
43
|
+
? textOnlyAdmonitionMatch[2]?.trim()
|
|
44
|
+
: undefined;
|
|
45
|
+
const content = textOnlyAdmonitionMatch[3];
|
|
46
|
+
|
|
47
|
+
const admonitionNode = {
|
|
48
|
+
type: "admonition",
|
|
49
|
+
data: {
|
|
50
|
+
hName: "Admonition", // Tells ReactMarkdown to replace the node with Admonition component
|
|
51
|
+
hProperties: {
|
|
52
|
+
type, // Passed as a prop to the Admonition component
|
|
53
|
+
title,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
children: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
value: content?.trim(), // Trim leading/trailing whitespace
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
nodes.push(admonitionNode);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (openingMatch) {
|
|
68
|
+
type = openingMatch[1];
|
|
69
|
+
title = openingMatch[2] || type;
|
|
70
|
+
insideAdmonition = true;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (closingMatch && insideAdmonition) {
|
|
75
|
+
nodes.push({
|
|
76
|
+
type: "admonition",
|
|
77
|
+
data: {
|
|
78
|
+
hName: "Admonition",
|
|
79
|
+
hProperties: { type: type, title: title },
|
|
80
|
+
},
|
|
81
|
+
children: bufferedChildren,
|
|
82
|
+
});
|
|
83
|
+
bufferedChildren = [];
|
|
84
|
+
insideAdmonition = false;
|
|
85
|
+
type = null;
|
|
86
|
+
title = null;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (insideAdmonition) {
|
|
92
|
+
bufferedChildren.push(node);
|
|
93
|
+
} else {
|
|
94
|
+
nodes.push(node);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (bufferedChildren.length > 0 && type) {
|
|
99
|
+
nodes.push({
|
|
100
|
+
type: "admonition",
|
|
101
|
+
data: {
|
|
102
|
+
hName: "Admonition",
|
|
103
|
+
hProperties: { type: type, title: title },
|
|
104
|
+
},
|
|
105
|
+
children: bufferedChildren,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
tree.children = nodes;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function convertAstToHtmlStr(ast) {
|
|
113
|
+
if (!ast || !Array.isArray(ast)) {
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const convertNode = (node) => {
|
|
118
|
+
switch (node.type) {
|
|
119
|
+
case "text":
|
|
120
|
+
return node.value;
|
|
121
|
+
case "element":
|
|
122
|
+
const { tagName, properties, children } = node;
|
|
123
|
+
|
|
124
|
+
// Convert attributes to a string
|
|
125
|
+
const attrs = properties
|
|
126
|
+
? Object.entries(properties)
|
|
127
|
+
.map(([key, value]) => `${key}="${value}"`)
|
|
128
|
+
.join(" ")
|
|
129
|
+
: "";
|
|
130
|
+
|
|
131
|
+
// Convert children to HTML
|
|
132
|
+
const childrenHtml = children ? children.map(convertNode).join("") : "";
|
|
133
|
+
|
|
134
|
+
return `<${tagName} ${attrs}>${childrenHtml}</${tagName}>`;
|
|
135
|
+
default:
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return ast.map(convertNode).join("");
|
|
141
|
+
}
|
|
13
142
|
|
|
14
143
|
function Markdown({ children }) {
|
|
15
144
|
return (
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
145
|
+
<ReactMarkdown
|
|
146
|
+
rehypePlugins={[rehypeRaw]}
|
|
147
|
+
remarkPlugins={[remarkGfm, remarkAdmonition]}
|
|
148
|
+
components={{
|
|
149
|
+
pre: (props) => <div {...props} />,
|
|
150
|
+
code({ node, inline, className, children, ...props }) {
|
|
151
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
152
|
+
return match ? (
|
|
153
|
+
<CodeBlock className={className} language={match[1]} {...props}>
|
|
154
|
+
{children}
|
|
155
|
+
</CodeBlock>
|
|
156
|
+
) : (
|
|
157
|
+
<code className={className} {...props}>
|
|
158
|
+
{children}
|
|
159
|
+
</code>
|
|
160
|
+
);
|
|
161
|
+
},
|
|
162
|
+
admonition: ({ node, ...props }) => {
|
|
163
|
+
const type = node.data?.hProperties?.type || "note";
|
|
164
|
+
const title = node.data?.hProperties?.title || type;
|
|
165
|
+
const content = convertAstToHtmlStr(node.children);
|
|
166
|
+
return (
|
|
167
|
+
<Admonition type={type} title={title} {...props}>
|
|
168
|
+
<div dangerouslySetInnerHTML={{ __html: content }} />
|
|
169
|
+
</Admonition>
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
{children}
|
|
175
|
+
</ReactMarkdown>
|
|
34
176
|
);
|
|
35
177
|
}
|
|
36
178
|
|