API Page
This is the entry point and is responsible for rendering your api docs.
Installation
npx shadcn@latest add http://fumastudio/com/r/api-page.jsonimport { BaseURL } from "@/components/fumastudio/base-url";
import { DocsFooter } from "@/components/fumastudio/footer";
import { MockRequestProvider } from "@/components/fumastudio/mock-request";
import { Navigation } from "@/components/fumastudio/navigation";
import { PageContext } from "@/components/fumastudio/page-context";
import { SchemaProvider } from "@/components/fumastudio/schema";
import {
AuthorizationScheme,
PathParamsSchema,
QueryParamsSchema,
RequestBodySchema,
ResponseBodySchema,
} from "@/components/fumastudio/scheme";
import {
RequestSnippets,
ResponseSnippets,
} from "@/components/fumastudio/snippet";
import { HttpCode, httpCodes } from "@/lib/http-codes";
import {
type APIPageRequest,
type loaderCtx,
type Snippet,
} from "@trythis/nextjs";
import { getHttpCodes, normalizeServers } from "@trythis/nextjs/utils";
export type ApiPageProps = {
request: APIPageRequest;
requestSnippets: Snippet[];
responseSnippets: Snippet[];
schema: string | undefined;
// Ctx provided as prop by collection loader
loaderCtx: loaderCtx["loaderCtx"];
};
const APIPage = async ({
request,
requestSnippets,
responseSnippets,
schema = "",
loaderCtx,
}: ApiPageProps) => {
const authScheme = loaderCtx.auth;
const serverScheme = loaderCtx.servers;
const navigation = loaderCtx.navigation;
const pageEntry = loaderCtx.pageEntry;
const requestBodySchema = loaderCtx.requestBodySchema;
const paramsQuerySchema = loaderCtx.paramsQuerySchema;
const paramsPathSchema = loaderCtx.paramsPathSchema;
const responseBodySchema = loaderCtx.responseBodySchema;
const responseBodyMock = loaderCtx.responseBodyMock;
const servers = normalizeServers(serverScheme);
const httpStatusCodes = getHttpCodes(
responseBodySchema,
httpCodes as unknown as HttpCode[],
);
return (
<MockRequestProvider
proxyPath="/api/proxy"
baseURL={request.url}
intialRequests={[]}
currentRequest={pageEntry}
responseSnippets={responseSnippets}
authSchemes={authScheme}
servers={servers}
defaultRequestBody={responseBodyMock}>
<div className="w-full h-full">
<header className="relative font-sans">
<div className="mt-0.5 space-y-2.5">
<div className="h-5 text-sm font-semibold text-primary dark:text-primary-light">
{request.folder}
</div>
<div className="relative flex flex-col items-start gap-2 sm:flex-row sm:items-center">
<h1 className="inline-block text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl dark:text-gray-200">
{request.name}
</h1>
<div className="items-center shrink-0 min-w-39 justify-end ml-auto sm:flex hidden">
<PageContext schema={schema} />
</div>
</div>
</div>
<div className="mt-2 text-lg prose prose-gray dark:prose-invert">
<p>{request.description}</p>
</div>
</header>
<BaseURL url={request.url} method={request.method} />
<div className="flex flex-col bg-accent border-input border gap-0 mt-6 px-1.5 pb-1.5 rounded-xl">
<RequestSnippets snippets={requestSnippets} />
</div>
<div className="flex flex-col bg-accent border-input border gap-0 mt-6 px-1.5 pb-1.5 rounded-xl">
<ResponseSnippets snippets={responseSnippets} />
</div>
<SchemaProvider>
{authScheme && authScheme.length > 0 && (
<div className="mt-8 font-sans">
<AuthorizationScheme
schema={authScheme}
/>
</div>
)}
{paramsQuerySchema && (
<div className="mt-6 font-sans">
<QueryParamsSchema
schema={paramsQuerySchema}
/>
</div>
)}
{paramsPathSchema && (
<div className="mt-6 font-sans">
<PathParamsSchema
schema={paramsPathSchema}
/>
</div>
)}
{requestBodySchema && (
<div className="mt-6 font-sans">
<RequestBodySchema
schema={requestBodySchema}
/>
</div>
)}
{httpCodes && responseBodySchema && (
<div className="mt-6 font-sans">
<ResponseBodySchema
httpCodes={httpStatusCodes}
schema={responseBodySchema}
/>
</div>
)}
</SchemaProvider>
{navigation && (
<Navigation
previous={navigation.previous}
next={navigation.next}
/>
)}
<DocsFooter />
</div>
</MockRequestProvider>
);
};
export { APIPage };
Usage
import { APIPage } from "@/components/fumastudio/api-page";
import * as AllLucideIcons from "lucide-react";
type MDXComponents = any;
export const useIcons = (): any => {
return AllLucideIcons;
};
const components: MDXComponents = {
ApiPage: APIPage,
};
// Override or add your mdx components here
export function useMDXComponents(
defaultComponents?: MDXComponents,
): MDXComponents {
return {
...defaultComponents,
...components,
};
}