diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 665b9079d..934e835ad 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -80,6 +80,14 @@ const config = { autoCollapseCategories: true, }, }, + api: { + schemaExpansion: { + enabled: true, + default: 0, + max: 4, + persist: true, + }, + }, algolia: { apiKey: "6869800b232f5f8362e83901d79110ee", appId: "XC7919KOX3", diff --git a/package.json b/package.json index 4c1da9730..4dbbd930a 100644 --- a/package.json +++ b/package.json @@ -56,9 +56,9 @@ "@tailwindcss/postcss": "^4.3.0", "algoliasearch": "^5.55.1", "clsx": "^2.1.1", - "docusaurus-plugin-openapi-docs": "5.0.2", + "docusaurus-plugin-openapi-docs": "5.1.2", "docusaurus-plugin-sass": "^0.2.2", - "docusaurus-theme-openapi-docs": "5.0.2", + "docusaurus-theme-openapi-docs": "5.1.2", "fast-xml-parser": "^4.5.5", "motion": "^12.39.0", "react": "^19.2.7", diff --git a/src/theme/ApiExplorer/Request/_Request.scss b/src/theme/ApiExplorer/Request/_Request.scss deleted file mode 100644 index 53e3f95b2..000000000 --- a/src/theme/ApiExplorer/Request/_Request.scss +++ /dev/null @@ -1,127 +0,0 @@ -.openapi-explorer__request-form { - background-color: var(--ifm-pre-background); - border-radius: var(--openapi-card-border-radius); - border: 1px solid var(--openapi-explorer-border-color); - box-shadow: 0 2px 3px hsla(222, 8%, 43%, 0.1), - 0 8px 16px -10px hsla(222, 8%, 43%, 0.2); - color: var(--ifm-pre-color); - line-height: var(--ifm-pre-line-height); - margin-bottom: var(--ifm-spacing-vertical); - margin-top: 0; - overflow: auto; - transition: 300ms; - - /* hack for view calculation when monaco is hidden */ - position: relative; - - &:empty { - display: none; - } - - &:hover { - box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15), - 0 2px 3px hsla(222, 8%, 43%, 0.15), - 0 16px 16px -10px hsla(222, 8%, 43%, 0.2); - } - - .required { - font-size: var(--ifm-code-font-size); - color: var(--openapi-required); - - &.request-body { - padding-left: 0.25rem; - } - } -} - -.openapi-explorer__request-header-container { - display: flex; - justify-content: space-between; - border-bottom: 1px solid var(--openapi-explorer-border-color); - margin: 0; - padding: 0.75rem var(--ifm-pre-padding); - text-transform: uppercase; - font-size: 12px; - font-weight: bold; -} - -.openapi-explorer__expand-details-btn { - &:hover { - cursor: pointer; - } -} - -.openapi-explorer__details-outer-container { - padding: 1rem; -} - -.openapi-explorer__details-container[open] { - .openapi-explorer__details-summary::before { - transform: rotate(180deg); - margin-top: 0.25rem; - } -} - -.openapi-explorer__details-summary { - display: inline-flex; - align-items: center; - padding: 0.35rem 0; - font-size: 14px; - list-style: none; - - &:hover { - cursor: pointer; - } - - &::-webkit-details-marker { - display: none; - } - - &::before { - margin-right: 0.25rem; - margin-bottom: 0.25rem; - margin-top: 0.25rem; - background-image: var(--openapi-explorer-caret-bg); - border: none !important; - transform: rotate(90deg); - content: ""; - height: 1rem; - width: 1rem; - } -} - -.openapi-explorer__request-btn { - border: none; - border-radius: var(--ifm-global-radius); - padding: 0.5rem 1rem; - margin-top: 1rem; - background-color: var(--ifm-color-primary-light); - text-transform: uppercase; - font-weight: bold; - font-size: 12px; - color: white; - cursor: pointer; - transition: 300ms; - - &:hover { - background-color: var(--ifm-color-primary-lightest); - } - - &:active { - background-color: var(--ifm-color-primary-light); - } -} - -.openapi-security__summary-container { - background: var(--ifm-pre-background); - border-radius: var(--ifm-pre-border-radius); -} - -// Prevent auto zoom on mobile iOS devices when focusing on input elmenents -@media screen and (-webkit-min-device-pixel-ratio: 0) and (max-device-width: 1024px) { - .prism-code, - select, - input { - font-size: 1rem; - } -} diff --git a/src/theme/ApiExplorer/Request/index.js b/src/theme/ApiExplorer/Request/index.js deleted file mode 100644 index b7da09305..000000000 --- a/src/theme/ApiExplorer/Request/index.js +++ /dev/null @@ -1,437 +0,0 @@ -"use strict"; -var __createBinding = - (this && this.__createBinding) || - (Object.create - ? function (o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if ( - !desc || - ("get" in desc ? !m.__esModule : desc.writable || desc.configurable) - ) { - desc = { - enumerable: true, - get: function () { - return m[k]; - }, - }; - } - Object.defineProperty(o, k2, desc); - } - : function (o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; - }); -var __setModuleDefault = - (this && this.__setModuleDefault) || - (Object.create - ? function (o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); - } - : function (o, v) { - o["default"] = v; - }); -var __importStar = - (this && this.__importStar) || - (function () { - var ownKeys = function (o) { - ownKeys = - Object.getOwnPropertyNames || - function (o) { - var ar = []; - for (var k in o) - if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; - return ar; - }; - return ownKeys(o); - }; - return function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) - for (var k = ownKeys(mod), i = 0; i < k.length; i++) - if (k[i] !== "default") __createBinding(result, mod, k[i]); - __setModuleDefault(result, mod); - return result; - }; - })(); -var __importDefault = - (this && this.__importDefault) || - function (mod) { - return mod && mod.__esModule ? mod : { default: mod }; - }; -Object.defineProperty(exports, "__esModule", { value: true }); -// @ts-nocheck -const react_1 = __importStar(require("react")); -const client_1 = require("@docusaurus/plugin-content-docs/client"); -const Translate_1 = require("@docusaurus/Translate"); -const Accept_1 = __importDefault(require("@theme/ApiExplorer/Accept")); -const Authorization_1 = __importDefault( - require("@theme/ApiExplorer/Authorization") -); -const Body_1 = __importDefault(require("@theme/ApiExplorer/Body")); -const buildPostmanRequest_1 = __importDefault( - require("@theme/ApiExplorer/buildPostmanRequest") -); -const ContentType_1 = __importDefault( - require("@theme/ApiExplorer/ContentType") -); -const ParamOptions_1 = __importDefault( - require("@theme/ApiExplorer/ParamOptions") -); -const slice_1 = require("@theme/ApiExplorer/Response/slice"); -const Server_1 = __importDefault(require("@theme/ApiExplorer/Server")); -const hooks_1 = require("@theme/ApiItem/hooks"); -const translationIds_1 = require("@theme/translationIds"); -const sdk = __importStar(require("postman-collection")); -const react_hook_form_1 = require("react-hook-form"); -const makeRequest_1 = __importDefault(require("./makeRequest")); -function Request({ item }) { - const postman = new sdk.Request(item.postman); - const metadata = (0, client_1.useDoc)(); - const { proxy, hide_send_button: hideSendButton } = metadata.frontMatter; - const pathParams = (0, hooks_1.useTypedSelector)( - (state) => state.params.path - ); - const queryParams = (0, hooks_1.useTypedSelector)( - (state) => state.params.query - ); - const cookieParams = (0, hooks_1.useTypedSelector)( - (state) => state.params.cookie - ); - const contentType = (0, hooks_1.useTypedSelector)( - (state) => state.contentType.value - ); - const headerParams = (0, hooks_1.useTypedSelector)( - (state) => state.params.header - ); - const body = (0, hooks_1.useTypedSelector)((state) => state.body); - const accept = (0, hooks_1.useTypedSelector)((state) => state.accept.value); - const acceptOptions = (0, hooks_1.useTypedDispatch)( - (state) => state.accept.options - ); - const authSelected = (0, hooks_1.useTypedSelector)( - (state) => state.auth.selected - ); - const server = (0, hooks_1.useTypedSelector)((state) => state.server.value); - const serverOptions = (0, hooks_1.useTypedSelector)( - (state) => state.server.options - ); - const auth = (0, hooks_1.useTypedSelector)((state) => state.auth); - const dispatch = (0, hooks_1.useTypedDispatch)(); - const [expandAccept, setExpandAccept] = (0, react_1.useState)(true); - const [expandAuth, setExpandAuth] = (0, react_1.useState)(true); - const [expandBody, setExpandBody] = (0, react_1.useState)(true); - const [expandParams, setExpandParams] = (0, react_1.useState)(true); - const [expandServer, setExpandServer] = (0, react_1.useState)(true); - const allParams = [ - ...pathParams, - ...queryParams, - ...cookieParams, - ...headerParams, - ]; - const postmanRequest = (0, buildPostmanRequest_1.default)(postman, { - queryParams, - pathParams, - cookieParams, - contentType, - accept, - headerParams, - body, - server, - auth, - }); - const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - const paramsObject = { - path: [], - query: [], - header: [], - cookie: [], - }; - item.parameters?.forEach((param) => { - const paramType = param.in; - const paramsArray = paramsObject[paramType]; - paramsArray.push(param); - }); - const methods = (0, react_hook_form_1.useForm)({ shouldFocusError: false }); - const handleEventStream = async (res) => { - res.headers && - dispatch((0, slice_1.setHeaders)(Object.fromEntries(res.headers))); - dispatch((0, slice_1.setCode)(res.status)); - const reader = res.body.getReader(); - const decoder = new TextDecoder(); - let result = ""; - while (true) { - const { done, value } = await reader.read(); - if (done) break; - result += decoder.decode(value, { stream: true }); - dispatch((0, slice_1.setResponse)(result)); - } - }; - const handleResponse = async (res) => { - dispatch((0, slice_1.setResponse)(await res.text())); - dispatch((0, slice_1.setCode)(res.status)); - res.headers && - dispatch((0, slice_1.setHeaders)(Object.fromEntries(res.headers))); - }; - const onSubmit = async (data) => { - dispatch( - (0, slice_1.setResponse)( - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.FETCHING_MESSAGE, - message: "Fetching...", - }) - ) - ); - try { - await delay(1200); - const res = await (0, makeRequest_1.default)(postmanRequest, proxy, body); - if (res.headers.get("content-type")?.includes("text/event-stream")) { - await handleEventStream(res); - } else { - await handleResponse(res); - } - } catch (e) { - console.log(e); - dispatch( - (0, slice_1.setResponse)( - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.CONNECTION_FAILED, - message: "Connection failed", - }) - ) - ); - dispatch((0, slice_1.clearCode)()); - dispatch((0, slice_1.clearHeaders)()); - } - }; - const showServerOptions = serverOptions.length > 0; - const showAcceptOptions = acceptOptions.length > 1; - const showRequestBody = contentType !== undefined; - const showRequestButton = item.servers && !hideSendButton; - const showAuth = authSelected !== undefined; - const showParams = allParams.length > 0; - const requestBodyRequired = item.requestBody?.required; - if ( - !showAcceptOptions && - !showAuth && - !showParams && - !showRequestBody && - !showServerOptions - ) { - return null; - } - const expandAllDetails = () => { - setExpandAccept(true); - setExpandAuth(true); - setExpandBody(true); - setExpandParams(true); - setExpandServer(true); - }; - const collapseAllDetails = () => { - setExpandAccept(false); - setExpandAuth(false); - setExpandBody(false); - setExpandParams(false); - setExpandServer(false); - }; - const allDetailsExpanded = - expandParams && expandBody && expandServer && expandAuth && expandAccept; - return react_1.default.createElement( - react_hook_form_1.FormProvider, - { ...methods }, - react_1.default.createElement( - "form", - { - className: "openapi-explorer__request-form", - onSubmit: methods.handleSubmit(onSubmit), - }, - react_1.default.createElement( - "div", - { className: "openapi-explorer__request-header-container" }, - react_1.default.createElement( - "span", - { className: "openapi-explorer__request-title" }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.REQUEST_TITLE, - message: "Request", - }) - ), - allDetailsExpanded - ? react_1.default.createElement( - "span", - { - className: "openapi-explorer__expand-details-btn", - onClick: collapseAllDetails, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.COLLAPSE_ALL, - message: "Collapse all", - }) - ) - : react_1.default.createElement( - "span", - { - className: "openapi-explorer__expand-details-btn", - onClick: expandAllDetails, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.EXPAND_ALL, - message: "Expand all", - }) - ) - ), - react_1.default.createElement( - "div", - { className: "openapi-explorer__details-outer-container" }, - showServerOptions && - item.method !== "event" && - react_1.default.createElement( - "details", - { - open: expandServer, - className: "openapi-explorer__details-container", - }, - react_1.default.createElement( - "summary", - { - className: "openapi-explorer__details-summary", - onClick: (e) => { - e.preventDefault(); - setExpandServer(!expandServer); - }, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.BASE_URL_TITLE, - message: "Base URL", - }) - ), - react_1.default.createElement(Server_1.default, null) - ), - showAuth && - react_1.default.createElement( - "details", - { - open: expandAuth, - className: "openapi-explorer__details-container", - }, - react_1.default.createElement( - "summary", - { - className: "openapi-explorer__details-summary", - onClick: (e) => { - e.preventDefault(); - setExpandAuth(!expandAuth); - }, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.AUTH_TITLE, - message: "Auth", - }) - ), - react_1.default.createElement(Authorization_1.default, null) - ), - showParams && - react_1.default.createElement( - "details", - { - open: - expandParams || Object.keys(methods.formState.errors).length, - className: "openapi-explorer__details-container", - }, - react_1.default.createElement( - "summary", - { - className: "openapi-explorer__details-summary", - onClick: (e) => { - e.preventDefault(); - setExpandParams(!expandParams); - }, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.PARAMETERS_TITLE, - message: "Parameters", - }) - ), - react_1.default.createElement(ParamOptions_1.default, null) - ), - showRequestBody && - react_1.default.createElement( - "details", - { - open: expandBody, - className: "openapi-explorer__details-container", - }, - react_1.default.createElement( - "summary", - { - className: "openapi-explorer__details-summary", - onClick: (e) => { - e.preventDefault(); - setExpandBody(!expandBody); - }, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.BODY_TITLE, - message: "Body", - }), - requestBodyRequired && - react_1.default.createElement( - "span", - { className: "openapi-schema__required" }, - "\u00A0", - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.REQUIRED_LABEL, - message: "required", - }) - ) - ), - react_1.default.createElement( - react_1.default.Fragment, - null, - react_1.default.createElement(ContentType_1.default, null), - react_1.default.createElement(Body_1.default, { - jsonRequestBodyExample: item.jsonRequestBodyExample, - requestBodyMetadata: item.requestBody, - required: requestBodyRequired, - }) - ) - ), - showAcceptOptions && - react_1.default.createElement( - "details", - { - open: expandAccept, - className: "openapi-explorer__details-container", - }, - react_1.default.createElement( - "summary", - { - className: "openapi-explorer__details-summary", - onClick: (e) => { - e.preventDefault(); - setExpandAccept(!expandAccept); - }, - }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.ACCEPT_TITLE, - message: "Accept", - }) - ), - react_1.default.createElement(Accept_1.default, null) - ), - showRequestButton && - item.method !== "event" && - react_1.default.createElement( - "button", - { className: "openapi-explorer__request-btn", type: "submit" }, - (0, Translate_1.translate)({ - id: translationIds_1.OPENAPI_REQUEST.SEND_BUTTON, - message: "Send API Request", - }) - ) - ) - ) - ); -} -exports.default = Request; diff --git a/src/theme/ApiExplorer/Request/makeRequest.js b/src/theme/ApiExplorer/Request/makeRequest.js deleted file mode 100644 index ca477ff12..000000000 --- a/src/theme/ApiExplorer/Request/makeRequest.js +++ /dev/null @@ -1,217 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function fetchWithtimeout(url, options, timeout = 30000) { - return Promise.race([ - fetch(url, options), - new Promise((_, reject) => - setTimeout(() => reject(new Error("Request timed out")), timeout) - ), - ]); -} -async function loadImage(content) { - return new Promise((accept, reject) => { - const reader = new FileReader(); - reader.onabort = () => { - console.log("file reading was aborted"); - reject(); - }; - reader.onerror = () => { - console.log("file reading has failed"); - reject(); - }; - reader.onload = () => { - // Do whatever you want with the file contents - const binaryStr = reader.result; - accept(binaryStr); - }; - reader.readAsArrayBuffer(content); - }); -} -async function makeRequest(request, proxy, _body) { - const headers = request.toJSON().header; - let myHeaders = new Headers(); - if (headers) { - headers.forEach((header) => { - if (header.key && header.value) { - myHeaders.append(header.key, header.value); - } - }); - } - // The following code handles multiple files in the same formdata param. - // It removes the form data params where the src property is an array of filepath strings - // Splits that array into different form data params with src set as a single filepath string - // TODO: - // if (request.body && request.body.mode === 'formdata') { - // let formdata = request.body.formdata, - // formdataArray = []; - // formdata.members.forEach((param) => { - // let key = param.key, - // type = param.type, - // disabled = param.disabled, - // contentType = param.contentType; - // // check if type is file or text - // if (type === 'file') { - // // if src is not of type string we check for array(multiple files) - // if (typeof param.src !== 'string') { - // // if src is an array(not empty), iterate over it and add files as separate form fields - // if (Array.isArray(param.src) && param.src.length) { - // param.src.forEach((filePath) => { - // addFormParam( - // formdataArray, - // key, - // param.type, - // filePath, - // disabled, - // contentType - // ); - // }); - // } - // // if src is not an array or string, or is an empty array, add a placeholder for file path(no files case) - // else { - // addFormParam( - // formdataArray, - // key, - // param.type, - // '/path/to/file', - // disabled, - // contentType - // ); - // } - // } - // // if src is string, directly add the param with src as filepath - // else { - // addFormParam( - // formdataArray, - // key, - // param.type, - // param.src, - // disabled, - // contentType - // ); - // } - // } - // // if type is text, directly add it to formdata array - // else { - // addFormParam( - // formdataArray, - // key, - // param.type, - // param.value, - // disabled, - // contentType - // ); - // } - // }); - // request.body.update({ - // mode: 'formdata', - // formdata: formdataArray, - // }); - // } - const body = request.body?.toJSON(); - let myBody = undefined; - if (body !== undefined && Object.keys(body).length > 0) { - switch (body.mode) { - case "urlencoded": { - myBody = new URLSearchParams(); - if (Array.isArray(body.urlencoded)) { - for (const data of body.urlencoded) { - if (data.key && data.value) { - myBody.append(data.key, data.value); - } - } - } - break; - } - case "raw": { - myBody = (body.raw ?? "").toString(); - break; - } - case "formdata": { - // The Content-Type header will be set automatically based on the type of body. - myHeaders.delete("Content-Type"); - myBody = new FormData(); - const members = request.body?.formdata?.members; - if (Array.isArray(members)) { - for (const data of members) { - if (data.key && data.value.content) { - myBody.append(data.key, data.value.content); - } - // handle generic key-value payload - if (data.key && typeof data.value === "string") { - myBody.append(data.key, data.value); - } - } - } - break; - } - case "file": { - if (_body.type === "raw" && _body.content?.type === "file") { - myBody = await loadImage(_body.content.value.content); - } - break; - } - default: - break; - } - } - const requestOptions = { - method: request.method, - headers: myHeaders, - body: myBody, - }; - let finalUrl = request.url.toString(); - if (proxy) { - // Ensure the proxy ends with a slash. - let normalizedProxy = proxy.replace(/\/$/, "") + "/"; - finalUrl = normalizedProxy + request.url.toString(); - } - return fetchWithtimeout(finalUrl, requestOptions).then((response) => { - const contentType = response.headers.get("content-type"); - let fileExtension = ""; - if (contentType) { - if (contentType.includes("application/pdf")) { - fileExtension = ".pdf"; - } else if (contentType.includes("image/jpeg")) { - fileExtension = ".jpg"; - } else if (contentType.includes("image/png")) { - fileExtension = ".png"; - } else if (contentType.includes("image/gif")) { - fileExtension = ".gif"; - } else if (contentType.includes("image/webp")) { - fileExtension = ".webp"; - } else if (contentType.includes("video/mpeg")) { - fileExtension = ".mpeg"; - } else if (contentType.includes("video/mp4")) { - fileExtension = ".mp4"; - } else if (contentType.includes("audio/mpeg")) { - fileExtension = ".mp3"; - } else if (contentType.includes("audio/ogg")) { - fileExtension = ".ogg"; - } else if (contentType.includes("application/octet-stream")) { - fileExtension = ".bin"; - } else if (contentType.includes("application/zip")) { - fileExtension = ".zip"; - } - if (fileExtension) { - return response.blob().then((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}`); - // These two lines are necessary to make the link click in Firefox - link.style.display = "none"; - document.body.appendChild(link); - link.click(); - // After link is clicked, it's safe to remove it. - setTimeout(() => document.body.removeChild(link), 0); - return response; - }); - } else { - return response; - } - } - return response; - }); -} -exports.default = makeRequest; diff --git a/yarn.lock b/yarn.lock index 5e99b4f99..e47f6f300 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5905,10 +5905,10 @@ dns-packet@^5.2.2: dependencies: "@leichtgewicht/ip-codec" "^2.0.1" -docusaurus-plugin-openapi-docs@5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-5.0.2.tgz#f00028621deb9179065fe7d6a541256692ef941b" - integrity sha512-WCC2m6PpylXZfNga+ScelTG0a7jUGtbB9+AmbR9lUj93FPryTs8VHTMJ3fKtO0senJTWgOU3MDvZw0v+mE3ztA== +docusaurus-plugin-openapi-docs@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-5.1.2.tgz#1ef66a26d80e2a3baf4caae4e72a0dcf85c6d608" + integrity sha512-xlgl/8+2iqSQWdhTJay0lfXqWduaGVTYrn+9i+uT3Uk5gkeDjfQOIVnHGnIHfKg0pUjIm008fvEQVAxk3TvgaQ== dependencies: "@apidevtools/json-schema-ref-parser" "^15.3.3" "@redocly/openapi-core" "^2.25.2" @@ -5933,10 +5933,10 @@ docusaurus-plugin-sass@^0.2.2: dependencies: sass-loader "^16.0.2" -docusaurus-theme-openapi-docs@5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-5.0.2.tgz#2ab6f6b04fc2e494e24971d31432a9187c84a2fe" - integrity sha512-BD6WhbunR6kXqtoUUDlhxO4HlCNM2nYENGr/TbiTEknkgXYKQz+FEIhY4Hyz5GSLpuhPih0CDuNl7Xkfpcz0Yw== +docusaurus-theme-openapi-docs@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-5.1.2.tgz#8591e3be971920c5eb347b9aab4bac77db5c7c31" + integrity sha512-uJx+a4qHmpOnl+e7YzsPJSga6d6TLGEVZZPtI7KkzC/PgG7bS8E4P8hknvWqmAEahxhLWEb8izIA3up/0g9RwA== dependencies: "@hookform/error-message" "^2.0.1" "@reduxjs/toolkit" "^2.8.2"