@fumadocs/cli 1.3.7 → 1.3.8

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/config.d.ts CHANGED
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  //#region src/config.d.ts
4
4
  declare const frameworks: readonly ["next", "waku", "react-router", "tanstack-start"];
5
5
  type Framework = (typeof frameworks)[number];
6
- declare function createConfigSchema(cwd?: any): z.ZodObject<{
6
+ declare function createConfigSchema(cwd?: any): Promise<z.ZodObject<{
7
7
  $schema: z.ZodOptional<z.ZodDefault<z.ZodString>>;
8
8
  aliases: z.ZodDefault<z.ZodObject<{
9
9
  uiDir: z.ZodDefault<z.ZodString>;
@@ -21,8 +21,8 @@ declare function createConfigSchema(cwd?: any): z.ZodObject<{
21
21
  commands: z.ZodDefault<z.ZodObject<{
22
22
  format: z.ZodOptional<z.ZodString>;
23
23
  }, z.core.$strip>>;
24
- }, z.core.$strip>;
25
- type ConfigSchema = ReturnType<typeof createConfigSchema>;
24
+ }, z.core.$strip>>;
25
+ type ConfigSchema = Awaited<ReturnType<typeof createConfigSchema>>;
26
26
  type ConfigInput = z.input<ConfigSchema>;
27
27
  type LoadedConfig = z.output<ConfigSchema>;
28
28
  declare function createOrLoadConfig(file?: string): Promise<LoadedConfig>;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;cAKM,UAAA;AAAA,KACM,SAAA,WAAoB,UAAA;AAAA,iBAEhB,kBAAA,CAAmB,GAAA,SAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;KA2DjD,YAAA,GAAe,UAAA,QAAkB,kBAAA;AAAA,KAE1B,WAAA,GAAc,CAAA,CAAE,KAAA,CAAM,YAAA;AAAA,KACtB,YAAA,GAAe,CAAA,CAAE,MAAA,CAAO,YAAA;AAAA,iBAEd,kBAAA,CAAmB,IAAA,YAAsB,OAAA,CAAQ,YAAA;;;;;;iBAejD,UAAA,CAAW,IAAA,YAAsB,OAAA,CAAQ,YAAA;AAAA,iBAezC,gBAAA,CAAiB,GAAA,YAAY,OAAA"}
1
+ {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;cAMM,UAAA;AAAA,KACM,SAAA,WAAoB,UAAA;AAAA,iBAMV,kBAAA,CAAmB,GAAA,SAAmB,OAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;KA2CvD,YAAA,GAAe,OAAA,CAAQ,UAAA,QAAkB,kBAAA;AAAA,KAElC,WAAA,GAAc,CAAA,CAAE,KAAA,CAAM,YAAA;AAAA,KACtB,YAAA,GAAe,CAAA,CAAE,MAAA,CAAO,YAAA;AAAA,iBAEd,kBAAA,CAAmB,IAAA,YAAsB,OAAA,CAAQ,YAAA;;;;;;iBAejD,UAAA,CAAW,IAAA,YAAsB,OAAA,CAAQ,YAAA;AAAA,iBAezC,gBAAA,CAAiB,GAAA,YAAY,OAAA"}
package/dist/config.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import fs from "node:fs/promises";
2
2
  import { z } from "zod";
3
- import { existsSync, readFileSync } from "node:fs";
3
+ import { existsSync } from "node:fs";
4
4
  import path from "node:path";
5
+ import { detectFramework } from "fuma-cli/detect";
5
6
  //#region src/config.ts
6
7
  const frameworks = [
7
8
  "next",
@@ -9,9 +10,10 @@ const frameworks = [
9
10
  "react-router",
10
11
  "tanstack-start"
11
12
  ];
12
- function createConfigSchema(cwd = process.cwd()) {
13
- const srcDir = path.resolve(cwd, "src");
14
- const packageJsonPath = path.resolve(cwd, "package.json");
13
+ function isSupportedFramework(v) {
14
+ return frameworks.includes(v);
15
+ }
16
+ async function createConfigSchema(cwd = process.cwd()) {
15
17
  const defaultAliases = {
16
18
  uiDir: "./components/ui",
17
19
  componentsDir: "./components",
@@ -19,6 +21,8 @@ function createConfigSchema(cwd = process.cwd()) {
19
21
  cssDir: "./styles",
20
22
  libDir: "./lib"
21
23
  };
24
+ let framework = await detectFramework(cwd);
25
+ if (!isSupportedFramework(framework)) framework = "next";
22
26
  return z.object({
23
27
  $schema: z.string().default("node_modules/@fumadocs/cli/dist/schema.json").optional(),
24
28
  aliases: z.object({
@@ -28,35 +32,21 @@ function createConfigSchema(cwd = process.cwd()) {
28
32
  cssDir: z.string().default(defaultAliases.componentsDir),
29
33
  libDir: z.string().default(defaultAliases.libDir)
30
34
  }).default(defaultAliases),
31
- baseDir: z.string().default(() => existsSync(srcDir) ? "src" : ""),
32
- uiLibrary: z.enum(["radix-ui", "base-ui"]).default("radix-ui"),
33
- framework: z.literal(frameworks).default(() => {
34
- return detectFrameworkFromPackageJson(packageJsonPath) ?? "next";
35
+ baseDir: z.string().default(() => {
36
+ if (framework === "react-router" && existsSync(path.resolve(cwd, "app"))) return "app";
37
+ if (existsSync(path.resolve(cwd, "src"))) return "src";
38
+ return "";
35
39
  }),
40
+ uiLibrary: z.enum(["radix-ui", "base-ui"]).default("radix-ui"),
41
+ framework: z.literal(frameworks).default(framework),
36
42
  commands: z.object({ format: z.string().optional() }).default({})
37
43
  });
38
44
  }
39
- function detectFrameworkFromPackageJson(pkgPath) {
40
- try {
41
- const pkgRaw = readFileSync(pkgPath, "utf-8");
42
- const pkg = JSON.parse(pkgRaw);
43
- const deps = {
44
- ...pkg.dependencies,
45
- ...pkg.devDependencies
46
- };
47
- if (deps["next"]) return "next";
48
- if (deps["waku"]) return "waku";
49
- if (deps["react-router"] || deps["react-router-dom"]) return "react-router";
50
- if (deps["@tanstack/react-start"]) return "tanstack-start";
51
- } catch {
52
- return;
53
- }
54
- }
55
45
  async function createOrLoadConfig(file = "./cli.json") {
56
46
  const inited = await initConfig(file);
57
47
  if (inited) return inited;
58
48
  const content = await fs.readFile(file, "utf-8");
59
- return createConfigSchema().parse(JSON.parse(content));
49
+ return (await createConfigSchema()).parse(JSON.parse(content));
60
50
  }
61
51
  /**
62
52
  * Write new config, skip if a config already exists
@@ -70,7 +60,7 @@ async function initConfig(file = "./cli.json") {
70
60
  return defaultConfig;
71
61
  }
72
62
  async function getDefaultConfig(cwd) {
73
- return createConfigSchema(cwd).parse({});
63
+ return (await createConfigSchema(cwd)).parse({});
74
64
  }
75
65
  //#endregion
76
66
  export { createConfigSchema, createOrLoadConfig, getDefaultConfig, initConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { z } from 'zod';\nimport { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\n\nconst frameworks = ['next', 'waku', 'react-router', 'tanstack-start'] as const;\nexport type Framework = (typeof frameworks)[number];\n\nexport function createConfigSchema(cwd = process.cwd()) {\n const srcDir = path.resolve(cwd, 'src');\n const packageJsonPath = path.resolve(cwd, 'package.json');\n const defaultAliases = {\n uiDir: './components/ui',\n componentsDir: './components',\n layoutDir: './layouts',\n cssDir: './styles',\n libDir: './lib',\n };\n\n return z.object({\n $schema: z.string().default('node_modules/@fumadocs/cli/dist/schema.json').optional(),\n aliases: z\n .object({\n uiDir: z.string().default(defaultAliases.uiDir),\n componentsDir: z.string().default(defaultAliases.uiDir),\n layoutDir: z.string().default(defaultAliases.layoutDir),\n cssDir: z.string().default(defaultAliases.componentsDir),\n libDir: z.string().default(defaultAliases.libDir),\n })\n .default(defaultAliases),\n\n baseDir: z.string().default(() => (existsSync(srcDir) ? 'src' : '')),\n uiLibrary: z.enum(['radix-ui', 'base-ui']).default('radix-ui'),\n framework: z.literal(frameworks).default(() => {\n return detectFrameworkFromPackageJson(packageJsonPath) ?? 'next';\n }),\n\n commands: z\n .object({\n /**\n * command to format output code automatically\n */\n format: z.string().optional(),\n })\n .default({}),\n });\n}\n\nfunction detectFrameworkFromPackageJson(pkgPath: string): Framework | undefined {\n try {\n const pkgRaw = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(pkgRaw);\n\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n if (deps['next']) return 'next';\n if (deps['waku']) return 'waku';\n if (deps['react-router'] || deps['react-router-dom']) return 'react-router';\n if (deps['@tanstack/react-start']) return 'tanstack-start';\n } catch {\n return;\n }\n}\n\ntype ConfigSchema = ReturnType<typeof createConfigSchema>;\n\nexport type ConfigInput = z.input<ConfigSchema>;\nexport type LoadedConfig = z.output<ConfigSchema>;\n\nexport async function createOrLoadConfig(file = './cli.json'): Promise<LoadedConfig> {\n const inited = await initConfig(file);\n if (inited) return inited;\n\n const content = await fs.readFile(file, 'utf-8');\n const configSchema = createConfigSchema();\n\n return configSchema.parse(JSON.parse(content));\n}\n\n/**\n * Write new config, skip if a config already exists\n *\n * @returns the created config, `undefined` if not created\n */\nexport async function initConfig(file = './cli.json'): Promise<LoadedConfig | undefined> {\n if (\n await fs\n .stat(file)\n .then(() => true)\n .catch(() => false)\n ) {\n return;\n }\n\n const defaultConfig = await getDefaultConfig();\n await fs.writeFile(file, JSON.stringify(defaultConfig, null, 2));\n return defaultConfig;\n}\n\nexport async function getDefaultConfig(cwd?: string) {\n return createConfigSchema(cwd).parse({} satisfies ConfigInput);\n}\n"],"mappings":";;;;;AAKA,MAAM,aAAa;CAAC;CAAQ;CAAQ;CAAgB;CAAiB;AAGrE,SAAgB,mBAAmB,MAAM,QAAQ,KAAK,EAAE;CACtD,MAAM,SAAS,KAAK,QAAQ,KAAK,MAAM;CACvC,MAAM,kBAAkB,KAAK,QAAQ,KAAK,eAAe;CACzD,MAAM,iBAAiB;EACrB,OAAO;EACP,eAAe;EACf,WAAW;EACX,QAAQ;EACR,QAAQ;EACT;AAED,QAAO,EAAE,OAAO;EACd,SAAS,EAAE,QAAQ,CAAC,QAAQ,8CAA8C,CAAC,UAAU;EACrF,SAAS,EACN,OAAO;GACN,OAAO,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GAC/C,eAAe,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GACvD,WAAW,EAAE,QAAQ,CAAC,QAAQ,eAAe,UAAU;GACvD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,cAAc;GACxD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,OAAO;GAClD,CAAC,CACD,QAAQ,eAAe;EAE1B,SAAS,EAAE,QAAQ,CAAC,cAAe,WAAW,OAAO,GAAG,QAAQ,GAAI;EACpE,WAAW,EAAE,KAAK,CAAC,YAAY,UAAU,CAAC,CAAC,QAAQ,WAAW;EAC9D,WAAW,EAAE,QAAQ,WAAW,CAAC,cAAc;AAC7C,UAAO,+BAA+B,gBAAgB,IAAI;IAC1D;EAEF,UAAU,EACP,OAAO,EAIN,QAAQ,EAAE,QAAQ,CAAC,UAAU,EAC9B,CAAC,CACD,QAAQ,EAAE,CAAC;EACf,CAAC;;AAGJ,SAAS,+BAA+B,SAAwC;AAC9E,KAAI;EACF,MAAM,SAAS,aAAa,SAAS,QAAQ;EAC7C,MAAM,MAAM,KAAK,MAAM,OAAO;EAE9B,MAAM,OAAO;GACX,GAAG,IAAI;GACP,GAAG,IAAI;GACR;AAED,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,mBAAmB,KAAK,oBAAqB,QAAO;AAC7D,MAAI,KAAK,yBAA0B,QAAO;SACpC;AACN;;;AASJ,eAAsB,mBAAmB,OAAO,cAAqC;CACnF,MAAM,SAAS,MAAM,WAAW,KAAK;AACrC,KAAI,OAAQ,QAAO;CAEnB,MAAM,UAAU,MAAM,GAAG,SAAS,MAAM,QAAQ;AAGhD,QAFqB,oBAAoB,CAErB,MAAM,KAAK,MAAM,QAAQ,CAAC;;;;;;;AAQhD,eAAsB,WAAW,OAAO,cAAiD;AACvF,KACE,MAAM,GACH,KAAK,KAAK,CACV,WAAW,KAAK,CAChB,YAAY,MAAM,CAErB;CAGF,MAAM,gBAAgB,MAAM,kBAAkB;AAC9C,OAAM,GAAG,UAAU,MAAM,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAChE,QAAO;;AAGT,eAAsB,iBAAiB,KAAc;AACnD,QAAO,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAuB"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { z } from 'zod';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { detectFramework } from 'fuma-cli/detect';\n\nconst frameworks = ['next', 'waku', 'react-router', 'tanstack-start'] as const;\nexport type Framework = (typeof frameworks)[number];\n\nfunction isSupportedFramework(v: string): v is Framework {\n return frameworks.includes(v as Framework);\n}\n\nexport async function createConfigSchema(cwd = process.cwd()) {\n const defaultAliases = {\n uiDir: './components/ui',\n componentsDir: './components',\n layoutDir: './layouts',\n cssDir: './styles',\n libDir: './lib',\n };\n\n let framework = await detectFramework(cwd);\n if (!isSupportedFramework(framework)) framework = 'next';\n\n return z.object({\n $schema: z.string().default('node_modules/@fumadocs/cli/dist/schema.json').optional(),\n aliases: z\n .object({\n uiDir: z.string().default(defaultAliases.uiDir),\n componentsDir: z.string().default(defaultAliases.uiDir),\n layoutDir: z.string().default(defaultAliases.layoutDir),\n cssDir: z.string().default(defaultAliases.componentsDir),\n libDir: z.string().default(defaultAliases.libDir),\n })\n .default(defaultAliases),\n\n baseDir: z.string().default(() => {\n if (framework === 'react-router' && existsSync(path.resolve(cwd, 'app'))) return 'app';\n if (existsSync(path.resolve(cwd, 'src'))) return 'src';\n return '';\n }),\n uiLibrary: z.enum(['radix-ui', 'base-ui']).default('radix-ui'),\n framework: z.literal(frameworks).default(framework),\n\n commands: z\n .object({\n /**\n * command to format output code automatically\n */\n format: z.string().optional(),\n })\n .default({}),\n });\n}\n\ntype ConfigSchema = Awaited<ReturnType<typeof createConfigSchema>>;\n\nexport type ConfigInput = z.input<ConfigSchema>;\nexport type LoadedConfig = z.output<ConfigSchema>;\n\nexport async function createOrLoadConfig(file = './cli.json'): Promise<LoadedConfig> {\n const inited = await initConfig(file);\n if (inited) return inited;\n\n const content = await fs.readFile(file, 'utf-8');\n const configSchema = await createConfigSchema();\n\n return configSchema.parse(JSON.parse(content));\n}\n\n/**\n * Write new config, skip if a config already exists\n *\n * @returns the created config, `undefined` if not created\n */\nexport async function initConfig(file = './cli.json'): Promise<LoadedConfig | undefined> {\n if (\n await fs\n .stat(file)\n .then(() => true)\n .catch(() => false)\n ) {\n return;\n }\n\n const defaultConfig = await getDefaultConfig();\n await fs.writeFile(file, JSON.stringify(defaultConfig, null, 2));\n return defaultConfig;\n}\n\nexport async function getDefaultConfig(cwd?: string) {\n const schema = await createConfigSchema(cwd);\n return schema.parse({} satisfies ConfigInput);\n}\n"],"mappings":";;;;;;AAMA,MAAM,aAAa;CAAC;CAAQ;CAAQ;CAAgB;CAAiB;AAGrE,SAAS,qBAAqB,GAA2B;AACvD,QAAO,WAAW,SAAS,EAAe;;AAG5C,eAAsB,mBAAmB,MAAM,QAAQ,KAAK,EAAE;CAC5D,MAAM,iBAAiB;EACrB,OAAO;EACP,eAAe;EACf,WAAW;EACX,QAAQ;EACR,QAAQ;EACT;CAED,IAAI,YAAY,MAAM,gBAAgB,IAAI;AAC1C,KAAI,CAAC,qBAAqB,UAAU,CAAE,aAAY;AAElD,QAAO,EAAE,OAAO;EACd,SAAS,EAAE,QAAQ,CAAC,QAAQ,8CAA8C,CAAC,UAAU;EACrF,SAAS,EACN,OAAO;GACN,OAAO,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GAC/C,eAAe,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GACvD,WAAW,EAAE,QAAQ,CAAC,QAAQ,eAAe,UAAU;GACvD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,cAAc;GACxD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,OAAO;GAClD,CAAC,CACD,QAAQ,eAAe;EAE1B,SAAS,EAAE,QAAQ,CAAC,cAAc;AAChC,OAAI,cAAc,kBAAkB,WAAW,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAE,QAAO;AACjF,OAAI,WAAW,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAE,QAAO;AACjD,UAAO;IACP;EACF,WAAW,EAAE,KAAK,CAAC,YAAY,UAAU,CAAC,CAAC,QAAQ,WAAW;EAC9D,WAAW,EAAE,QAAQ,WAAW,CAAC,QAAQ,UAAU;EAEnD,UAAU,EACP,OAAO,EAIN,QAAQ,EAAE,QAAQ,CAAC,UAAU,EAC9B,CAAC,CACD,QAAQ,EAAE,CAAC;EACf,CAAC;;AAQJ,eAAsB,mBAAmB,OAAO,cAAqC;CACnF,MAAM,SAAS,MAAM,WAAW,KAAK;AACrC,KAAI,OAAQ,QAAO;CAEnB,MAAM,UAAU,MAAM,GAAG,SAAS,MAAM,QAAQ;AAGhD,SAFqB,MAAM,oBAAoB,EAE3B,MAAM,KAAK,MAAM,QAAQ,CAAC;;;;;;;AAQhD,eAAsB,WAAW,OAAO,cAAiD;AACvF,KACE,MAAM,GACH,KAAK,KAAK,CACV,WAAW,KAAK,CAChB,YAAY,MAAM,CAErB;CAGF,MAAM,gBAAgB,MAAM,kBAAkB;AAC9C,OAAM,GAAG,UAAU,MAAM,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAChE,QAAO;;AAGT,eAAsB,iBAAiB,KAAc;AAEnD,SADe,MAAM,mBAAmB,IAAI,EAC9B,MAAM,EAAE,CAAuB"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createOrLoadConfig, initConfig } from "./config.js";
3
- import { t as FumadocsComponentInstaller } from "./installer-Baahnmei.js";
3
+ import { t as FumadocsComponentInstaller } from "./installer-uSQQCb1q.js";
4
4
  import fs from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { Command } from "commander";
@@ -61,7 +61,7 @@ async function runTree(args) {
61
61
  }
62
62
  //#endregion
63
63
  //#region package.json
64
- var version = "1.3.7";
64
+ var version = "1.3.8";
65
65
  //#endregion
66
66
  //#region src/commands/shared.ts
67
67
  const UIRegistries = {
@@ -1,7 +1,7 @@
1
+ import { detectPackageManager } from "fuma-cli/detect";
1
2
  import picocolors from "picocolors";
2
3
  import { box, confirm, isCancel, log, outro, spinner } from "@clack/prompts";
3
4
  import { ComponentInstaller } from "fuma-cli/registry/installer";
4
- import { detectPackageManager } from "fuma-cli/detect";
5
5
  //#region src/registry/plugins/preserve.ts
6
6
  /**
7
7
  * keep references to `fumadocs-ui/layouts/*` components as original, unless the user is installing them directly.
@@ -125,4 +125,4 @@ var FumadocsComponentInstaller = class extends ComponentInstaller {
125
125
  //#endregion
126
126
  export { FumadocsComponentInstaller as t };
127
127
 
128
- //# sourceMappingURL=installer-Baahnmei.js.map
128
+ //# sourceMappingURL=installer-uSQQCb1q.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"installer-Baahnmei.js","names":[],"sources":["../src/registry/plugins/preserve.ts","../src/registry/installer.ts"],"sourcesContent":["import type { InstallerPlugin } from 'fuma-cli/registry/installer';\n\n/**\n * keep references to `fumadocs-ui/layouts/*` components as original, unless the user is installing them directly.\n */\nexport function pluginPreserveLayouts(): InstallerPlugin {\n const layoutNames = [\n 'layouts/home',\n 'layouts/flux',\n 'layouts/notebook',\n 'layouts/docs',\n 'layouts/shared',\n ];\n // original specifier -> new specifier\n const layoutComps: Record<string, string> = {\n '@/<dir>/home/index.tsx': 'layouts/home',\n '@/<dir>/shared/index.tsx': 'layouts/shared',\n '@/<dir>/shared/client.tsx': 'layouts/shared',\n '@/<dir>/notebook/index.tsx': 'layouts/notebook',\n '@/<dir>/notebook/client.tsx': 'layouts/notebook',\n '@/<dir>/notebook/page/index.tsx': 'layouts/notebook/page',\n '@/<dir>/notebook/page/client.tsx': 'layouts/notebook/page',\n '@/<dir>/docs/index.tsx': 'layouts/docs',\n '@/<dir>/docs/client.tsx': 'layouts/docs',\n '@/<dir>/docs/page/index.tsx': 'layouts/docs/page',\n '@/<dir>/docs/page/client.tsx': 'layouts/docs/page',\n '@/<dir>/flux/index.tsx': 'layouts/flux',\n '@/<dir>/flux/page/index.tsx': 'layouts/flux/page',\n '@/<dir>/flux/page/client.tsx': 'layouts/flux/page',\n };\n const layoutNameSet = new Set(layoutNames);\n\n return {\n beforeInstall(comp, { stack }) {\n const isDirectInstall = layoutNameSet.has(stack[0].name);\n if (isDirectInstall) return;\n\n return {\n ...comp,\n $subComponents: comp.$subComponents.filter((child) => !layoutNameSet.has(child.name)),\n };\n },\n transformImport(specifier, { stack }) {\n const isDirectInstall = layoutNameSet.has(stack[0].name);\n // skip if direct install or unrelated to layout component\n if (isDirectInstall || !(specifier in layoutComps)) return specifier;\n\n return `fumadocs-ui/${layoutComps[specifier]}`;\n },\n };\n}\n","import { ComponentInstaller } from 'fuma-cli/registry/installer';\nimport { pluginPreserveLayouts } from './plugins/preserve';\nimport { RegistryConnector } from 'fuma-cli/registry/connector';\nimport type { LoadedConfig } from '@/config';\nimport { box, confirm, isCancel, log, outro, spinner, SpinnerResult } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { detectPackageManager } from 'fuma-cli/detect';\n\nexport class FumadocsComponentInstaller extends ComponentInstaller {\n private interactive: {\n name: string;\n spin: SpinnerResult;\n } | null = null;\n\n constructor(connector: RegistryConnector, config: LoadedConfig, cwd?: string) {\n super(connector, {\n cwd,\n framework: config.framework,\n outDir: {\n base: config.baseDir,\n components: config.aliases.componentsDir,\n css: config.aliases.cssDir,\n layout: config.aliases.layoutDir,\n lib: config.aliases.libDir,\n ui: config.aliases.uiDir,\n },\n io: {\n onWarn: (message) => {\n this.interactive?.spin.message(message);\n },\n confirmFileOverride: async (options) => {\n if (!this.interactive) return true;\n const { name, spin } = this.interactive;\n spin.clear();\n const value = await confirm({\n message: `Do you want to override ${options.path}?`,\n initialValue: false,\n });\n if (isCancel(value)) {\n outro('Installation terminated');\n process.exit(0);\n }\n spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));\n return value;\n },\n onFileDownloaded: (options) => {\n this.interactive?.spin.message(options.path);\n },\n },\n plugins: [pluginPreserveLayouts()],\n });\n }\n\n async installInteractive(name: string, subRegistry?: string): Promise<void> {\n if (this.interactive) {\n throw new Error(`cannot install while installing another component`);\n }\n\n const spin = spinner();\n spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));\n\n try {\n this.interactive = { name, spin };\n const deps = await super.install(name, subRegistry).then((res) => res.deps());\n spin.stop(picocolors.bold(picocolors.greenBright(`${name} installed`)));\n\n if (deps.hasRequired()) {\n log.message();\n box([...deps.dependencies, ...deps.devDependencies].join('\\n'), 'New Dependencies');\n const pm = (await detectPackageManager())?.name ?? 'npm';\n const value = await confirm({\n message: `Do you want to install with ${pm}?`,\n });\n\n if (isCancel(value)) {\n outro('Installation terminated');\n process.exit(0);\n }\n\n if (value) {\n const spin = spinner({\n errorMessage: 'Failed to install dependencies',\n });\n spin.start('Installing dependencies');\n await deps.installRequired(pm);\n spin.stop('Dependencies installed');\n } else {\n await deps.writeRequired();\n }\n }\n } catch (e) {\n spin.error(e instanceof Error ? e.message : String(e));\n process.exit(-1);\n } finally {\n this.interactive = null;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"installer-uSQQCb1q.js","names":[],"sources":["../src/registry/plugins/preserve.ts","../src/registry/installer.ts"],"sourcesContent":["import type { InstallerPlugin } from 'fuma-cli/registry/installer';\n\n/**\n * keep references to `fumadocs-ui/layouts/*` components as original, unless the user is installing them directly.\n */\nexport function pluginPreserveLayouts(): InstallerPlugin {\n const layoutNames = [\n 'layouts/home',\n 'layouts/flux',\n 'layouts/notebook',\n 'layouts/docs',\n 'layouts/shared',\n ];\n // original specifier -> new specifier\n const layoutComps: Record<string, string> = {\n '@/<dir>/home/index.tsx': 'layouts/home',\n '@/<dir>/shared/index.tsx': 'layouts/shared',\n '@/<dir>/shared/client.tsx': 'layouts/shared',\n '@/<dir>/notebook/index.tsx': 'layouts/notebook',\n '@/<dir>/notebook/client.tsx': 'layouts/notebook',\n '@/<dir>/notebook/page/index.tsx': 'layouts/notebook/page',\n '@/<dir>/notebook/page/client.tsx': 'layouts/notebook/page',\n '@/<dir>/docs/index.tsx': 'layouts/docs',\n '@/<dir>/docs/client.tsx': 'layouts/docs',\n '@/<dir>/docs/page/index.tsx': 'layouts/docs/page',\n '@/<dir>/docs/page/client.tsx': 'layouts/docs/page',\n '@/<dir>/flux/index.tsx': 'layouts/flux',\n '@/<dir>/flux/page/index.tsx': 'layouts/flux/page',\n '@/<dir>/flux/page/client.tsx': 'layouts/flux/page',\n };\n const layoutNameSet = new Set(layoutNames);\n\n return {\n beforeInstall(comp, { stack }) {\n const isDirectInstall = layoutNameSet.has(stack[0].name);\n if (isDirectInstall) return;\n\n return {\n ...comp,\n $subComponents: comp.$subComponents.filter((child) => !layoutNameSet.has(child.name)),\n };\n },\n transformImport(specifier, { stack }) {\n const isDirectInstall = layoutNameSet.has(stack[0].name);\n // skip if direct install or unrelated to layout component\n if (isDirectInstall || !(specifier in layoutComps)) return specifier;\n\n return `fumadocs-ui/${layoutComps[specifier]}`;\n },\n };\n}\n","import { ComponentInstaller } from 'fuma-cli/registry/installer';\nimport { pluginPreserveLayouts } from './plugins/preserve';\nimport { RegistryConnector } from 'fuma-cli/registry/connector';\nimport type { LoadedConfig } from '@/config';\nimport { box, confirm, isCancel, log, outro, spinner, SpinnerResult } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { detectPackageManager } from 'fuma-cli/detect';\n\nexport class FumadocsComponentInstaller extends ComponentInstaller {\n private interactive: {\n name: string;\n spin: SpinnerResult;\n } | null = null;\n\n constructor(connector: RegistryConnector, config: LoadedConfig, cwd?: string) {\n super(connector, {\n cwd,\n framework: config.framework,\n outDir: {\n base: config.baseDir,\n components: config.aliases.componentsDir,\n css: config.aliases.cssDir,\n layout: config.aliases.layoutDir,\n lib: config.aliases.libDir,\n ui: config.aliases.uiDir,\n },\n io: {\n onWarn: (message) => {\n this.interactive?.spin.message(message);\n },\n confirmFileOverride: async (options) => {\n if (!this.interactive) return true;\n const { name, spin } = this.interactive;\n spin.clear();\n const value = await confirm({\n message: `Do you want to override ${options.path}?`,\n initialValue: false,\n });\n if (isCancel(value)) {\n outro('Installation terminated');\n process.exit(0);\n }\n spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));\n return value;\n },\n onFileDownloaded: (options) => {\n this.interactive?.spin.message(options.path);\n },\n },\n plugins: [pluginPreserveLayouts()],\n });\n }\n\n async installInteractive(name: string, subRegistry?: string): Promise<void> {\n if (this.interactive) {\n throw new Error(`cannot install while installing another component`);\n }\n\n const spin = spinner();\n spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));\n\n try {\n this.interactive = { name, spin };\n const deps = await super.install(name, subRegistry).then((res) => res.deps());\n spin.stop(picocolors.bold(picocolors.greenBright(`${name} installed`)));\n\n if (deps.hasRequired()) {\n log.message();\n box([...deps.dependencies, ...deps.devDependencies].join('\\n'), 'New Dependencies');\n const pm = (await detectPackageManager())?.name ?? 'npm';\n const value = await confirm({\n message: `Do you want to install with ${pm}?`,\n });\n\n if (isCancel(value)) {\n outro('Installation terminated');\n process.exit(0);\n }\n\n if (value) {\n const spin = spinner({\n errorMessage: 'Failed to install dependencies',\n });\n spin.start('Installing dependencies');\n await deps.installRequired(pm);\n spin.stop('Dependencies installed');\n } else {\n await deps.writeRequired();\n }\n }\n } catch (e) {\n spin.error(e instanceof Error ? e.message : String(e));\n process.exit(-1);\n } finally {\n this.interactive = null;\n }\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as FumadocsComponentInstaller } from "../installer-Baahnmei.js";
1
+ import { t as FumadocsComponentInstaller } from "../installer-uSQQCb1q.js";
2
2
  export { FumadocsComponentInstaller };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fumadocs/cli",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "description": "The CLI tool for Fumadocs",
5
5
  "keywords": [
6
6
  "Docs",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "25.6.0",
38
- "tsdown": "0.21.7",
38
+ "tsdown": "0.21.8",
39
39
  "tsconfig": "0.0.0"
40
40
  },
41
41
  "scripts": {