docusaurus-theme-openapi-docs 1.5.1 → 1.6.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.
Files changed (40) hide show
  1. package/lib/index.js +2 -11
  2. package/lib/markdown/utils.js +18 -1
  3. package/lib/theme/ApiDemoPanel/Curl/index.js +36 -9
  4. package/lib/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  5. package/lib/theme/ApiDemoPanel/Request/index.js +3 -2
  6. package/lib/theme/ApiDemoPanel/SecuritySchemes/index.js +195 -9
  7. package/lib/theme/ApiLogo/index.js +24 -1
  8. package/lib/theme/ParamsItem/index.js +33 -6
  9. package/lib/theme/SchemaItem/index.js +26 -12
  10. package/lib/theme/SchemaItem/styles.module.css +5 -0
  11. package/lib/theme/SchemaTabs/index.js +2 -2
  12. package/lib/theme/SchemaTabs/styles.module.css +5 -0
  13. package/lib/theme/styles.css +57 -2
  14. package/lib-next/index.js +2 -13
  15. package/lib-next/markdown/utils.js +17 -1
  16. package/lib-next/theme/ApiDemoPanel/Curl/index.js +37 -8
  17. package/lib-next/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  18. package/lib-next/theme/ApiDemoPanel/Request/index.js +4 -2
  19. package/lib-next/theme/ApiDemoPanel/SecuritySchemes/index.js +210 -9
  20. package/lib-next/theme/ApiLogo/index.js +35 -9
  21. package/lib-next/theme/ParamsItem/index.js +33 -6
  22. package/lib-next/theme/SchemaItem/index.js +26 -12
  23. package/lib-next/theme/SchemaItem/styles.module.css +5 -0
  24. package/lib-next/theme/SchemaTabs/index.js +2 -2
  25. package/lib-next/theme/SchemaTabs/styles.module.css +5 -0
  26. package/lib-next/theme/styles.css +57 -2
  27. package/package.json +8 -7
  28. package/src/index.ts +3 -13
  29. package/src/markdown/utils.ts +18 -1
  30. package/src/theme/ApiDemoPanel/Curl/index.tsx +36 -8
  31. package/src/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  32. package/src/theme/ApiDemoPanel/Request/index.tsx +4 -2
  33. package/src/theme/ApiDemoPanel/SecuritySchemes/index.tsx +213 -9
  34. package/src/theme/ApiLogo/index.tsx +37 -10
  35. package/src/theme/ParamsItem/index.js +33 -6
  36. package/src/theme/SchemaItem/index.js +26 -12
  37. package/src/theme/SchemaItem/styles.module.css +5 -0
  38. package/src/theme/SchemaTabs/index.js +2 -2
  39. package/src/theme/SchemaTabs/styles.module.css +5 -0
  40. package/src/theme/styles.css +57 -2
package/lib/index.js CHANGED
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = docusaurusThemeOpenAPI;
7
7
  var _path = _interopRequireDefault(require("path"));
8
- var _webpack = require("webpack");
9
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
9
  /* ============================================================================
11
10
  * Copyright (c) Palo Alto Networks
@@ -14,6 +13,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
14
13
  * LICENSE file in the root directory of this source tree.
15
14
  * ========================================================================== */
16
15
 
