create-fumadocs-app 16.0.32 → 16.0.34
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/bin.d.ts +1 -1
- package/dist/bin.js +155 -206
- package/dist/bin.js.map +1 -0
- package/dist/constants-CReWPhck.js +150 -0
- package/dist/constants-CReWPhck.js.map +1 -0
- package/dist/index-CC4EFQ5p.d.ts +67 -0
- package/dist/index-CC4EFQ5p.d.ts.map +1 -0
- package/dist/index.d.ts +2 -63
- package/dist/index.js +4 -7
- package/dist/plugins/biome.base.d.ts +40 -45
- package/dist/plugins/biome.base.d.ts.map +1 -0
- package/dist/plugins/biome.base.js +37 -17
- package/dist/plugins/biome.base.js.map +1 -0
- package/dist/plugins/biome.d.ts +4 -2
- package/dist/plugins/biome.d.ts.map +1 -0
- package/dist/plugins/biome.js +30 -40
- package/dist/plugins/biome.js.map +1 -0
- package/dist/plugins/biome.next.d.ts +41 -49
- package/dist/plugins/biome.next.d.ts.map +1 -0
- package/dist/plugins/biome.next.js +43 -17
- package/dist/plugins/biome.next.js.map +1 -0
- package/dist/plugins/eslint.d.ts +4 -2
- package/dist/plugins/eslint.d.ts.map +1 -0
- package/dist/plugins/eslint.js +30 -33
- package/dist/plugins/eslint.js.map +1 -0
- package/dist/plugins/next-use-src.d.ts +5 -2
- package/dist/plugins/next-use-src.d.ts.map +1 -0
- package/dist/plugins/next-use-src.js +33 -35
- package/dist/plugins/next-use-src.js.map +1 -0
- package/dist/plugins/orama-cloud.d.ts +4 -2
- package/dist/plugins/orama-cloud.d.ts.map +1 -0
- package/dist/plugins/orama-cloud.js +210 -276
- package/dist/plugins/orama-cloud.js.map +1 -0
- package/dist/src-DWqRvlfn.js +89 -0
- package/dist/src-DWqRvlfn.js.map +1 -0
- package/package.json +19 -18
- package/template/+next+fuma-docs-mdx/app/docs/[[...slug]]/page.tsx +2 -9
- package/template/+next+fuma-docs-mdx/app/docs/layout.tsx +1 -1
- package/template/+next+fuma-docs-mdx/app/og/docs/[...slug]/route.tsx +2 -9
- package/template/+next+fuma-docs-mdx/package.json +2 -2
- package/template/+next+fuma-docs-mdx/source.config.ts +1 -6
- package/template/+orama-cloud/@app/components/search.tsx +1 -6
- package/template/react-router/app/docs/page.tsx +1 -6
- package/template/react-router/app/root.tsx +1 -3
- package/template/react-router/package.json +6 -6
- package/template/react-router/tsconfig.json +1 -6
- package/template/react-router-spa/app/components/search.tsx +1 -6
- package/template/react-router-spa/app/docs/page.tsx +2 -7
- package/template/react-router-spa/app/root.tsx +1 -3
- package/template/react-router-spa/package.json +6 -6
- package/template/react-router-spa/tsconfig.json +1 -6
- package/template/tanstack-start/content/docs/index.mdx +1 -4
- package/template/tanstack-start/package.json +4 -4
- package/template/tanstack-start/src/components/not-found.tsx +2 -2
- package/template/tanstack-start/src/routes/__root.tsx +1 -6
- package/template/tanstack-start/src/routes/docs/$.tsx +1 -6
- package/template/tanstack-start/src/routes/index.tsx +1 -3
- package/template/tanstack-start-spa/content/docs/index.mdx +1 -4
- package/template/tanstack-start-spa/package.json +5 -5
- package/template/tanstack-start-spa/src/components/not-found.tsx +2 -2
- package/template/tanstack-start-spa/src/components/search.tsx +1 -6
- package/template/tanstack-start-spa/src/routes/__root.tsx +1 -6
- package/template/tanstack-start-spa/src/routes/docs/$.tsx +2 -7
- package/template/waku/package.json +4 -4
- package/template/waku/src/pages/docs/[...slugs].tsx +2 -9
- package/template/waku/src/pages/docs/_layout.tsx +1 -1
- package/dist/chunk-BEZTHMLF.js +0 -51
- package/dist/chunk-CYYUEPDV.js +0 -179
- package/dist/chunk-JCFTHRDR.js +0 -50
- package/dist/chunk-Y54WH7LQ.js +0 -130
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orama-cloud.js","names":["path","SyntaxKind","path","path","tasks: Promise<unknown>[]"],"sources":["../../src/transform/shared.ts","../../src/transform/react-router.ts","../../src/transform/tanstack-start.ts","../../src/transform/index.ts","../../src/plugins/orama-cloud.ts"],"sourcesContent":["import { IndentationText, Project, QuoteKind } from 'ts-morph';\nimport fs from 'node:fs/promises';\n\nconst project = new Project({\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Single,\n },\n});\n\nexport async function createSourceFile(path: string) {\n return project.createSourceFile(path, (await fs.readFile(path)).toString(), {\n overwrite: true,\n });\n}\n\nexport function getCodeValue(v: string) {\n return new Function(`return ${v}`)();\n}\n","import { ArrayLiteralExpression, MethodDeclaration, SourceFile, ts } from 'ts-morph';\nimport { getCodeValue } from '@/transform/shared';\nimport SyntaxKind = ts.SyntaxKind;\n\n/**\n * filter items in a specific array initializer in the prerender function\n */\nexport function filterReactRouterPrerenderArray(\n sourceFile: SourceFile,\n array: 'paths' | 'excluded',\n filter: (item: string) => boolean,\n) {\n const methodBody = getPrerenderMethod(sourceFile)?.getBody();\n if (!methodBody) return;\n\n const initializer = methodBody\n .getDescendantsOfKind(SyntaxKind.VariableDeclaration)\n .find((item) => item.getName() === array)\n ?.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);\n\n if (!initializer) return;\n for (const element of initializer.getElements()) {\n if (!filter(getCodeValue(element.getText()))) {\n initializer.removeElement(element);\n }\n }\n}\n\n/**\n * Add a new route to route config\n */\nexport function addReactRouterRoute(\n sourceFile: SourceFile,\n routes: { path: string; entry: string }[],\n) {\n modifyReactRouterRoutes(sourceFile, (arr) => {\n for (const { path, entry } of routes) {\n arr.addElement(`route('${path}', '${entry}')`);\n }\n });\n}\n\n/**\n * Remove routes from route config (root level only)\n */\nexport function filterReactRouterRoute(\n sourceFile: SourceFile,\n filter: (item: { path: string; entry: string }) => boolean,\n) {\n modifyReactRouterRoutes(sourceFile, (arr) => {\n for (const element of arr.getElements()) {\n if (\n !element.isKind(SyntaxKind.CallExpression) ||\n element.getFirstChildByKind(SyntaxKind.Identifier)?.getText() !== 'route'\n )\n continue;\n const args = element.getArguments();\n\n if (\n filter({\n path: getCodeValue(args[0].getText()),\n entry: getCodeValue(args[1].getText()),\n })\n )\n continue;\n\n arr.removeElement(element);\n }\n });\n}\n\nexport function modifyReactRouterRoutes(\n sourceFile: SourceFile,\n mod: (array: ArrayLiteralExpression) => void,\n) {\n const initializer = sourceFile\n .getDefaultExportSymbol()\n ?.getValueDeclaration()\n ?.getFirstDescendantByKind(SyntaxKind.ArrayLiteralExpression);\n if (initializer) mod(initializer);\n}\n\n/**\n * Find the prerender method from the config\n */\nfunction getPrerenderMethod(sourceFile: SourceFile): MethodDeclaration | null {\n return (\n sourceFile\n .getDefaultExportSymbol()\n ?.getValueDeclaration()\n ?.getFirstDescendantByKind(SyntaxKind.ObjectLiteralExpression)\n ?.getProperty('prerender')\n ?.asKind(SyntaxKind.MethodDeclaration) ?? null\n );\n}\n","import { CallExpression, SourceFile, SyntaxKind } from 'ts-morph';\nimport { getCodeValue } from '@/transform/shared';\n\n/**\n * Add path to the `pages` array in tanstack start vite config.\n *\n * If the `pages` property doesn't exist, create one.\n */\nexport function addTanstackPrerender(sourceFile: SourceFile, paths: string[]) {\n const optionsArg = getTanstackStartCall(sourceFile)\n ?.getArguments()[0]\n ?.asKind(SyntaxKind.ObjectLiteralExpression);\n if (!optionsArg) {\n return;\n }\n\n const pagesProperty = optionsArg.getProperty('pages')?.asKind(SyntaxKind.PropertyAssignment);\n\n function toItem(path: string) {\n return `{ path: '${path}' }`;\n }\n\n if (pagesProperty) {\n const initializer = pagesProperty.getInitializerIfKindOrThrow(\n SyntaxKind.ArrayLiteralExpression,\n );\n\n const existingPaths = new Set<string>();\n for (const element of initializer.getElements()) {\n const value = element\n .asKind(SyntaxKind.ObjectLiteralExpression)\n ?.getProperty('path')\n ?.asKind(SyntaxKind.PropertyAssignment)\n ?.getInitializer()\n ?.getText();\n\n if (value) {\n existingPaths.add(getCodeValue(value));\n }\n }\n\n for (const path of paths) {\n if (existingPaths.has(path)) continue;\n initializer.addElement(toItem(path));\n }\n } else {\n optionsArg.addProperty(`pages: [\\n${paths.map((path) => ` ${toItem(path)}`).join(',\\n')}\\n]`);\n }\n}\n\n/**\n * Find the tanstackStart call expression\n */\nfunction getTanstackStartCall(sourceFile: SourceFile): CallExpression | undefined {\n const pluginsProperty = sourceFile\n .getDefaultExportSymbol()\n ?.getValueDeclaration()\n ?.getFirstDescendantByKind(SyntaxKind.ObjectLiteralExpression)\n ?.getProperty('plugins')\n ?.getFirstChildByKind(SyntaxKind.ArrayLiteralExpression);\n\n if (!pluginsProperty) return;\n\n for (const element of pluginsProperty.getElements()) {\n const expression = element.asKind(SyntaxKind.CallExpression);\n if (expression?.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'tanstackStart') {\n return expression;\n }\n }\n}\n","import { TemplatePluginContext } from '@/index';\nimport { createSourceFile } from '@/transform/shared';\nimport path from 'node:path';\nimport {\n addReactRouterRoute,\n filterReactRouterPrerenderArray,\n filterReactRouterRoute,\n} from '@/transform/react-router';\nimport fs from 'node:fs/promises';\nimport { addTanstackPrerender } from '@/transform/tanstack-start';\nimport { StructureKind, SyntaxKind } from 'ts-morph';\n\ninterface RootLayoutMod {\n addSearchDialog: (specifier: string) => void;\n}\n\nexport async function rootProvider(\n { appDir, template }: TemplatePluginContext,\n fn: (mod: RootLayoutMod) => void,\n) {\n const file = await createSourceFile(path.join(appDir, template.rootProviderPath));\n fn({\n addSearchDialog(specifier) {\n const elements = file.getDescendantsOfKind(SyntaxKind.JsxElement);\n\n for (const element of elements) {\n const provider = element.getFirstChildByKind(SyntaxKind.JsxOpeningElement);\n if (provider?.getTagNameNode().getText() !== 'RootProvider') continue;\n\n // Skip if search prop already exists\n if (\n provider\n .getAttributes()\n .some(\n (attr) =>\n attr.isKind(SyntaxKind.JsxAttribute) && attr.getNameNode().getText() === 'search',\n )\n )\n continue;\n\n provider.addAttribute({\n kind: StructureKind.JsxAttribute,\n name: 'search',\n initializer: '{{ SearchDialog }}',\n });\n file.addImportDeclaration({\n moduleSpecifier: specifier,\n defaultImport: 'SearchDialog',\n });\n break;\n }\n },\n });\n await file.save();\n}\n\ninterface ReactRouterRoutesMod {\n /**\n * @param path API route's path\n * @param entry route's file path\n * @param code create the file if specified\n */\n addRoute: (path: string, entry: string, code?: string) => void;\n\n /**\n * @param path API route's path\n */\n removeRoute: (path: string) => void;\n}\n\nexport async function reactRouterRoutes(\n { dest, appDir }: TemplatePluginContext,\n fn: (mod: ReactRouterRoutesMod) => void,\n) {\n const configFile = await createSourceFile(path.join(dest, 'react-router.config.ts'));\n const routesFile = await createSourceFile(path.join(appDir, 'routes.ts'));\n const tasks: Promise<unknown>[] = [];\n\n function normalizePath(v: string) {\n return v.split('/').filter(Boolean).join('/');\n }\n\n fn({\n addRoute: (p, entry, code) => {\n addReactRouterRoute(routesFile, [{ path: p, entry }]);\n\n if (code) {\n tasks.push(fs.writeFile(path.join(appDir, entry), code));\n }\n },\n removeRoute: (p) => {\n const normalizedPath = normalizePath(p);\n\n filterReactRouterRoute(routesFile, (item) => {\n if (normalizePath(item.path) !== normalizedPath) return true;\n\n tasks.push(fs.unlink(path.join(appDir, item.entry)).catch(() => null));\n return false;\n });\n\n filterReactRouterPrerenderArray(\n configFile,\n 'excluded',\n (item) => normalizePath(item) !== normalizedPath,\n );\n\n filterReactRouterPrerenderArray(\n configFile,\n 'paths',\n (item) => normalizePath(item) !== normalizedPath,\n );\n },\n });\n\n await Promise.all([...tasks, routesFile.save(), configFile.save()]);\n}\n\nexport interface TanstackStartRoutesMod {\n addRoute: (options: {\n /**\n * file path relative to `routes`\n */\n path: string;\n\n /**\n * Generated route path of `path`\n */\n route: string;\n\n /**\n * if specified, create the file\n */\n code?: string;\n\n /**\n * if true, add to prerender list\n */\n prerender?: boolean;\n }) => void;\n\n removeRoute: (options: {\n /**\n * file path relative to routes directory\n */\n path: string;\n\n route: string;\n }) => void;\n}\n\nexport async function tanstackStartRoutes(\n { appDir, dest }: TemplatePluginContext,\n fn: (mod: TanstackStartRoutesMod) => void,\n) {\n const configFile = await createSourceFile(path.join(dest, 'vite.config.ts'));\n const tasks: Promise<unknown>[] = [];\n\n fn({\n addRoute(options) {\n if (options.code) {\n tasks.push(fs.writeFile(path.join(appDir, 'routes', options.path), options.code));\n }\n\n if (options.prerender) {\n addTanstackPrerender(configFile, [options.route]);\n }\n },\n removeRoute(options) {\n tasks.push(fs.unlink(path.join(appDir, 'routes', options.path)).catch(() => null));\n },\n });\n\n await Promise.all([...tasks, configFile.save()]);\n}\n","import { TemplatePlugin } from '@/index';\nimport { copy, pick, writeFile } from '@/utils';\nimport path from 'node:path';\nimport { depVersions, sourceDir } from '@/constants';\nimport fs from 'node:fs/promises';\nimport { reactRouterRoutes, rootProvider, tanstackStartRoutes } from '@/transform';\n\nexport function oramaCloud(): TemplatePlugin {\n return {\n packageJson(packageJson) {\n return {\n ...packageJson,\n scripts: {\n ...packageJson.scripts,\n build: `${packageJson.scripts!.build} && bun scripts/sync-content.ts`,\n },\n dependencies: {\n ...packageJson.dependencies,\n ...pick(depVersions, ['@orama/core']),\n },\n };\n },\n readme(content) {\n return `${content}\\n\\n## Orama Cloud\n \nThis project uses Orama Cloud for 3rd party search solution.\n\nSee https://fumadocs.dev/docs/headless/search/orama-cloud for integrating Orama Cloud to Fumadocs.`;\n },\n async afterWrite() {\n const { dest, appDir, template } = this;\n await copy(path.join(sourceDir, 'template/+orama-cloud/@root'), dest);\n await copy(path.join(sourceDir, 'template/+orama-cloud/@app'), appDir);\n\n await rootProvider(this, (mod) => mod.addSearchDialog('@/components/search'));\n\n if (template.value === 'tanstack-start') {\n await tanstackStartRoutes(this, (mod) => {\n mod.addRoute({\n path: 'static[.]json.ts',\n route: '/static.json',\n code: route.tanstack,\n prerender: true,\n });\n mod.removeRoute({\n path: 'api/search.ts',\n route: '/api/search',\n });\n });\n } else if (template.value.startsWith('react-router')) {\n await reactRouterRoutes(this, (mod) => {\n mod.addRoute('static.json', 'routes/static.ts', route['react-router']);\n mod.removeRoute('api/search');\n });\n } else if (template.value.startsWith('+next')) {\n await Promise.all([\n fs.unlink(path.join(appDir, 'app/api/search/route.ts')).catch(() => null),\n writeFile(path.join(appDir, 'app/static.json/route.ts'), route.next),\n ]);\n } else {\n await Promise.all([\n fs.unlink(path.join(appDir, 'pages/api/search.ts')).catch(() => null),\n writeFile(path.join(appDir, 'pages/static.json.ts'), route.waku),\n ]);\n }\n\n const filePath = {\n '+next+fuma-docs-mdx': '.next/server/app/static.json.body',\n 'tanstack-start': '.output/public/static.json',\n 'tanstack-start-spa': 'dist/client/static.json',\n 'react-router': 'build/client/static.json',\n 'react-router-spa': 'build/client/static.json',\n waku: 'dist/public/static.json',\n }[template.value];\n\n await writeFile(\n path.join(dest, 'scripts/sync-content.ts'),\n `import { type OramaDocument, sync } from 'fumadocs-core/search/orama-cloud';\nimport * as fs from 'node:fs/promises';\nimport { OramaCloud } from '@orama/core';\n\n// the path of pre-rendered \\`static.json\\`\nconst filePath = '${filePath}';\n\nasync function main() {\n const orama = new OramaCloud({\n projectId: process.env.NEXT_PUBLIC_ORAMA_PROJECT_ID,\n apiKey: process.env.ORAMA_PRIVATE_API_KEY,\n });\n\n const content = await fs.readFile(filePath);\n const records = JSON.parse(content.toString()) as OramaDocument[];\n\n await sync(orama, {\n index: process.env.NEXT_PUBLIC_ORAMA_DATASOURCE_ID,\n documents: records,\n });\n\n console.log(\\`search updated: \\${records.length} records\\`);\n}\n\nvoid main();`,\n );\n },\n };\n}\n\nconst route = {\n next: `import { exportSearchIndexes } from '@/lib/export-search-indexes';\n\nexport const revalidate = false;\n\nexport async function GET() {\n return Response.json(await exportSearchIndexes());\n}`,\n 'react-router': `import { exportSearchIndexes } from '@/lib/export-search-indexes';\n\nexport async function loader() {\n return Response.json(await exportSearchIndexes());\n}`,\n tanstack: `import { createFileRoute } from '@tanstack/react-router';\nimport { exportSearchIndexes } from '@/lib/export-search-indexes';\n\nexport const Route = createFileRoute('/static.json')({\n server: {\n handlers: {\n GET: async () => Response.json(await exportSearchIndexes()),\n },\n },\n});`,\n waku: `import { exportSearchIndexes } from '@/lib/export-search-indexes';\n\nexport async function GET() {\n return Response.json(await exportSearchIndexes());\n}\n\nexport const getConfig = () => ({\n render: 'static',\n});`,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { a as copy, i as templates, r as sourceDir, s as tryGitInit, t as depVersions } from "./constants-CReWPhck.js";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { x } from "tinyexec";
|
|
5
|
+
|
|
6
|
+
//#region src/auto-install.ts
|
|
7
|
+
const managers = [
|
|
8
|
+
"npm",
|
|
9
|
+
"yarn",
|
|
10
|
+
"bun",
|
|
11
|
+
"pnpm"
|
|
12
|
+
];
|
|
13
|
+
function getPackageManager() {
|
|
14
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
15
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
16
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
17
|
+
if (userAgent.startsWith("bun")) return "bun";
|
|
18
|
+
return "npm";
|
|
19
|
+
}
|
|
20
|
+
async function autoInstall(manager, dest) {
|
|
21
|
+
await x(manager, ["install"], {
|
|
22
|
+
throwOnError: true,
|
|
23
|
+
nodeOptions: {
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
NODE_ENV: "development",
|
|
27
|
+
DISABLE_OPENCOLLECTIVE: "1"
|
|
28
|
+
},
|
|
29
|
+
cwd: dest
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/index.ts
|
|
36
|
+
async function create(createOptions) {
|
|
37
|
+
const { outputDir, plugins = [], packageManager = "npm", initializeGit = false, installDeps = false, log = console.log } = createOptions;
|
|
38
|
+
let template = templates.find((item) => item.value === createOptions.template);
|
|
39
|
+
for (const plugin of plugins) template = await plugin.template?.call({ dest: outputDir }, template) ?? template;
|
|
40
|
+
const appDir = path.join(outputDir, template.appDir);
|
|
41
|
+
const projectName = path.basename(outputDir);
|
|
42
|
+
const pluginContext = {
|
|
43
|
+
template,
|
|
44
|
+
dest: outputDir,
|
|
45
|
+
log,
|
|
46
|
+
appDir
|
|
47
|
+
};
|
|
48
|
+
await copy(path.join(sourceDir, "template", template.value), outputDir, { rename(file) {
|
|
49
|
+
file = file.replace("example.gitignore", ".gitignore");
|
|
50
|
+
return template.rename?.(file) ?? file;
|
|
51
|
+
} });
|
|
52
|
+
const packageJsonPath = path.join(outputDir, "package.json");
|
|
53
|
+
let packageJson = await initPackageJson(projectName, packageJsonPath);
|
|
54
|
+
for (const plugin of plugins) packageJson = await plugin.packageJson?.call(pluginContext, packageJson) ?? packageJson;
|
|
55
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
56
|
+
const readmePath = path.join(outputDir, "README.md");
|
|
57
|
+
let readme = `# ${projectName}\n\n${await fs.readFile(readmePath)}`;
|
|
58
|
+
for (const plugin of plugins) readme = await plugin.readme?.call(pluginContext, readme) ?? readme;
|
|
59
|
+
await fs.writeFile(readmePath, readme);
|
|
60
|
+
for (const plugin of plugins) await plugin.afterWrite?.call(pluginContext);
|
|
61
|
+
if (installDeps) try {
|
|
62
|
+
await autoInstall(packageManager, outputDir);
|
|
63
|
+
log("Installed dependencies");
|
|
64
|
+
} catch (err) {
|
|
65
|
+
log(`Failed to install dependencies: ${err}`);
|
|
66
|
+
}
|
|
67
|
+
if (initializeGit && await tryGitInit(outputDir)) log("Initialized Git repository");
|
|
68
|
+
}
|
|
69
|
+
async function initPackageJson(projectName, packageJsonPath) {
|
|
70
|
+
function replaceWorkspaceDeps(deps = {}) {
|
|
71
|
+
for (const k in deps) if (deps[k].startsWith("workspace:") && k in depVersions) deps[k] = depVersions[k];
|
|
72
|
+
return deps;
|
|
73
|
+
}
|
|
74
|
+
const packageJson = JSON.parse((await fs.readFile(packageJsonPath)).toString());
|
|
75
|
+
return {
|
|
76
|
+
...packageJson,
|
|
77
|
+
name: projectName,
|
|
78
|
+
scripts: {
|
|
79
|
+
...packageJson.scripts,
|
|
80
|
+
postinstall: "fumadocs-mdx"
|
|
81
|
+
},
|
|
82
|
+
dependencies: replaceWorkspaceDeps(packageJson.dependencies),
|
|
83
|
+
devDependencies: replaceWorkspaceDeps(packageJson.devDependencies)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
export { getPackageManager as n, managers as r, create as t };
|
|
89
|
+
//# sourceMappingURL=src-DWqRvlfn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-DWqRvlfn.js","names":["pluginContext: TemplatePluginContext","packageJson: PackageJsonType"],"sources":["../src/auto-install.ts","../src/index.ts"],"sourcesContent":["import { x } from 'tinyexec';\n\nexport type PackageManager = (typeof managers)[number];\n\nexport const managers = ['npm', 'yarn', 'bun', 'pnpm'] as const;\n\nexport function getPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent ?? '';\n\n if (userAgent.startsWith('yarn')) {\n return 'yarn';\n }\n\n if (userAgent.startsWith('pnpm')) {\n return 'pnpm';\n }\n\n if (userAgent.startsWith('bun')) {\n return 'bun';\n }\n\n return 'npm';\n}\n\nexport async function autoInstall(manager: PackageManager, dest: string) {\n await x(manager, ['install'], {\n throwOnError: true,\n nodeOptions: {\n env: {\n ...process.env,\n NODE_ENV: 'development',\n DISABLE_OPENCOLLECTIVE: '1',\n },\n cwd: dest,\n },\n });\n}\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { copy, tryGitInit } from '@/utils';\nimport type { PackageManager } from './auto-install';\nimport { autoInstall } from './auto-install';\nimport { depVersions, sourceDir, type TemplateInfo, templates } from './constants';\n\nexport type Template = TemplateInfo['value'];\nexport interface Options {\n outputDir: string;\n template: Template;\n\n /**\n * the package manager to use\n *\n * @defaultValue 'npm'\n */\n packageManager?: PackageManager;\n\n installDeps?: boolean;\n initializeGit?: boolean;\n log?: (message: string) => void;\n plugins?: TemplatePlugin[];\n}\n\nexport interface TemplatePluginContext {\n template: TemplateInfo;\n log: (message: string) => void;\n /**\n * output directory\n */\n dest: string;\n\n /**\n * output directory for app code (e.g. under `/src`)\n */\n appDir: string;\n}\n\nexport type PackageJsonType = {\n name?: string;\n version?: string;\n private?: boolean;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n} & Record<string, unknown>;\n\ntype Awaitable<T> = T | Promise<T>;\n\nexport interface TemplatePlugin {\n template?: (\n this: Pick<TemplatePluginContext, 'dest'>,\n info: TemplateInfo,\n ) => Awaitable<void | TemplateInfo>;\n packageJson?: (\n this: TemplatePluginContext,\n packageJson: PackageJsonType,\n ) => Awaitable<void | PackageJsonType>;\n afterWrite?: (this: TemplatePluginContext) => Awaitable<void>;\n readme?: (this: TemplatePluginContext, content: string) => Awaitable<void | string>;\n}\n\nexport async function create(createOptions: Options): Promise<void> {\n const {\n outputDir,\n plugins = [],\n packageManager = 'npm',\n initializeGit = false,\n installDeps = false,\n log = console.log,\n } = createOptions;\n\n let template = templates.find((item) => item.value === createOptions.template)!;\n for (const plugin of plugins) {\n template = (await plugin.template?.call({ dest: outputDir }, template)) ?? template;\n }\n\n const appDir = path.join(outputDir, template.appDir);\n const projectName = path.basename(outputDir);\n const pluginContext: TemplatePluginContext = {\n template,\n dest: outputDir,\n log,\n appDir,\n };\n\n await copy(path.join(sourceDir, 'template', template.value), outputDir, {\n rename(file) {\n file = file.replace('example.gitignore', '.gitignore');\n\n return template.rename?.(file) ?? file;\n },\n });\n\n const packageJsonPath = path.join(outputDir, 'package.json');\n let packageJson = await initPackageJson(projectName, packageJsonPath);\n for (const plugin of plugins) {\n packageJson = (await plugin.packageJson?.call(pluginContext, packageJson)) ?? packageJson;\n }\n await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n\n const readmePath = path.join(outputDir, 'README.md');\n let readme = `# ${projectName}\\n\\n${await fs.readFile(readmePath)}`;\n for (const plugin of plugins) {\n readme = (await plugin.readme?.call(pluginContext, readme)) ?? readme;\n }\n await fs.writeFile(readmePath, readme);\n\n for (const plugin of plugins) {\n await plugin.afterWrite?.call(pluginContext);\n }\n\n if (installDeps) {\n try {\n await autoInstall(packageManager, outputDir);\n log('Installed dependencies');\n } catch (err) {\n log(`Failed to install dependencies: ${err}`);\n }\n }\n\n if (initializeGit && (await tryGitInit(outputDir))) {\n log('Initialized Git repository');\n }\n}\n\nasync function initPackageJson(\n projectName: string,\n packageJsonPath: string,\n): Promise<PackageJsonType> {\n function replaceWorkspaceDeps(deps: Record<string, string> = {}) {\n for (const k in deps) {\n if (deps[k].startsWith('workspace:') && k in depVersions) {\n deps[k] = depVersions[k as keyof typeof depVersions];\n }\n }\n\n return deps;\n }\n\n const packageJson: PackageJsonType = JSON.parse((await fs.readFile(packageJsonPath)).toString());\n\n return {\n ...packageJson,\n name: projectName,\n scripts: {\n ...packageJson.scripts,\n postinstall: 'fumadocs-mdx',\n },\n dependencies: replaceWorkspaceDeps(packageJson.dependencies),\n devDependencies: replaceWorkspaceDeps(packageJson.devDependencies),\n };\n}\n"],"mappings":";;;;;;AAIA,MAAa,WAAW;CAAC;CAAO;CAAQ;CAAO;CAAO;AAEtD,SAAgB,oBAAoC;CAClD,MAAM,YAAY,QAAQ,IAAI,yBAAyB;AAEvD,KAAI,UAAU,WAAW,OAAO,CAC9B,QAAO;AAGT,KAAI,UAAU,WAAW,OAAO,CAC9B,QAAO;AAGT,KAAI,UAAU,WAAW,MAAM,CAC7B,QAAO;AAGT,QAAO;;AAGT,eAAsB,YAAY,SAAyB,MAAc;AACvE,OAAM,EAAE,SAAS,CAAC,UAAU,EAAE;EAC5B,cAAc;EACd,aAAa;GACX,KAAK;IACH,GAAG,QAAQ;IACX,UAAU;IACV,wBAAwB;IACzB;GACD,KAAK;GACN;EACF,CAAC;;;;;AC4BJ,eAAsB,OAAO,eAAuC;CAClE,MAAM,EACJ,WACA,UAAU,EAAE,EACZ,iBAAiB,OACjB,gBAAgB,OAChB,cAAc,OACd,MAAM,QAAQ,QACZ;CAEJ,IAAI,WAAW,UAAU,MAAM,SAAS,KAAK,UAAU,cAAc,SAAS;AAC9E,MAAK,MAAM,UAAU,QACnB,YAAY,MAAM,OAAO,UAAU,KAAK,EAAE,MAAM,WAAW,EAAE,SAAS,IAAK;CAG7E,MAAM,SAAS,KAAK,KAAK,WAAW,SAAS,OAAO;CACpD,MAAM,cAAc,KAAK,SAAS,UAAU;CAC5C,MAAMA,gBAAuC;EAC3C;EACA,MAAM;EACN;EACA;EACD;AAED,OAAM,KAAK,KAAK,KAAK,WAAW,YAAY,SAAS,MAAM,EAAE,WAAW,EACtE,OAAO,MAAM;AACX,SAAO,KAAK,QAAQ,qBAAqB,aAAa;AAEtD,SAAO,SAAS,SAAS,KAAK,IAAI;IAErC,CAAC;CAEF,MAAM,kBAAkB,KAAK,KAAK,WAAW,eAAe;CAC5D,IAAI,cAAc,MAAM,gBAAgB,aAAa,gBAAgB;AACrE,MAAK,MAAM,UAAU,QACnB,eAAe,MAAM,OAAO,aAAa,KAAK,eAAe,YAAY,IAAK;AAEhF,OAAM,GAAG,UAAU,iBAAiB,KAAK,UAAU,aAAa,MAAM,EAAE,CAAC;CAEzE,MAAM,aAAa,KAAK,KAAK,WAAW,YAAY;CACpD,IAAI,SAAS,KAAK,YAAY,MAAM,MAAM,GAAG,SAAS,WAAW;AACjE,MAAK,MAAM,UAAU,QACnB,UAAU,MAAM,OAAO,QAAQ,KAAK,eAAe,OAAO,IAAK;AAEjE,OAAM,GAAG,UAAU,YAAY,OAAO;AAEtC,MAAK,MAAM,UAAU,QACnB,OAAM,OAAO,YAAY,KAAK,cAAc;AAG9C,KAAI,YACF,KAAI;AACF,QAAM,YAAY,gBAAgB,UAAU;AAC5C,MAAI,yBAAyB;UACtB,KAAK;AACZ,MAAI,mCAAmC,MAAM;;AAIjD,KAAI,iBAAkB,MAAM,WAAW,UAAU,CAC/C,KAAI,6BAA6B;;AAIrC,eAAe,gBACb,aACA,iBAC0B;CAC1B,SAAS,qBAAqB,OAA+B,EAAE,EAAE;AAC/D,OAAK,MAAM,KAAK,KACd,KAAI,KAAK,GAAG,WAAW,aAAa,IAAI,KAAK,YAC3C,MAAK,KAAK,YAAY;AAI1B,SAAO;;CAGT,MAAMC,cAA+B,KAAK,OAAO,MAAM,GAAG,SAAS,gBAAgB,EAAE,UAAU,CAAC;AAEhG,QAAO;EACL,GAAG;EACH,MAAM;EACN,SAAS;GACP,GAAG,YAAY;GACf,aAAa;GACd;EACD,cAAc,qBAAqB,YAAY,aAAa;EAC5D,iBAAiB,qBAAqB,YAAY,gBAAgB;EACnE"}
|
package/package.json
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fumadocs-app",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.34",
|
|
4
4
|
"description": "Create a new documentation site with Fumadocs",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"react",
|
|
7
6
|
"Docs",
|
|
8
|
-
"Fumadocs"
|
|
7
|
+
"Fumadocs",
|
|
8
|
+
"react"
|
|
9
9
|
],
|
|
10
10
|
"homepage": "https://fumadocs.dev",
|
|
11
|
-
"repository": "github:fuma-nama/fumadocs",
|
|
12
11
|
"license": "MIT",
|
|
13
12
|
"author": "Fuma Nama",
|
|
14
|
-
"
|
|
13
|
+
"repository": "github:fuma-nama/fumadocs",
|
|
15
14
|
"bin": "./dist/bin.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/*",
|
|
17
|
+
"template/*"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
16
20
|
"module": "./dist/index.js",
|
|
17
21
|
"types": "./dist/index.d.ts",
|
|
18
22
|
"exports": {
|
|
19
23
|
".": {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js"
|
|
22
26
|
},
|
|
23
27
|
"./plugins/*": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
28
|
+
"types": "./dist/plugins/*.d.ts",
|
|
29
|
+
"import": "./dist/plugins/*.js"
|
|
26
30
|
}
|
|
27
31
|
},
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
32
35
|
"dependencies": {
|
|
33
36
|
"@clack/prompts": "^0.11.0",
|
|
34
37
|
"@commander-js/extra-typings": "^14.0.0",
|
|
@@ -41,6 +44,7 @@
|
|
|
41
44
|
"@types/cross-spawn": "^6.0.6",
|
|
42
45
|
"@types/node": "24.10.2",
|
|
43
46
|
"tinyglobby": "^0.2.15",
|
|
47
|
+
"tsdown": "^0.18.3",
|
|
44
48
|
"typescript": "^5.9.3",
|
|
45
49
|
"eslint-config-custom": "0.0.0",
|
|
46
50
|
"tsconfig": "0.0.0"
|
|
@@ -48,13 +52,10 @@
|
|
|
48
52
|
"engines": {
|
|
49
53
|
"node": ">=18.17.0"
|
|
50
54
|
},
|
|
51
|
-
"publishConfig": {
|
|
52
|
-
"access": "public"
|
|
53
|
-
},
|
|
54
55
|
"scripts": {
|
|
55
|
-
"build": "pnpm run sync &&
|
|
56
|
+
"build": "pnpm run sync && tsdown",
|
|
56
57
|
"clean": "rimraf dist",
|
|
57
|
-
"dev": "
|
|
58
|
+
"dev": "tsdown --watch",
|
|
58
59
|
"lint": "eslint .",
|
|
59
60
|
"types:check": "tsc --noEmit",
|
|
60
61
|
"sync": "bun ./scripts/sync.ts"
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { getPageImage, source } from '@/lib/source';
|
|
2
|
-
import {
|
|
3
|
-
DocsBody,
|
|
4
|
-
DocsDescription,
|
|
5
|
-
DocsPage,
|
|
6
|
-
DocsTitle,
|
|
7
|
-
} from 'fumadocs-ui/layouts/docs/page';
|
|
2
|
+
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
|
|
8
3
|
import { notFound } from 'next/navigation';
|
|
9
4
|
import { getMDXComponents } from '@/mdx-components';
|
|
10
5
|
import type { Metadata } from 'next';
|
|
@@ -37,9 +32,7 @@ export async function generateStaticParams() {
|
|
|
37
32
|
return source.generateParams();
|
|
38
33
|
}
|
|
39
34
|
|
|
40
|
-
export async function generateMetadata(
|
|
41
|
-
props: PageProps<'/docs/[[...slug]]'>,
|
|
42
|
-
): Promise<Metadata> {
|
|
35
|
+
export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise<Metadata> {
|
|
43
36
|
const params = await props.params;
|
|
44
37
|
const page = source.getPage(params.slug);
|
|
45
38
|
if (!page) notFound();
|
|
@@ -4,7 +4,7 @@ import { baseOptions } from '@/lib/layout.shared';
|
|
|
4
4
|
|
|
5
5
|
export default function Layout({ children }: LayoutProps<'/docs'>) {
|
|
6
6
|
return (
|
|
7
|
-
<DocsLayout tree={source.
|
|
7
|
+
<DocsLayout tree={source.getPageTree()} {...baseOptions()}>
|
|
8
8
|
{children}
|
|
9
9
|
</DocsLayout>
|
|
10
10
|
);
|
|
@@ -5,20 +5,13 @@ import { generate as DefaultImage } from 'fumadocs-ui/og';
|
|
|
5
5
|
|
|
6
6
|
export const revalidate = false;
|
|
7
7
|
|
|
8
|
-
export async function GET(
|
|
9
|
-
_req: Request,
|
|
10
|
-
{ params }: RouteContext<'/og/docs/[...slug]'>,
|
|
11
|
-
) {
|
|
8
|
+
export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
|
|
12
9
|
const { slug } = await params;
|
|
13
10
|
const page = source.getPage(slug.slice(0, -1));
|
|
14
11
|
if (!page) notFound();
|
|
15
12
|
|
|
16
13
|
return new ImageResponse(
|
|
17
|
-
<DefaultImage
|
|
18
|
-
title={page.data.title}
|
|
19
|
-
description={page.data.description}
|
|
20
|
-
site="My App"
|
|
21
|
-
/>,
|
|
14
|
+
<DefaultImage title={page.data.title} description={page.data.description} site="My App" />,
|
|
22
15
|
{
|
|
23
16
|
width: 1200,
|
|
24
17
|
height: 630,
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"fumadocs-core": "workspace:*",
|
|
13
13
|
"fumadocs-mdx": "workspace:*",
|
|
14
14
|
"fumadocs-ui": "workspace:*",
|
|
15
|
-
"lucide-react": "^0.
|
|
16
|
-
"next": "16.
|
|
15
|
+
"lucide-react": "^0.562.0",
|
|
16
|
+
"next": "16.1.1",
|
|
17
17
|
"react": "^19.2.3",
|
|
18
18
|
"react-dom": "^19.2.3"
|
|
19
19
|
},
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineConfig,
|
|
3
|
-
defineDocs,
|
|
4
|
-
frontmatterSchema,
|
|
5
|
-
metaSchema,
|
|
6
|
-
} from 'fumadocs-mdx/config';
|
|
1
|
+
import { defineConfig, defineDocs, frontmatterSchema, metaSchema } from 'fumadocs-mdx/config';
|
|
7
2
|
|
|
8
3
|
// You can customise Zod schemas for frontmatter and `meta.json` here
|
|
9
4
|
// see https://fumadocs.dev/docs/mdx/collections
|
|
@@ -30,12 +30,7 @@ export default function CustomSearchDialog(props: SharedProps) {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
|
-
<SearchDialog
|
|
34
|
-
search={search}
|
|
35
|
-
onSearchChange={setSearch}
|
|
36
|
-
isLoading={query.isLoading}
|
|
37
|
-
{...props}
|
|
38
|
-
>
|
|
33
|
+
<SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
|
|
39
34
|
<SearchDialogOverlay />
|
|
40
35
|
<SearchDialogContent>
|
|
41
36
|
<SearchDialogHeader>
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { Route } from './+types/page';
|
|
2
2
|
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
|
-
import {
|
|
4
|
-
DocsBody,
|
|
5
|
-
DocsDescription,
|
|
6
|
-
DocsPage,
|
|
7
|
-
DocsTitle,
|
|
8
|
-
} from 'fumadocs-ui/layouts/docs/page';
|
|
3
|
+
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
|
|
9
4
|
import { source } from '@/lib/source';
|
|
10
5
|
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
11
6
|
import browserCollections from 'fumadocs-mdx:collections/browser';
|
|
@@ -53,9 +53,7 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
|
|
|
53
53
|
if (isRouteErrorResponse(error)) {
|
|
54
54
|
message = error.status === 404 ? '404' : 'Error';
|
|
55
55
|
details =
|
|
56
|
-
error.status === 404
|
|
57
|
-
? 'The requested page could not be found.'
|
|
58
|
-
: error.statusText || details;
|
|
56
|
+
error.status === 404 ? 'The requested page could not be found.' : error.statusText || details;
|
|
59
57
|
} else if (import.meta.env.DEV && error && error instanceof Error) {
|
|
60
58
|
details = error.message;
|
|
61
59
|
stack = error.stack;
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
"types:check": "react-router typegen && fumadocs-mdx && tsc --noEmit"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@react-router/node": "^7.
|
|
13
|
-
"@react-router/serve": "^7.
|
|
12
|
+
"@react-router/node": "^7.11.0",
|
|
13
|
+
"@react-router/serve": "^7.11.0",
|
|
14
14
|
"fumadocs-core": "workspace:*",
|
|
15
15
|
"fumadocs-mdx": "workspace:*",
|
|
16
16
|
"fumadocs-ui": "workspace:*",
|
|
17
17
|
"isbot": "^5.1.32",
|
|
18
18
|
"react": "^19.2.3",
|
|
19
19
|
"react-dom": "^19.2.3",
|
|
20
|
-
"react-router": "^7.
|
|
20
|
+
"react-router": "^7.11.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@react-router/dev": "^7.
|
|
23
|
+
"@react-router/dev": "^7.11.0",
|
|
24
24
|
"@tailwindcss/vite": "^4.1.18",
|
|
25
25
|
"@types/mdx": "^2.0.13",
|
|
26
26
|
"@types/node": "^24.10.2",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"react-router-devtools": "^6.0.0",
|
|
30
30
|
"tailwindcss": "^4.1.18",
|
|
31
31
|
"typescript": "^5.9.3",
|
|
32
|
-
"vite": "^7.
|
|
33
|
-
"vite-tsconfig-paths": "^6.0.
|
|
32
|
+
"vite": "^7.3.0",
|
|
33
|
+
"vite-tsconfig-paths": "^6.0.3"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"include": [
|
|
3
|
-
"**/*",
|
|
4
|
-
"**/.server/**/*",
|
|
5
|
-
"**/.client/**/*",
|
|
6
|
-
".react-router/types/**/*"
|
|
7
|
-
],
|
|
2
|
+
"include": ["**/*", "**/.server/**/*", "**/.client/**/*", ".react-router/types/**/*"],
|
|
8
3
|
"compilerOptions": {
|
|
9
4
|
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
5
|
"types": ["node", "vite/client"],
|
|
@@ -30,12 +30,7 @@ export default function DefaultSearchDialog(props: SharedProps) {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
|
-
<SearchDialog
|
|
34
|
-
search={search}
|
|
35
|
-
onSearchChange={setSearch}
|
|
36
|
-
isLoading={query.isLoading}
|
|
37
|
-
{...props}
|
|
38
|
-
>
|
|
33
|
+
<SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
|
|
39
34
|
<SearchDialogOverlay />
|
|
40
35
|
<SearchDialogContent>
|
|
41
36
|
<SearchDialogHeader>
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { Route } from './+types/page';
|
|
2
2
|
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
|
-
import {
|
|
4
|
-
DocsBody,
|
|
5
|
-
DocsDescription,
|
|
6
|
-
DocsPage,
|
|
7
|
-
DocsTitle,
|
|
8
|
-
} from 'fumadocs-ui/layouts/docs/page';
|
|
3
|
+
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
|
|
9
4
|
import { source } from '@/lib/source';
|
|
10
5
|
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
11
6
|
import browserCollections from 'fumadocs-mdx:collections/browser';
|
|
@@ -19,7 +14,7 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|
|
19
14
|
|
|
20
15
|
return {
|
|
21
16
|
path: page.path,
|
|
22
|
-
pageTree: await source.serializePageTree(source.
|
|
17
|
+
pageTree: await source.serializePageTree(source.getPageTree()),
|
|
23
18
|
};
|
|
24
19
|
}
|
|
25
20
|
|
|
@@ -54,9 +54,7 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
|
|
|
54
54
|
if (isRouteErrorResponse(error)) {
|
|
55
55
|
message = error.status === 404 ? '404' : 'Error';
|
|
56
56
|
details =
|
|
57
|
-
error.status === 404
|
|
58
|
-
? 'The requested page could not be found.'
|
|
59
|
-
: error.statusText || details;
|
|
57
|
+
error.status === 404 ? 'The requested page could not be found.' : error.statusText || details;
|
|
60
58
|
} else if (import.meta.env.DEV && error && error instanceof Error) {
|
|
61
59
|
details = error.message;
|
|
62
60
|
stack = error.stack;
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
"types:check": "react-router typegen && fumadocs-mdx && tsc --noEmit"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@orama/orama": "^3.1.
|
|
13
|
-
"@react-router/node": "^7.
|
|
12
|
+
"@orama/orama": "^3.1.18",
|
|
13
|
+
"@react-router/node": "^7.11.0",
|
|
14
14
|
"fumadocs-core": "workspace:*",
|
|
15
15
|
"fumadocs-mdx": "workspace:*",
|
|
16
16
|
"fumadocs-ui": "workspace:*",
|
|
17
17
|
"isbot": "^5.1.32",
|
|
18
18
|
"react": "^19.2.3",
|
|
19
19
|
"react-dom": "^19.2.3",
|
|
20
|
-
"react-router": "^7.
|
|
20
|
+
"react-router": "^7.11.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@react-router/dev": "^7.
|
|
23
|
+
"@react-router/dev": "^7.11.0",
|
|
24
24
|
"@tailwindcss/vite": "^4.1.18",
|
|
25
25
|
"@types/mdx": "^2.0.13",
|
|
26
26
|
"@types/node": "^24.10.2",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"serve": "^14.2.5",
|
|
31
31
|
"tailwindcss": "^4.1.18",
|
|
32
32
|
"typescript": "^5.9.3",
|
|
33
|
-
"vite": "^7.
|
|
34
|
-
"vite-tsconfig-paths": "^6.0.
|
|
33
|
+
"vite": "^7.3.0",
|
|
34
|
+
"vite-tsconfig-paths": "^6.0.3"
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"include": [
|
|
3
|
-
"**/*",
|
|
4
|
-
"**/.server/**/*",
|
|
5
|
-
"**/.client/**/*",
|
|
6
|
-
".react-router/types/**/*"
|
|
7
|
-
],
|
|
2
|
+
"include": ["**/*", "**/.server/**/*", "**/.client/**/*", ".react-router/types/**/*"],
|
|
8
3
|
"compilerOptions": {
|
|
9
4
|
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
5
|
"types": ["node", "vite/client"],
|
|
@@ -11,10 +11,7 @@ Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
|
|
|
11
11
|
Hello World!
|
|
12
12
|
|
|
13
13
|
<Cards>
|
|
14
|
-
<Card
|
|
15
|
-
title="Learn more about Tanstack Start"
|
|
16
|
-
href="https://tanstack.com/start"
|
|
17
|
-
/>
|
|
14
|
+
<Card title="Learn more about Tanstack Start" href="https://tanstack.com/start" />
|
|
18
15
|
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
|
|
19
16
|
</Cards>
|
|
20
17
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "example-tanstack-start",
|
|
3
3
|
"private": true,
|
|
4
|
-
"sideEffects": false,
|
|
5
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite dev",
|
|
8
8
|
"build": "vite build",
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"fumadocs-core": "workspace:*",
|
|
17
17
|
"fumadocs-mdx": "workspace:*",
|
|
18
18
|
"fumadocs-ui": "workspace:*",
|
|
19
|
-
"lucide-react": "^0.
|
|
19
|
+
"lucide-react": "^0.562.0",
|
|
20
20
|
"react": "^19.2.3",
|
|
21
21
|
"react-dom": "^19.2.3",
|
|
22
22
|
"tailwind-merge": "^3.4.0",
|
|
23
|
-
"vite": "^7.
|
|
23
|
+
"vite": "^7.3.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@tailwindcss/vite": "^4.1.18",
|
|
@@ -32,6 +32,6 @@
|
|
|
32
32
|
"nitro": "3.0.1-alpha.1",
|
|
33
33
|
"tailwindcss": "^4.1.18",
|
|
34
34
|
"typescript": "^5.9.3",
|
|
35
|
-
"vite-tsconfig-paths": "^6.0.
|
|
35
|
+
"vite-tsconfig-paths": "^6.0.3"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -13,8 +13,8 @@ export function NotFound() {
|
|
|
13
13
|
<h1 className="text-6xl font-bold text-fd-muted-foreground">404</h1>
|
|
14
14
|
<h2 className="text-2xl font-semibold">Page Not Found</h2>
|
|
15
15
|
<p className="text-fd-muted-foreground max-w-md">
|
|
16
|
-
The page you are looking for might have been removed, had its name
|
|
17
|
-
|
|
16
|
+
The page you are looking for might have been removed, had its name changed, or is
|
|
17
|
+
temporarily unavailable.
|
|
18
18
|
</p>
|
|
19
19
|
<Link
|
|
20
20
|
to="/"
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createRootRoute,
|
|
3
|
-
HeadContent,
|
|
4
|
-
Outlet,
|
|
5
|
-
Scripts,
|
|
6
|
-
} from '@tanstack/react-router';
|
|
1
|
+
import { createRootRoute, HeadContent, Outlet, Scripts } from '@tanstack/react-router';
|
|
7
2
|
import * as React from 'react';
|
|
8
3
|
import appCss from '@/styles/app.css?url';
|
|
9
4
|
import { RootProvider } from 'fumadocs-ui/provider/tanstack';
|
|
@@ -3,12 +3,7 @@ import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
|
3
3
|
import { createServerFn } from '@tanstack/react-start';
|
|
4
4
|
import { source } from '@/lib/source';
|
|
5
5
|
import browserCollections from 'fumadocs-mdx:collections/browser';
|
|
6
|
-
import {
|
|
7
|
-
DocsBody,
|
|
8
|
-
DocsDescription,
|
|
9
|
-
DocsPage,
|
|
10
|
-
DocsTitle,
|
|
11
|
-
} from 'fumadocs-ui/layouts/docs/page';
|
|
6
|
+
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
|
|
12
7
|
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
13
8
|
import { baseOptions } from '@/lib/layout.shared';
|
|
14
9
|
import { useFumadocsLoader } from 'fumadocs-core/source/client';
|
|
@@ -10,9 +10,7 @@ function Home() {
|
|
|
10
10
|
return (
|
|
11
11
|
<HomeLayout {...baseOptions()}>
|
|
12
12
|
<div className="flex flex-col flex-1 justify-center px-4 py-8 text-center">
|
|
13
|
-
<h1 className="font-medium text-xl mb-4">
|
|
14
|
-
Fumadocs on Tanstack Start.
|
|
15
|
-
</h1>
|
|
13
|
+
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
|
|
16
14
|
<Link
|
|
17
15
|
to="/docs/$"
|
|
18
16
|
params={{
|
|
@@ -11,10 +11,7 @@ Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
|
|
|
11
11
|
Hello World!
|
|
12
12
|
|
|
13
13
|
<Cards>
|
|
14
|
-
<Card
|
|
15
|
-
title="Learn more about Tanstack Start"
|
|
16
|
-
href="https://tanstack.com/start"
|
|
17
|
-
/>
|
|
14
|
+
<Card title="Learn more about Tanstack Start" href="https://tanstack.com/start" />
|
|
18
15
|
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
|
|
19
16
|
</Cards>
|
|
20
17
|
|