create-fumadocs-app 16.0.38 → 16.0.40

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.
Files changed (35) hide show
  1. package/dist/bin.js +2 -2
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{constants-CG8Fydtp.js → constants-Dh14AMSp.js} +43 -34
  4. package/dist/constants-Dh14AMSp.js.map +1 -0
  5. package/dist/index.js +2 -2
  6. package/dist/plugins/biome.js +1 -1
  7. package/dist/plugins/eslint.js +1 -1
  8. package/dist/plugins/orama-cloud.js +1 -1
  9. package/dist/plugins/orama-cloud.js.map +1 -1
  10. package/dist/{src-DO725G4h.js → src-Bc7PC9ke.js} +2 -2
  11. package/dist/src-Bc7PC9ke.js.map +1 -0
  12. package/package.json +3 -3
  13. package/template/+next+fuma-docs-mdx/app/docs/[[...slug]]/page.tsx +15 -1
  14. package/template/+next+fuma-docs-mdx/app/llms.mdx/docs/[[...slug]]/route.ts +20 -0
  15. package/template/+next+fuma-docs-mdx/components/ai/page-actions.tsx +230 -0
  16. package/template/+next+fuma-docs-mdx/lib/cn.ts +1 -0
  17. package/template/+next+fuma-docs-mdx/next.config.mjs +8 -0
  18. package/template/+next+fuma-docs-mdx/package.json +4 -3
  19. package/template/+next+fuma-docs-mdx+static/package.json +2 -2
  20. package/template/react-router/app/docs/page.tsx +8 -2
  21. package/template/react-router/package.json +9 -9
  22. package/template/react-router-spa/app/docs/page.tsx +8 -2
  23. package/template/react-router-spa/package.json +8 -8
  24. package/template/tanstack-start/package.json +7 -7
  25. package/template/tanstack-start/src/routes/docs/$.tsx +13 -7
  26. package/template/tanstack-start-spa/package.json +9 -9
  27. package/template/tanstack-start-spa/src/lib/source.ts +2 -8
  28. package/template/tanstack-start-spa/src/routes/docs/$.tsx +13 -7
  29. package/template/tanstack-start-spa/src/routes/index.tsx +13 -11
  30. package/template/waku/package.json +5 -5
  31. package/template/waku/src/pages/_root.tsx +20 -0
  32. package/template/waku/waku.config.ts +5 -0
  33. package/dist/constants-CG8Fydtp.js.map +0 -1
  34. package/dist/src-DO725G4h.js.map +0 -1
  35. package/template/waku/src/pages/_layout.tsx +0 -7
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { i as templates, n as isCI } from "./constants-CG8Fydtp.js";
3
- import { n as getPackageManager, r as managers, t as create } from "./src-DO725G4h.js";
2
+ import { i as templates, n as isCI } from "./constants-Dh14AMSp.js";
3
+ import { n as getPackageManager, r as managers, t as create } from "./src-Bc7PC9ke.js";
4
4
  import fs from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { cancel, confirm, group, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","names":["plugins: TemplatePlugin[]"],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport {\n cancel,\n confirm,\n group,\n intro,\n isCancel,\n outro,\n select,\n spinner,\n text,\n} from '@clack/prompts';\nimport pc from 'picocolors';\nimport { getPackageManager, managers } from './auto-install';\nimport { create, type Template, type TemplatePlugin } from './index';\nimport { isCI, templates } from './constants';\nimport { Option, program } from '@commander-js/extra-typings';\n\nconst command = program\n .argument('[name]', 'the project name')\n .option('--src', '(Next.js only) enable `src/` directory')\n .option('--install', 'install packages automatically')\n .option('--no-git', 'disable auto Git repository initialization')\n .addOption(\n new Option(\n '--linter <name>',\n 'configure a linter/formatter, ESLint is currently Next.js only.',\n ).choices(['eslint', 'biome']),\n )\n .addOption(\n new Option('--search <name>', 'configure a search solution').choices(['orama', 'orama-cloud']),\n )\n .addOption(\n new Option('--template <name>', 'choose a template').choices(\n templates.map((item) => item.value),\n ),\n )\n .addOption(\n new Option('--pm <name>', 'choose a package manager')\n .choices(managers)\n .default(getPackageManager()),\n );\n\nasync function main(): Promise<void> {\n command.parse(process.argv);\n const defaultName = command.args[0];\n const config = command.opts();\n intro(pc.bgCyan(pc.bold('Create Fumadocs App')));\n\n const options = await group(\n {\n name: async () => {\n if (defaultName) return defaultName;\n if (isCI) return 'untitled';\n\n return text({\n message: 'Project name',\n placeholder: 'my-app',\n defaultValue: 'my-app',\n });\n },\n template: async () => {\n if (config.template) return config.template;\n if (isCI) return '+next+fuma-docs-mdx';\n\n return select<Template>({\n message: 'Choose a template',\n initialValue: '+next+fuma-docs-mdx',\n options: templates,\n });\n },\n src: async ({ results }: { results: { template?: Template } }) => {\n if (config.src !== undefined) return config.src;\n if (isCI || !results.template?.startsWith('+next')) return false;\n\n return confirm({\n message: 'Use `/src` directory?',\n initialValue: false,\n });\n },\n lint: async ({ results }: { results: { template?: Template } }) => {\n if (config.linter !== undefined) return config.linter;\n if (isCI) return 'disabled';\n\n return select({\n message: 'Configure linter?',\n options: results.template?.startsWith('+next')\n ? [\n {\n value: 'disabled',\n label: 'Disabled',\n },\n {\n value: 'eslint',\n label: 'ESLint',\n },\n {\n value: 'biome',\n label: 'Biome',\n },\n ]\n : [\n {\n value: 'disabled',\n label: 'Disabled',\n },\n {\n value: 'biome',\n label: 'Biome',\n },\n ],\n });\n },\n search: async () => {\n if (config.search !== undefined) return config.search;\n if (isCI) return 'orama';\n\n return select({\n message: 'Choose a search solution?',\n options: [\n {\n value: 'orama',\n label: 'Default',\n hint: 'local search powered by Orama, recommended',\n },\n {\n value: 'orama-cloud',\n label: 'Orama Cloud',\n hint: '3rd party search solution, signup needed',\n },\n ],\n });\n },\n installDeps: async () => {\n if (config.install !== undefined) return config.install;\n if (isCI) return false;\n\n return confirm({\n message: `Do you want to install packages automatically? (detected as ${config.pm})`,\n });\n },\n },\n {\n onCancel: () => {\n cancel('Installation Stopped.');\n process.exit(0);\n },\n },\n );\n\n const projectName = options.name.toLowerCase().replace(/\\s/, '-');\n if (!isCI) await checkDir(projectName);\n\n const info = spinner();\n info.start(`Generating Project`);\n const plugins: TemplatePlugin[] = [];\n\n if (options.src) {\n const { nextUseSrc } = await import('./plugins/next-use-src');\n plugins.push(nextUseSrc());\n }\n\n if (options.search === 'orama-cloud') {\n const { oramaCloud } = await import('./plugins/orama-cloud');\n plugins.push(oramaCloud());\n }\n\n if (options.lint === 'eslint') {\n const { eslint } = await import('./plugins/eslint');\n plugins.push(eslint());\n }\n\n if (options.lint === 'biome') {\n const { biome } = await import('./plugins/biome');\n plugins.push(biome());\n }\n\n await create({\n packageManager: config.pm,\n template: options.template,\n outputDir: projectName,\n installDeps: options.installDeps,\n initializeGit: config.git,\n plugins,\n log: (message) => {\n info.message(message);\n },\n });\n\n info.stop('Project Generated');\n\n outro(pc.bgGreen(pc.bold('Done')));\n\n console.log(pc.bold('\\nOpen the project'));\n console.log(pc.cyan(`cd ${projectName}`));\n\n console.log(pc.bold('\\nRun Development Server'));\n if (config.pm === 'npm' || config.pm === 'bun') {\n console.log(pc.cyan(`${config.pm} run dev`));\n } else {\n console.log(pc.cyan(`${config.pm} dev`));\n }\n console.log(pc.bold('\\nYou can now open the project and start writing documents'));\n\n process.exit(0);\n}\n\nasync function checkDir(outputDir: string) {\n const destDir = await fs.readdir(outputDir).catch(() => null);\n if (!destDir || destDir.length === 0) return;\n const del = await confirm({\n message: `directory ${outputDir} already exists, do you want to delete its files?`,\n });\n\n if (isCancel(del)) {\n cancel();\n process.exit(1);\n }\n\n if (!del) return;\n\n const info = spinner();\n info.start(`Deleting files in ${outputDir}`);\n\n await Promise.all(\n destDir.map((item) => {\n return fs.rm(path.join(outputDir, item), {\n recursive: true,\n force: true,\n });\n }),\n );\n\n info.stop(`Deleted files in ${outputDir}`);\n}\n\nmain().catch((e: unknown) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport {\n cancel,\n confirm,\n group,\n intro,\n isCancel,\n outro,\n select,\n spinner,\n text,\n} from '@clack/prompts';\nimport pc from 'picocolors';\nimport { getPackageManager, managers } from './auto-install';\nimport { create, type Template, type TemplatePlugin } from './index';\nimport { isCI, templates } from './constants';\nimport { Option, program } from '@commander-js/extra-typings';\n\nconst command = program\n .argument('[name]', 'the project name')\n .option('--src', '(Next.js only) enable `src/` directory')\n .option('--install', 'install packages automatically')\n .option('--no-git', 'disable auto Git repository initialization')\n .addOption(\n new Option(\n '--linter <name>',\n 'configure a linter/formatter, ESLint is currently Next.js only.',\n ).choices(['eslint', 'biome']),\n )\n .addOption(\n new Option('--search <name>', 'configure a search solution').choices(['orama', 'orama-cloud']),\n )\n .addOption(\n new Option('--template <name>', 'choose a template').choices(\n templates.map((item) => item.value),\n ),\n )\n .addOption(\n new Option('--pm <name>', 'choose a package manager')\n .choices(managers)\n .default(getPackageManager()),\n );\n\nasync function main(): Promise<void> {\n command.parse(process.argv);\n const defaultName = command.args[0];\n const config = command.opts();\n intro(pc.bgCyan(pc.bold('Create Fumadocs App')));\n\n const options = await group(\n {\n name: async () => {\n if (defaultName) return defaultName;\n if (isCI) return 'untitled';\n\n return text({\n message: 'Project name',\n placeholder: 'my-app',\n defaultValue: 'my-app',\n });\n },\n template: async () => {\n if (config.template) return config.template;\n if (isCI) return '+next+fuma-docs-mdx';\n\n return select<Template>({\n message: 'Choose a template',\n initialValue: '+next+fuma-docs-mdx',\n options: templates,\n });\n },\n src: async ({ results }: { results: { template?: Template } }) => {\n if (config.src !== undefined) return config.src;\n if (isCI || !results.template?.startsWith('+next')) return false;\n\n return confirm({\n message: 'Use `/src` directory?',\n initialValue: false,\n });\n },\n lint: async ({ results }: { results: { template?: Template } }) => {\n if (config.linter !== undefined) return config.linter;\n if (isCI) return 'disabled';\n\n return select({\n message: 'Configure linter?',\n options: results.template?.startsWith('+next')\n ? [\n {\n value: 'disabled',\n label: 'Disabled',\n },\n {\n value: 'eslint',\n label: 'ESLint',\n },\n {\n value: 'biome',\n label: 'Biome',\n },\n ]\n : [\n {\n value: 'disabled',\n label: 'Disabled',\n },\n {\n value: 'biome',\n label: 'Biome',\n },\n ],\n });\n },\n search: async () => {\n if (config.search !== undefined) return config.search;\n if (isCI) return 'orama';\n\n return select({\n message: 'Choose a search solution?',\n options: [\n {\n value: 'orama',\n label: 'Default',\n hint: 'local search powered by Orama, recommended',\n },\n {\n value: 'orama-cloud',\n label: 'Orama Cloud',\n hint: '3rd party search solution, signup needed',\n },\n ],\n });\n },\n installDeps: async () => {\n if (config.install !== undefined) return config.install;\n if (isCI) return false;\n\n return confirm({\n message: `Do you want to install packages automatically? (detected as ${config.pm})`,\n });\n },\n },\n {\n onCancel: () => {\n cancel('Installation Stopped.');\n process.exit(0);\n },\n },\n );\n\n const projectName = options.name.toLowerCase().replace(/\\s/, '-');\n if (!isCI) await checkDir(projectName);\n\n const info = spinner();\n info.start(`Generating Project`);\n const plugins: TemplatePlugin[] = [];\n\n if (options.src) {\n const { nextUseSrc } = await import('./plugins/next-use-src');\n plugins.push(nextUseSrc());\n }\n\n if (options.search === 'orama-cloud') {\n const { oramaCloud } = await import('./plugins/orama-cloud');\n plugins.push(oramaCloud());\n }\n\n if (options.lint === 'eslint') {\n const { eslint } = await import('./plugins/eslint');\n plugins.push(eslint());\n }\n\n if (options.lint === 'biome') {\n const { biome } = await import('./plugins/biome');\n plugins.push(biome());\n }\n\n await create({\n packageManager: config.pm,\n template: options.template,\n outputDir: projectName,\n installDeps: options.installDeps,\n initializeGit: config.git,\n plugins,\n log: (message) => {\n info.message(message);\n },\n });\n\n info.stop('Project Generated');\n\n outro(pc.bgGreen(pc.bold('Done')));\n\n console.log(pc.bold('\\nOpen the project'));\n console.log(pc.cyan(`cd ${projectName}`));\n\n console.log(pc.bold('\\nRun Development Server'));\n if (config.pm === 'npm' || config.pm === 'bun') {\n console.log(pc.cyan(`${config.pm} run dev`));\n } else {\n console.log(pc.cyan(`${config.pm} dev`));\n }\n console.log(pc.bold('\\nYou can now open the project and start writing documents'));\n\n process.exit(0);\n}\n\nasync function checkDir(outputDir: string) {\n const destDir = await fs.readdir(outputDir).catch(() => null);\n if (!destDir || destDir.length === 0) return;\n const del = await confirm({\n message: `directory ${outputDir} already exists, do you want to delete its files?`,\n });\n\n if (isCancel(del)) {\n cancel();\n process.exit(1);\n }\n\n if (!del) return;\n\n const info = spinner();\n info.start(`Deleting files in ${outputDir}`);\n\n await Promise.all(\n destDir.map((item) => {\n return fs.rm(path.join(outputDir, item), {\n recursive: true,\n force: true,\n });\n }),\n );\n\n info.stop(`Deleted files in ${outputDir}`);\n}\n\nmain().catch((e: unknown) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -77,7 +77,10 @@ async function tryGitInit(cwd) {
77
77
  });