16
+ const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
17
17
  function docusaurusThemeOpenAPI() {
18
18
  return {
19
19
  name: "docusaurus-theme-openapi",
@@ -29,16 +29,7 @@ function docusaurusThemeOpenAPI() {
29
29
  },
30
30
  configureWebpack() {
31
31
  return {
32
- plugins: [new _webpack.ProvidePlugin({
33
- Buffer: [require.resolve("buffer/"), "Buffer"],
34
- process: require.resolve("process/browser")
35
- })],
36
- resolve: {
37
- fallback: {
38
- buffer: require.resolve("buffer/"),
39
- process: require.resolve("process/browser")
40
- }
41
- }
32
+ plugins: [new NodePolyfillPlugin()]
42
33
  };
43
34
  }
44
35
  };
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.create = create;
7
7
  exports.guard = guard;
8
8
  exports.render = render;
9
+ exports.toString = toString;
9
10
  /* ============================================================================
10
11
  * Copyright (c) Palo Alto Networks
11
12
  *
@@ -25,7 +26,7 @@ function create(tag, props) {
25
26
  return `<${tag}${propString}>${render(children)}</${tag}>`;
26
27
  }
27
28
  function guard(value, cb) {
28
- if (value) {
29
+ if (value !== undefined) {
29
30
  const children = cb(value);
30
31
  return render(children);
31
32
  }
@@ -36,4 +37,20 @@ function render(children) {
36
37
  return children.filter(c => c !== undefined).join("");
37
38
  }
38
39
  return children !== null && children !== void 0 ? children : "";
40
+ }
41
+ function toString(value) {
42
+ // Return as-is if already string
43
+ if (typeof value === "string") {
44
+ return value;
45
+ }
46
+ // Return undefined if null or undefined
47
+ if (value == null) {
48
+ return undefined;
49
+ }
50
+ // Return formatted array if Array
51
+ if (Array.isArray(value)) {
52
+ return `[${value.join(", ")}]`;
53
+ }
54
+ // Coerce to string in all other cases,
55
+ return value + "";
39
56
  }
@@ -12,6 +12,7 @@ var _CodeTabs = _interopRequireDefault(require("@theme/ApiDemoPanel/CodeTabs"));
12
12
  var _hooks = require("@theme/ApiItem/hooks");
13
13
  var _CodeBlock = _interopRequireDefault(require("@theme/CodeBlock"));
14
14
  var _clsx = _interopRequireDefault(require("clsx"));
15
+ var _merge = _interopRequireDefault(require("lodash/merge"));
15
16
  var _stylesModule = _interopRequireDefault(require("./styles.module.css"));
16
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
18
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -88,6 +89,15 @@ const languageSet = [{
88
89
  trimRequestBody: true
89
90
  },
90
91
  variant: "cURL"
92
+ }, {
93
+ highlight: "java",
94
+ language: "java",
95
+ logoClass: "java",
96
+ options: {
97
+ followRedirect: true,
98
+ trimRequestBody: true
99
+ },
100
+ variant: "OkHttp"
91
101
  }];
92
102
  exports.languageSet = languageSet;
93
103
  function CodeTab({
@@ -122,15 +132,30 @@ function Curl({
122
132
  const headerParams = (0, _hooks.useTypedSelector)(state => state.params.header);
123
133
  const auth = (0, _hooks.useTypedSelector)(state => state.auth);
124
134
 
125
- // TODO
135
+ // User-defined languages array
136
+ // Can override languageSet, change order of langs, override options and variants
126
137
  const langs = [...((_ref = siteConfig === null || siteConfig === void 0 ? void 0 : (_siteConfig$themeConf = siteConfig.themeConfig) === null || _siteConfig$themeConf === void 0 ? void 0 : _siteConfig$themeConf.languageTabs) !== null && _ref !== void 0 ? _ref : languageSet), ...codeSamples];
127
- const defaultLang = languageSet.filter(lang => lang.language === localStorage.getItem("docusaurus.tab.code-samples"));
138
+
139
+ // Filter languageSet by user-defined langs
140
+ const filteredLanguageSet = languageSet.filter(ls => {
141
+ return langs.some(lang => {
142
+ return lang.language === ls.language;
143
+ });
144
+ });
145
+
146
+ // Merge user-defined langs into languageSet
147
+ const mergedLangs = (0, _merge.default)(filteredLanguageSet, langs);
148
+
149
+ // Read defaultLang from localStorage
150
+ const defaultLang = mergedLangs.filter(lang => lang.language === localStorage.getItem("docusaurus.tab.code-samples"));
128
151
  const [language, setLanguage] = (0, _react.useState)(() => {
129
152
  var _defaultLang$;
130
- if (langs.length === 1) {
131
- return langs[0];
153
+ // Return first index if only 1 user-defined language exists
154
+ if (mergedLangs.length === 1) {
155
+ return mergedLangs[0];
132
156
  }
133
- return (_defaultLang$ = defaultLang[0]) !== null && _defaultLang$ !== void 0 ? _defaultLang$ : langs[0];
157
+ // Fall back to language in localStorage or first user-defined language
158
+ return (_defaultLang$ = defaultLang[0]) !== null && _defaultLang$ !== void 0 ? _defaultLang$ : mergedLangs[0];
134
159
  });
135
160
  const [codeText, setCodeText] = (0, _react.useState)("");
136
161
  (0, _react.useEffect)(() => {
@@ -155,7 +180,7 @@ function Curl({
155
180
  } else if (language && !!language.source) {
156
181
  setCodeText(language.source);
157
182
  } else if (language && !language.options) {
158
- const langSource = languageSet.filter(lang => lang.language === language.language);
183
+ const langSource = mergedLangs.filter(lang => lang.language === language.language);
159
184
 
160
185
  // Merges user-defined language with default languageSet
161
186
  // This allows users to define only the minimal properties necessary in languageTabs
@@ -184,17 +209,19 @@ function Curl({
184
209
  } else {
185
210
  setCodeText("");
186
211
  }
187
- }, [accept, body, contentType, cookieParams, headerParams, language, pathParams, postman, queryParams, server, auth]);
212
+ }, [accept, body, contentType, cookieParams, headerParams, language, pathParams, postman, queryParams, server, auth, mergedLangs]);
188
213
  if (language === undefined) {
189
214
  return null;
190
215
  }
191
216
  return <>
192
217
  <_CodeTabs.default groupId="code-samples" action={setLanguage}>
193
- {langs.map(lang => {
218
+ {mergedLangs.map(lang => {
194
219
  return <CodeTab value={lang.language} label={""} key={lang.variant ? `${lang.language}-${lang.variant}` : lang.language} attributes={{
195
220
  className: `code__tab--${lang.logoClass}`
196
221
  }}>
197
- <_CodeBlock.default language={lang.highlight}>{codeText}</_CodeBlock.default>
222
+ <_CodeBlock.default language={lang.highlight} className={_stylesModule.default.codeBlock}>
223
+ {codeText}
224
+ </_CodeBlock.default>
198
225
  </CodeTab>;
199
226
  })}
200
227
  </_CodeTabs.default>
@@ -82,3 +82,8 @@
82
82
  background: var(--ifm-menu-color-background-active);
83
83
  color: var(--ifm-menu-color-active);
84
84
  }
85
+
86
+ .codeBlock code {
87
+ max-width: revert;
88
+ max-height: revert;
89
+ }
@@ -31,7 +31,8 @@ function Request({
31
31
  const postman = new _postmanCollection.default.Request(item.postman);
32
32
  const metadata = (0, _internal.useDoc)();
33
33
  const {
34
- proxy
34
+ proxy,
35
+ hide_send_button
35
36
  } = metadata.frontMatter;
36
37
  const params = {
37
38
  path: [],
@@ -49,7 +50,7 @@ function Request({
49
50
  <summary>
50
51
  <div className={`details__request-summary`}>
51
52
  <h4>Request</h4>
52
- {item.servers && <_Execute.default postman={postman} proxy={proxy} />}
53
+ {item.servers && !hide_send_button && <_Execute.default postman={postman} proxy={proxy} />}
53
54
  </div>
54
55
  </summary>
55
56
  <div className={_stylesModule.default.optionsPanel}>
@@ -16,35 +16,167 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
16
16
  * ========================================================================== */
17
17
 
18
18
  function SecuritySchemes(props) {
19
+ var _options$selected, _options$selected$;
19
20
  const options = (0, _hooks.useTypedSelector)(state => state.auth.options);
20
21
  const selected = (0, _hooks.useTypedSelector)(state => state.auth.selected);
21
22
  const infoAuthPath = `/${props.infoPath}#authentication`;
22
23
  if (selected === undefined) return null;
24
+ if (((_options$selected = options[selected]) === null || _options$selected === void 0 ? void 0 : (_options$selected$ = _options$selected[0]) === null || _options$selected$ === void 0 ? void 0 : _options$selected$.type) === undefined) {
25
+ return null;
26
+ }
23
27
  const selectedAuth = options[selected];
24
28
  return <details className={`details__demo-panel`} open={false}>
25
29
  <summary className={`details__request-summary`}>
26
30
  <h4>Authorization</h4>
27
31
  </summary>
28
32
  {selectedAuth.map(auth => {
33
+ const isHttp = auth.type === "http";
29
34
  const isApiKey = auth.type === "apiKey";
30
- const isBearer = auth.type === "http" && auth.key === "Bearer";
31
35
  const isOauth2 = auth.type === "oauth2";
32
- if (isApiKey || isBearer) {
36
+ const isOpenId = auth.type === "openIdConnect";
37
+ if (isHttp) {
38
+ var _auth$name;
39
+ if (auth.scheme === "bearer") {
40
+ const {
41
+ name,
42
+ key,
43
+ type,
44
+ scopes,
45
+ ...rest
46
+ } = auth;
47
+ return <_react.default.Fragment key={auth.key}>
48
+ <pre style={{
49
+ display: "flex",
50
+ flexDirection: "column",
51
+ background: "var(--openapi-card-background-color)"
52
+ }}>
53
+ <span>
54
+ <strong>name:</strong>{" "}
55
+ <_Link.default to={infoAuthPath}>{name !== null && name !== void 0 ? name : key}</_Link.default>
56
+ </span>
57
+ <span>
58
+ <strong>type: </strong>
59
+ {type}
60
+ </span>
61
+ {scopes && scopes.length > 0 && <span>
62
+ <strong>scopes: </strong>
63
+ <code>
64
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
65
+ </code>
66
+ </span>}
67
+ {Object.keys(rest).map((k, i) => {
68
+ return <span key={k}>
69
+ <strong>{k}: </strong>
70
+ {typeof rest[k] === "object" ? JSON.stringify(rest[k], null, 2) : String(rest[k])}
71
+ </span>;
72
+ })}
73
+ </pre>
74
+ </_react.default.Fragment>;
75
+ }
76
+ if (auth.scheme === "basic") {
77
+ const {
78
+ name,
79
+ key,
80
+ type,
81
+ scopes,
82
+ ...rest
83
+ } = auth;
84
+ return <_react.default.Fragment key={auth.key}>
85
+ <pre style={{
86
+ display: "flex",
87
+ flexDirection: "column",
88
+ background: "var(--openapi-card-background-color)"
89
+ }}>
90
+ <span>
91
+ <strong>name:</strong>{" "}
92
+ <_Link.default to={infoAuthPath}>{name !== null && name !== void 0 ? name : key}</_Link.default>
93
+ </span>
94
+ <span>
95
+ <strong>type: </strong>
96
+ {type}
97
+ </span>
98
+ {scopes && scopes.length > 0 && <span>
99
+ <strong>scopes: </strong>
100
+ <code>
101
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
102
+ </code>
103
+ </span>}
104
+ {Object.keys(rest).map((k, i) => {
105
+ return <span key={k}>
106
+ <strong>{k}: </strong>
107
+ {typeof rest[k] === "object" ? JSON.stringify(rest[k], null, 2) : String(rest[k])}
108
+ </span>;
109
+ })}
110
+ </pre>
111
+ </_react.default.Fragment>;
112
+ }
33
113
  return <_react.default.Fragment key={auth.key}>
34
114
  <pre style={{
35
115
  display: "flex",
36
116
  flexDirection: "column",
37
117
  background: "var(--openapi-card-background-color)"
38
118
  }}>
39
- <span>type: {auth.type}</span>
40
119
  <span>
41
- name: <_Link.default to={infoAuthPath}>{auth.name}</_Link.default>
120
+ <strong>name:</strong>{" "}
121
+ <_Link.default to={infoAuthPath}>{(_auth$name = auth.name) !== null && _auth$name !== void 0 ? _auth$name : auth.key}</_Link.default>
42
122
  </span>
43
- <span>in: {auth.in}</span>
123
+ <span>
124
+ <strong>type: </strong>
125
+ {auth.type}
126
+ </span>
127
+ <span>
128
+ <strong>in: </strong>
129
+ {auth.in}
130
+ </span>
131
+ </pre>
132
+ </_react.default.Fragment>;
133
+ }
134
+ if (isApiKey) {
135
+ const {
136
+ name,
137
+ key,
138
+ type,
139
+ scopes,
140
+ ...rest
141
+ } = auth;
142
+ return <_react.default.Fragment key={auth.key}>
143
+ <pre style={{
144
+ display: "flex",
145
+ flexDirection: "column",
146
+ background: "var(--openapi-card-background-color)"
147
+ }}>
148
+ <span>
149
+ <strong>name:</strong>{" "}
150
+ <_Link.default to={infoAuthPath}>{name !== null && name !== void 0 ? name : key}</_Link.default>
151
+ </span>
152
+ <span>
153
+ <strong>type: </strong>
154
+ {type}
155
+ </span>
156
+ {scopes && scopes.length > 0 && <span>
157
+ <strong>scopes: </strong>
158
+ <code>
159
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
160
+ </code>
161
+ </span>}
162
+ {Object.keys(rest).map((k, i) => {
163
+ return <span key={k}>
164
+ <strong>{k}: </strong>
165
+ {typeof rest[k] === "object" ? JSON.stringify(rest[k], null, 2) : String(rest[k])}
166
+ </span>;
167
+ })}
44
168
  </pre>
45
169
  </_react.default.Fragment>;
46
170
  }
47
171
  if (isOauth2) {
172
+ const {
173
+ name,
174
+ key,
175
+ type,
176
+ scopes,
177
+ flows,
178
+ ...rest
179
+ } = auth;
48
180
  return <_react.default.Fragment key={selected}>
49
181
  <pre style={{
50
182
  display: "flex",
@@ -52,14 +184,68 @@ function SecuritySchemes(props) {
52
184
  background: "var(--openapi-card-background-color)"
53
185
  }}>
54
186
  <span>
55
- type: <_Link.default to={infoAuthPath}>{auth.type}</_Link.default>
187
+ <strong>name:</strong>{" "}
188
+ <_Link.default to={infoAuthPath}>{name !== null && name !== void 0 ? name : key}</_Link.default>
189
+ </span>
190
+ <span>
191
+ <strong>type: </strong>
192
+ {type}
56
193
  </span>
57
- {Object.keys(auth.flows).map(flow => {
58
- return <span key={flow}>flow: {flow}</span>;
194
+ {scopes && scopes.length > 0 && <span>
195
+ <strong>scopes: </strong>
196
+ <code>
197
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
198
+ </code>
199
+ </span>}
200
+ {Object.keys(rest).map((k, i) => {
201
+ return <span key={k}>
202
+ <strong>{k}: </strong>
203
+ {typeof rest[k] === "object" ? JSON.stringify(rest[k], null, 2) : String(rest[k])}
204
+ </span>;
59
205
  })}
206
+ {flows && <span>
207
+ <code>
208
+ <strong>flows: </strong>
209
+ {JSON.stringify(flows, null, 2)}
210
+ </code>
211
+ </span>}
212
+ </pre>
213
+ </_react.default.Fragment>;
214
+ }
215
+ if (isOpenId) {
216
+ const {
217
+ name,
218
+ key,
219
+ scopes,
220
+ type,
221
+ ...rest
222
+ } = auth;
223
+ return <_react.default.Fragment key={auth.key}>
224
+ <pre style={{
225
+ display: "flex",
226
+ flexDirection: "column",
227
+ background: "var(--openapi-card-background-color)"
228
+ }}>
229
+ <span>
230
+ <strong>name:</strong>{" "}
231
+ <_Link.default to={infoAuthPath}>{name !== null && name !== void 0 ? name : key}</_Link.default>
232
+ </span>
60
233
  <span>
61
- scopes: <code>{auth.scopes.toString()}</code>
234
+ <strong>type: </strong>
235
+ {type}
62
236
  </span>
237
+ {scopes && scopes.length > 0 && <span>
238
+ <strong>scopes: </strong>
239
+ <code>
240
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
241
+ </code>
242
+ </span>}
243
+ {Object.keys(rest).map((k, i) => {
244
+ return <span key={k}>
245
+ <strong>{k}: </strong>
246
+ {typeof rest[k] === "object" ? JSON.stringify(rest[k], null, 2) : String(rest[k])}
247
+ </span>;
248
+ })}
63
249
  </pre>
64
250
  </_react.default.Fragment>;
65
251
  }
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = ApiLogo;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _themeCommon = require("@docusaurus/theme-common");
9
+ var _useBaseUrl = _interopRequireDefault(require("@docusaurus/useBaseUrl"));
10
+ var _ThemedImage = _interopRequireDefault(require("@theme/ThemedImage"));
9
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
12
  /* ============================================================================
11
13
  * Copyright (c) Palo Alto Networks
@@ -22,5 +24,26 @@ function ApiLogo(props) {
22
24
  logo,
23
25
  darkLogo
24
26
  } = props;
25
- return logo ? <img alt={colorMode === "dark" && darkLogo ? darkLogo.altText : logo.altText} src={colorMode === "dark" && darkLogo ? darkLogo.url : logo.url} width="250px" /> : <div />;
27
+ const altText = () => {
28
+ if (colorMode === "dark") {
29
+ var _darkLogo$altText;
30
+ return (_darkLogo$altText = darkLogo === null || darkLogo === void 0 ? void 0 : darkLogo.altText) !== null && _darkLogo$altText !== void 0 ? _darkLogo$altText : logo === null || logo === void 0 ? void 0 : logo.altText;
31
+ }
32
+ return logo === null || logo === void 0 ? void 0 : logo.altText;
33
+ };
34
+ const lightLogoUrl = (0, _useBaseUrl.default)(logo === null || logo === void 0 ? void 0 : logo.url);
35
+ const darkLogoUrl = (0, _useBaseUrl.default)(darkLogo === null || darkLogo === void 0 ? void 0 : darkLogo.url);
36
+ if (logo && darkLogo) {
37
+ return <_ThemedImage.default alt={altText()} sources={{
38
+ light: lightLogoUrl,
39
+ dark: darkLogoUrl
40
+ }} className="openapi__logo" />;
41
+ }
42
+ if (logo || darkLogo) {
43
+ return <_ThemedImage.default alt={altText()} sources={{
44
+ light: lightLogoUrl !== null && lightLogoUrl !== void 0 ? lightLogoUrl : darkLogoUrl,
45
+ dark: lightLogoUrl !== null && lightLogoUrl !== void 0 ? lightLogoUrl : darkLogoUrl
46
+ }} className="openapi__logo" />;
47
+ }
48
+ return undefined;
26
49
  }
@@ -8,6 +8,8 @@
8
8
  import React from "react";
9
9
 
10
10
  import CodeBlock from "@theme/CodeBlock";
11
+ import SchemaTabs from "@theme/SchemaTabs";
12
+ import TabItem from "@theme/TabItem";
11
13
  /* eslint-disable import/no-extraneous-dependencies*/
12
14
  import { createDescription } from "docusaurus-theme-openapi-docs/lib/markdown/createDescription";
13
15
  /* eslint-disable import/no-extraneous-dependencies*/
@@ -16,7 +18,10 @@ import {
16
18
  getSchemaName,
17
19
  } from "docusaurus-theme-openapi-docs/lib/markdown/schema";
18
20
  /* eslint-disable import/no-extraneous-dependencies*/
19
- import { guard } from "docusaurus-theme-openapi-docs/lib/markdown/utils";
21
+ import {
22
+ guard,
23
+ toString,
24
+ } from "docusaurus-theme-openapi-docs/lib/markdown/utils";
20
25
  import ReactMarkdown from "react-markdown";
21
26
  import rehypeRaw from "rehype-raw";
22
27
 
@@ -25,6 +30,10 @@ import styles from "./styles.module.css";
25
30
  function ParamsItem({
26
31
  param: { description, example, examples, name, required, schema },
27
32
  }) {
33
+ if (!schema || !schema?.type) {
34
+ schema = { type: "any" };
35
+ }
36
+
28
37
  const renderSchemaName = guard(schema, (schema) => (
29
38
  <span className={styles.schemaName}> {getSchemaName(schema)}</span>
30
39
  ));
@@ -76,17 +85,35 @@ function ParamsItem({
76
85
  )
77
86
  );
78
87
 
79
- const renderExample = guard(example, (example) => (
80
- <div>{`Example: ${example}`}</div>
88
+ const renderExample = guard(toString(example), (example) => (
89
+ <div>
90
+ <strong>Example: </strong>
91
+ {example}
92
+ </div>
81
93
  ));
82
94
 
83
95
  const renderExamples = guard(examples, (examples) => {
84
96
  const exampleEntries = Object.entries(examples);
85
97
  return (
86
98
  <>
87
- {exampleEntries.map(([k, v]) => (
88
- <div>{`Example (${k}): ${v.value}`}</div>
89
- ))}
99
+ <strong>Examples:</strong>
100
+ <SchemaTabs>
101
+ {exampleEntries.map(([exampleName, exampleProperties]) => (
102
+ <TabItem value={exampleName} label={exampleName}>
103
+ {exampleProperties.summary && <p>{exampleProperties.summary}</p>}
104
+ {exampleProperties.description && (
105
+ <p>
106
+ <strong>Description: </strong>
107
+ <span>{exampleProperties.description}</span>
108
+ </p>
109
+ )}
110
+ <p>
111
+ <strong>Example: </strong>
112
+ <code>{exampleProperties.value}</code>
113
+ </p>
114
+ </TabItem>
115
+ ))}
116
+ </SchemaTabs>
90
117
  </>
91
118
  );
92
119
  });
@@ -11,7 +11,10 @@ import CodeBlock from "@theme/CodeBlock";
11
11
  /* eslint-disable import/no-extraneous-dependencies*/
12
12
  import { createDescription } from "docusaurus-theme-openapi-docs/lib/markdown/createDescription";
13
13
  /* eslint-disable import/no-extraneous-dependencies*/
14
- import { guard } from "docusaurus-theme-openapi-docs/lib/markdown/utils";
14
+ import {
15
+ guard,
16
+ toString,
17
+ } from "docusaurus-theme-openapi-docs/lib/markdown/utils";
15
18
  import ReactMarkdown from "react-markdown";
16
19
  import rehypeRaw from "rehype-raw";
17
20
 
@@ -23,11 +26,20 @@ function SchemaItem({
23
26
  name,
24
27
  qualifierMessage,
25
28
  required,
26
- deprecated,
27
- schemaDescription,
28
29
  schemaName,
29
- defaultValue,
30
+ schema,
30
31
  }) {
32
+ let deprecated;
33
+ let schemaDescription;
34
+ let defaultValue;
35
+ let nullable;
36
+ if (schema) {
37
+ deprecated = schema.deprecated;
38
+ schemaDescription = schema.description;
39
+ defaultValue = schema.default;
40
+ nullable = schema.nullable;
41
+ }
42
+
31
43
  const renderRequired = guard(
32
44
  Array.isArray(required) ? required.includes(name) : required,
33
45
  () => <strong className={styles.required}> required</strong>
@@ -37,6 +49,10 @@ function SchemaItem({
37
49
  <strong className={styles.deprecated}> deprecated</strong>
38
50
  ));
39
51
 
52
+ const renderNullable = guard(nullable, () => (
53
+ <strong className={styles.nullable}> nullable</strong>
54
+ ));
55
+
40
56
  const renderSchemaDescription = guard(schemaDescription, (description) => (
41
57
  <div>
42
58
  <ReactMarkdown
@@ -67,19 +83,17 @@ function SchemaItem({
67
83
  </div>
68
84
  ));
69
85
 
70
- const renderDefaultValue = guard(
71
- typeof defaultValue === "boolean" ? defaultValue.toString() : defaultValue,
72
- (value) => (
73
- <div className={styles.schemaQualifierMessage}>
74
- <ReactMarkdown children={`**Default value:** \`${value}\``} />
75
- </div>
76
- )
77
- );
86
+ const renderDefaultValue = guard(toString(defaultValue), (value) => (
87
+ <div className={styles.schemaQualifierMessage}>
88
+ <ReactMarkdown children={`**Default value:** \`${value}\``} />
89
+ </div>
90
+ ));
78
91
 
79
92
  const schemaContent = (
80
93
  <div>
81
94
  <strong className={deprecated && styles.strikethrough}>{name}</strong>
82
95
  <span className={styles.schemaName}> {schemaName}</span>
96
+ {renderNullable}
83
97
  {!deprecated && renderRequired}
84
98
  {renderDeprecated}
85
99
  {renderQualifierMessage}
@@ -28,6 +28,11 @@
28
28
  color: var(--openapi-deprecated);
29
29
  }
30
30
 
31
+ .nullable {
32
+ font-size: var(--ifm-code-font-size);
33
+ color: var(--openapi-nullable);
34
+ }
35
+
31
36
  .strikethrough {
32
37
  text-decoration: line-through;
33
38
  }
@@ -241,11 +241,11 @@ function SchemaTabsComponent(props) {
241
241
  (tabItem) => tabItem.props.value === defaultValue
242
242
  )[0],
243
243
  {
244
- className: "margin-vert--md",
244
+ className: styles.marginVertical,
245
245
  }
246
246
  )
247
247
  ) : (
248
- <div className="margin-vert--md">
248
+ <div className={styles.marginVertical}>
249
249
  {children.map((tabItem, i) =>
250
250
  cloneElement(tabItem, {
251
251
  key: i,
@@ -103,3 +103,8 @@
103
103
  width: 100%;
104
104
  }
105
105
  }
106
+
107
+ .marginVertical {
108
+ margin-top: 1rem !important;
109
+ margin-bottom: unset !important;
110
+ }