docusaurus-theme-openapi-docs 4.5.0 → 4.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 (119) hide show
  1. package/lib/markdown/schema.js +9 -1
  2. package/lib/theme/ApiExplorer/Accept/slice.d.ts +5 -2
  3. package/lib/theme/ApiExplorer/Authorization/index.js +50 -9
  4. package/lib/theme/ApiExplorer/Authorization/slice.d.ts +145 -3
  5. package/lib/theme/ApiExplorer/Authorization/slice.js +3 -1
  6. package/lib/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.d.ts +7 -0
  7. package/lib/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.js +126 -0
  8. package/lib/theme/ApiExplorer/Body/FormBodyItem/index.d.ts +9 -0
  9. package/lib/theme/ApiExplorer/Body/FormBodyItem/index.js +110 -0
  10. package/lib/theme/ApiExplorer/Body/index.js +94 -100
  11. package/lib/theme/ApiExplorer/Body/slice.d.ts +1056 -11
  12. package/lib/theme/ApiExplorer/Body/slice.js +22 -2
  13. package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +2 -1
  14. package/lib/theme/ApiExplorer/CodeSnippets/index.js +37 -26
  15. package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +5 -1
  16. package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +3 -3
  17. package/lib/theme/ApiExplorer/CodeTabs/index.js +2 -2
  18. package/lib/theme/ApiExplorer/ContentType/slice.d.ts +5 -2
  19. package/lib/theme/ApiExplorer/FormFileUpload/index.js +6 -1
  20. package/lib/theme/ApiExplorer/FormItem/index.js +6 -1
  21. package/lib/theme/ApiExplorer/FormTextInput/index.d.ts +2 -0
  22. package/lib/theme/ApiExplorer/FormTextInput/index.js +8 -1
  23. package/lib/theme/ApiExplorer/LiveEditor/index.js +11 -4
  24. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.js +15 -5
  25. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.js +11 -3
  26. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +12 -4
  27. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.js +11 -2
  28. package/lib/theme/ApiExplorer/ParamOptions/index.js +11 -1
  29. package/lib/theme/ApiExplorer/ParamOptions/slice.d.ts +0 -4
  30. package/lib/theme/ApiExplorer/ParamOptions/slice.js +4 -4
  31. package/lib/theme/ApiExplorer/Request/index.js +110 -17
  32. package/lib/theme/ApiExplorer/Request/makeRequest.d.ts +7 -1
  33. package/lib/theme/ApiExplorer/Request/makeRequest.js +94 -24
  34. package/lib/theme/ApiExplorer/Response/index.js +34 -14
  35. package/lib/theme/ApiExplorer/Response/slice.d.ts +31 -7
  36. package/lib/theme/ApiExplorer/SecuritySchemes/index.js +208 -69
  37. package/lib/theme/ApiExplorer/Server/index.js +16 -2
  38. package/lib/theme/ApiExplorer/Server/slice.d.ts +49 -3
  39. package/lib/theme/ApiExplorer/buildPostmanRequest.js +46 -57
  40. package/lib/theme/ApiExplorer/index.js +11 -1
  41. package/lib/theme/ApiExplorer/persistenceMiddleware.d.ts +19 -0
  42. package/lib/theme/ApiExplorer/{persistanceMiddleware.js → persistenceMiddleware.js} +16 -9
  43. package/lib/theme/ApiExplorer/storage-utils.d.ts +2 -2
  44. package/lib/theme/ApiExplorer/storage-utils.js +3 -3
  45. package/lib/theme/ApiItem/Layout/index.d.ts +1 -1
  46. package/lib/theme/ApiItem/hooks.d.ts +9 -9
  47. package/lib/theme/ApiItem/index.js +12 -8
  48. package/lib/theme/ApiItem/store.d.ts +55 -43
  49. package/lib/theme/ApiTabs/index.js +6 -1
  50. package/lib/theme/Example/_Example.scss +11 -0
  51. package/lib/theme/Example/index.d.ts +24 -0
  52. package/lib/theme/Example/index.js +170 -0
  53. package/lib/theme/ParamsDetails/index.js +9 -1
  54. package/lib/theme/ParamsItem/index.d.ts +1 -1
  55. package/lib/theme/ParamsItem/index.js +43 -74
  56. package/lib/theme/RequestSchema/index.js +18 -4
  57. package/lib/theme/ResponseExamples/index.js +23 -3
  58. package/lib/theme/ResponseSchema/index.js +97 -82
  59. package/lib/theme/Schema/index.js +106 -23
  60. package/lib/theme/SchemaItem/index.js +64 -36
  61. package/lib/theme/SchemaTabs/index.js +4 -1
  62. package/lib/theme/StatusCodes/index.js +11 -2
  63. package/lib/theme/styles.scss +5 -0
  64. package/lib/theme/translationIds.d.ts +90 -0
  65. package/lib/theme/translationIds.js +114 -0
  66. package/lib/types.d.ts +9 -1
  67. package/package.json +28 -28
  68. package/src/markdown/schema.ts +11 -1
  69. package/src/theme/ApiExplorer/Authorization/index.tsx +51 -10
  70. package/src/theme/ApiExplorer/Authorization/slice.ts +1 -1
  71. package/src/theme/ApiExplorer/Body/FileArrayFormBodyItem/index.tsx +77 -0
  72. package/src/theme/ApiExplorer/Body/FormBodyItem/index.tsx +120 -0
  73. package/src/theme/ApiExplorer/Body/index.tsx +87 -107
  74. package/src/theme/ApiExplorer/Body/json2xml.d.ts +8 -0
  75. package/src/theme/ApiExplorer/Body/slice.ts +40 -1
  76. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +43 -29
  77. package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +5 -1
  78. package/src/theme/ApiExplorer/CodeTabs/index.tsx +6 -5
  79. package/src/theme/ApiExplorer/ContentType/index.tsx +1 -1
  80. package/src/theme/ApiExplorer/FormFileUpload/index.tsx +6 -1
  81. package/src/theme/ApiExplorer/FormItem/index.tsx +8 -1
  82. package/src/theme/ApiExplorer/FormTextInput/index.tsx +10 -1
  83. package/src/theme/ApiExplorer/LiveEditor/index.tsx +11 -4
  84. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx +16 -6
  85. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx +12 -4
  86. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +12 -4
  87. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx +12 -3
  88. package/src/theme/ApiExplorer/ParamOptions/index.tsx +10 -2
  89. package/src/theme/ApiExplorer/ParamOptions/slice.ts +1 -1
  90. package/src/theme/ApiExplorer/Request/index.tsx +108 -17
  91. package/src/theme/ApiExplorer/Request/makeRequest.ts +106 -25
  92. package/src/theme/ApiExplorer/Response/index.tsx +30 -8
  93. package/src/theme/ApiExplorer/SecuritySchemes/index.tsx +157 -69
  94. package/src/theme/ApiExplorer/Server/index.tsx +12 -4
  95. package/src/theme/ApiExplorer/buildPostmanRequest.ts +47 -63
  96. package/src/theme/ApiExplorer/index.tsx +10 -1
  97. package/src/theme/ApiExplorer/{persistanceMiddleware.ts → persistenceMiddleware.ts} +23 -13
  98. package/src/theme/ApiExplorer/storage-utils.ts +4 -4
  99. package/src/theme/ApiItem/Layout/index.tsx +1 -1
  100. package/src/theme/ApiItem/index.tsx +12 -7
  101. package/src/theme/ApiTabs/index.tsx +6 -1
  102. package/src/theme/Example/_Example.scss +11 -0
  103. package/src/theme/Example/index.tsx +168 -0
  104. package/src/theme/Markdown/index.d.ts +8 -0
  105. package/src/theme/ParamsDetails/index.tsx +10 -1
  106. package/src/theme/ParamsItem/index.tsx +38 -54
  107. package/src/theme/RequestSchema/index.tsx +19 -4
  108. package/src/theme/ResponseExamples/index.tsx +23 -3
  109. package/src/theme/ResponseSchema/index.tsx +73 -61
  110. package/src/theme/Schema/index.tsx +128 -33
  111. package/src/theme/SchemaItem/index.tsx +51 -33
  112. package/src/theme/SchemaTabs/index.tsx +4 -1
  113. package/src/theme/StatusCodes/index.tsx +13 -2
  114. package/src/theme/styles.scss +5 -0
  115. package/src/theme/translationIds.ts +111 -0
  116. package/src/theme-openapi.d.ts +7 -275
  117. package/src/types.ts +9 -1
  118. package/tsconfig.tsbuildinfo +1 -1
  119. package/lib/theme/ApiExplorer/persistanceMiddleware.d.ts +0 -3