78
78
  return true;
79
79
  } catch {
80
- await fs.rmdir(join(cwd, ".git"), { recursive: true }).catch(() => null);
80
+ await fs.rm(join(cwd, ".git"), {
81
+ recursive: true,
82
+ force: true
83
+ });
81
84
  return false;
82
85
  }
83
86
  }
@@ -122,7 +125,7 @@ var package_exports$4 = /* @__PURE__ */ __exportAll({
122
125
  version: () => version$4
123
126
  });
124
127
  var name$4 = "fumadocs-core";
125
- var version$4 = "16.4.5";
128
+ var version$4 = "16.4.7";
126
129
  var description$4 = "The React.js library for building a documentation website";
127
130
  var keywords$4 = ["Docs", "Fumadocs"];
128
131
  var homepage$4 = "https://fumadocs.dev";
@@ -234,10 +237,10 @@ var scripts$4 = {
234
237
  "types:check": "tsc --noEmit"
235
238
  };
236
239
  var dependencies$4 = {
237
- "@formatjs/intl-localematcher": "^0.7.4",
240
+ "@formatjs/intl-localematcher": "^0.7.5",
238
241
  "@orama/orama": "^3.1.18",
239
- "@shikijs/rehype": "^3.20.0",
240
- "@shikijs/transformers": "^3.20.0",
242
+ "@shikijs/rehype": "^3.21.0",
243
+ "@shikijs/transformers": "^3.21.0",
241
244
  "estree-util-value-to-estree": "^3.5.0",
242
245
  "github-slugger": "^2.0.0",
243
246
  "hast-util-to-estree": "^3.1.3",
@@ -250,22 +253,22 @@ var dependencies$4 = {
250
253
  "remark-gfm": "^4.0.1",
251
254
  "remark-rehype": "^11.1.2",
252
255
  "scroll-into-view-if-needed": "^3.1.0",
253
- "shiki": "^3.20.0",
256
+ "shiki": "^3.21.0",
254
257
  "tinyglobby": "^0.2.15",
255
258
  "unist-util-visit": "^5.0.0"
256
259
  };
257
260
  var devDependencies$4 = {
258
261
  "@mdx-js/mdx": "^3.1.1",
259
- "@mixedbread/sdk": "^0.46.0",
262
+ "@mixedbread/sdk": "^0.50.0",
260
263
  "@orama/core": "^1.2.16",
261
264
  "@oramacloud/client": "^2.1.4",
262
- "@tanstack/react-router": "1.144.0",
265
+ "@tanstack/react-router": "1.147.1",
263
266
  "@types/estree-jsx": "^1.0.5",
264
267
  "@types/hast": "^3.0.4",
265
268
  "@types/mdast": "^4.0.4",
266
269
  "@types/negotiator": "^0.6.4",
267
- "@types/node": "24.10.2",
268
- "@types/react": "^19.2.7",
270
+ "@types/node": "25.0.5",
271
+ "@types/react": "^19.2.8",
269
272
  "@types/react-dom": "^19.2.3",
270
273
  "algoliasearch": "5.46.2",
271
274
  "eslint-config-custom": "workspace:*",
@@ -273,16 +276,16 @@ var devDependencies$4 = {
273
276
  "mdast-util-mdx-jsx": "^3.2.0",
274
277
  "mdast-util-mdxjs-esm": "^2.0.1",
275
278
  "next": "16.1.1",
276
- "react-router": "^7.11.0",
279
+ "react-router": "^7.12.0",
277
280
  "remark-directive": "^4.0.0",
278
281
  "remark-mdx": "^3.1.1",
279
282
  "remove-markdown": "^0.6.2",
280
283
  "tsconfig": "workspace:*",
281
- "tsdown": "^0.18.4",
284
+ "tsdown": "^0.19.0",
282
285
  "typescript": "^5.9.3",
283
286
  "unified": "^11.0.5",
284
287
  "vfile": "^6.0.3",
285
- "waku": "1.0.0-alpha.0",
288
+ "waku": "1.0.0-alpha.1",
286
289
  "zod": "^4.3.5"
287
290
  };
288
291
  var peerDependencies$4 = {
@@ -358,7 +361,7 @@ var package_exports$3 = /* @__PURE__ */ __exportAll({
358
361
  version: () => version$3
359
362
  });
360
363
  var name$3 = "@fumadocs/ui";
361
- var version$3 = "16.4.5";
364
+ var version$3 = "16.4.7";
362
365
  var description$3 = "The low-level primitives for Fumadocs UI.";
363
366
  var keywords$3 = ["Docs", "Fumadocs"];
364
367
  var homepage$3 = "https://fumadocs.dev";
@@ -383,7 +386,6 @@ var scripts$3 = {
383
386
  "types:check": "tsc --noEmit"
384
387
  };
385
388
  var dependencies$3 = {
386
- "fumadocs-core": "workspace:*",
387
389
  "next-themes": "^0.4.6",
388
390
  "postcss-selector-parser": "^7.1.1",
389
391
  "tailwind-merge": "^3.4.0"
@@ -392,8 +394,8 @@ var devDependencies$3 = {
392
394
  "@fumadocs/cli": "workspace:*",
393
395
  "@types/bun": "^1.3.5",
394
396
  "@types/lodash.merge": "^4.6.9",
395
- "@types/node": "^24.10.2",
396
- "@types/react": "^19.2.7",
397
+ "@types/node": "^25.0.5",
398
+ "@types/react": "^19.2.8",
397
399
  "@types/react-dom": "^19.2.3",
398
400
  "class-variance-authority": "^0.7.1",
399
401
  "eslint-config-custom": "workspace:*",
@@ -402,10 +404,11 @@ var devDependencies$3 = {
402
404
  "next": "16.1.1",
403
405
  "tailwindcss": "^4.1.18",
404
406
  "tsconfig": "workspace:*",
405
- "tsdown": "^0.18.4"
407
+ "tsdown": "^0.19.0"
406
408
  };
407
409
  var peerDependencies$3 = {
408
410
  "@types/react": "*",
411
+ "fumadocs-core": "workspace:*",
409
412
  "next": "16.x.x",
410
413
  "react": "^19.2.0",
411
414
  "react-dom": "^19.2.0",
@@ -462,7 +465,7 @@ var package_exports$2 = /* @__PURE__ */ __exportAll({
462
465
  version: () => version$2
463
466
  });
464
467
  var name$2 = "fumadocs-mdx";
465
- var version$2 = "14.2.4";
468
+ var version$2 = "14.2.5";
466
469
  var description$2 = "The built-in source for Fumadocs";
467
470
  var keywords$2 = ["Docs", "NextJs"];
468
471
  var homepage$2 = "https://fumadocs.dev";
@@ -548,9 +551,9 @@ var devDependencies$2 = {
548
551
  "@types/js-yaml": "^4.0.9",
549
552
  "@types/mdast": "^4.0.4",
550
553
  "@types/mdx": "^2.0.13",
551
- "@types/node": "^24.10.2",
554
+ "@types/node": "^25.0.5",
552
555
  "@types/picomatch": "^4.0.2",
553
- "@types/react": "^19.2.7",
556
+ "@types/react": "^19.2.8",
554
557
  "eslint-config-custom": "workspace:*",
555
558
  "fumadocs-core": "workspace:*",
556
559
  "mdast-util-directive": "^3.1.0",
@@ -562,8 +565,8 @@ var devDependencies$2 = {
562
565
  "remark-stringify": "^11.0.0",
563
566
  "rollup": "^4.55.1",
564
567
  "tsconfig": "workspace:*",
565
- "tsdown": "^0.18.4",
566
- "vite": "^7.3.0",
568
+ "tsdown": "^0.19.0",
569
+ "vite": "^7.3.1",
567
570
  "webpack": "^5.104.1"
568
571
  };
569
572
  var peerDependencies$2 = {
@@ -627,7 +630,7 @@ var package_exports$1 = /* @__PURE__ */ __exportAll({
627
630
  version: () => version$1
628
631
  });
629
632
  var name$1 = "fumadocs-ui";
630
- var version$1 = "16.4.5";
633
+ var version$1 = "16.4.7";
631
634
  var description$1 = "The Radix UI version of Fumadocs UI";
632
635
  var keywords$1 = ["Docs", "Fumadocs"];
633
636
  var homepage$1 = "https://fumadocs.dev";
@@ -734,7 +737,6 @@ var dependencies$1 = {
734
737
  "@radix-ui/react-slot": "^1.2.4",
735
738
  "@radix-ui/react-tabs": "^1.1.13",
736
739
  "class-variance-authority": "^0.7.1",
737
- "fumadocs-core": "workspace:*",
738
740
  "lucide-react": "^0.562.0",
739
741
  "next-themes": "^0.4.6",
740
742
  "react-medium-image-zoom": "^5.4.0",
@@ -743,21 +745,25 @@ var dependencies$1 = {
743
745
  var devDependencies$1 = {
744
746
  "@fumadocs/cli": "workspace:*",
745
747
  "@tailwindcss/cli": "^4.1.18",
746
- "@types/node": "^24.10.2",
747
- "@types/react": "^19.2.7",
748
+ "@types/node": "^25.0.5",
749
+ "@types/react": "^19.2.8",
748
750
  "@types/react-dom": "^19.2.3",
749
751
  "eslint-config-custom": "workspace:*",
752
+ "fumadocs-core": "workspace:*",
750
753
  "tailwindcss": "^4.1.18",
751
754
  "tsconfig": "workspace:*",
752
- "tsdown": "^0.18.4"
755
+ "tsdown": "^0.19.0"
753
756
  };
754
757
  var peerDependencies$1 = {
755
758
  "@types/react": "*",
759
+ "fumadocs-core": "workspace:*",
760
+ "next": "16.x.x",
756
761
  "react": "^19.2.0",
757
762
  "react-dom": "^19.2.0",
758
763
  "tailwindcss": "^4.0.0"
759
764
  };
760
765
  var peerDependenciesMeta$1 = {
766
+ "next": { "optional": true },
761
767
  "@types/react": { "optional": true },
762
768
  "tailwindcss": { "optional": true }
763
769
  };
@@ -804,7 +810,7 @@ var package_exports = /* @__PURE__ */ __exportAll({
804
810
  version: () => version
805
811
  });
806
812
  var name = "@fumadocs/base-ui";
807
- var version = "16.4.5";
813
+ var version = "16.4.7";
808
814
  var description = "The Base UI version of Fumadocs UI";
809
815
  var keywords = ["Docs", "Fumadocs"];
810
816
  var homepage = "https://fumadocs.dev";
@@ -894,7 +900,6 @@ var dependencies = {
894
900
  "@base-ui/react": "^1.0.0",
895
901
  "@fumadocs/ui": "workspace:*",
896
902
  "class-variance-authority": "^0.7.1",
897
- "fumadocs-core": "workspace:*",
898
903
  "lucide-react": "^0.562.0",
899
904
  "next-themes": "^0.4.6",
900
905
  "react-medium-image-zoom": "^5.4.0",
@@ -903,21 +908,25 @@ var dependencies = {
903
908
  var devDependencies = {
904
909
  "@fumadocs/cli": "workspace:*",
905
910
  "@tailwindcss/cli": "^4.1.18",
906
- "@types/node": "^24.10.2",
907
- "@types/react": "^19.2.7",
911
+ "@types/node": "^25.0.5",
912
+ "@types/react": "^19.2.8",
908
913
  "@types/react-dom": "^19.2.3",
909
914
  "eslint-config-custom": "workspace:*",
915
+ "fumadocs-core": "workspace:*",
910
916
  "tailwindcss": "^4.1.18",
911
917
  "tsconfig": "workspace:*",
912
- "tsdown": "^0.18.4"
918
+ "tsdown": "^0.19.0"
913
919
  };
914
920
  var peerDependencies = {
915
921
  "@types/react": "*",
922
+ "fumadocs-core": "workspace:*",
923
+ "next": "16.x.x",
916
924
  "react": "^19.2.0",
917
925
  "react-dom": "^19.2.0",
918
926
  "tailwindcss": "^4.0.0"
919
927
  };
920
928
  var peerDependenciesMeta = {
929
+ "next": { "optional": true },
921
930
  "@types/react": { "optional": true },
922
931
  "tailwindcss": { "optional": true }
923
932
  };
@@ -1004,4 +1013,4 @@ for (const workspace of workspaces) depVersions[workspace.name] = workspace.vers
1004
1013
 
1005
1014
  //#endregion
1006
1015
  export { copy as a, writeFile as c, templates as i, isCI as n, pick as o, sourceDir as r, tryGitInit as s, depVersions as t };
1007
- //# sourceMappingURL=constants-CG8Fydtp.js.map
1016
+ //# sourceMappingURL=constants-Dh14AMSp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-Dh14AMSp.js","names":["files","corePkg","uiPkg","mdxPkg","radixPkg","basePkg","versionPkg.dependencies"],"sources":["../src/utils.ts","../../create-app-versions/package.json","../../core/package.json","../../ui/package.json","../../mdx/package.json","../../radix-ui/package.json","../../base-ui/package.json","../src/constants.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path, { join } from 'node:path';\nimport { x } from 'tinyexec';\n\nexport async function writeFile(file: string, content: string) {\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, content);\n}\n\nexport async function copy(\n from: string,\n to: string,\n options: {\n rename?: (s: string) => string;\n filter?: (s: string) => boolean;\n filterDir?: (dir: string) => boolean;\n } = {},\n): Promise<void> {\n const { rename = (s) => s, filterDir = () => true, filter = () => true } = options;\n const stats = await fs.stat(from);\n\n if (stats.isDirectory() && filterDir(from)) {\n const files = await fs.readdir(from);\n\n await Promise.all(\n files.map((file) => copy(path.join(from, file), path.join(to, file), options)),\n );\n }\n\n if (stats.isFile() && filter(from)) {\n to = rename(to);\n await fs.mkdir(path.dirname(to), { recursive: true });\n await fs.copyFile(from, to);\n }\n}\n\nasync function isInGitRepository(cwd: string) {\n const { exitCode } = await x('git', ['rev-parse', '--is-inside-work-tree'], {\n nodeOptions: { cwd },\n });\n\n return exitCode === 0;\n}\n\nasync function isDefaultBranchSet(cwd: string) {\n const { exitCode } = await x('git', ['config', 'init.defaultBranch'], {\n nodeOptions: { cwd },\n });\n\n return exitCode === 0;\n}\n\n/*\nInitialize a Git repo on the project.\n\nBased on https://github.com/vercel/next.js/blob/canary/packages/create-next-app/helpers/git.ts\n*/\nexport async function tryGitInit(cwd: string): Promise<boolean> {\n const { exitCode } = await x('git', ['--version']);\n if (exitCode !== 0) return false;\n\n if (await isInGitRepository(cwd)) return false;\n\n try {\n await x('git', ['init'], {\n throwOnError: true,\n nodeOptions: { cwd },\n });\n\n if (!(await isDefaultBranchSet(cwd))) {\n await x('git', ['checkout', '-b', 'main'], {\n throwOnError: true,\n nodeOptions: {\n cwd,\n },\n });\n }\n\n await x('git', ['add', '-A'], {\n throwOnError: true,\n nodeOptions: {\n cwd,\n },\n });\n\n await x('git', ['commit', '-m', 'Initial commit from Create Fumadocs App'], {\n throwOnError: true,\n nodeOptions: {\n cwd,\n },\n });\n return true;\n } catch {\n await fs.rm(join(cwd, '.git'), { recursive: true, force: true });\n\n return false;\n }\n}\n\nexport function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n const result: Partial<T> = {};\n\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n\n return result as Pick<T, K>;\n}\n","","","","","","","import { fileURLToPath } from 'node:url';\nimport versionPkg from '../../create-app-versions/package.json';\nimport * as corePkg from '../../core/package.json';\nimport * as uiPkg from '../../ui/package.json';\nimport * as mdxPkg from '../../mdx/package.json';\nimport * as radixPkg from '../../radix-ui/package.json';\nimport * as basePkg from '../../base-ui/package.json';\n\nexport const sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);\n\nexport const isCI = Boolean(process.env.CI);\n\nexport interface TemplateInfo {\n value:\n | '+next+fuma-docs-mdx'\n | 'waku'\n | 'react-router'\n | 'react-router-spa'\n | 'tanstack-start'\n | 'tanstack-start-spa'\n | '+next+fuma-docs-mdx+static';\n label: string;\n appDir: string;\n /**\n * path to root provider, relative to `appDir``\n */\n rootProviderPath: string;\n hint?: string;\n /**\n * rename files when copying from template\n */\n rename?: (name: string) => string;\n}\n\nexport const templates: TemplateInfo[] = [\n {\n value: '+next+fuma-docs-mdx',\n label: 'Next.js: Fumadocs MDX',\n hint: 'recommended',\n appDir: '',\n rootProviderPath: 'app/layout.tsx',\n },\n {\n value: '+next+fuma-docs-mdx+static',\n label: 'Next.js Static: Fumadocs MDX',\n appDir: '',\n rootProviderPath: 'components/provider.tsx',\n },\n {\n value: 'waku',\n label: 'Waku: Fumadocs MDX',\n appDir: 'src',\n rootProviderPath: 'components/provider.tsx',\n },\n {\n value: 'react-router',\n label: 'React Router: Fumadocs MDX (not RSC)',\n appDir: 'app',\n rootProviderPath: 'root.tsx',\n },\n {\n value: 'react-router-spa',\n label: 'React Router SPA: Fumadocs MDX (not RSC)',\n hint: 'SPA mode allows you to host the site statically, compatible with a CDN.',\n appDir: 'app',\n rootProviderPath: 'root.tsx',\n },\n {\n value: 'tanstack-start',\n label: 'Tanstack Start: Fumadocs MDX (not RSC)',\n appDir: 'src',\n rootProviderPath: 'routes/__root.tsx',\n },\n {\n value: 'tanstack-start-spa',\n label: 'Tanstack Start SPA: Fumadocs MDX (not RSC)',\n hint: 'SPA mode allows you to host the site statically, compatible with a CDN.',\n appDir: 'src',\n rootProviderPath: 'routes/__root.tsx',\n },\n];\n\nconst workspaces = [corePkg, uiPkg, mdxPkg, radixPkg, basePkg];\n\nexport const depVersions = versionPkg.dependencies;\n\nfor (const workspace of workspaces) {\n depVersions[workspace.name as keyof typeof depVersions] = workspace.version;\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./constants-CG8Fydtp.js";
2
- import { t as create } from "./src-DO725G4h.js";
1
+ import "./constants-Dh14AMSp.js";
2
+ import { t as create } from "./src-Bc7PC9ke.js";
3
3
 
4
4
  export { create };
@@ -1,4 +1,4 @@
1
- import { c as writeFile, o as pick, t as depVersions } from "../constants-CG8Fydtp.js";
1
+ import { c as writeFile, o as pick, t as depVersions } from "../constants-Dh14AMSp.js";
2
2
  import biome_base_default from "./biome.base.js";
3
3
  import biome_next_default from "./biome.next.js";
4
4
  import path from "node:path";
@@ -1,4 +1,4 @@
1
- import { c as writeFile, o as pick, t as depVersions } from "../constants-CG8Fydtp.js";
1
+ import { c as writeFile, o as pick, t as depVersions } from "../constants-Dh14AMSp.js";
2
2
  import path from "node:path";
3
3
 
4
4
  //#region src/plugins/eslint.ts
@@ -1,4 +1,4 @@
1
- import { a as copy, c as writeFile, o as pick, r as sourceDir, t as depVersions } from "../constants-CG8Fydtp.js";
1
+ import { a as copy, c as writeFile, o as pick, r as sourceDir, t as depVersions } from "../constants-Dh14AMSp.js";
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { IndentationText, Project, QuoteKind, StructureKind, SyntaxKind, ts } from "ts-morph";
@@ -1 +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 '+next+fuma-docs-mdx+static': '.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":";;;;;;AAGA,MAAM,UAAU,IAAI,QAAQ,EAC1B,sBAAsB;CACpB,iBAAiB,gBAAgB;CACjC,WAAW,UAAU;CACtB,EACF,CAAC;AAEF,eAAsB,iBAAiB,QAAc;AACnD,QAAO,QAAQ,iBAAiBA,SAAO,MAAM,GAAG,SAASA,OAAK,EAAE,UAAU,EAAE,EAC1E,WAAW,MACZ,CAAC;;AAGJ,SAAgB,aAAa,GAAW;AACtC,QAAO,IAAI,SAAS,UAAU,IAAI,EAAE;;;;;ICf/BC,eAAa,GAAG;;;;AAKvB,SAAgB,gCACd,YACA,OACA,QACA;CACA,MAAM,aAAa,mBAAmB,WAAW,EAAE,SAAS;AAC5D,KAAI,CAAC,WAAY;CAEjB,MAAM,cAAc,WACjB,qBAAqBA,aAAW,oBAAoB,CACpD,MAAM,SAAS,KAAK,SAAS,KAAK,MAAM,EACvC,qBAAqBA,aAAW,uBAAuB;AAE3D,KAAI,CAAC,YAAa;AAClB,MAAK,MAAM,WAAW,YAAY,aAAa,CAC7C,KAAI,CAAC,OAAO,aAAa,QAAQ,SAAS,CAAC,CAAC,CAC1C,aAAY,cAAc,QAAQ;;;;;AAQxC,SAAgB,oBACd,YACA,QACA;AACA,yBAAwB,aAAa,QAAQ;AAC3C,OAAK,MAAM,EAAE,cAAM,WAAW,OAC5B,KAAI,WAAW,UAAUC,OAAK,MAAM,MAAM,IAAI;GAEhD;;;;;AAMJ,SAAgB,uBACd,YACA,QACA;AACA,yBAAwB,aAAa,QAAQ;AAC3C,OAAK,MAAM,WAAW,IAAI,aAAa,EAAE;AACvC,OACE,CAAC,QAAQ,OAAOD,aAAW,eAAe,IAC1C,QAAQ,oBAAoBA,aAAW,WAAW,EAAE,SAAS,KAAK,QAElE;GACF,MAAM,OAAO,QAAQ,cAAc;AAEnC,OACE,OAAO;IACL,MAAM,aAAa,KAAK,GAAG,SAAS,CAAC;IACrC,OAAO,aAAa,KAAK,GAAG,SAAS,CAAC;IACvC,CAAC,CAEF;AAEF,OAAI,cAAc,QAAQ;;GAE5B;;AAGJ,SAAgB,wBACd,YACA,KACA;CACA,MAAM,cAAc,WACjB,wBAAwB,EACvB,qBAAqB,EACrB,yBAAyBA,aAAW,uBAAuB;AAC/D,KAAI,YAAa,KAAI,YAAY;;;;;AAMnC,SAAS,mBAAmB,YAAkD;AAC5E,QACE,WACG,wBAAwB,EACvB,qBAAqB,EACrB,yBAAyBA,aAAW,wBAAwB,EAC5D,YAAY,YAAY,EACxB,OAAOA,aAAW,kBAAkB,IAAI;;;;;;;;;;ACpFhD,SAAgB,qBAAqB,YAAwB,OAAiB;CAC5E,MAAM,aAAa,qBAAqB,WAAW,EAC/C,cAAc,CAAC,IACf,OAAO,WAAW,wBAAwB;AAC9C,KAAI,CAAC,WACH;CAGF,MAAM,gBAAgB,WAAW,YAAY,QAAQ,EAAE,OAAO,WAAW,mBAAmB;CAE5F,SAAS,OAAO,QAAc;AAC5B,SAAO,YAAYE,OAAK;;AAG1B,KAAI,eAAe;EACjB,MAAM,cAAc,cAAc,4BAChC,WAAW,uBACZ;EAED,MAAM,gCAAgB,IAAI,KAAa;AACvC,OAAK,MAAM,WAAW,YAAY,aAAa,EAAE;GAC/C,MAAM,QAAQ,QACX,OAAO,WAAW,wBAAwB,EACzC,YAAY,OAAO,EACnB,OAAO,WAAW,mBAAmB,EACrC,gBAAgB,EAChB,SAAS;AAEb,OAAI,MACF,eAAc,IAAI,aAAa,MAAM,CAAC;;AAI1C,OAAK,MAAMA,UAAQ,OAAO;AACxB,OAAI,cAAc,IAAIA,OAAK,CAAE;AAC7B,eAAY,WAAW,OAAOA,OAAK,CAAC;;OAGtC,YAAW,YAAY,aAAa,MAAM,KAAK,WAAS,KAAK,OAAOA,OAAK,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK;;;;;AAOlG,SAAS,qBAAqB,YAAoD;CAChF,MAAM,kBAAkB,WACrB,wBAAwB,EACvB,qBAAqB,EACrB,yBAAyB,WAAW,wBAAwB,EAC5D,YAAY,UAAU,EACtB,oBAAoB,WAAW,uBAAuB;AAE1D,KAAI,CAAC,gBAAiB;AAEtB,MAAK,MAAM,WAAW,gBAAgB,aAAa,EAAE;EACnD,MAAM,aAAa,QAAQ,OAAO,WAAW,eAAe;AAC5D,MAAI,YAAY,oBAAoB,WAAW,WAAW,EAAE,SAAS,KAAK,gBACxE,QAAO;;;;;;AClDb,eAAsB,aACpB,EAAE,QAAQ,YACV,IACA;CACA,MAAM,OAAO,MAAM,iBAAiB,KAAK,KAAK,QAAQ,SAAS,iBAAiB,CAAC;AACjF,IAAG,EACD,gBAAgB,WAAW;EACzB,MAAM,WAAW,KAAK,qBAAqB,WAAW,WAAW;AAEjE,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,WAAW,QAAQ,oBAAoB,WAAW,kBAAkB;AAC1E,OAAI,UAAU,gBAAgB,CAAC,SAAS,KAAK,eAAgB;AAG7D,OACE,SACG,eAAe,CACf,MACE,SACC,KAAK,OAAO,WAAW,aAAa,IAAI,KAAK,aAAa,CAAC,SAAS,KAAK,SAC5E,CAEH;AAEF,YAAS,aAAa;IACpB,MAAM,cAAc;IACpB,MAAM;IACN,aAAa;IACd,CAAC;AACF,QAAK,qBAAqB;IACxB,iBAAiB;IACjB,eAAe;IAChB,CAAC;AACF;;IAGL,CAAC;AACF,OAAM,KAAK,MAAM;;AAiBnB,eAAsB,kBACpB,EAAE,MAAM,UACR,IACA;CACA,MAAM,aAAa,MAAM,iBAAiB,KAAK,KAAK,MAAM,yBAAyB,CAAC;CACpF,MAAM,aAAa,MAAM,iBAAiB,KAAK,KAAK,QAAQ,YAAY,CAAC;CACzE,MAAMC,QAA4B,EAAE;CAEpC,SAAS,cAAc,GAAW;AAChC,SAAO,EAAE,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;;AAG/C,IAAG;EACD,WAAW,GAAG,OAAO,SAAS;AAC5B,uBAAoB,YAAY,CAAC;IAAE,MAAM;IAAG;IAAO,CAAC,CAAC;AAErD,OAAI,KACF,OAAM,KAAK,GAAG,UAAU,KAAK,KAAK,QAAQ,MAAM,EAAE,KAAK,CAAC;;EAG5D,cAAc,MAAM;GAClB,MAAM,iBAAiB,cAAc,EAAE;AAEvC,0BAAuB,aAAa,SAAS;AAC3C,QAAI,cAAc,KAAK,KAAK,KAAK,eAAgB,QAAO;AAExD,UAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,YAAY,KAAK,CAAC;AACtE,WAAO;KACP;AAEF,mCACE,YACA,aACC,SAAS,cAAc,KAAK,KAAK,eACnC;AAED,mCACE,YACA,UACC,SAAS,cAAc,KAAK,KAAK,eACnC;;EAEJ,CAAC;AAEF,OAAM,QAAQ,IAAI;EAAC,GAAG;EAAO,WAAW,MAAM;EAAE,WAAW,MAAM;EAAC,CAAC;;AAoCrE,eAAsB,oBACpB,EAAE,QAAQ,QACV,IACA;CACA,MAAM,aAAa,MAAM,iBAAiB,KAAK,KAAK,MAAM,iBAAiB,CAAC;CAC5E,MAAMA,QAA4B,EAAE;AAEpC,IAAG;EACD,SAAS,SAAS;AAChB,OAAI,QAAQ,KACV,OAAM,KAAK,GAAG,UAAU,KAAK,KAAK,QAAQ,UAAU,QAAQ,KAAK,EAAE,QAAQ,KAAK,CAAC;AAGnF,OAAI,QAAQ,UACV,sBAAqB,YAAY,CAAC,QAAQ,MAAM,CAAC;;EAGrD,YAAY,SAAS;AACnB,SAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,UAAU,QAAQ,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC;;EAErF,CAAC;AAEF,OAAM,QAAQ,IAAI,CAAC,GAAG,OAAO,WAAW,MAAM,CAAC,CAAC;;;;;ACrKlD,SAAgB,aAA6B;AAC3C,QAAO;EACL,YAAY,aAAa;AACvB,UAAO;IACL,GAAG;IACH,SAAS;KACP,GAAG,YAAY;KACf,OAAO,GAAG,YAAY,QAAS,MAAM;KACtC;IACD,cAAc;KACZ,GAAG,YAAY;KACf,GAAG,KAAK,aAAa,CAAC,cAAc,CAAC;KACtC;IACF;;EAEH,OAAO,SAAS;AACd,UAAO,GAAG,QAAQ;;;;;;EAMpB,MAAM,aAAa;GACjB,MAAM,EAAE,MAAM,QAAQ,aAAa;AACnC,SAAM,KAAK,KAAK,KAAK,WAAW,8BAA8B,EAAE,KAAK;AACrE,SAAM,KAAK,KAAK,KAAK,WAAW,6BAA6B,EAAE,OAAO;AAEtE,SAAM,aAAa,OAAO,QAAQ,IAAI,gBAAgB,sBAAsB,CAAC;AAE7E,OAAI,SAAS,UAAU,iBACrB,OAAM,oBAAoB,OAAO,QAAQ;AACvC,QAAI,SAAS;KACX,MAAM;KACN,OAAO;KACP,MAAM,MAAM;KACZ,WAAW;KACZ,CAAC;AACF,QAAI,YAAY;KACd,MAAM;KACN,OAAO;KACR,CAAC;KACF;YACO,SAAS,MAAM,WAAW,eAAe,CAClD,OAAM,kBAAkB,OAAO,QAAQ;AACrC,QAAI,SAAS,eAAe,oBAAoB,MAAM,gBAAgB;AACtE,QAAI,YAAY,aAAa;KAC7B;YACO,SAAS,MAAM,WAAW,QAAQ,CAC3C,OAAM,QAAQ,IAAI,CAChB,GAAG,OAAO,KAAK,KAAK,QAAQ,0BAA0B,CAAC,CAAC,YAAY,KAAK,EACzE,UAAU,KAAK,KAAK,QAAQ,2BAA2B,EAAE,MAAM,KAAK,CACrE,CAAC;OAEF,OAAM,QAAQ,IAAI,CAChB,GAAG,OAAO,KAAK,KAAK,QAAQ,sBAAsB,CAAC,CAAC,YAAY,KAAK,EACrE,UAAU,KAAK,KAAK,QAAQ,uBAAuB,EAAE,MAAM,KAAK,CACjE,CAAC;GAGJ,MAAM,WAAW;IACf,uBAAuB;IACvB,8BAA8B;IAC9B,kBAAkB;IAClB,sBAAsB;IACtB,gBAAgB;IAChB,oBAAoB;IACpB,MAAM;IACP,CAAC,SAAS;AAEX,SAAM,UACJ,KAAK,KAAK,MAAM,0BAA0B,EAC1C;;;;;oBAKY,SAAS;;;;;;;;;;;;;;;;;;;cAoBtB;;EAEJ;;AAGH,MAAM,QAAQ;CACZ,MAAM;;;;;;;CAON,gBAAgB;;;;;CAKhB,UAAU;;;;;;;;;;CAUV,MAAM;;;;;;;;;CASP"}
1
+ {"version":3,"file":"orama-cloud.js","names":["path","SyntaxKind","path","path"],"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 '+next+fuma-docs-mdx+static': '.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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"}
@@ -1,4 +1,4 @@
1
- import { a as copy, i as templates, r as sourceDir, s as tryGitInit, t as depVersions } from "./constants-CG8Fydtp.js";
1
+ import { a as copy, i as templates, r as sourceDir, s as tryGitInit, t as depVersions } from "./constants-Dh14AMSp.js";
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { x } from "tinyexec";
@@ -86,4 +86,4 @@ async function initPackageJson(projectName, packageJsonPath) {
86
86
 
87
87
  //#endregion
88
88
  export { getPackageManager as n, managers as r, create as t };
89
- //# sourceMappingURL=src-DO725G4h.js.map
89
+ //# sourceMappingURL=src-Bc7PC9ke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-Bc7PC9ke.js","names":[],"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,MAAM,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,MAAM,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,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fumadocs-app",
3
- "version": "16.0.38",
3
+ "version": "16.0.40",
4
4
  "description": "Create a new documentation site with Fumadocs",
5
5
  "keywords": [
6
6
  "Docs",
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/cross-spawn": "^6.0.6",
45
- "@types/node": "24.10.2",
45
+ "@types/node": "25.0.5",
46
46
  "tinyglobby": "^0.2.15",
47
- "tsdown": "^0.18.4",
47
+ "tsdown": "^0.19.0",
48
48
  "typescript": "^5.9.3",
49
49
  "eslint-config-custom": "0.0.0",
50
50
  "tsconfig": "0.0.0"
@@ -4,6 +4,7 @@ import { notFound } from 'next/navigation';
4
4
  import { getMDXComponents } from '@/mdx-components';
5
5
  import type { Metadata } from 'next';
6
6
  import { createRelativeLink } from 'fumadocs-ui/mdx';
7
+ import { LLMCopyButton, ViewOptions } from '@/components/ai/page-actions';
7
8
 
8
9
  export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
9
10
  const params = await props.params;
@@ -11,11 +12,24 @@ export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
11
12
  if (!page) notFound();
12
13
 
13
14
  const MDX = page.data.body;
15
+ const gitConfig = {
16
+ user: 'username',
17
+ repo: 'repo',
18
+ branch: 'main',
19
+ };
14
20
 
15
21
  return (
16
22
  <DocsPage toc={page.data.toc} full={page.data.full}>
17
23
  <DocsTitle>{page.data.title}</DocsTitle>
18
- <DocsDescription>{page.data.description}</DocsDescription>
24
+ <DocsDescription className="mb-0">{page.data.description}</DocsDescription>
25
+ <div className="flex flex-row gap-2 items-center border-b pb-6">
26
+ <LLMCopyButton markdownUrl={`${page.url}.mdx`} />
27
+ <ViewOptions
28
+ markdownUrl={`${page.url}.mdx`}
29
+ // update it to match your repo
30
+ githubUrl={`https://github.com/${gitConfig.user}/${gitConfig.repo}/blob/${gitConfig.branch}/docs/content/docs/${page.path}`}
31
+ />
32
+ </div>
19
33
  <DocsBody>
20
34
  <MDX
21
35
  components={getMDXComponents({
@@ -0,0 +1,20 @@
1
+ import { getLLMText, source } from '@/lib/source';
2
+ import { notFound } from 'next/navigation';
3
+
4
+ export const revalidate = false;
5
+
6
+ export async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/docs/[[...slug]]'>) {
7
+ const { slug } = await params;
8
+ const page = source.getPage(slug);
9
+ if (!page) notFound();
10
+
11
+ return new Response(await getLLMText(page), {
12
+ headers: {
13
+ 'Content-Type': 'text/markdown',
14
+ },
15
+ });
16
+ }
17
+
18
+ export function generateStaticParams() {
19
+ return source.generateParams();
20
+ }