diff --git a/README.md b/README.md index 642fcd31a..22ac9347f 100644 --- a/README.md +++ b/README.md @@ -155,25 +155,25 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following `config` can be configured with the following options: -| Name | Type | Default | Description | -| -------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------- | -| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. | -| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. | -| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. | -| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. | -| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. | -| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. | -| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. | -| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) | -| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. | -| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. | -| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. | -| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. | -| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. | -| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. | -| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. | -| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. | -| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. | +| Name | Type | Default | Description | +| -------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. | +| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. | +| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. | +| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. | +| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. | +| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. | +| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. | +| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) | +| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. | +| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. | +| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. | +| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. | +| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. | +| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. | +| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. | +| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. | +| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. | ### sidebarOptions @@ -221,6 +221,31 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following | --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.

**Function type:** `(item: ApiPageMetadata \| SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` | +## Theme Configuration Options + +The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`: + +| Name | Type | Default | Description | +| ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `proxy` | `string` | `null` | _Optional:_ Site-wide proxy URL to prepend to base URL when performing API requests. Can be overridden per-spec via plugin config. | +| `authPersistance` | `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. | +| `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. | + +Example: + +```typescript +// docusaurus.config.ts +{ + themeConfig: { + api: { + proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config) + authPersistance: "localStorage", + requestTimeout: 60000, // 60 seconds + }, + }, +} +``` + ## CLI Usage ```bash diff --git a/demo/docs/intro.mdx b/demo/docs/intro.mdx index d4779c3f7..71585306e 100644 --- a/demo/docs/intro.mdx +++ b/demo/docs/intro.mdx @@ -206,7 +206,7 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following | -------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. | | `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. | -| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. | +| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. | | `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. | | `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. | | `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. | @@ -285,6 +285,31 @@ petstore31: { | --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.

**Function type:** `(item: ApiPageMetadata \| SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` | +## Theme Configuration Options + +The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`: + +| Name | Type | Default | Description | +| ---------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| `proxy` | `string` | `null` | _Optional:_ Site-wide proxy URL to prepend to base URL when performing API requests. Can be overridden per-spec via plugin config. | +| `authPersistance`| `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. | +| `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. | + +Example: + +```typescript +// docusaurus.config.ts +{ + themeConfig: { + api: { + proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config) + authPersistance: "localStorage", + requestTimeout: 60000, // 60 seconds + }, + }, +} +``` + ## CLI Usage After you've installed and configured the plugin and theme, the CLI can be used to `generate` and `clean` API docs. diff --git a/packages/docusaurus-plugin-openapi-docs/README.md b/packages/docusaurus-plugin-openapi-docs/README.md index c09d4eb19..cde77d0f2 100644 --- a/packages/docusaurus-plugin-openapi-docs/README.md +++ b/packages/docusaurus-plugin-openapi-docs/README.md @@ -156,26 +156,26 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following `config` can be configured with the following options: -| Name | Type | Default | Description | -| -------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- | -| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. | -| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. | -| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. | -| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. | -| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. | -| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. | -| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. | -| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) | -| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. | -| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. | -| `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security. | -| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. | -| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. | -| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. | -| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. | -| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. | -| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. | -| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. | +| Name | Type | Default | Description | +| -------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. | +| `outputDir` | `string` | `null` | Desired output path for generated MDX and sidebar files. | +| `proxy` | `string` | `null` | _Optional:_ Proxy URL to prepend to base URL when performing API requests from browser. Overrides site-wide `themeConfig.api.proxy` if set. | +| `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. | +| `infoTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **info** pages only. | +| `tagTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **tag** pages only. | +| `schemaTemplate` | `string` | `null` | _Optional:_ Customize MDX content for **schema** pages only. | +| `downloadUrl` | `string` | `null` | _Optional:_ Designated URL for downloading OpenAPI specification. (requires `info` section/doc) | +| `hideSendButton` | `boolean` | `null` | _Optional:_ If set to `true`, hides the “Send API Request” button in the API demo panel. | +| `showExtensions` | `boolean` | `null` | _Optional:_ If set to `true`, renders operation‑level vendor‑extensions in descriptions. | +| `maskCredentials` | `boolean` | `true` | _Optional:_ If set to `false`, disables credential masking in generated code snippets. By default, credentials are masked for security. | +| `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. | +| `version` | `string` | `null` | _Optional:_ Version assigned to a single or micro‑spec API specified in `specPath`. | +| `label` | `string` | `null` | _Optional:_ Version label used when generating the version‑selector dropdown menu. | +| `baseUrl` | `string` | `null` | _Optional:_ Base URL for versioned docs in the version‑selector dropdown. | +| `versions` | `object` | `null` | _Optional:_ Options for versioning configuration. See below for a list of supported options. | +| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content via generator functions. See below for a list of supported options. | +| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates standalone schema pages and adds them to the sidebar. | ### sidebarOptions @@ -224,6 +224,31 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following | --------------- | ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `createDocItem` | `function` | `null` | Optional: Returns a `SidebarItemDoc` object containing metadata for a sidebar item.

