Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 36 additions & 30 deletions docs/app/(docs)/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as Twoslash from 'fumadocs-twoslash/ui';
import { Callout } from 'fumadocs-ui/components/callout';
import { TypeTable } from 'fumadocs-ui/components/type-table';
import * as Preview from '@/components/preview';
import { createMetadata } from '@/lib/metadata';
import { createMetadata, getPageImage } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Wrapper } from '@/components/preview/wrapper';
import { Mermaid } from '@/components/mdx/mermaid';
Expand All @@ -16,21 +16,21 @@ import {
HoverCardTrigger,
} from '@/components/ui/hover-card';
import Link from 'fumadocs-core/link';
import { AutoTypeTable } from 'fumadocs-typescript/ui';
import { createGenerator } from 'fumadocs-typescript';
import { getPageTreePeers } from 'fumadocs-core/page-tree';
import { Card, Cards } from 'fumadocs-ui/components/card';
import { getMDXComponents } from '@/mdx-components';
import { APIPage } from 'fumadocs-openapi/ui';
import { LLMCopyButton, ViewOptions } from '@/components/ai/page-actions';
import * as path from 'node:path';
import { Banner } from 'fumadocs-ui/components/banner';
import { openapi } from '@/lib/openapi';
import { Installation } from '@/components/preview/installation';
import { Customisation } from '@/components/preview/customisation';
import { DocsPage } from 'fumadocs-ui/page';
import {
DocsBody,
DocsPage,
PageLastUpdate,
} from 'fumadocs-ui/layouts/docs/page';
import { NotFound } from '@/components/not-found';
// import { getSuggestions } from '@/app/(docs)/[...slug]/suggestions';
import { PathUtils } from 'fumadocs-core/source';