@@ -55,20 +55,10 @@ function setQueryParams(postman: sdk.Request, queryParams: Param[]) {
55
55
  }
56
56
  }
57
57
 
58
- const decodedValue = decodeURI(param.value);
59
- const tryJson = () => {
60
- try {
61
- return JSON.parse(decodedValue);
62
- } catch (e) {
63
- return false;
64
- }
65
- };
66
-
67
- const jsonResult = tryJson();
68
-
69
58
  // Handle object values
70
- if (jsonResult && typeof jsonResult === "object") {
71
- if (param.style === "deepObject") {
59
+ if (param.style === "deepObject") {
60
+ const jsonResult = tryDecodeJsonParam(param.value);
61
+ if (jsonResult && typeof jsonResult === "object") {
72
62
  return Object.entries(jsonResult).map(
73
63
  ([key, val]) =>
74
64
  new sdk.QueryParam({
@@ -76,7 +66,10 @@ function setQueryParams(postman: sdk.Request, queryParams: Param[]) {
76
66
  value: String(val),
77
67
  })
78
68
  );
79
- } else if (param.explode) {
69
+ }
70
+ } else if (param.explode) {
71
+ const jsonResult = tryDecodeJsonParam(param.value);
72
+ if (jsonResult && typeof jsonResult === "object") {
80
73
  return Object.entries(jsonResult).map(
81
74
  ([key, val]) =>
82
75
  new sdk.QueryParam({
@@ -94,17 +87,9 @@ function setQueryParams(postman: sdk.Request, queryParams: Param[]) {
94
87
  }
95
88
  }
96
89
 
97
- // Handle boolean values
98
- if (typeof decodedValue === "boolean") {
99
- return new sdk.QueryParam({
100
- key: param.name,
101
- value: decodedValue ? "true" : "false",
102
- });
103
- }
104
-
105
90
  // Parameter allows empty value: "/hello?extended"
106
91
  if (param.allowEmptyValue) {
107
- if (decodedValue === "true") {
92
+ if (param.value === "true") {
108
93
  return new sdk.QueryParam({
109
94
  key: param.name,
110
95
  value: null,
@@ -150,18 +135,9 @@ function setPathParams(postman: sdk.Request, pathParams: Param[]) {
150
135
  });
151
136
  }
152
137
 
153
- const decodedValue = decodeURI(param.value);
154
- const tryJson = () => {
155
- try {
156
- return JSON.parse(decodedValue);
157
- } catch (e) {
158
- return false;
159
- }
160
- };
138
+ const jsonResult = tryDecodeJsonParam(param.value);
161
139
 
162
- const jsonResult = tryJson();
163
-
164
- if (typeof jsonResult === "object") {
140
+ if (jsonResult && typeof jsonResult === "object") {
165
141
  if (param.style === "matrix") {
166
142
  serializedValue = Object.entries(jsonResult)
167
143
  .map(([key, val]) => `;${key}=${val}`)
@@ -172,7 +148,7 @@ function setPathParams(postman: sdk.Request, pathParams: Param[]) {
172
148
  .join(",");
173
149
  }
174
150
  } else {
175
- serializedValue = decodedValue || `:${param.name}`;
151
+ serializedValue = param.value;
176
152
  }
177
153
 
178
154
  return new sdk.Variable({
@@ -191,17 +167,8 @@ function buildCookie(cookieParams: Param[]) {
191
167
  const cookies = cookieParams
192
168
  .map((param) => {
193
169
  if (param.value) {
194
- const decodedValue = decodeURI(param.value as string);
195
- const tryJson = () => {
196
- try {
197
- return JSON.parse(decodedValue);
198
- } catch (e) {
199
- return false;
200
- }
201
- };
202
-
203
- const jsonResult = tryJson();
204
- if (typeof jsonResult === "object") {
170
+ const jsonResult = tryDecodeJsonParam(param.value as string);
171
+ if (jsonResult && typeof jsonResult === "object") {
205
172
  if (param.style === "form") {
206
173
  // Handle form style
207
174
  if (param.explode) {
@@ -266,16 +233,9 @@ function setHeaders(
266
233
 
267
234
  headerParams.forEach((param) => {
268
235
  if (param.value) {
269
- const decodedValue = decodeURI(param.value as string);
270
- const tryJson = () => {
271
- try {
272
- return JSON.parse(decodedValue);
273
- } catch (e) {
274
- return false;
275
- }
276
- };
277
-
278
- const jsonResult = tryJson();
236
+ const jsonResult = Array.isArray(param.value)
237
+ ? param.value.map(tryDecodeJsonParam)
238
+ : tryDecodeJsonParam(param.value);
279
239
  if (Array.isArray(param.value)) {
280
240
  if (param.style === "simple") {
281
241
  if (param.explode) {
@@ -324,6 +284,14 @@ function setHeaders(
324
284
  }
325
285
  }
326
286
 
287
+ function tryDecodeJsonParam(value: string): any {
288
+ try {
289
+ return JSON.parse(decodeURI(value));
290
+ } catch (e) {
291
+ return false;
292
+ }
293
+ }
294
+
327
295
  // TODO: this is all a bit hacky
328
296
  function setBody(clonedPostman: sdk.Request, body: Body) {
329
297
  if (clonedPostman.body === undefined) {
@@ -345,7 +313,11 @@ function setBody(clonedPostman: sdk.Request, body: Body) {
345
313
  switch (clonedPostman.body.mode) {
346
314
  case "raw": {
347
315
  // check file even though it should already be set from above
348
- if (body.type !== "raw" || body.content?.type === "file") {
316
+ if (
317
+ body.type !== "raw" ||
318
+ body.content?.type === "file" ||
319
+ body.content?.type === "file[]"
320
+ ) {
349
321
  clonedPostman.body = undefined;
350
322
  return;
351
323
  }
@@ -360,15 +332,23 @@ function setBody(clonedPostman: sdk.Request, body: Body) {
360
332
  clonedPostman.body.raw = `${body.content?.value}`;
361
333
  return;
362
334
  }
363
- const params = Object.entries(body.content)
335
+ const params: sdk.FormParam[] = [];
336
+ Object.entries(body.content)
364
337
  .filter((entry): entry is [string, NonNullable<Content>] => !!entry[1])
365
- .map(([key, content]) => {
338
+ .forEach(([key, content]) => {
366
339
  if (content.type === "file") {
367
- return new sdk.FormParam({ key: key, ...content });
340
+ params.push(new sdk.FormParam({ key: key, ...content }));
341
+ } else if (content.type === "file[]") {
342
+ content.value.forEach((file) =>
343
+ params.push(new sdk.FormParam({ key, value: file }))
344
+ );
345
+ } else {
346
+ params.push(new sdk.FormParam({ key: key, value: content.value }));
368
347
  }
369
- return new sdk.FormParam({ key: key, value: content.value });
370
348
  });
371
- clonedPostman.body.formdata?.assimilate(params, false);
349
+ params.forEach((param) => {
350
+ clonedPostman.body?.formdata?.add(param);
351
+ });
372
352
  return;
373
353
  }
374
354
  case "urlencoded": {
@@ -382,7 +362,11 @@ function setBody(clonedPostman: sdk.Request, body: Body) {
382
362
  const params = Object.entries(body.content)
383
363
  .filter((entry): entry is [string, NonNullable<Content>] => !!entry[1])
384
364
  .map(([key, content]) => {
385
- if (content.type !== "file" && content.value) {
365
+ if (
366
+ content.type !== "file" &&
367
+ content.type !== "file[]" &&
368
+ content.value
369
+ ) {
386
370
  return new sdk.QueryParam({ key: key, value: content.value });
387
371
  }
388
372
  return undefined;
@@ -7,6 +7,7 @@
7
7
 
8
8
  import React from "react";
9
9
 
10
+ import { useDoc } from "@docusaurus/plugin-content-docs/client";
10
11
  import CodeSnippets from "@theme/ApiExplorer/CodeSnippets";
11
12
  import Request from "@theme/ApiExplorer/Request";
12
13
  import Response from "@theme/ApiExplorer/Response";
@@ -21,8 +22,15 @@ function ApiExplorer({
21
22
  item: NonNullable<ApiItem>;
22
23
  infoPath: string;
23
24
  }) {
25
+ const metadata = useDoc();
26
+ const { mask_credentials } = metadata.frontMatter;
27
+
24
28
  const postman = new sdk.Request(
25
- item.postman ? (item.postman as any).toJSON() : {}
29
+ item.postman
30
+ ? sdk.Request.isRequest(item.postman)
31
+ ? (item.postman as any).toJSON()
32
+ : (item.postman as any)
33
+ : {}
26
34
  );
27
35
 
28
36
  return (
@@ -32,6 +40,7 @@ function ApiExplorer({
32
40
  <CodeSnippets
33
41
  postman={postman}
34
42
  codeSamples={(item as any)["x-codeSamples"] ?? []}
43
+ maskCredentials={mask_credentials}
35
44
  />
36
45
  )}
37
46
  <Request item={item} />
@@ -5,25 +5,29 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { Middleware } from "@reduxjs/toolkit";
8
+ import type { Middleware } from "@reduxjs/toolkit";
9
9
  import {
10
10
  setAuthData,
11
11
  setSelectedAuth,
12
12
  } from "@theme/ApiExplorer/Authorization/slice";
13
- import { AppDispatch, RootState } from "@theme/ApiItem/store";
14
- /* eslint-disable import/no-extraneous-dependencies*/
15
- import { ThemeConfig } from "docusaurus-theme-openapi-docs/src/types";
13
+ import type { AppDispatch, RootState } from "@theme/ApiItem/store";
14
+ import type { ServerObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
15
+ import type { ThemeConfig } from "docusaurus-theme-openapi-docs/src/types";
16
16
 
17
17
  import { createStorage, hashArray } from "./storage-utils";
18
18
 
19
- export function createPersistanceMiddleware(options: ThemeConfig["api"]) {
20
- const persistanceMiddleware: Middleware<{}, RootState, AppDispatch> =
21
- (storeAPI) => (next) => (action) => {
19
+ export function createPersistenceMiddleware(options: ThemeConfig["api"]) {
20
+ const persistenceMiddleware: Middleware<{}, RootState, AppDispatch> =
21
+ (storeAPI) =>
22
+ (next) =>
23
+ (action: ReturnType<typeof setAuthData | typeof setSelectedAuth> | any) => {
22
24
  const result = next(action);
23
25
 
24
26
  const state = storeAPI.getState();
25
27
 
26
- const storage = createStorage("sessionStorage");
28
+ const storage = createStorage(
29
+ options?.authPersistence ?? "sessionStorage"
30
+ );
27
31
 
28
32
  if (action.type === setAuthData.type) {
29
33
  for (const [key, value] of Object.entries(state.auth.data)) {
@@ -58,14 +62,20 @@ export function createPersistanceMiddleware(options: ThemeConfig["api"]) {
58
62
  }
59
63
 
60
64
  if (action.type === "server/setServerVariable") {
61
- const server = storage.getItem("server") ?? "{}";
65
+ const server = storage.getItem("server");
66
+ if (!server) {
67
+ return result;
68
+ }
62
69
  const variables = JSON.parse(action.payload);
63
- let serverObject = JSON.parse(server);
64
- serverObject.variables[variables.key].default = variables.value;
65
- storage.setItem("server", JSON.stringify(serverObject));
70
+
71
+ const serverObject = (JSON.parse(server) as ServerObject) ?? {};
72
+ if (serverObject.variables?.[variables.key]) {
73
+ serverObject.variables[variables.key].default = variables.value;
74
+ storage.setItem("server", JSON.stringify(serverObject));
75
+ }
66
76
  }
67
77
 
68
78
  return result;
69
79
  };
70
- return persistanceMiddleware;
80
+ return persistenceMiddleware;
71
81
  }
@@ -17,10 +17,10 @@ export function hashArray(arr: string[]) {
17
17
  return hash(res);
18
18
  }
19
19
 
20
- type Persistance = false | "localStorage" | "sessionStorage" | undefined;
20
+ type Persistence = false | "localStorage" | "sessionStorage" | undefined;
21
21
 
22
- export function createStorage(persistance: Persistance): Storage {
23
- if (persistance === false) {
22
+ export function createStorage(persistence: Persistence): Storage {
23
+ if (persistence === false) {
24
24
  return {
25
25
  getItem: () => null,
26
26
  setItem: () => {},
@@ -31,7 +31,7 @@ export function createStorage(persistance: Persistance): Storage {
31
31
  };
32
32
  }
33
33
 
34
- if (persistance === "sessionStorage") {
34
+ if (persistence === "sessionStorage") {
35
35
  return sessionStorage;
36
36
  }
37
37
 
@@ -9,11 +9,11 @@ import React, { type JSX } from "react";
9
9
 
10
10
  import { useDoc } from "@docusaurus/plugin-content-docs/client";
11
11
  import { useWindowSize } from "@docusaurus/theme-common";
12
- import type { Props } from "@theme/ApiItem/Layout";
13
12
  import ContentVisibility from "@theme/ContentVisibility";
14
13
  import DocBreadcrumbs from "@theme/DocBreadcrumbs";
15
14
  import DocItemContent from "@theme/DocItem/Content";
16
15
  import DocItemFooter from "@theme/DocItem/Footer";
16
+ import type { Props } from "@theme/DocItem/Layout";
17
17
  import DocItemPaginator from "@theme/DocItem/Paginator";
18
18
  import DocItemTOCDesktop from "@theme/DocItem/TOC/Desktop";
19
19
  import DocItemTOCMobile from "@theme/DocItem/TOC/Mobile";
@@ -14,7 +14,8 @@ import { HtmlClassNameProvider } from "@docusaurus/theme-common";
14
14
  import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
15
15
  import useIsBrowser from "@docusaurus/useIsBrowser";
16
16
  import { createAuth } from "@theme/ApiExplorer/Authorization/slice";
17
- import { createPersistanceMiddleware } from "@theme/ApiExplorer/persistanceMiddleware";
17
+ import { createPersistenceMiddleware } from "@theme/ApiExplorer/persistenceMiddleware";
18
+ import { createStorage } from "@theme/ApiExplorer/storage-utils";
18
19
  import DocItemLayout from "@theme/ApiItem/Layout";
19
20
  import CodeBlock from "@theme/CodeBlock";
20
21
  import type { Props } from "@theme/DocItem";
@@ -90,11 +91,11 @@ export default function ApiItem(props: Props): JSX.Element {
90
91
 
91
92
  // Define store2
92
93
  let store2: any = {};
93
- const persistanceMiddleware = createPersistanceMiddleware(options);
94
+ const persistenceMiddleware = createPersistenceMiddleware(options);
94
95
 
95
96
  // Init store for SSR
96
97
  if (!isBrowser) {
97
- store2 = createStoreWithoutState({}, [persistanceMiddleware]);
98
+ store2 = createStoreWithoutState({}, [persistenceMiddleware]);
98
99
  }
99
100
 
100
101
  // Init store for CSR to hydrate components
@@ -129,11 +130,15 @@ export default function ApiItem(props: Props): JSX.Element {
129
130
  securitySchemes: api?.securitySchemes,
130
131
  options,
131
132
  });
133
+
134
+ const storage = createStorage(options?.authPersistence ?? "sessionStorage");
132
135
  // TODO: determine way to rehydrate without flashing
133
136
  // const acceptValue = window?.sessionStorage.getItem("accept");
134
137
  // const contentTypeValue = window?.sessionStorage.getItem("contentType");
135
- const server = window?.sessionStorage.getItem("server");
136
- const serverObject = (JSON.parse(server!) as ServerObject) ?? {};
138
+ const server = storage.getItem("server");
139
+ const serverObject = server
140
+ ? (JSON.parse(server) as ServerObject)
141
+ : undefined;
137
142
 
138
143
  store2 = createStoreWithState(
139
144
  {
@@ -146,7 +151,7 @@ export default function ApiItem(props: Props): JSX.Element {
146
151
  options: contentTypeArray,
147
152
  },
148
153
  server: {
149
- value: serverObject.url ? serverObject : undefined,
154
+ value: serverObject?.url ? serverObject : undefined,
150
155
  options: servers,
151
156
  },
152
157
  response: { value: undefined },
@@ -154,7 +159,7 @@ export default function ApiItem(props: Props): JSX.Element {
154
159
  params,
155
160
  auth,
156
161
  },
157
- [persistanceMiddleware]
162
+ [persistenceMiddleware]
158
163
  );
159
164
  }
160
165
 
@@ -20,8 +20,10 @@ import {
20
20
  useTabs,
21
21
  } from "@docusaurus/theme-common/internal";
22
22
  import { TabItemProps } from "@docusaurus/theme-common/lib/utils/tabsUtils";
23
+ import { translate } from "@docusaurus/Translate";
23
24
  import useIsBrowser from "@docusaurus/useIsBrowser";
24
25
  import Heading from "@theme/Heading";
26
+ import { OPENAPI_TABS } from "@theme/translationIds";
25
27
  import clsx from "clsx";
26
28
 
27
29
  export interface TabListProps extends TabProps {
@@ -35,7 +37,10 @@ function TabList({
35
37
  selectedValue,
36
38
  selectValue,
37
39
  tabValues,
38
- label = "Responses",
40
+ label = translate({
41
+ id: OPENAPI_TABS.RESPONSES_LABEL,
42
+ message: "Responses",
43
+ }),
39
44
  id = "responses",
40
45
  }: TabListProps & ReturnType<typeof useTabs>) {
41
46
  const tabRefs: (HTMLLIElement | null)[] = [];
@@ -0,0 +1,11 @@
1
+ .openapi-examples {
2
+ > .openapi-tabs__schema-container {
3
+ margin: 0.4rem;
4
+
5
+ @layer docusaurus.infima {
6
+ > .margin-top--md {
7
+ margin: 0.2rem !important;
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,168 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ import React from "react";
9
+
10
+ import { translate } from "@docusaurus/Translate";
11
+ import { ExampleObject } from "@theme/ParamsItem";
12
+ import SchemaTabs from "@theme/SchemaTabs";
13
+ import TabItem from "@theme/TabItem";
14
+ import { OPENAPI_SCHEMA_ITEM } from "@theme/translationIds";
15
+
16
+ const EXAMPLE_CLASS_NAME = "openapi-example";
17
+ const EXAMPLES_CLASS_NAME = "openapi-examples";
18
+
19
+ type ExampleType = string;
20
+ type ExamplesType = Record<string, ExampleObject> | string[];
21
+
22
+ /**
23
+ * Example Component Props
24
+ */
25
+ type ExampleProps = {
26
+ example?: ExampleType;
27
+ examples?: ExamplesType;
28
+ };
29
+
30
+ /**
31
+ * Example Component
32
+ */
33
+ export const Example = ({ example, examples }: ExampleProps) => {
34
+ if (example !== undefined) {
35
+ return renderExample(example);
36
+ }
37
+ if (examples !== undefined) {
38
+ return renderExamples(examples);
39
+ }
40
+ return undefined;
41
+ };
42
+
43
+ /**
44
+ * Format example value
45
+ *
46
+ * @param example
47
+ * @returns
48
+ */
49
+ const formatExample = (example: any) => {
50
+ if (typeof example === "object" && example !== null) {
51
+ return JSON.stringify(example);
52
+ }
53
+ return String(example);
54
+ };
55
+
56
+ const renderExample = (example: ExampleType) => {
57
+ return (
58
+ <div className={EXAMPLE_CLASS_NAME}>
59
+ <strong>
60
+ {translate({
61
+ id: OPENAPI_SCHEMA_ITEM.EXAMPLE,
62
+ message: "Example:",
63
+ })}{" "}
64
+ </strong>
65
+ <span>
66
+ <code>{formatExample(example)}</code>
67
+ </span>
68
+ </div>
69
+ );
70
+ };
71
+
72
+ const renderExamples = (examples: ExamplesType) => {
73
+ if (Array.isArray(examples)) {
74
+ return renderStringArrayExamples(examples);
75
+ }
76
+ return renderExamplesRecord(examples);
77
+ };
78
+
79
+ /**
80
+ * Render string examples
81
+ *
82
+ * @param examples
83
+ * @returns
84
+ */
85
+ export function renderStringArrayExamples(examples: string[]) {
86
+ if (examples.length === 0) {
87
+ return undefined;
88
+ }
89
+ // If there's only one example, display it without tabs
90
+ if (examples.length === 1) {
91
+ return renderExample(examples[0]);
92
+ }
93
+
94
+ // Multiple examples - use tabs
95
+ const exampleEntries = examples.reduce(
96
+ (acc, example, index) => ({
97
+ ...acc,
98
+ [`Example ${index + 1}`]: {
99
+ value: example,
100
+ },
101
+ }),
102
+ {} as Record<string, ExampleObject>
103
+ );
104
+ return renderExamplesRecord(exampleEntries);
105
+ }
106
+
107
+ export const renderExamplesRecord = (
108
+ examples: Record<string, ExampleObject>
109
+ ) => {
110
+ const exampleEntries = Object.entries(examples);
111
+ // If there's only one example, display it without tabs
112
+ if (exampleEntries.length === 1) {
113
+ const firstExample = exampleEntries[0][1];
114
+ if (!firstExample) {
115
+ return undefined;
116
+ }
117
+ return renderExample(firstExample.value);
118
+ }
119
+
120
+ return (
121
+ <div className={EXAMPLES_CLASS_NAME}>
122
+ <strong>
123
+ {translate({
124
+ id: OPENAPI_SCHEMA_ITEM.EXAMPLES,
125
+ message: "Examples:",
126
+ })}
127
+ </strong>
128
+ <SchemaTabs>
129
+ {exampleEntries.map(([exampleName, exampleProperties]) =>
130
+ renderExampleObject(exampleName, exampleProperties)
131
+ )}
132
+ </SchemaTabs>
133
+ </div>
134
+ );
135
+ };
136
+
137
+ /**
138
+ * Render example object
139
+ *
140
+ * @param exampleName
141
+ * @param exampleProperties
142
+ * @returns
143
+ */
144
+ const renderExampleObject = (
145
+ exampleName: string,
146
+ exampleProperties: ExampleObject
147
+ ) => {
148
+ return (
149
+ // @ts-ignore
150
+ <TabItem value={exampleName} label={exampleName}>
151
+ {exampleProperties.summary && <p>{exampleProperties.summary}</p>}
152
+ {exampleProperties.description && (
153
+ <p>
154
+ <strong>
155
+ {translate({
156
+ id: OPENAPI_SCHEMA_ITEM.DESCRIPTION,
157
+ message: "Description:",
158
+ })}{" "}
159
+ </strong>
160
+ <span>{exampleProperties.description}</span>
161
+ </p>
162
+ )}
163
+ {exampleProperties.value !== undefined
164
+ ? renderExample(exampleProperties.value)
165
+ : undefined}
166
+ </TabItem>
167
+ );
168
+ };
@@ -0,0 +1,8 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ export default function Markdown(props: any): JSX.Element;
@@ -7,6 +7,9 @@
7
7
 
8
8
  import React from "react";
9
9
 
10
+ import { translate } from "@docusaurus/Translate";
11
+ import { OPENAPI_PARAMS_DETAILS } from "@theme/translationIds";
12
+
10
13
  import BrowserOnly from "@docusaurus/BrowserOnly";
11
14
  import Details from "@theme/Details";
12
15
  import ParamsItem from "@theme/ParamsItem";
@@ -31,7 +34,13 @@ const ParamsDetailsComponent: React.FC<Props> = ({ parameters }) => {
31
34
  const summaryElement = (
32
35
  <summary>
33
36
  <h3 className="openapi-markdown__details-summary-header-params">
34
- {`${type.charAt(0).toUpperCase() + type.slice(1)} Parameters`}
37
+ {translate(
38
+ {
39
+ id: OPENAPI_PARAMS_DETAILS.PARAMETERS_TITLE,
40
+ message: "{type} Parameters",
41
+ },
42
+ { type: type.charAt(0).toUpperCase() + type.slice(1) }
43
+ )}
35
44
  </h3>
36
45
  </summary>
37
46
  );