mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 06:31:49 +00:00
CLI: Add Waku template
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'create-fumadocs-app': patch
|
||||
---
|
||||
|
||||
Support Waku template
|
||||
@@ -3,10 +3,10 @@ import type { ReactNode } from 'react';
|
||||
import { WakuProvider } from 'fumadocs-core/framework/waku';
|
||||
import { RootProvider } from 'fumadocs-ui/provider/base';
|
||||
|
||||
export const Provider = ({ children }: { children: ReactNode }) => {
|
||||
export function Provider({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<WakuProvider>
|
||||
<RootProvider>{children}</RootProvider>
|
||||
</WakuProvider>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ export const templates = [
|
||||
'+next+fuma-docs-mdx',
|
||||
'react-router',
|
||||
'tanstack-start',
|
||||
'waku',
|
||||
] as const;
|
||||
|
||||
export type Template = (typeof templates)[number];
|
||||
@@ -137,7 +138,9 @@ export async function create(options: Options): Promise<void> {
|
||||
);
|
||||
}
|
||||
|
||||
const packageJson = await createPackageJson(projectName, dest, options);
|
||||
const packageJson = isNext
|
||||
? await createNextPackageJson(projectName, options)
|
||||
: await createPackageJson(projectName, dest);
|
||||
await fs.writeFile(
|
||||
path.join(dest, 'package.json'),
|
||||
JSON.stringify(packageJson, null, 2),
|
||||
@@ -189,39 +192,10 @@ async function copy(
|
||||
}
|
||||
}
|
||||
|
||||
async function createPackageJson(
|
||||
async function createNextPackageJson(
|
||||
projectName: string,
|
||||
dir: string,
|
||||
options: Options,
|
||||
): Promise<object> {
|
||||
function replaceWorkspaceDeps(deps: Record<string, string>) {
|
||||
for (const k in deps) {
|
||||
if (deps[k].startsWith('workspace:') && k in localVersions) {
|
||||
deps[k] = localVersions[k as keyof typeof localVersions];
|
||||
}
|
||||
}
|
||||
|
||||
return deps;
|
||||
}
|
||||
|
||||
if (
|
||||
options.template === 'tanstack-start' ||
|
||||
options.template === 'react-router'
|
||||
) {
|
||||
const packageJson = JSON.parse(
|
||||
await fs
|
||||
.readFile(path.join(dir, 'package.json'))
|
||||
.then((res) => res.toString()),
|
||||
);
|
||||
|
||||
return {
|
||||
name: projectName,
|
||||
...packageJson,
|
||||
dependencies: replaceWorkspaceDeps(packageJson.dependencies),
|
||||
devDependencies: replaceWorkspaceDeps(packageJson.devDependencies),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
name: projectName,
|
||||
version: '0.0.0',
|
||||
@@ -278,6 +252,34 @@ async function createPackageJson(
|
||||
};
|
||||
}
|
||||
|
||||
async function createPackageJson(
|
||||
projectName: string,
|
||||
dir: string,
|
||||
): Promise<object> {
|
||||
function replaceWorkspaceDeps(deps: Record<string, string>) {
|
||||
for (const k in deps) {
|
||||
if (deps[k].startsWith('workspace:') && k in localVersions) {
|
||||
deps[k] = localVersions[k as keyof typeof localVersions];
|
||||
}
|
||||
}
|
||||
|
||||
return deps;
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
await fs
|
||||
.readFile(path.join(dir, 'package.json'))
|
||||
.then((res) => res.toString()),
|
||||
);
|
||||
|
||||
return {
|
||||
name: projectName,
|
||||
...packageJson,
|
||||
dependencies: replaceWorkspaceDeps(packageJson.dependencies),
|
||||
devDependencies: replaceWorkspaceDeps(packageJson.devDependencies),
|
||||
};
|
||||
}
|
||||
|
||||
function pick<T extends object, K extends keyof T>(
|
||||
obj: T,
|
||||
keys: K[],
|
||||
|
||||
@@ -96,14 +96,17 @@ async function main(config: Options): Promise<void> {
|
||||
value: '+next+content-collections',
|
||||
label: 'Next.js: Content Collections',
|
||||
},
|
||||
{
|
||||
value: 'waku',
|
||||
label: 'Waku: Fumadocs MDX',
|
||||
},
|
||||
{
|
||||
value: 'react-router',
|
||||
label: 'React Router: MDX Remote',
|
||||
label: 'React Router: Fumadocs MDX (not RSC)',
|
||||
},
|
||||
{
|
||||
value: 'tanstack-start',
|
||||
label: 'Tanstack Start: MDX Remote',
|
||||
hint: 'Experimental',
|
||||
label: 'Tanstack Start: Fumadocs MDX (not RSC)',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
This is a Waku application generated with [Create Fumadocs](https://github.com/fuma-nama/fumadocs).
|
||||
|
||||
Run development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Hello World
|
||||
description: Your favourite docs framework.
|
||||
icon: Rocket
|
||||
---
|
||||
|
||||
Hey there! Fumadocs is a docs framework that works on Waku!
|
||||
|
||||
## Heading
|
||||
|
||||
Hello World!
|
||||
|
||||
<Cards>
|
||||
<Card title="Learn more about Waku" href="https://waku.gg" />
|
||||
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
|
||||
</Cards>
|
||||
|
||||
### CodeBlock
|
||||
|
||||
```ts
|
||||
console.log('Hello World');
|
||||
```
|
||||
|
||||
#### Table
|
||||
|
||||
| Head | Description |
|
||||
| ------------------------------- | ----------------------------------- |
|
||||
| `hello` | Hello World |
|
||||
| very **important** | Hey |
|
||||
| _Surprisingly_ | Fumadocs |
|
||||
| very long text that looks weird | hello world hello world hello world |
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Test
|
||||
description: This is another page
|
||||
---
|
||||
|
||||
Hello World again!
|
||||
|
||||
## Installation
|
||||
|
||||
```npm
|
||||
npm i fumadocs-core fumadocs-ui
|
||||
```
|
||||
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
/node_modules/
|
||||
|
||||
dist
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "example-waku",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "waku dev",
|
||||
"build": "waku build",
|
||||
"start": "waku start"
|
||||
},
|
||||
"dependencies": {
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-mdx": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-server-dom-webpack": "^19.1.1",
|
||||
"waku": "^0.23.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.1.0",
|
||||
"@types/react": "^19.1.9",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.7.2",
|
||||
"vite": "7.0.5"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
|
||||
|
||||
export const docs = defineDocs({
|
||||
dir: 'content/docs',
|
||||
});
|
||||
|
||||
export default defineConfig();
|
||||
@@ -0,0 +1,12 @@
|
||||
'use client';
|
||||
import type { ReactNode } from 'react';
|
||||
import { WakuProvider } from 'fumadocs-core/framework/waku';
|
||||
import { RootProvider } from 'fumadocs-ui/provider/base';
|
||||
|
||||
export function Provider({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<WakuProvider>
|
||||
<RootProvider>{children}</RootProvider>
|
||||
</WakuProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import '../styles/globals.css';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Provider } from '../components/provider';
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
path: string;
|
||||
}) {
|
||||
return <Provider>{children}</Provider>;
|
||||
}
|
||||
|
||||
export const getConfig = async () => {
|
||||
return {
|
||||
render: 'static',
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createFromSource } from 'fumadocs-core/search/server';
|
||||
import { source } from '../../source';
|
||||
|
||||
export const { GET } = createFromSource(source);
|
||||
@@ -0,0 +1,50 @@
|
||||
import { source } from '../../source';
|
||||
import { PageProps } from 'waku/router';
|
||||
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
||||
import {
|
||||
DocsBody,
|
||||
DocsDescription,
|
||||
DocsPage,
|
||||
DocsTitle,
|
||||
} from 'fumadocs-ui/page';
|
||||
|
||||
export default function DocPage({ slugs }: PageProps<'/docs/[...slugs]'>) {
|
||||
const page = source.getPage(slugs);
|
||||
|
||||
if (!page) {
|
||||
return (
|
||||
<div className="text-center py-12">
|
||||
<h1 className="text-3xl font-bold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Page Not Found
|
||||
</h1>
|
||||
<p className="text-gray-600 dark:text-gray-400">
|
||||
The page you are looking for does not exist.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const MDX = page.data.default;
|
||||
return (
|
||||
<DocsPage toc={page.data.toc}>
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
<DocsDescription>{page.data.description}</DocsDescription>
|
||||
<DocsBody>
|
||||
<MDX
|
||||
components={{
|
||||
...defaultMdxComponents,
|
||||
}}
|
||||
/>
|
||||
</DocsBody>
|
||||
</DocsPage>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getConfig() {
|
||||
const pages = source.getPages().map((page) => page.slugs);
|
||||
|
||||
return {
|
||||
render: 'static' as const,
|
||||
staticPaths: pages,
|
||||
} as const;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
import { source } from '../../source';
|
||||
|
||||
export default function Layout({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
path: string;
|
||||
}) {
|
||||
return (
|
||||
<DocsLayout
|
||||
tree={source.pageTree}
|
||||
nav={{
|
||||
title: 'Waku',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export const getConfig = async () => {
|
||||
return {
|
||||
render: 'static',
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
||||
import { Link } from 'waku';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<HomeLayout
|
||||
nav={{
|
||||
title: 'Waku',
|
||||
}}
|
||||
className="text-center py-32 justify-center"
|
||||
>
|
||||
<h1 className="font-medium text-xl mb-4">Fumadocs on Waku.</h1>
|
||||
<Link
|
||||
to="/docs"
|
||||
className="px-3 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm mx-auto"
|
||||
>
|
||||
Open Docs
|
||||
</Link>
|
||||
</HomeLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export const getConfig = async () => {
|
||||
return {
|
||||
render: 'static',
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { loader } from 'fumadocs-core/source';
|
||||
import { create, docs } from '../source.generated.js';
|
||||
|
||||
export const source = loader({
|
||||
source: await create.sourceAsync(docs.doc, docs.meta),
|
||||
baseUrl: '/docs',
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
@import 'tailwindcss';
|
||||
@import 'fumadocs-ui/css/neutral.css';
|
||||
@import 'fumadocs-ui/css/preset.css';
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["dom", "dom.iterable", "ES2022"],
|
||||
"jsx": "react-jsx",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { defineConfig } from 'waku/config';
|
||||
import mdx from 'fumadocs-mdx/vite';
|
||||
import * as MdxConfig from './source.config.js';
|
||||
import type { UserConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
unstable_viteConfigs: {
|
||||
common() {
|
||||
return {
|
||||
plugins: [mdx(MdxConfig)],
|
||||
} as UserConfig;
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user