function PreviewRenderer({ preview }: { preview: string }): ReactNode {
if (preview && preview in Preview) {
Expand All @@ -41,8 +41,6 @@ function PreviewRenderer({ preview }: { preview: string }): ReactNode {
return null;
}

const generator = createGenerator();

export const revalidate = false;

export default async function Page(props: PageProps<'/[...slug]'>) {
Expand All @@ -55,51 +53,62 @@ export default async function Page(props: PageProps<'/[...slug]'>) {
<NotFound getSuggestions={() => Promise.resolve([])} />
);

const preview = page.data.preview;
const { body: Mdx, toc, lastModified } = page.data;
if (page.data.type === 'openapi') {
const { APIPage } = await import('@/components/api-page');
return (
<DocsPage full>
<h1 className="text-[1.75em] font-semibold">{page.data.title}</h1>

<DocsBody>
<APIPage {...page.data.getAPIPageProps()} />
</DocsBody>
</DocsPage>
);
}

const { body: Mdx, toc, lastModified } = await page.data.load();

return (
<DocsPage
toc={toc}
lastUpdate={lastModified ? new Date(lastModified) : undefined}
tableOfContent={{
style: 'clerk',
}}
>
<h1 className="text-[1.75em] font-semibold">{page.data.title}</h1>
<p className="text-lg text-fd-muted-foreground">
<p className="text-lg text-fd-muted-foreground mb-2">
{page.data.description}
</p>
<div className="flex flex-row gap-2 items-center border-b pt-2 pb-6">
<div className="flex flex-row flex-wrap gap-2 items-center border-b pb-6">
<LLMCopyButton markdownUrl={`${page.url}.mdx`} />
<ViewOptions
markdownUrl={`${page.url}.mdx`}
githubUrl={`https://github.com/${owner}/${repo}/blob/master/docs/content/docs/${page.path}`}
/>
</div>
<div className="prose flex-1 text-fd-foreground/90">
{preview ? <PreviewRenderer preview={preview} /> : null}
{page.data.preview && <PreviewRenderer preview={page.data.preview} />}
<Mdx
components={getMDXComponents({
...Twoslash,
a: ({ href, ...props }) => {
const found = source.getPageByHref(href ?? '', {
dir: path.dirname(page.path),
dir: PathUtils.dirname(page.path),
});

if (!found) return <Link href={href} {...props} />;

return (
<HoverCard>
<HoverCardTrigger asChild>
<Link
href={
found.hash
? `${found.page.url}#${found.hash}`
: found.page.url
}
{...props}
/>
<HoverCardTrigger
href={
found.hash
? `${found.page.url}#${found.hash}`
: found.page.url
}
{...props}
>
{props.children}
</HoverCardTrigger>
<HoverCardContent className="text-sm">
<p className="font-medium">{found.page.data.title}</p>
Expand All @@ -113,12 +122,8 @@ export default async function Page(props: PageProps<'/[...slug]'>) {
Banner,
Mermaid,
TypeTable,
AutoTypeTable: (props) => (
<AutoTypeTable generator={generator} {...props} />
),
Wrapper,
blockquote: Callout as unknown as FC<ComponentProps<'blockquote'>>,
APIPage: (props) => <APIPage {...openapi.getAPIPageProps(props)} />,
DocsCategory: ({ url }) => {
return <DocsCategory url={url ?? page.url} />;
},
Expand All @@ -129,6 +134,7 @@ export default async function Page(props: PageProps<'/[...slug]'>) {
{page.data.index ? <DocsCategory url={page.url} /> : null}
</div>
<Feedback onRateAction={onRateAction} />
{lastModified && <PageLastUpdate date={lastModified} />}
</DocsPage>
);
}
Expand Down Expand Up @@ -159,7 +165,7 @@ export async function generateMetadata(
page.data.description ?? 'The platform for building ai-driven automations';

const image = {
url: ['/og', ...slug, 'image.webp'].join('/'),
url: getPageImage(page).url,
width: 1200,
height: 630,
};
Expand Down
16 changes: 6 additions & 10 deletions docs/app/(docs)/[...slug]/suggestions.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { OramaClient } from '@oramacloud/client';
import type { Suggestion } from '@/components/not-found';

const client = new OramaClient({
endpoint: 'https://cloud.orama.run/v1/indexes/docs-fk97oe',
api_key: '',
});
import { DataSourceId, orama } from '@/lib/orama/client';

export async function getSuggestions(pathname: string): Promise<Suggestion[]> {
const results = await client.search({
const results = await orama.search({
term: pathname,
mode: 'vector',
datasources: [DataSourceId],
groupBy: {
properties: ['url'],
maxResult: 1,
max_results: 1,
},
});

Expand All @@ -23,8 +19,8 @@ export async function getSuggestions(pathname: string): Promise<Suggestion[]> {

return {
id: doc.id,
href: doc.document.url,
title: doc.document.title,
href: doc.document.url as string,
title: doc.document.title as string,
};
});
}
14 changes: 10 additions & 4 deletions docs/app/(docs)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions, linkItems, logo } from '@/lib/layout.shared';
import { source } from '@/lib/source';
// import { AISearchTrigger } from '@/components/ai/search';
import {
AISearch,
AISearchPanel,
AISearchTrigger,
} from '@/components/ai/search';
import 'katex/dist/katex.min.css';

export default function Layout({ children }: LayoutProps<'/'>) {
Expand All @@ -11,15 +15,14 @@ export default function Layout({ children }: LayoutProps<'/'>) {
<DocsLayout
{...base}
tree={source.pageTree}

// just icon items
links={linkItems.filter((item) => item.type === 'icon')}
nav={{
...base.nav,
title: (
<>
{logo}
<span className="font-medium [.uwu_&]:hidden max-md:hidden">
<span className="font-medium in-[.uwu]:hidden max-md:hidden">
ByteChef
</span>
</>
Expand Down Expand Up @@ -54,7 +57,10 @@ export default function Layout({ children }: LayoutProps<'/'>) {
>
{children}

{/*<AISearchTrigger />*/}
{/*<AISearch>*/}
{/* <AISearchPanel />*/}
{/* <AISearchTrigger />*/}
{/*</AISearch>*/}
</DocsLayout>
);
}
26 changes: 24 additions & 2 deletions docs/app/api/search/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
import { createSearchAPI } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(source);
export const { GET } = createSearchAPI('advanced', {
language: 'english',
indexes: async () => {
const pages = source.getPages();
const indexes = await Promise.all(
pages.map(async (page) => {
if (page.data.type === 'openapi') return undefined;

const loaded = await page.data.load();

return {
title: page.data.title,
description: page.data.description,
url: page.url,
id: page.url,
structuredData: loaded.structuredData,
};
}),
);

return indexes.filter((v): v is NonNullable<typeof v> => v !== undefined);
},
});
39 changes: 34 additions & 5 deletions docs/app/global.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
@import 'tailwindcss' source(none);
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import 'fumadocs-twoslash/twoslash.css';
@import 'fumadocs-openapi/css/preset.css';

@plugin 'tailwindcss-animate';

@theme {
--spacing-page: 1436px;
--color-brand: hsl(26, 73%, 51%);
--color-brand-foreground: white;
--color-brand-secondary: #c6bb58;
--color-brand-secondary-foreground: #97890c;
--color-brand-200: hsl(33, 100%, 50%);

--color-landing-foreground: #59592a;
--color-landing-foreground-200: #a8a866;
}

.dark {
--color-landing-foreground: #e4e2d0;
--color-landing-foreground-200: #b7af7e;

--color-brand: #fff383;
--color-brand-secondary: #fc7744;
--color-brand-secondary-foreground: #521700;
--color-brand-foreground: black;
--color-brand-200: #fff7c8;
}

@theme inline {
--default-mono-font-family: var(--font-mono);
--animate-marquee: marquee var(--duration) infinite linear;
Expand Down Expand Up @@ -62,17 +84,24 @@

:root {
--headless-color: hsl(250, 80%, 54%);
--ui-color: hsl(220, 91%, 54%);
--ui-color: hsl(41, 100%, 40%);
}

html {
scrollbar-gutter: stable;
}

html:has(body[data-scroll-locked]) {
scrollbar-gutter: auto;
}

body {
overscroll-behavior-y: none;
background-color: var(--color-fd-background);
}

.dark {
--headless-color: hsl(250 100% 80%);
--ui-color: hsl(217 92% 76%);
--ui-color: #fff383;
}

@keyframes circuit_1 {
Expand Down
5 changes: 1 addition & 4 deletions docs/app/llms-full.txt/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { getLLMText } from '@/lib/get-llm-text';
export const revalidate = false;

export async function GET() {
const scan = source
.getPages()
.filter((file) => file.slugs[0] !== 'openapi')
.map(getLLMText);
const scan = source.getPages().map(getLLMText);
const scanned = await Promise.all(scan);

return new Response(scanned.join('\n\n'));
Expand Down
31 changes: 14 additions & 17 deletions docs/app/og/[...slug]/generate.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import { type ImageResponseOptions } from '@takumi-rs/image-response';
import type { ReactNode } from 'react';
import fs from 'node:fs/promises';
import { readFile } from 'node:fs/promises';
import type { ImageResponseOptions } from '@takumi-rs/image-response';

export interface GenerateProps {
title: ReactNode;
description?: ReactNode;
}

const font = fs.readFile('./lib/og/JetBrainsMono-Regular.ttf');
const fontBold = fs.readFile('./lib/og/JetBrainsMono-Bold.ttf');
const font = readFile('./lib/og/JetBrainsMono-Regular.ttf').then((data) => ({
name: 'Mono',
data,
weight: 400,
}));
const fontBold = readFile('./lib/og/JetBrainsMono-Bold.ttf').then((data) => ({
name: 'Mono',
data,
weight: 600,
}));

export async function getImageResponseOptions(): Promise<ImageResponseOptions> {
return {
format: 'webp',
width: 1200,
height: 630,
fonts: [
{
name: 'Mono',
data: await font,
weight: 400,
},
{
name: 'Mono',
data: await fontBold,
weight: 600,
},
],
format: 'webp',
fonts: await Promise.all([font, fontBold]),
};
}

Expand Down
Loading