create-fumadocs-app 15.1.3 → 15.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-K4QGKCVK.js → chunk-LCUIXVWC.js} +159 -68
- package/dist/create-app.js +1 -1
- package/dist/index.js +48 -24
- package/package.json +2 -2
- package/template/react-router/README.md +12 -0
- package/template/react-router/app/app.css +6 -0
- package/template/react-router/app/docs/page.tsx +63 -0
- package/template/react-router/app/docs/search.ts +18 -0
- package/template/react-router/app/root.tsx +78 -0
- package/template/react-router/app/routes/home.tsx +34 -0
- package/template/react-router/app/routes.ts +7 -0
- package/template/react-router/app/source.ts +60 -0
- package/template/react-router/content/docs/index.mdx +32 -0
- package/template/react-router/content/docs/test.mdx +8 -0
- package/template/react-router/example.gitignore +6 -0
- package/template/react-router/public/favicon.ico +0 -0
- package/template/react-router/react-router.config.ts +9 -0
- package/template/react-router/tsconfig.json +27 -0
- package/template/react-router/vite.config.ts +13 -0
- package/template/tanstack-start/README.md +12 -0
- package/template/tanstack-start/app/api.ts +6 -0
- package/template/tanstack-start/app/app.css +6 -0
- package/template/tanstack-start/app/client.tsx +7 -0
- package/template/tanstack-start/app/router.tsx +15 -0
- package/template/tanstack-start/app/routes/__root.tsx +49 -0
- package/template/tanstack-start/app/routes/api/search.ts +20 -0
- package/template/tanstack-start/app/routes/docs/$.tsx +71 -0
- package/template/tanstack-start/app/routes/index.tsx +25 -0
- package/template/tanstack-start/app/ssr.tsx +13 -0
- package/template/tanstack-start/app.config.ts +43 -0
- package/template/tanstack-start/content/docs/index.mdx +35 -0
- package/template/tanstack-start/example.gitignore +4 -0
- package/template/tanstack-start/lib/source.ts +70 -0
- package/template/tanstack-start/tsconfig.json +15 -0
- /package/template/{+shared → +next}/README.md +0 -0
- /package/template/{+shared → +next}/app/(home)/layout.tsx +0 -0
- /package/template/{+shared → +next}/app/(home)/page.tsx +0 -0
- /package/template/{+shared → +next}/app/api/search/route.ts +0 -0
- /package/template/{+shared → +next}/app/docs/layout.tsx +0 -0
- /package/template/{+shared → +next}/app/layout.config.tsx +0 -0
- /package/template/{+shared → +next}/app/layout.tsx +0 -0
- /package/template/{+shared → +next}/content/docs/index.mdx +0 -0
- /package/template/{+shared → +next}/content/docs/test.mdx +0 -0
- /package/template/{+shared → +next}/example.gitignore +0 -0
- /package/template/{content-collections → +next+content-collections}/app/docs/[[...slug]]/page.tsx +0 -0
- /package/template/{content-collections → +next+content-collections}/content-collections.ts +0 -0
- /package/template/{content-collections → +next+content-collections}/lib/source.ts +0 -0
- /package/template/{content-collections → +next+content-collections}/next.config.mjs +0 -0
- /package/template/{content-collections → +next+content-collections}/tsconfig.json +0 -0
- /package/template/{+eslint → +next+eslint}/.eslintrc.json +0 -0
- /package/template/{fuma-docs-mdx → +next+fuma-docs-mdx}/app/docs/[[...slug]]/page.tsx +0 -0
- /package/template/{fuma-docs-mdx → +next+fuma-docs-mdx}/lib/source.ts +0 -0
- /package/template/{fuma-docs-mdx → +next+fuma-docs-mdx}/next.config.mjs +0 -0
- /package/template/{fuma-docs-mdx → +next+fuma-docs-mdx}/source.config.ts +0 -0
- /package/template/{fuma-docs-mdx → +next+fuma-docs-mdx}/tsconfig.json +0 -0
- /package/template/{+tailwindcss → +next+tailwindcss}/app/(home)/page.tsx +0 -0
- /package/template/{+tailwindcss → +next+tailwindcss}/app/global.css +0 -0
- /package/template/{+tailwindcss → +next+tailwindcss}/app/layout.tsx +0 -0
- /package/template/{+tailwindcss → +next+tailwindcss}/postcss.config.mjs +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loader,
|
|
3
|
+
type MetaData,
|
|
4
|
+
type PageData,
|
|
5
|
+
type Source,
|
|
6
|
+
type VirtualFile,
|
|
7
|
+
} from 'fumadocs-core/source';
|
|
8
|
+
import matter from 'gray-matter';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
|
|
11
|
+
const files = Object.entries(
|
|
12
|
+
import.meta.glob<true, 'raw'>('/content/docs/**/*', {
|
|
13
|
+
eager: true,
|
|
14
|
+
query: '?raw',
|
|
15
|
+
import: 'default',
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const virtualFiles: VirtualFile[] = files.flatMap(([file, content]) => {
|
|
20
|
+
const ext = path.extname(file);
|
|
21
|
+
const virtualPath = path.relative(
|
|
22
|
+
'content/docs',
|
|
23
|
+
path.join(process.cwd(), file),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (ext === '.mdx' || ext === '.md') {
|
|
27
|
+
const parsed = matter(content);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
type: 'page',
|
|
31
|
+
path: virtualPath,
|
|
32
|
+
data: {
|
|
33
|
+
...parsed.data,
|
|
34
|
+
content: parsed.content,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (ext === '.json') {
|
|
40
|
+
return {
|
|
41
|
+
type: 'meta',
|
|
42
|
+
path: virtualPath,
|
|
43
|
+
data: JSON.parse(content),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return [];
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const source = loader({
|
|
51
|
+
source: {
|
|
52
|
+
files: virtualFiles,
|
|
53
|
+
} as Source<{
|
|
54
|
+
pageData: PageData & {
|
|
55
|
+
content: string;
|
|
56
|
+
};
|
|
57
|
+
metaData: MetaData;
|
|
58
|
+
}>,
|
|
59
|
+
baseUrl: '/docs',
|
|
60
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hello World
|
|
3
|
+
description: |
|
|
4
|
+
Your first `document`
|
|
5
|
+
You'll love it!
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Hey there! Fumadocs is the docs framework that also works on React Router!
|
|
9
|
+
|
|
10
|
+
## Heading
|
|
11
|
+
|
|
12
|
+
Hello World
|
|
13
|
+
|
|
14
|
+
<Cards>
|
|
15
|
+
<Card title="Learn more about React Router" href="https://reactrouter.com" />
|
|
16
|
+
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
|
|
17
|
+
</Cards>
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
console.log('I love React!');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Heading
|
|
24
|
+
|
|
25
|
+
#### Heading
|
|
26
|
+
|
|
27
|
+
| Head | Description |
|
|
28
|
+
| ------------------------------- | ----------------------------------- |
|
|
29
|
+
| `hello` | Hello World |
|
|
30
|
+
| very **important** | Hey |
|
|
31
|
+
| _Surprisingly_ | Fumadocs |
|
|
32
|
+
| very long text that looks weird | hello world hello world hello world |
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Config } from '@react-router/dev/config';
|
|
2
|
+
import { source } from './app/source';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
ssr: true,
|
|
6
|
+
async prerender({ getStaticPaths }) {
|
|
7
|
+
return [...getStaticPaths(), ...source.getPages().map((page) => page.url)];
|
|
8
|
+
},
|
|
9
|
+
} satisfies Config;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"**/*",
|
|
4
|
+
"**/.server/**/*",
|
|
5
|
+
"**/.client/**/*",
|
|
6
|
+
".react-router/types/**/*"
|
|
7
|
+
],
|
|
8
|
+
"compilerOptions": {
|
|
9
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
|
+
"types": ["node", "vite/client"],
|
|
11
|
+
"target": "esnext",
|
|
12
|
+
"module": "esnext",
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"rootDirs": [".", "./.react-router/types"],
|
|
16
|
+
"baseUrl": ".",
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./app/*"]
|
|
19
|
+
},
|
|
20
|
+
"esModuleInterop": true,
|
|
21
|
+
"verbatimModuleSyntax": true,
|
|
22
|
+
"noEmit": true,
|
|
23
|
+
"resolveJsonModule": true,
|
|
24
|
+
"skipLibCheck": true,
|
|
25
|
+
"strict": true
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { reactRouter } from '@react-router/dev/vite';
|
|
2
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
3
|
+
import { defineConfig } from 'vite';
|
|
4
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
build: {
|
|
8
|
+
rollupOptions: {
|
|
9
|
+
external: ['shiki'],
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
|
|
13
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
|
|
2
|
+
import { routeTree } from './routeTree.gen';
|
|
3
|
+
|
|
4
|
+
export function createRouter() {
|
|
5
|
+
return createTanStackRouter({
|
|
6
|
+
routeTree,
|
|
7
|
+
scrollRestoration: true,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare module '@tanstack/react-router' {
|
|
12
|
+
interface Register {
|
|
13
|
+
router: ReturnType<typeof createRouter>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { Outlet, createRootRoute, HeadContent } from '@tanstack/react-router';
|
|
3
|
+
import { RootProvider } from 'fumadocs-ui/provider/base';
|
|
4
|
+
import appCss from '../app.css?url';
|
|
5
|
+
import { TanstackProvider } from 'fumadocs-core/framework/tanstack';
|
|
6
|
+
import { Scripts } from '@tanstack/react-router';
|
|
7
|
+
|
|
8
|
+
export const Route = createRootRoute({
|
|
9
|
+
head: () => ({
|
|
10
|
+
meta: [
|
|
11
|
+
{
|
|
12
|
+
charSet: 'utf-8',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'viewport',
|
|
16
|
+
content: 'width=device-width, initial-scale=1',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: 'Fumadocs on TanStack Start',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
links: [{ rel: 'stylesheet', href: appCss }],
|
|
23
|
+
}),
|
|
24
|
+
component: RootComponent,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
function RootComponent() {
|
|
28
|
+
return (
|
|
29
|
+
<RootDocument>
|
|
30
|
+
<Outlet />
|
|
31
|
+
</RootDocument>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
|
|
36
|
+
return (
|
|
37
|
+
<html suppressHydrationWarning>
|
|
38
|
+
<head>
|
|
39
|
+
<HeadContent />
|
|
40
|
+
</head>
|
|
41
|
+
<body>
|
|
42
|
+
<TanstackProvider>
|
|
43
|
+
<RootProvider>{children}</RootProvider>
|
|
44
|
+
</TanstackProvider>
|
|
45
|
+
<Scripts />
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createAPIFileRoute } from '@tanstack/react-start/api';
|
|
2
|
+
import { createSearchAPI } from 'fumadocs-core/search/server';
|
|
3
|
+
import { source } from '@/lib/source';
|
|
4
|
+
import { structure } from 'fumadocs-core/mdx-plugins';
|
|
5
|
+
|
|
6
|
+
const server = createSearchAPI('advanced', {
|
|
7
|
+
indexes: source.getPages().map((page) => ({
|
|
8
|
+
id: page.url,
|
|
9
|
+
url: page.url,
|
|
10
|
+
title: page.data.title ?? '',
|
|
11
|
+
description: page.data.description,
|
|
12
|
+
structuredData: structure(page.data.content),
|
|
13
|
+
})),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const APIRoute = createAPIFileRoute('/api/search')({
|
|
17
|
+
GET: ({ request }) => {
|
|
18
|
+
return server.GET(request);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createFileRoute, notFound } from '@tanstack/react-router';
|
|
2
|
+
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
|
+
import { source } from '@/lib/source';
|
|
4
|
+
import {
|
|
5
|
+
DocsBody,
|
|
6
|
+
DocsDescription,
|
|
7
|
+
DocsPage,
|
|
8
|
+
DocsTitle,
|
|
9
|
+
} from 'fumadocs-ui/page';
|
|
10
|
+
import { executeMdxSync } from '@fumadocs/mdx-remote/client';
|
|
11
|
+
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
12
|
+
import { createServerFn } from '@tanstack/react-start';
|
|
13
|
+
import type { PageTree } from 'fumadocs-core/server';
|
|
14
|
+
import { createCompiler } from '@fumadocs/mdx-remote';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
|
|
17
|
+
export const Route = createFileRoute('/docs/$')({
|
|
18
|
+
component: Page,
|
|
19
|
+
async loader({ params }) {
|
|
20
|
+
const slugs = (params._splat ?? '').split('/');
|
|
21
|
+
|
|
22
|
+
return loader({ data: slugs });
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const compiler = createCompiler({
|
|
27
|
+
development: false,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const loader = createServerFn({
|
|
31
|
+
method: 'GET',
|
|
32
|
+
})
|
|
33
|
+
.validator((slugs: string[]) => slugs)
|
|
34
|
+
.handler(async ({ data: slugs }) => {
|
|
35
|
+
const page = source.getPage(slugs);
|
|
36
|
+
if (!page) throw notFound();
|
|
37
|
+
|
|
38
|
+
const { content, ...rest } = page.data;
|
|
39
|
+
const compiled = await compiler.compileFile({
|
|
40
|
+
path: path.resolve('content/docs', page.file.path),
|
|
41
|
+
value: content,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
tree: source.pageTree as object,
|
|
46
|
+
...rest,
|
|
47
|
+
compiled: compiled.toString(),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
function Page() {
|
|
52
|
+
const { tree, compiled, ...data } = Route.useLoaderData();
|
|
53
|
+
const { toc, default: MdxContent } = executeMdxSync(compiled);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<DocsLayout
|
|
57
|
+
nav={{
|
|
58
|
+
title: 'Tanstack Start',
|
|
59
|
+
}}
|
|
60
|
+
tree={tree as PageTree.Root}
|
|
61
|
+
>
|
|
62
|
+
<DocsPage toc={toc}>
|
|
63
|
+
<DocsTitle>{data.title}</DocsTitle>
|
|
64
|
+
<DocsDescription>{data.title}</DocsDescription>
|
|
65
|
+
<DocsBody>
|
|
66
|
+
<MdxContent components={defaultMdxComponents} />
|
|
67
|
+
</DocsBody>
|
|
68
|
+
</DocsPage>
|
|
69
|
+
</DocsLayout>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createFileRoute, Link } from '@tanstack/react-router';
|
|
2
|
+
import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('/')({
|
|
5
|
+
component: Home,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
function Home() {
|
|
9
|
+
return (
|
|
10
|
+
<HomeLayout
|
|
11
|
+
nav={{
|
|
12
|
+
title: 'Tanstack Start',
|
|
13
|
+
}}
|
|
14
|
+
className="text-center py-32"
|
|
15
|
+
>
|
|
16
|
+
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
|
|
17
|
+
<Link
|
|
18
|
+
to="/docs/$"
|
|
19
|
+
className="px-3 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm mx-auto"
|
|
20
|
+
>
|
|
21
|
+
Open Docs
|
|
22
|
+
</Link>
|
|
23
|
+
</HomeLayout>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// app/ssr.tsx
|
|
2
|
+
import {
|
|
3
|
+
createStartHandler,
|
|
4
|
+
defaultStreamHandler,
|
|
5
|
+
} from '@tanstack/react-start/server';
|
|
6
|
+
import { getRouterManifest } from '@tanstack/react-start/router-manifest';
|
|
7
|
+
|
|
8
|
+
import { createRouter } from './router';
|
|
9
|
+
|
|
10
|
+
export default createStartHandler({
|
|
11
|
+
createRouter,
|
|
12
|
+
getRouterManifest,
|
|
13
|
+
})(defaultStreamHandler);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { defineConfig } from '@tanstack/react-start/config';
|
|
2
|
+
import tsConfigPaths from 'vite-tsconfig-paths';
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
server: {
|
|
7
|
+
hooks: {
|
|
8
|
+
'prerender:routes': async (routes) => {
|
|
9
|
+
const { source } = await import('./lib/source');
|
|
10
|
+
const pages = source.getPages();
|
|
11
|
+
|
|
12
|
+
for (const page of pages) {
|
|
13
|
+
routes.add(page.url);
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
prerender: {
|
|
18
|
+
routes: ['/'],
|
|
19
|
+
crawlLinks: true,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
vite: {
|
|
23
|
+
build: {
|
|
24
|
+
rollupOptions: {
|
|
25
|
+
// Shiki results in a huge bundle because Rollup tries to bundle every language/theme
|
|
26
|
+
external: ['shiki'],
|
|
27
|
+
// most React.js libraries now include 'use client'
|
|
28
|
+
onwarn(warning, warn) {
|
|
29
|
+
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
warn(warning);
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
plugins: [
|
|
37
|
+
tsConfigPaths({
|
|
38
|
+
projects: ['./tsconfig.json'],
|
|
39
|
+
}),
|
|
40
|
+
tailwindcss(),
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hello World
|
|
3
|
+
description: |
|
|
4
|
+
Your first `document`
|
|
5
|
+
You'll love it!
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
|
|
9
|
+
|
|
10
|
+
## Heading
|
|
11
|
+
|
|
12
|
+
Hello World!
|
|
13
|
+
|
|
14
|
+
<Cards>
|
|
15
|
+
<Card
|
|
16
|
+
title="Learn more about Tanstack Start"
|
|
17
|
+
href="https://tanstack.com/start"
|
|
18
|
+
/>
|
|
19
|
+
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
|
|
20
|
+
</Cards>
|
|
21
|
+
|
|
22
|
+
### CodeBlock
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
console.log('Hello World');
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### Table
|
|
29
|
+
|
|
30
|
+
| Head | Description |
|
|
31
|
+
| ------------------------------- | ----------------------------------- |
|
|
32
|
+
| `hello` | Hello World |
|
|
33
|
+
| very **important** | Hey |
|
|
34
|
+
| _Surprisingly_ | Fumadocs |
|
|
35
|
+
| very long text that looks weird | hello world hello world hello world |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loader,
|
|
3
|
+
type MetaData,
|
|
4
|
+
type PageData,
|
|
5
|
+
type Source,
|
|
6
|
+
type VirtualFile,
|
|
7
|
+
} from 'fumadocs-core/source';
|
|
8
|
+
import matter from 'gray-matter';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import FastGlob from 'fast-glob';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
|
|
13
|
+
let files: [string, string][];
|
|
14
|
+
|
|
15
|
+
if (typeof import.meta.glob === 'function') {
|
|
16
|
+
files = Object.entries(
|
|
17
|
+
import.meta.glob<true, 'raw'>('/content/docs/**/*', {
|
|
18
|
+
eager: true,
|
|
19
|
+
query: '?raw',
|
|
20
|
+
import: 'default',
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
23
|
+
} else {
|
|
24
|
+
files = FastGlob.sync('content/docs/**/*').map((file) => {
|
|
25
|
+
return [file, fs.readFileSync(file).toString()];
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const virtualFiles: VirtualFile[] = files.flatMap(([file, content]) => {
|
|
30
|
+
const ext = path.extname(file);
|
|
31
|
+
const virtualPath = path.relative(
|
|
32
|
+
'content/docs',
|
|
33
|
+
path.join(process.cwd(), file),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (ext === '.mdx' || ext === '.md') {
|
|
37
|
+
const parsed = matter(content);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
type: 'page',
|
|
41
|
+
path: virtualPath,
|
|
42
|
+
data: {
|
|
43
|
+
...parsed.data,
|
|
44
|
+
content: parsed.content,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (ext === '.json') {
|
|
50
|
+
return {
|
|
51
|
+
type: 'meta',
|
|
52
|
+
path: virtualPath,
|
|
53
|
+
data: JSON.parse(content),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return [];
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const source = loader({
|
|
61
|
+
source: {
|
|
62
|
+
files: virtualFiles,
|
|
63
|
+
} as Source<{
|
|
64
|
+
pageData: PageData & {
|
|
65
|
+
content: string;
|
|
66
|
+
};
|
|
67
|
+
metaData: MetaData;
|
|
68
|
+
}>,
|
|
69
|
+
baseUrl: '/docs',
|
|
70
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"moduleResolution": "Bundler",
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
+
"types": ["node", "vite/client"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"target": "ESNext",
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"strictNullChecks": true,
|
|
11
|
+
"paths": {
|
|
12
|
+
"@/*": ["./*"]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/template/{content-collections → +next+content-collections}/app/docs/[[...slug]]/page.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|