**Function type:** `(item: ApiPageMetadata \| SchemaPageMetadata, context: { sidebarOptions: SidebarOptions; basePath: string }) => SidebarItemDoc` | +## Theme Configuration Options + +The `docusaurus-theme-openapi-docs` theme can be configured with the following options in `themeConfig.api`: + +| Name | Type | Default | Description | +| ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `proxy` | `string` | `null` | _Optional:_ Site-wide proxy URL to prepend to base URL when performing API requests. Can be overridden per-spec via plugin config. | +| `authPersistance` | `string` | `null` | _Optional:_ Determines how auth credentials are persisted. Options: `"localStorage"`, `"sessionStorage"`, or `false` to disable. | +| `requestTimeout` | `number` | `30000` | _Optional:_ Request timeout in milliseconds for API requests made from the browser. Defaults to 30 seconds. | + +Example: + +```typescript +// docusaurus.config.ts +{ + themeConfig: { + api: { + proxy: "https://cors.pan.dev", // Site-wide proxy (can be overridden per-spec in plugin config) + authPersistance: "localStorage", + requestTimeout: 60000, // 60 seconds + }, + }, +} +``` + ## Supported Vendor Extensions The plugin extracts a number of vendor extensions from the OpenAPI spec to enrich the generated docs. The theme renders some of these values as part of the UI. diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/index.tsx b/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/index.tsx index a1b3bcf93..e3cf6d617 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/index.tsx +++ b/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/index.tsx @@ -10,6 +10,8 @@ import React, { useState } from "react"; import { useDoc } from "@docusaurus/plugin-content-docs/client"; import { translate } from "@docusaurus/Translate"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import type { ThemeConfig } from "docusaurus-theme-openapi-docs/src/types"; import Accept from "@theme/ApiExplorer/Accept"; import Authorization from "@theme/ApiExplorer/Authorization"; import Body from "@theme/ApiExplorer/Body"; @@ -31,12 +33,18 @@ import { ApiItem } from "docusaurus-plugin-openapi-docs/src/types"; import * as sdk from "postman-collection"; import { FormProvider, useForm } from "react-hook-form"; -import makeRequest from "./makeRequest"; +import makeRequest, { RequestError, RequestErrorType } from "./makeRequest"; function Request({ item }: { item: ApiItem }) { const postman = new sdk.Request(item.postman); const metadata = useDoc(); - const { proxy, hide_send_button: hideSendButton } = metadata.frontMatter; + const { proxy: frontMatterProxy, hide_send_button: hideSendButton } = + metadata.frontMatter; + const { siteConfig } = useDocusaurusContext(); + const themeConfig = siteConfig.themeConfig as ThemeConfig; + const requestTimeout = themeConfig.api?.requestTimeout; + // Frontmatter proxy (per-spec) takes precedence over theme config proxy (site-wide) + const proxy = frontMatterProxy ?? themeConfig.api?.proxy; const pathParams = useTypedSelector((state: any) => state.params.path); const queryParams = useTypedSelector((state: any) => state.params.query); @@ -118,6 +126,36 @@ function Request({ item }: { item: ApiItem }) { res.headers && dispatch(setHeaders(Object.fromEntries(res.headers))); }; + const getErrorMessage = (errorType: RequestErrorType): string => { + switch (errorType) { + case "timeout": + return translate({ + id: OPENAPI_REQUEST.ERROR_TIMEOUT, + message: + "The request timed out waiting for the server to respond. Please try again. If the issue persists, try using a different client (e.g., curl) with a longer timeout.", + }); + case "network": + return translate({ + id: OPENAPI_REQUEST.ERROR_NETWORK, + message: + "Unable to reach the server. Please check your network connection and verify the server URL is correct. If the server is running, this may be a CORS issue.", + }); + case "cors": + return translate({ + id: OPENAPI_REQUEST.ERROR_CORS, + message: + "The request was blocked, possibly due to CORS restrictions. Ensure the server allows requests from this origin, or try using a proxy.", + }); + case "unknown": + default: + return translate({ + id: OPENAPI_REQUEST.ERROR_UNKNOWN, + message: + "An unexpected error occurred while making the request. Please try again.", + }); + } + }; + const onSubmit = async (data) => { dispatch( setResponse( @@ -129,7 +167,12 @@ function Request({ item }: { item: ApiItem }) { ); try { await delay(1200); - const res = await makeRequest(postmanRequest, proxy, body); + const res = await makeRequest( + postmanRequest, + proxy, + body, + requestTimeout + ); if (res.headers.get("content-type")?.includes("text/event-stream")) { await handleEventStream(res); } else { @@ -137,14 +180,18 @@ function Request({ item }: { item: ApiItem }) { } } catch (e) { console.log(e); - dispatch( - setResponse( - translate({ - id: OPENAPI_REQUEST.CONNECTION_FAILED, - message: "Connection failed", - }) - ) - ); + + let errorMessage: string; + if (e instanceof RequestError) { + errorMessage = getErrorMessage(e.type); + } else { + errorMessage = translate({ + id: OPENAPI_REQUEST.CONNECTION_FAILED, + message: "Connection failed", + }); + } + + dispatch(setResponse(errorMessage)); dispatch(clearCode()); dispatch(clearHeaders()); } diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/makeRequest.ts b/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/makeRequest.ts index 6c335709b..914311703 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/makeRequest.ts +++ b/packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Request/makeRequest.ts @@ -8,17 +8,83 @@ import { Body } from "@theme/ApiExplorer/Body/slice"; import * as sdk from "postman-collection"; +// Custom error types for better error handling +export type RequestErrorType = + | "timeout" + | "network" + | "cors" + | "abort" + | "unknown"; + +export class RequestError extends Error { + type: RequestErrorType; + originalError?: Error; + + constructor(type: RequestErrorType, message: string, originalError?: Error) { + super(message); + this.name = "RequestError"; + this.type = type; + this.originalError = originalError; + } +} + +const DEFAULT_REQUEST_TIMEOUT = 30000; // 30 seconds + function fetchWithtimeout( url: string, options: RequestInit, - timeout = 5000 -): any { - return Promise.race([ - fetch(url, options), - new Promise((_, reject) => - setTimeout(() => reject(new Error("Request timed out")), timeout) - ), - ]); + timeout = DEFAULT_REQUEST_TIMEOUT +): Promise { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + + return fetch(url, { + ...options, + signal: controller.signal, + }) + .then((response) => { + clearTimeout(timeoutId); + return response; + }) + .catch((error) => { + clearTimeout(timeoutId); + + // Check if it was an abort due to timeout + if (error.name === "AbortError") { + throw new RequestError( + "timeout", + "The request timed out waiting for the server to respond. Please try again. If the issue persists, try using a different client (e.g., curl) with a longer timeout.", + error + ); + } + + // Check for network errors (offline, DNS failure, etc.) + if (error instanceof TypeError && error.message === "Failed to fetch") { + // This could be CORS, network failure, or the server being unreachable + throw new RequestError( + "network", + "Unable to reach the server. Please check your network connection and verify the server URL is correct. If the server is running, this may be a CORS issue.", + error + ); + } + + // Handle other TypeErrors that might indicate CORS issues + if (error instanceof TypeError) { + throw new RequestError( + "cors", + "The request was blocked, possibly due to CORS restrictions. Ensure the server allows requests from this origin, or try using a proxy.", + error + ); + } + + // Generic error fallback + throw new RequestError( + "unknown", + error.message || + "An unexpected error occurred while making the request.", + error + ); + }); } async function loadImage(content: Blob): Promise { @@ -47,7 +113,8 @@ async function loadImage(content: Blob): Promise { async function makeRequest( request: sdk.Request, proxy: string | undefined, - _body: Body + _body: Body, + timeout: number = DEFAULT_REQUEST_TIMEOUT ) { const headers = request.toJSON().header; @@ -194,7 +261,8 @@ async function makeRequest( finalUrl = normalizedProxy + request.url.toString(); } - return fetchWithtimeout(finalUrl, requestOptions).then((response: any) => { + try { + const response = await fetchWithtimeout(finalUrl, requestOptions, timeout); const contentType = response.headers.get("content-type"); let fileExtension = ""; @@ -224,32 +292,45 @@ async function makeRequest( } if (fileExtension) { - return response.blob().then((blob: any) => { - const url = window.URL.createObjectURL(blob); + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - // Now the file name includes the extension - link.setAttribute("download", `file${fileExtension}`); + const link = document.createElement("a"); + link.href = url; + // Now the file name includes the extension + link.setAttribute("download", `file${fileExtension}`); - // These two lines are necessary to make the link click in Firefox - link.style.display = "none"; - document.body.appendChild(link); + // These two lines are necessary to make the link click in Firefox + link.style.display = "none"; + document.body.appendChild(link); - link.click(); + link.click(); - // After link is clicked, it's safe to remove it. - setTimeout(() => document.body.removeChild(link), 0); + // After link is clicked, it's safe to remove it. + setTimeout(() => document.body.removeChild(link), 0); - return response; - }); + return response; } else { return response; } } return response; - }); + } catch (error) { + // Re-throw RequestError instances as-is + if (error instanceof RequestError) { + throw error; + } + + // Wrap unexpected errors + throw new RequestError( + "unknown", + error instanceof Error + ? error.message + : "An unexpected error occurred while processing the response.", + error instanceof Error ? error : undefined + ); + } } export default makeRequest; diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/translationIds.ts b/packages/docusaurus-theme-openapi-docs/src/theme/translationIds.ts index 46e47bab4..7616cd560 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/translationIds.ts +++ b/packages/docusaurus-theme-openapi-docs/src/theme/translationIds.ts @@ -29,6 +29,10 @@ export const OPENAPI_REQUEST = { PARAMETERS_TITLE: "theme.openapi.request.parameters.title", FETCHING_MESSAGE: "theme.openapi.request.fetchingMessage", CONNECTION_FAILED: "theme.openapi.request.connectionFailed", + ERROR_TIMEOUT: "theme.openapi.request.error.timeout", + ERROR_NETWORK: "theme.openapi.request.error.network", + ERROR_CORS: "theme.openapi.request.error.cors", + ERROR_UNKNOWN: "theme.openapi.request.error.unknown", }; export const OPENAPI_SERVER = { diff --git a/packages/docusaurus-theme-openapi-docs/src/types.ts b/packages/docusaurus-theme-openapi-docs/src/types.ts index e65019ea5..af1780daa 100644 --- a/packages/docusaurus-theme-openapi-docs/src/types.ts +++ b/packages/docusaurus-theme-openapi-docs/src/types.ts @@ -12,6 +12,8 @@ export interface ThemeConfig { api?: { proxy?: string; authPersistance?: false | "localStorage" | "sessionStorage"; + /** Request timeout in milliseconds. Defaults to 30000 (30 seconds). */ + requestTimeout?: number; }; }