/* ============================================================================ * Copyright (c) Palo Alto Networks * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * ========================================================================== */ import React from "react"; import BrowserOnly from "@docusaurus/BrowserOnly"; import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment"; import { DocProvider } from "@docusaurus/plugin-content-docs/client"; import { HtmlClassNameProvider } from "@docusaurus/theme-common"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import useIsBrowser from "@docusaurus/useIsBrowser"; import { createAuth } from "@theme/ApiExplorer/Authorization/slice"; import { createPersistenceMiddleware } from "@theme/ApiExplorer/persistenceMiddleware"; import { createStorage } from "@theme/ApiExplorer/storage-utils"; import DocItemLayout from "@theme/ApiItem/Layout"; import CodeBlock from "@theme/CodeBlock"; import type { Props } from "@theme/DocItem"; import DocItemMetadata from "@theme/DocItem/Metadata"; import SkeletonLoader from "@theme/SkeletonLoader"; import clsx from "clsx"; import type { ParameterObject, ServerObject, } from "docusaurus-plugin-openapi-docs/src/openapi/types"; import type { ApiItem as ApiItemType } from "docusaurus-plugin-openapi-docs/src/types"; import type { DocFrontMatter, ThemeConfig, } from "docusaurus-theme-openapi-docs/src/types"; import { ungzip } from "pako"; import { Provider } from "react-redux"; import { createStoreWithoutState, createStoreWithState } from "./store"; let ApiExplorer = (_: { item: any; infoPath: any }) =>
; if (ExecutionEnvironment.canUseDOM) { ApiExplorer = require("@theme/ApiExplorer").default; } interface ApiFrontMatter extends DocFrontMatter { readonly api?: ApiItemType; } interface SchemaFrontMatter extends DocFrontMatter { readonly schema?: boolean; } interface SampleFrontMatter extends DocFrontMatter { readonly sample?: any; } function base64ToUint8Array(base64: string) { const binary = atob(base64); const len = binary.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binary.charCodeAt(i); } return bytes; } // @ts-ignore export default function ApiItem(props: Props): JSX.Element { const docHtmlClassName = `docs-doc-id-${props.content.metadata.id}`; const MDXComponent = props.content; const { frontMatter } = MDXComponent; const { info_path: infoPath } = frontMatter as DocFrontMatter; let { api } = frontMatter as ApiFrontMatter; const { schema } = frontMatter as SchemaFrontMatter; const { sample } = frontMatter as SampleFrontMatter; // decompress and parse if (api) { try { api = JSON.parse( new TextDecoder().decode(ungzip(base64ToUint8Array(api as any))) ); } catch {} } const { siteConfig } = useDocusaurusContext(); const themeConfig = siteConfig.themeConfig as ThemeConfig; const options = themeConfig.api; const isBrowser = useIsBrowser(); // Regex for 2XX status const statusRegex = new RegExp("(20[0-9]|2[1-9][0-9])"); // Define store2 let store2: any = {}; const persistenceMiddleware = createPersistenceMiddleware(options); // Init store for SSR if (!isBrowser) { store2 = createStoreWithoutState({}, [persistenceMiddleware]); } // Init store for CSR to hydrate components if (isBrowser) { // Create list of only 2XX response content types to create request samples from let acceptArray: any = []; for (const [code, content] of Object.entries(api?.responses ?? [])) { if (statusRegex.test(code)) { acceptArray.push(Object.keys(content.content ?? {})); } } acceptArray = acceptArray.flat(); const content = api?.requestBody?.content ?? {}; const contentTypeArray = Object.keys(content); const servers = api?.servers ?? []; const params = { path: [] as ParameterObject[], query: [] as ParameterObject[], header: [] as ParameterObject[], cookie: [] as ParameterObject[], }; api?.parameters?.forEach( (param: { in: "path" | "query" | "header" | "cookie" }) => { const paramType = param.in; const paramsArray: ParameterObject[] = params[paramType]; paramsArray?.push(param as ParameterObject); } ); const auth = createAuth({ security: api?.security, securitySchemes: api?.securitySchemes, options, }); const storage = createStorage(options?.authPersistence ?? "sessionStorage"); // TODO: determine way to rehydrate without flashing // const acceptValue = window?.sessionStorage.getItem("accept"); // const contentTypeValue = window?.sessionStorage.getItem("contentType"); const server = storage.getItem("server"); const serverObject = server ? (JSON.parse(server) as ServerObject) : undefined; store2 = createStoreWithState( { accept: { value: acceptArray[0], options: acceptArray, }, contentType: { value: contentTypeArray[0], options: contentTypeArray, }, server: { value: serverObject?.url ? serverObject : undefined, options: servers, }, response: { value: undefined }, body: { type: "empty" }, params, auth, schemaSelection: { selections: {} }, encodingSelection: {}, }, [persistenceMiddleware] ); } if (api) { return (