docusaurus-theme-openapi-docs 3.0.0-beta.1 → 3.0.0-beta.3

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 (30) hide show
  1. package/lib/markdown/utils.d.ts +2 -2
  2. package/lib/theme/ApiExplorer/Authorization/slice.d.ts +1 -1
  3. package/lib/theme/ApiExplorer/Body/slice.d.ts +3 -3
  4. package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +4 -2
  5. package/lib/theme/ApiExplorer/FloatingButton/_FloatingButton.scss +3 -1
  6. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +4 -4
  7. package/lib/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +2 -1
  8. package/lib/theme/ApiExplorer/ParamOptions/slice.d.ts +1 -1
  9. package/lib/theme/ApiExplorer/Request/_Request.scss +4 -2
  10. package/lib/theme/ApiExplorer/Request/makeRequest.js +50 -1
  11. package/lib/theme/ApiExplorer/Response/_Response.scss +4 -2
  12. package/lib/theme/ApiExplorer/Response/index.js +19 -19
  13. package/lib/theme/ApiExplorer/buildPostmanRequest.d.ts +1 -1
  14. package/lib/theme/ApiExplorer/storage-utils.d.ts +1 -1
  15. package/lib/theme/ApiItem/store.d.ts +2 -2
  16. package/lib/theme/ApiTabs/index.js +2 -2
  17. package/lib/theme/ParamsItem/index.js +2 -2
  18. package/lib/types.d.ts +4 -4
  19. package/package.json +7 -6
  20. package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +4 -2
  21. package/src/theme/ApiExplorer/FloatingButton/_FloatingButton.scss +3 -1
  22. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +4 -4
  23. package/src/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +2 -1
  24. package/src/theme/ApiExplorer/Request/_Request.scss +4 -2
  25. package/src/theme/ApiExplorer/Request/makeRequest.ts +59 -4
  26. package/src/theme/ApiExplorer/Response/_Response.scss +4 -2
  27. package/src/theme/ApiExplorer/Response/index.tsx +2 -2
  28. package/src/theme/ApiTabs/index.js +2 -2
  29. package/src/theme/ParamsItem/index.js +2 -2
  30. package/src/theme-openapi.d.ts +2 -0
@@ -1,5 +1,5 @@
1
- export declare type Children = string | undefined | (string | undefined)[];
2
- export declare type Props = Record<string, any> & {
1
+ export type Children = string | undefined | (string | undefined)[];
2
+ export type Props = Record<string, any> & {
3
3
  children?: Children;
4
4
  };
5
5
  export declare function create(tag: string, props: Props): string;
@@ -8,7 +8,7 @@ export declare function createAuth({ security, securitySchemes, options, }: {
8
8
  };
9
9
  options?: ThemeConfig["api"];
10
10
  }): AuthState;
