Checkpoint

This commit is contained in:
2026-07-26 02:20:45 -03:00
parent f04cbb7e02
commit 0f506ec19e
38 changed files with 1757 additions and 154 deletions
+67
View File
@@ -0,0 +1,67 @@
import { getPageImageUrl, getPageMarkdownUrl, source } from "@/lib/source";
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
MarkdownCopyButton,
ViewOptionsPopover,
} from "fumadocs-ui/layouts/docs/page";
import { notFound } from "next/navigation";
import { getMDXComponents } from "@/components/mdx";
import type { Metadata } from "next";
import { createRelativeLink } from "fumadocs-ui/mdx";
import { gitConfig } from "@/lib/shared";
export default async function Page(props: PageProps<"/[[...slug]]">) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) notFound();
const MDX = page.data.body;
const markdownUrl = getPageMarkdownUrl(page).url;
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription className="mb-0">
{page.data.description}
</DocsDescription>
<div className="flex flex-row gap-2 items-center border-b pb-6">
<MarkdownCopyButton markdownUrl={markdownUrl} />
<ViewOptionsPopover
markdownUrl={markdownUrl}
githubUrl={`https://github.com/${gitConfig.user}/${gitConfig.repo}/blob/${gitConfig.branch}/content/docs/${page.path}`}
/>
</div>
<DocsBody>
<MDX
components={getMDXComponents({
// this allows you to link to other pages with relative file paths
a: createRelativeLink(source, page),
})}
/>
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
return source.generateParams();
}
export async function generateMetadata(
props: PageProps<"/[[...slug]]">,
): Promise<Metadata> {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) notFound();
return {
title: page.data.title,
description: page.data.description,
openGraph: {
images: getPageImageUrl(page).url,
},
};
}
+11
View File
@@ -0,0 +1,11 @@
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({ children }: LayoutProps<'/'>) {
return (
<DocsLayout tree={source.getPageTree()} {...baseOptions()}>
{children}
</DocsLayout>
);
}
+9
View File
@@ -0,0 +1,9 @@
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
export const revalidate = false;
export const { staticGET: GET } = createFromSource(source, {
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
+12
View File
@@ -0,0 +1,12 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
html {
scrollbar-gutter: stable;
}
html > body[data-scroll-locked] {
margin-right: 0px !important;
--removed-body-scroll-bar-size: 0px !important;
}
+17
View File
@@ -0,0 +1,17 @@
import { Inter } from 'next/font/google';
import { Provider } from '@/components/provider';
import './global.css';
const inter = Inter({
subsets: ['latin'],
});
export default function Layout({ children }: LayoutProps<'/'>) {
return (
<html lang="en" className={inter.className} suppressHydrationWarning>
<body className="flex flex-col min-h-screen">
<Provider>{children}</Provider>
</body>
</html>
);
}
+10
View File
@@ -0,0 +1,10 @@
import { getLLMText, source } from '@/lib/source';
export const revalidate = false;
export async function GET() {
const scan = source.getPages().map(getLLMText);
const scanned = await Promise.all(scan);
return new Response(scanned.join('\n\n'));
}
@@ -0,0 +1,23 @@
import { getLLMText, getPageMarkdownUrl, source } from '@/lib/source';
import { notFound } from 'next/navigation';
export const revalidate = false;
export async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/docs/[[...slug]]'>) {
const { slug } = await params;
// remove the appended "content.md"
const page = source.getPage(slug?.slice(0, -1));
if (!page) notFound();
return new Response(await getLLMText(page), {
headers: {
'Content-Type': 'text/markdown',
},
});
}
export function generateStaticParams() {
return source.getPages().map((page) => ({
slug: getPageMarkdownUrl(page).segments,
}));
}
+8
View File
@@ -0,0 +1,8 @@
import { source } from '@/lib/source';
import { llms } from 'fumadocs-core/source';
export const revalidate = false;
export function GET() {
return new Response(llms(source).index());
}
+29
View File
@@ -0,0 +1,29 @@
import { getPageImageUrl, source } from '@/lib/source';
import { notFound } from 'next/navigation';
import { ImageResponse } from 'takumi-js/response';
import { generate as DefaultImage } from 'fumadocs-ui/og/takumi';
import { appName } from '@/lib/shared';
export const revalidate = false;
export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
const { slug } = await params;
const page = source.getPage(slug.slice(0, -1));
if (!page) notFound();
return new ImageResponse(
<DefaultImage title={page.data.title} description={page.data.description} site={appName} />,
{
width: 1200,
height: 630,
format: 'webp',
},
);
}
export function generateStaticParams() {
return source.getPages().map((page) => ({
lang: page.locale,
slug: getPageImageUrl(page).segments,
}));
}
+49
View File
@@ -0,0 +1,49 @@
'use client';
import { Image, type ImageProps } from 'fumadocs-core/framework';
import type { ComponentProps } from 'react';
import Zoom, { type UncontrolledProps } from 'react-medium-image-zoom';
import '../styles/image-zoom.css';
export type ImageZoomProps = ImageProps & {
/**
* Image props when zoom in
*/
zoomInProps?: ComponentProps<'img'>;
/**
* Props for `react-medium-image-zoom`
*/
rmiz?: UncontrolledProps;
};
function getImageSrc(src: ImageProps['src']): string {
if (typeof src === 'string') return src;
if (typeof src === 'object') {
// Next.js
if ('default' in src) return (src as { default: { src: string } }).default.src;
return src.src;
}
return '';
}
export function ImageZoom({ zoomInProps, children, rmiz, ...props }: ImageZoomProps) {
return (
<Zoom
zoomMargin={20}
wrapElement="span"
{...rmiz}
zoomImg={{
src: getImageSrc(props.src),
sizes: undefined,
...zoomInProps,
}}
>
{children ?? (
<Image sizes="(max-width: 768px) 100vw, (max-width: 1200px) 70vw, 900px" {...props} />
)}
</Zoom>
);
}
+18
View File
@@ -0,0 +1,18 @@
import defaultMdxComponents from "fumadocs-ui/mdx";
import Image from "next/image";
import type { MDXComponents } from "mdx/types";
export function getMDXComponents(components?: MDXComponents) {
return {
...defaultMdxComponents,
img: (props) => <Image {...(props as any)} />,
...components,
} satisfies MDXComponents;
}
export const useMDXComponents = getMDXComponents;
declare global {
type MDXProvidedComponents = ReturnType<typeof getMDXComponents>;
}
+8
View File
@@ -0,0 +1,8 @@
'use client';
import SearchDialog from '@/components/search';
import { RootProvider } from 'fumadocs-ui/provider/next';
import { type ReactNode } from 'react';
export function Provider({ children }: { children: ReactNode }) {
return <RootProvider search={{ SearchDialog }}>{children}</RootProvider>;
}
+48
View File
@@ -0,0 +1,48 @@
'use client';
import {
SearchDialog,
SearchDialogClose,
SearchDialogContent,
SearchDialogHeader,
SearchDialogIcon,
SearchDialogInput,
SearchDialogList,
SearchDialogOverlay,
type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
import { useDocsSearch } from 'fumadocs-core/search/client';
import { oramaStaticClient } from 'fumadocs-core/search/client/orama-static';
import { create } from '@orama/orama';
import { useI18n } from 'fumadocs-ui/contexts/i18n';
function initOrama() {
return create({
schema: { _: 'string' },
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
}
export default function DefaultSearchDialog(props: SharedProps) {
const { locale } = useI18n(); // (optional) for i18n
const { search, setSearch, query } = useDocsSearch({
client: oramaStaticClient({
initOrama,
locale,
}),
});
return (
<SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
<SearchDialogOverlay />
<SearchDialogContent>
<SearchDialogHeader>
<SearchDialogIcon />
<SearchDialogInput />
<SearchDialogClose />
</SearchDialogHeader>
<SearchDialogList items={query.data !== 'empty' ? query.data : null} />
</SearchDialogContent>
</SearchDialog>
);
}
+1
View File
@@ -0,0 +1 @@
export { cn } from 'cnfast';
+12
View File
@@ -0,0 +1,12 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import { appName, gitConfig } from './shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
// JSX supported
title: appName,
},
githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
};
}
+11
View File
@@ -0,0 +1,11 @@
export const appName = 'Duckity';
export const docsRoute = '/';
export const docsImageRoute = '/og/docs';
export const docsContentRoute = '/llms.mdx/docs';
// fill this with your actual GitHub info, for example:
export const gitConfig = {
user: 'duckity',
repo: 'documentation',
branch: 'main',
};
+54
View File
@@ -0,0 +1,54 @@
import { docs } from "collections/server";
import { loader } from "fumadocs-core/source";
import { icons } from "lucide-react";
import { createElement } from "react";
import { docsContentRoute, docsImageRoute, docsRoute } from "./shared";
// See https://fumadocs.dev/docs/headless/source-api for more info
export const source = loader({
baseUrl: docsRoute,
source: docs.toFumadocsSource(),
plugins: [],
icon(icon) {
if (!icon) {
// You may set a default icon
return;
}
if (icon in icons) return createElement(icons[icon as keyof typeof icons]);
},
});
export function getPageImageUrl(page: (typeof source)["$inferPage"]) {
const segments = [...page.slugs, "image.webp"];
return {
segments,
url:
"/" +
[page.locale, ...docsImageRoute.split("/"), ...segments]
.filter(Boolean)
.join("/"),
};
}
export function getPageMarkdownUrl(page: (typeof source)["$inferPage"]) {
const segments = [...page.slugs, "content.md"];
return {
segments,
url:
"/" +
[page.locale, ...docsContentRoute.split("/"), ...segments]
.filter(Boolean)
.join("/"),
};
}
export async function getLLMText(page: (typeof source)["$inferPage"]) {
const processed = await page.data.getText("processed");
return `# ${page.data.title} (${page.url})
${processed}`;
}
+77
View File
@@ -0,0 +1,77 @@
[data-rmiz] {
display: block;
position: relative;
}
[data-rmiz-ghost] {
pointer-events: none;
position: absolute;
}
[data-rmiz-btn-zoom],
[data-rmiz-btn-unzoom] {
display: none;
}
[data-rmiz-content='found'] img {
cursor: zoom-in;
}
[data-rmiz-modal][open] {
width: 100vw /* fallback */;
width: 100dvw;
height: 100vh /* fallback */;
height: 100dvh;
background-color: transparent;
max-width: none;
max-height: none;
margin: 0;
padding: 0;
position: fixed;
overflow: hidden;
}
[data-rmiz-modal]:focus-visible {
outline: none;
}
[data-rmiz-modal-overlay] {
transition: background-color 0.3s;
position: absolute;
inset: 0;
}
[data-rmiz-modal-overlay='visible'] {
background-color: var(--color-fd-background);
}
[data-rmiz-modal-overlay='hidden'] {
background-color: transparent;
}
[data-rmiz-modal-content] {
width: 100%;
height: 100%;
position: relative;
}
[data-rmiz-modal]::backdrop {
display: none;
}
[data-rmiz-modal-img] {
cursor: zoom-out;
image-rendering: high-quality;
transform-origin: 0 0;
transition: transform 0.3s;
position: absolute;
}
@media (prefers-reduced-motion: reduce) {
[data-rmiz-modal-overlay],
[data-rmiz-modal-img] {
transition-duration: 0.01ms !important;
}
}