11
- export declare type Scheme = {
11
+ export type Scheme = {
12
12
  key: string;
13
13
  scopes: string[];
14
14
  } & SecuritySchemeObject;
@@ -10,7 +10,7 @@ export interface StringContent {
10
10
  type: "string";
11
11
  value?: string;
12
12
  }
13
- export declare type Content = FileContent | StringContent | undefined;
13
+ export type Content = FileContent | StringContent | undefined;
14
14
  export interface FormBody {
15
15
  type: "form";
16
16
  content: {
@@ -24,8 +24,8 @@ export interface RawBody {
24
24
  export interface EmptyBody {
25
25
  type: "empty";
26
26
  }
27
- export declare type Body = EmptyBody | FormBody | RawBody;
28
- export declare type State = Body;
27
+ export type Body = EmptyBody | FormBody | RawBody;
28
+ export type State = Body;
29
29
  export declare const slice: import("@reduxjs/toolkit").Slice<EmptyBody | FormBody | RawBody, {
30
30
  clearRawBody: (_state: import("immer/dist/internal").WritableDraft<EmptyBody> | import("immer/dist/internal").WritableDraft<FormBody> | import("immer/dist/internal").WritableDraft<RawBody>) => {
31
31
  type: "empty";
@@ -18,12 +18,14 @@
18
18
  background-color: var(--ifm-pre-background);
19
19
  border-radius: var(--ifm-global-radius);
20
20
  border: 1px solid var(--openapi-explorer-border-color);
21
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
21
+ box-shadow:
22
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
22
23
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
23
24
  transition: 300ms;
24
25
 
25
26
  &:hover {
26
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
27
+ box-shadow:
28
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
27
29
  0 2px 3px hsla(222, 8%, 43%, 0.15),
28
30
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
29
31
  }
@@ -11,7 +11,9 @@
11
11
  padding: 0.4rem 0.5rem;
12
12
  opacity: 0;
13
13
  visibility: hidden;
14
- transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out,
14
+ transition:
15
+ opacity 0.2s ease-in-out,
16
+ visibility 0.2s ease-in-out,
15
17
  bottom 0.2s ease-in-out;
16
18
  position: absolute;
17
19
  right: calc(var(--ifm-pre-padding) / 2);
@@ -42,10 +42,10 @@ function ParamMultiSelectFormItem({ param }) {
42
42
  const paramTypeToWatch = pathParams.length
43
43
  ? pathParams
44
44
  : queryParams.length
45
- ? queryParams
46
- : cookieParams.length
47
- ? cookieParams
48
- : headerParams;
45
+ ? queryParams
46
+ : cookieParams.length
47
+ ? cookieParams
48
+ : headerParams;
49
49
  const handleChange = (e, onChange) => {
50
50
  const values = Array.prototype.filter
51
51
  .call(e.target.options, (o) => o.selected)
@@ -107,7 +107,8 @@
107
107
  }
108
108
 
109
109
  &:active {
110
- box-shadow: inset 0 0 0 1px var(--openapi-input-border),
110
+ box-shadow:
111
+ inset 0 0 0 1px var(--openapi-input-border),
111
112
  inset 0 0 0 2px var(--openapi-inverse-color);
112
113
  }
113
114
  }
@@ -1,6 +1,6 @@
1
1
  import { PayloadAction } from "@reduxjs/toolkit";
2
2
  import { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
3
- export declare type Param = ParameterObject & {
3
+ export type Param = ParameterObject & {
4
4
  value?: string[] | string;
5
5
  };
6
6
  export interface State {
@@ -2,7 +2,8 @@
2
2
  background-color: var(--ifm-pre-background);
3
3
  border-radius: var(--openapi-card-border-radius);
4
4
  border: 1px solid var(--openapi-explorer-border-color);
5
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
5
+ box-shadow:
6
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
6
7
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
7
8
  color: var(--ifm-pre-color);
8
9
  line-height: var(--ifm-pre-line-height);
@@ -19,7 +20,8 @@
19
20
  }
20
21
 
21
22
  &:hover {
22
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
23
+ box-shadow:
24
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
23
25
  0 2px 3px hsla(222, 8%, 43%, 0.15),
24
26
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
25
27
  }
@@ -141,6 +141,10 @@ async function makeRequest(request, proxy, _body) {
141
141
  if (data.key && data.value.content) {
142
142
  myBody.append(data.key, data.value.content);
143
143
  }
144
+ // handle generic key-value payload
145
+ if (data.key && typeof data.value === "string") {
146
+ myBody.append(data.key, data.value);
147
+ }
144
148
  }
145
149
  }
146
150
  break;
@@ -166,7 +170,52 @@ async function makeRequest(request, proxy, _body) {
166
170
  let normalizedProxy = proxy.replace(/\/$/, "") + "/";
167
171
  finalUrl = normalizedProxy + request.url.toString();
168
172
  }
169
- return await fetchWithtimeout(finalUrl, requestOptions).then((response) => {
173
+ return fetchWithtimeout(finalUrl, requestOptions).then((response) => {
174
+ const contentType = response.headers.get("content-type");
175
+ let fileExtension = "";
176
+ if (contentType) {
177
+ if (contentType.includes("application/pdf")) {
178
+ fileExtension = ".pdf";
179
+ } else if (contentType.includes("image/jpeg")) {
180
+ fileExtension = ".jpg";
181
+ } else if (contentType.includes("image/png")) {
182
+ fileExtension = ".png";
183
+ } else if (contentType.includes("image/gif")) {
184
+ fileExtension = ".gif";
185
+ } else if (contentType.includes("image/webp")) {
186
+ fileExtension = ".webp";
187
+ } else if (contentType.includes("video/mpeg")) {
188
+ fileExtension = ".mpeg";
189
+ } else if (contentType.includes("video/mp4")) {
190
+ fileExtension = ".mp4";
191
+ } else if (contentType.includes("audio/mpeg")) {
192
+ fileExtension = ".mp3";
193
+ } else if (contentType.includes("audio/ogg")) {
194
+ fileExtension = ".ogg";
195
+ } else if (contentType.includes("application/octet-stream")) {
196
+ fileExtension = ".bin";
197
+ } else if (contentType.includes("application/zip")) {
198
+ fileExtension = ".zip";
199
+ }
200
+ if (fileExtension) {
201
+ return response.blob().then((blob) => {
202
+ const url = window.URL.createObjectURL(blob);
203
+ const link = document.createElement("a");
204
+ link.href = url;
205
+ // Now the file name includes the extension
206
+ link.setAttribute("download", `file${fileExtension}`);
207
+ // These two lines are necessary to make the link click in Firefox
208
+ link.style.display = "none";
209
+ document.body.appendChild(link);
210
+ link.click();
211
+ // After link is clicked, it's safe to remove it.
212
+ setTimeout(() => document.body.removeChild(link), 0);
213
+ return response;
214
+ });
215
+ } else {
216
+ return response;
217
+ }
218
+ }
170
219
  return response;
171
220
  });
172
221
  }
@@ -2,7 +2,8 @@
2
2
  background-color: var(--ifm-pre-background);
3
3
  border-radius: var(--openapi-card-border-radius);
4
4
  border: 1px solid var(--openapi-explorer-border-color);
5
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
5
+ box-shadow:
6
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
6
7
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
7
8
  color: var(--ifm-pre-color);
8
9
  line-height: var(--ifm-pre-line-height);
@@ -12,7 +13,8 @@
12
13
  transition: 300ms;
13
14
 
14
15
  &:hover {
15
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
16
+ box-shadow:
17
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
16
18
  0 2px 3px hsla(222, 8%, 43%, 0.15),
17
19
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
18
20
  }
@@ -58,8 +58,8 @@ function Response({ item }) {
58
58
  (parseInt(code) >= 400
59
59
  ? "openapi-response__dot--danger"
60
60
  : parseInt(code) >= 200 && parseInt(code) < 300
61
- ? "openapi-response__dot--success"
62
- : "openapi-response__dot--info");
61
+ ? "openapi-response__dot--success"
62
+ : "openapi-response__dot--info");
63
63
  if (!item.servers || hideSendButton) {
64
64
  return null;
65
65
  }
@@ -165,25 +165,25 @@ function Response({ item }) {
165
165
  )
166
166
  )
167
167
  : prettyResponse === "Fetching..."
168
- ? react_1.default.createElement(
169
- "div",
170
- { className: "openapi-explorer__loading-container" },
171
- react_1.default.createElement(
168
+ ? react_1.default.createElement(
172
169
  "div",
173
- { className: "openapi-response__lds-ring" },
174
- react_1.default.createElement("div", null),
175
- react_1.default.createElement("div", null),
176
- react_1.default.createElement("div", null),
177
- react_1.default.createElement("div", null)
170
+ { className: "openapi-explorer__loading-container" },
171
+ react_1.default.createElement(
172
+ "div",
173
+ { className: "openapi-response__lds-ring" },
174
+ react_1.default.createElement("div", null),
175
+ react_1.default.createElement("div", null),
176
+ react_1.default.createElement("div", null),
177
+ react_1.default.createElement("div", null)
178
+ )
179
+ )
180
+ : react_1.default.createElement(
181
+ "p",
182
+ { className: "openapi-explorer__response-placeholder-message" },
183
+ "Click the ",
184
+ react_1.default.createElement("code", null, "Send API Request"),
185
+ " button above and see the response here!"
178
186
  )
179
- )
180
- : react_1.default.createElement(
181
- "p",
182
- { className: "openapi-explorer__response-placeholder-message" },
183
- "Click the ",
184
- react_1.default.createElement("code", null, "Send API Request"),
185
- " button above and see the response here!"
186
- )
187
187
  )
188
188
  );
189
189
  }
@@ -2,7 +2,7 @@ import sdk from "@paloaltonetworks/postman-collection";
2
2
  import { AuthState } from "@theme/ApiExplorer/Authorization/slice";
3
3
  import { Body } from "@theme/ApiExplorer/Body/slice";
4
4
  import { ParameterObject, ServerObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
5
- declare type Param = {
5
+ type Param = {
6
6
  value?: string | string[];
7
7
  } & ParameterObject;
8
8
  interface Options {
@@ -1,4 +1,4 @@
1
1
  export declare function hashArray(arr: string[]): string;
2
- declare type Persistance = false | "localStorage" | "sessionStorage" | undefined;
2
+ type Persistance = false | "localStorage" | "sessionStorage" | undefined;
3
3
  export declare function createStorage(persistance: Persistance): Storage;
4
4
  export {};
@@ -7,7 +7,7 @@ declare const rootReducer: import("redux").Reducer<import("redux").CombinedState
7
7
  params: unknown;
8
8
  auth: unknown;
9
9
  }>, import("redux").Action<any>>;
10
- export declare type RootState = ReturnType<typeof rootReducer>;
10
+ export type RootState = ReturnType<typeof rootReducer>;
11
11
  export declare const createStoreWithState: (preloadedState: RootState, middlewares: any[]) => import("@reduxjs/toolkit/dist/configureStore").ToolkitStore<import("redux").CombinedState<{
12
12
  accept: unknown;
13
13
  contentType: unknown;
@@ -42,5 +42,5 @@ export declare const createStoreWithoutState: (preloadedState: {}, middlewares:
42
42
  params: unknown;
43
43
  auth: unknown;
44
44
  }>, import("redux").AnyAction, undefined>, ...any[]]>>;
45
- export declare type AppDispatch = ReturnType<typeof createStoreWithState>["dispatch"];
45
+ export type AppDispatch = ReturnType<typeof createStoreWithState>["dispatch"];
46
46
  export {};
@@ -125,8 +125,8 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
125
125
  parseInt(value) >= 400
126
126
  ? "danger"
127
127
  : parseInt(value) >= 200 && parseInt(value) < 300
128
- ? "success"
129
- : "info",
128
+ ? "success"
129
+ : "info",
130
130
  {
131
131
  active: selectedValue === value,
132
132
  }
@@ -74,8 +74,8 @@ function ParamsItem({
74
74
  schema && schema.items
75
75
  ? schema.items.default
76
76
  : schema
77
- ? schema.default
78
- : undefined,
77
+ ? schema.default
78
+ : undefined,
79
79
  (value) => (
80
80
  <div>
81
81
  <ReactMarkdown children={`**Default value:** \`${value}\``} />
package/lib/types.d.ts CHANGED
@@ -9,8 +9,8 @@ export interface ThemeConfig {
9
9
  interface Map<T> {
10
10
  [key: string]: T;
11
11
  }
12
- export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
13
- export declare type SchemaObject = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf" | "not" | "items" | "properties" | "additionalProperties"> & {
12
+ export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
13
+ export type SchemaObject = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf" | "not" | "items" | "properties" | "additionalProperties"> & {
14
14
  type?: "string" | "number" | "integer" | "boolean" | "object" | "array";
15
15
  allOf?: SchemaObject[];
16
16
  oneOf?: SchemaObject[];
@@ -43,14 +43,14 @@ export interface ExternalDocumentationObject {
43
43
  description?: string;
44
44
  url: string;
45
45
  }
46
- export declare type FileChange = {
46
+ export type FileChange = {
47
47
  author?: string;
48
48
  /** Date can be any
49
49
  * [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
50
50
  */
51
51
  date?: Date | string;
52
52
  };
53
- export declare type DocFrontMatter = {
53
+ export type DocFrontMatter = {
54
54
  /**
55
55
  * The last part of the doc ID (will be refactored in the future to be the
56
56
  * full ID instead)
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": "3.0.0-beta.1",
4
+ "version": "3.0.0-beta.3",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,14 +28,15 @@
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/types": "^3.0.0",
31
+ "@docusaurus/types": "^3.0.1",
32
32
  "@types/crypto-js": "^4.1.0",
33
33
  "@types/file-saver": "^2.0.5",
34
34
  "@types/lodash": "^4.14.176",
35
- "concurrently": "^5.2.0"
35
+ "concurrently": "^5.2.0",
36
+ "eslint-plugin-prettier": "^5.0.1"
36
37
  },
37
38
  "dependencies": {
38
- "@docusaurus/theme-common": "^3.0.0",
39
+ "@docusaurus/theme-common": "^3.0.1",
39
40
  "@hookform/error-message": "^2.0.1",
40
41
  "@paloaltonetworks/postman-code-generators": "1.1.15-patch.2",
41
42
  "@paloaltonetworks/postman-collection": "^4.1.0",
@@ -43,7 +44,7 @@
43
44
  "clsx": "^1.1.1",
44
45
  "copy-text-to-clipboard": "^3.1.0",
45
46
  "crypto-js": "^4.1.1",
46
- "docusaurus-plugin-openapi-docs": "^3.0.0-beta.1",
47
+ "docusaurus-plugin-openapi-docs": "^3.0.0-beta.3",
47
48
  "docusaurus-plugin-sass": "^0.2.3",
48
49
  "file-saver": "^2.0.5",
49
50
  "lodash": "^4.17.20",
@@ -68,5 +69,5 @@
68
69
  "engines": {
69
70
  "node": ">=14"
70
71
  },
71
- "gitHead": "9641610aae936a5d9193f43068a2fdd337da0416"
72
+ "gitHead": "4836267b8bcc01d496449e6d531663a00dfdb4ed"
72
73
  }
@@ -18,12 +18,14 @@
18
18
  background-color: var(--ifm-pre-background);
19
19
  border-radius: var(--ifm-global-radius);
20
20
  border: 1px solid var(--openapi-explorer-border-color);
21
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
21
+ box-shadow:
22
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
22
23
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
23
24
  transition: 300ms;
24
25
 
25
26
  &:hover {
26
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
27
+ box-shadow:
28
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
27
29
  0 2px 3px hsla(222, 8%, 43%, 0.15),
28
30
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
29
31
  }
@@ -11,7 +11,9 @@
11
11
  padding: 0.4rem 0.5rem;
12
12
  opacity: 0;
13
13
  visibility: hidden;
14
- transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out,
14
+ transition:
15
+ opacity 0.2s ease-in-out,
16
+ visibility 0.2s ease-in-out,
15
17
  bottom 0.2s ease-in-out;
16
18
  position: absolute;
17
19
  right: calc(var(--ifm-pre-padding) / 2);
@@ -37,10 +37,10 @@ export default function ParamMultiSelectFormItem({ param }: ParamProps) {
37
37
  const paramTypeToWatch = pathParams.length
38
38
  ? pathParams
39
39
  : queryParams.length
40
- ? queryParams
41
- : cookieParams.length
42
- ? cookieParams
43
- : headerParams;
40
+ ? queryParams
41
+ : cookieParams.length
42
+ ? cookieParams
43
+ : headerParams;
44
44
 
45
45
  const handleChange = (e: any, onChange: any) => {
46
46
  const values = Array.prototype.filter
@@ -107,7 +107,8 @@
107
107
  }
108
108
 
109
109
  &:active {
110
- box-shadow: inset 0 0 0 1px var(--openapi-input-border),
110
+ box-shadow:
111
+ inset 0 0 0 1px var(--openapi-input-border),
111
112
  inset 0 0 0 2px var(--openapi-inverse-color);
112
113
  }
113
114
  }
@@ -2,7 +2,8 @@
2
2
  background-color: var(--ifm-pre-background);
3
3
  border-radius: var(--openapi-card-border-radius);
4
4
  border: 1px solid var(--openapi-explorer-border-color);
5
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
5
+ box-shadow:
6
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
6
7
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
7
8
  color: var(--ifm-pre-color);
8
9
  line-height: var(--ifm-pre-line-height);
@@ -19,7 +20,8 @@
19
20
  }
20
21
 
21
22
  &:hover {
22
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
23
+ box-shadow:
24
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
23
25
  0 2px 3px hsla(222, 8%, 43%, 0.15),
24
26
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
25
27
  }
@@ -161,6 +161,10 @@ async function makeRequest(
161
161
  if (data.key && data.value.content) {
162
162
  myBody.append(data.key, data.value.content);
163
163
  }
164
+ // handle generic key-value payload
165
+ if (data.key && typeof data.value === "string") {
166
+ myBody.append(data.key, data.value);
167
+ }
164
168
  }
165
169
  }
166
170
  break;
@@ -189,11 +193,62 @@ async function makeRequest(
189
193
  finalUrl = normalizedProxy + request.url.toString();
190
194
  }
191
195
 
192
- return await fetchWithtimeout(finalUrl, requestOptions).then(
193
- (response: any) => {
194
- return response;
196
+ return fetchWithtimeout(finalUrl, requestOptions).then((response: any) => {
197
+ const contentType = response.headers.get("content-type");
198
+ let fileExtension = "";
199
+
200
+ if (contentType) {
201
+ if (contentType.includes("application/pdf")) {
202
+ fileExtension = ".pdf";
203
+ } else if (contentType.includes("image/jpeg")) {
204
+ fileExtension = ".jpg";
205
+ } else if (contentType.includes("image/png")) {
206
+ fileExtension = ".png";
207
+ } else if (contentType.includes("image/gif")) {
208
+ fileExtension = ".gif";
209
+ } else if (contentType.includes("image/webp")) {
210
+ fileExtension = ".webp";
211
+ } else if (contentType.includes("video/mpeg")) {
212
+ fileExtension = ".mpeg";
213
+ } else if (contentType.includes("video/mp4")) {
214
+ fileExtension = ".mp4";
215
+ } else if (contentType.includes("audio/mpeg")) {
216
+ fileExtension = ".mp3";
217
+ } else if (contentType.includes("audio/ogg")) {
218
+ fileExtension = ".ogg";
219
+ } else if (contentType.includes("application/octet-stream")) {
220
+ fileExtension = ".bin";
221
+ } else if (contentType.includes("application/zip")) {
222
+ fileExtension = ".zip";
223
+ }
224
+
225
+ if (fileExtension) {
226
+ return response.blob().then((blob: any) => {
227
+ const url = window.URL.createObjectURL(blob);
228
+
229
+ const link = document.createElement("a");
230
+ link.href = url;
231
+ // Now the file name includes the extension
232
+ link.setAttribute("download", `file${fileExtension}`);
233
+
234
+ // These two lines are necessary to make the link click in Firefox
235
+ link.style.display = "none";
236
+ document.body.appendChild(link);
237
+
238
+ link.click();
239
+
240
+ // After link is clicked, it's safe to remove it.
241
+ setTimeout(() => document.body.removeChild(link), 0);
242
+
243
+ return response;
244
+ });
245
+ } else {
246
+ return response;
247
+ }
195
248
  }
196
- );
249
+
250
+ return response;
251
+ });
197
252
  }
198
253
 
199
254
  export default makeRequest;
@@ -2,7 +2,8 @@
2
2
  background-color: var(--ifm-pre-background);
3
3
  border-radius: var(--openapi-card-border-radius);
4
4
  border: 1px solid var(--openapi-explorer-border-color);
5
- box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1),
5
+ box-shadow:
6
+ 0 2px 3px hsla(222, 8%, 43%, 0.1),
6
7
  0 8px 16px -10px hsla(222, 8%, 43%, 0.2);
7
8
  color: var(--ifm-pre-color);
8
9
  line-height: var(--ifm-pre-line-height);
@@ -12,7 +13,8 @@
12
13
  transition: 300ms;
13
14
 
14
15
  &:hover {
15
- box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15),
16
+ box-shadow:
17
+ 0 0 0 2px rgba(38, 53, 61, 0.15),
16
18
  0 2px 3px hsla(222, 8%, 43%, 0.15),
17
19
  0 16px 16px -10px hsla(222, 8%, 43%, 0.2);
18
20
  }
@@ -52,8 +52,8 @@ function Response({ item }: { item: NonNullable<ApiItem> }) {
52
52
  (parseInt(code) >= 400
53
53
  ? "openapi-response__dot--danger"
54
54
  : parseInt(code) >= 200 && parseInt(code) < 300
55
- ? "openapi-response__dot--success"
56
- : "openapi-response__dot--info");
55
+ ? "openapi-response__dot--success"
56
+ : "openapi-response__dot--info");
57
57
 
58
58
  if (!item.servers || hideSendButton) {
59
59
  return null;
@@ -125,8 +125,8 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
125
125
  parseInt(value) >= 400
126
126
  ? "danger"
127
127
  : parseInt(value) >= 200 && parseInt(value) < 300
128
- ? "success"
129
- : "info",
128
+ ? "success"
129
+ : "info",
130
130
  {
131
131
  active: selectedValue === value,
132
132
  }
@@ -74,8 +74,8 @@ function ParamsItem({
74
74
  schema && schema.items
75
75
  ? schema.items.default
76
76
  : schema
77
- ? schema.default
78
- : undefined,
77
+ ? schema.default
78
+ : undefined,
79
79
  (value) => (
80
80
  <div>
81
81
  <ReactMarkdown children={`**Default value:** \`${value}\``} />
@@ -7,6 +7,8 @@
7
7
 
8
8
  /// <reference types="docusaurus-plugin-openapi-docs" />
9
9
 
10
+ /* eslint-disable @typescript-eslint/no-use-before-define */
11
+
10
12
  declare module "@docusaurus/plugin-content-docs-types" {
11
13
  // Makes all properties visible when hovering over the type
12
14
  type Expand<T extends Record<string, unknown>> = { [P in keyof T]: T[P] };