@fumadocs/cli 1.3.4 → 1.3.5

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 (41) hide show
  1. package/dist/config.d.ts +53 -2
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/index.js +87 -157
  4. package/dist/index.js.map +1 -1
  5. package/dist/installer-zD4jTQWp.js +128 -0
  6. package/dist/installer-zD4jTQWp.js.map +1 -0
  7. package/dist/registry/installer.d.ts +13 -0
  8. package/dist/registry/installer.d.ts.map +1 -0
  9. package/dist/registry/installer.js +2 -0
  10. package/package.json +7 -15
  11. package/dist/build/index.d.ts +0 -148
  12. package/dist/build/index.d.ts.map +0 -1
  13. package/dist/build/index.js +0 -289
  14. package/dist/build/index.js.map +0 -1
  15. package/dist/client-C2A4Jf2w.js +0 -102
  16. package/dist/client-C2A4Jf2w.js.map +0 -1
  17. package/dist/config-BIpj98KJ.d.ts +0 -53
  18. package/dist/config-BIpj98KJ.d.ts.map +0 -1
  19. package/dist/fs-C3j4H046.js +0 -18
  20. package/dist/fs-C3j4H046.js.map +0 -1
  21. package/dist/import-CSbSteB3.js +0 -124
  22. package/dist/import-CSbSteB3.js.map +0 -1
  23. package/dist/installer-BWoLnsXE.js +0 -673
  24. package/dist/installer-BWoLnsXE.js.map +0 -1
  25. package/dist/registry/client.d.ts +0 -112
  26. package/dist/registry/client.d.ts.map +0 -1
  27. package/dist/registry/client.js +0 -2
  28. package/dist/registry/installer/index.d.ts +0 -96
  29. package/dist/registry/installer/index.d.ts.map +0 -1
  30. package/dist/registry/installer/index.js +0 -2
  31. package/dist/registry/macros/route-handler.d.ts +0 -21
  32. package/dist/registry/macros/route-handler.d.ts.map +0 -1
  33. package/dist/registry/macros/route-handler.js +0 -11
  34. package/dist/registry/macros/route-handler.js.map +0 -1
  35. package/dist/registry/schema.d.ts +0 -2
  36. package/dist/registry/schema.js +0 -50
  37. package/dist/registry/schema.js.map +0 -1
  38. package/dist/schema-BAaUX4uu.d.ts +0 -77
  39. package/dist/schema-BAaUX4uu.d.ts.map +0 -1
  40. package/dist/types-79PW0lgM.d.ts +0 -6
  41. package/dist/types-79PW0lgM.d.ts.map +0 -1
@@ -0,0 +1,128 @@
1
+ import picocolors from "picocolors";
2
+ import { box, confirm, isCancel, log, outro, spinner } from "@clack/prompts";
3
+ import { ComponentInstaller } from "fuma-cli/registry/installer";
4
+ import { detect } from "package-manager-detector";
5
+ //#region src/registry/plugins/preserve.ts
6
+ /**
7
+ * keep references to `fumadocs-ui/layouts/*` components as original, unless the user is installing them directly.
8
+ */
9
+ function pluginPreserveLayouts() {
10
+ const layoutNames = [
11
+ "layouts/home",
12
+ "layouts/flux",
13
+ "layouts/notebook",
14
+ "layouts/docs",
15
+ "layouts/shared"
16
+ ];
17
+ const layoutComps = {
18
+ "@/<dir>/home/index.tsx": "layouts/home",
19
+ "@/<dir>/shared/index.tsx": "layouts/shared",
20
+ "@/<dir>/shared/client.tsx": "layouts/shared",
21
+ "@/<dir>/notebook/index.tsx": "layouts/notebook",
22
+ "@/<dir>/notebook/client.tsx": "layouts/notebook",
23
+ "@/<dir>/notebook/page/index.tsx": "layouts/notebook/page",
24
+ "@/<dir>/notebook/page/client.tsx": "layouts/notebook/page",
25
+ "@/<dir>/docs/index.tsx": "layouts/docs",
26
+ "@/<dir>/docs/client.tsx": "layouts/docs",
27
+ "@/<dir>/docs/page/index.tsx": "layouts/docs/page",
28
+ "@/<dir>/docs/page/client.tsx": "layouts/docs/page",
29
+ "@/<dir>/flux/index.tsx": "layouts/flux",
30
+ "@/<dir>/flux/page/index.tsx": "layouts/flux/page",
31
+ "@/<dir>/flux/page/client.tsx": "layouts/flux/page"
32
+ };
33
+ const layoutNameSet = new Set(layoutNames);
34
+ return {
35
+ beforeInstall(comp, { stack }) {
36
+ if (layoutNameSet.has(stack[0].name)) return;
37
+ return {
38
+ ...comp,
39
+ $subComponents: comp.$subComponents.filter((child) => !layoutNameSet.has(child.name))
40
+ };
41
+ },
42
+ transformImport(specifier, { stack }) {
43
+ if (layoutNameSet.has(stack[0].name) || !(specifier in layoutComps)) return specifier;
44
+ return `fumadocs-ui/${layoutComps[specifier]}`;
45
+ }
46
+ };
47
+ }
48
+ //#endregion
49
+ //#region src/registry/installer.ts
50
+ var FumadocsComponentInstaller = class extends ComponentInstaller {
51
+ constructor(connector, config, cwd) {
52
+ super(connector, {
53
+ cwd,
54
+ framework: config.framework,
55
+ outDir: {
56
+ base: config.baseDir,
57
+ components: config.aliases.componentsDir,
58
+ css: config.aliases.cssDir,
59
+ layout: config.aliases.layoutDir,
60
+ lib: config.aliases.libDir,
61
+ ui: config.aliases.uiDir
62
+ },
63
+ io: {
64
+ onWarn: (message) => {
65
+ this.interactive?.spin.message(message);
66
+ },
67
+ confirmFileOverride: async (options) => {
68
+ if (!this.interactive) return true;
69
+ const { name, spin } = this.interactive;
70
+ spin.clear();
71
+ const value = await confirm({
72
+ message: `Do you want to override ${options.path}?`,
73
+ initialValue: false
74
+ });
75
+ if (isCancel(value)) {
76
+ outro("Installation terminated");
77
+ process.exit(0);
78
+ }
79
+ spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));
80
+ return value;
81
+ },
82
+ onFileDownloaded: (options) => {
83
+ this.interactive?.spin.message(options.path);
84
+ }
85
+ },
86
+ plugins: [pluginPreserveLayouts()]
87
+ });
88
+ this.interactive = null;
89
+ }
90
+ async installInteractive(name, subRegistry) {
91
+ if (this.interactive) throw new Error(`cannot install while installing another component`);
92
+ const spin = spinner();
93
+ spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));
94
+ try {
95
+ this.interactive = {
96
+ name,
97
+ spin
98
+ };
99
+ const deps = await super.install(name, subRegistry).then((res) => res.deps());
100
+ spin.stop(picocolors.bold(picocolors.greenBright(`${name} installed`)));
101
+ if (deps.hasRequired()) {
102
+ log.message();
103
+ box([...deps.dependencies, ...deps.devDependencies].join("\n"), "New Dependencies");
104
+ const pm = (await detect())?.name ?? "npm";
105
+ const value = await confirm({ message: `Do you want to install with ${pm}?` });
106
+ if (isCancel(value)) {
107
+ outro("Installation terminated");
108
+ process.exit(0);
109
+ }
110
+ if (value) {
111
+ const spin = spinner({ errorMessage: "Failed to install dependencies" });
112
+ spin.start("Installing dependencies");
113
+ await deps.installRequired(pm);
114
+ spin.stop("Dependencies installed");
115
+ } else await deps.writeRequired();
116
+ }
117
+ } catch (e) {
118
+ spin.error(e instanceof Error ? e.message : String(e));
119
+ process.exit(-1);
120
+ } finally {
121
+ this.interactive = null;
122
+ }
123
+ }
124
+ };
125
+ //#endregion
126
+ export { FumadocsComponentInstaller as t };
127
+
128
+ //# sourceMappingURL=installer-zD4jTQWp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer-zD4jTQWp.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 { detect } from 'package-manager-detector';\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 detect())?.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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"}
@@ -0,0 +1,13 @@
1
+ import { LoadedConfig } from "../config.js";
2
+ import { ComponentInstaller } from "fuma-cli/registry/installer";
3
+ import { RegistryConnector } from "fuma-cli/registry/connector";
4
+
5
+ //#region src/registry/installer.d.ts
6
+ declare class FumadocsComponentInstaller extends ComponentInstaller {
7
+ private interactive;
8
+ constructor(connector: RegistryConnector, config: LoadedConfig, cwd?: string);
9
+ installInteractive(name: string, subRegistry?: string): Promise<void>;
10
+ }
11
+ //#endregion
12
+ export { FumadocsComponentInstaller };
13
+ //# sourceMappingURL=installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","names":[],"sources":["../../src/registry/installer.ts"],"mappings":";;;;;cAQa,0BAAA,SAAmC,kBAAA;EAAA,QACtC,WAAA;cAKI,SAAA,EAAW,iBAAA,EAAmB,MAAA,EAAQ,YAAA,EAAc,GAAA;EAuC1D,kBAAA,CAAmB,IAAA,UAAc,WAAA,YAAuB,OAAA;AAAA"}
@@ -0,0 +1,2 @@
1
+ import { t as FumadocsComponentInstaller } from "../installer-zD4jTQWp.js";
2
+ export { FumadocsComponentInstaller };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fumadocs/cli",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "The CLI tool for Fumadocs",
5
5
  "keywords": [
6
6
  "Docs",
@@ -18,33 +18,25 @@
18
18
  ],
19
19
  "type": "module",
20
20
  "exports": {
21
- "./build": "./dist/build/index.js",
22
21
  "./config": "./dist/config.js",
23
- "./registry/client": "./dist/registry/client.js",
24
- "./registry/installer": "./dist/registry/installer/index.js",
25
- "./registry/macros/route-handler": "./dist/registry/macros/route-handler.js",
26
- "./registry/schema": "./dist/registry/schema.js",
22
+ "./registry/installer": "./dist/registry/installer.js",
27
23
  "./package.json": "./package.json"
28
24
  },
29
25
  "publishConfig": {
30
26
  "access": "public"
31
27
  },
32
28
  "dependencies": {
33
- "@clack/prompts": "^1.1.0",
29
+ "@clack/prompts": "^1.2.0",
34
30
  "commander": "^14.0.3",
35
- "magic-string": "^0.30.21",
36
- "oxc-parser": "^0.121.0",
37
- "oxc-resolver": "^11.19.1",
31
+ "fuma-cli": "^0.0.3",
38
32
  "package-manager-detector": "^1.6.0",
39
33
  "picocolors": "^1.1.1",
40
- "tinyexec": "^1.0.4",
34
+ "tinyexec": "^1.1.1",
41
35
  "zod": "^4.3.6"
42
36
  },
43
37
  "devDependencies": {
44
- "@oxc-project/types": "^0.122.0",
45
- "@types/node": "25.5.0",
46
- "shadcn": "4.1.1",
47
- "tsdown": "0.21.6",
38
+ "@types/node": "25.5.2",
39
+ "tsdown": "0.21.7",
48
40
  "tsconfig": "0.0.0"
49
41
  },
50
42
  "scripts": {
@@ -1,148 +0,0 @@
1
- import { d as registryInfoSchema, n as CompiledFile, t as CompiledComponent } from "../schema-BAaUX4uu.js";
2
- import { n as DistributiveOmit } from "../types-79PW0lgM.js";
3
- import { z } from "zod";
4
- import { ResolverFactory } from "oxc-resolver";
5
-
6
- //#region src/build/compiler.d.ts
7
- type OnResolve = (reference: SourceReference, from: {
8
- component: Component;
9
- file: ComponentFile;
10
- }) => Reference;
11
- interface CompiledRegistry {
12
- name: string;
13
- components: CompiledComponent[];
14
- info: z.output<typeof registryInfoSchema>;
15
- }
16
- type ComponentFile = DistributiveOmit<CompiledFile, 'content'> & {
17
- path: string;
18
- };
19
- interface Component {
20
- name: string;
21
- title?: string;
22
- description?: string;
23
- files: ComponentFile[];
24
- dependencies?: Record<string, string>;
25
- devDependencies?: Record<string, string>;
26
- /**
27
- * Don't list the component in registry index file
28
- */
29
- unlisted?: boolean;
30
- /**
31
- * Map imported file paths, inherit from registry if not defined.
32
- */
33
- onResolve?: OnResolve;
34
- }
35
- interface PackageJson {
36
- dependencies?: Record<string, string>;
37
- devDependencies?: Record<string, string>;
38
- }
39
- interface Registry extends Omit<z.input<typeof registryInfoSchema>, 'indexes'> {
40
- name: string;
41
- packageJson: string | PackageJson;
42
- tsconfigPath: string;
43
- components: Component[];
44
- /**
45
- * The directory of registry, used to resolve relative paths
46
- */
47
- dir: string;
48
- /**
49
- * Map import paths of components
50
- */
51
- onResolve?: OnResolve;
52
- /**
53
- * When a referenced file is not found in component files, this function is called.
54
- * @returns file, or `false` to mark as external.
55
- */
56
- onUnknownFile?: (absolutePath: string) => ComponentFile | false | undefined;
57
- dependencies?: Record<string, string | null>;
58
- devDependencies?: Record<string, string | null>;
59
- }
60
- declare class RegistryCompiler {
61
- readonly raw: Registry;
62
- resolver: RegistryResolver;
63
- constructor(registry: Registry);
64
- private readPackageJson;
65
- compile(): Promise<CompiledRegistry>;
66
- }
67
- declare class RegistryResolver {
68
- private readonly compiler;
69
- private readonly deps;
70
- private readonly devDeps;
71
- private readonly fileToComponent;
72
- readonly oxc: ResolverFactory;
73
- constructor(compiler: RegistryCompiler, packageJson?: PackageJson);
74
- getDepFromSpecifier(specifier: string): string;
75
- getDepInfo(name: string): {
76
- type: 'runtime' | 'dev';
77
- name: string;
78
- version: string | null;
79
- } | undefined;
80
- getComponentByName(name: string): Component | undefined;
81
- getSubComponent(file: string): {
82
- component: Component;
83
- file: ComponentFile;
84
- } | undefined;
85
- }
86
- type SourceReference = {
87
- type: 'file';
88
- /**
89
- * Absolute path
90
- */
91
- file: string;
92
- } | {
93
- type: 'dependency';
94
- dep: string;
95
- specifier: string;
96
- } | {
97
- type: 'sub-component';
98
- resolved: {
99
- type: 'local';
100
- component: Component;
101
- file: ComponentFile;
102
- } | {
103
- type: 'remote';
104
- component: Component;
105
- file: ComponentFile;
106
- registryName: string;
107
- };
108
- } | {
109
- type: 'unknown-specifier';
110
- specifier: string;
111
- };
112
- type Reference = SourceReference | {
113
- type: 'custom';
114
- specifier: string;
115
- };
116
- declare class ComponentCompiler {
117
- private readonly compiler;
118
- private readonly component;
119
- private readonly processedFiles;
120
- private readonly registry;
121
- private readonly subComponents;
122
- private readonly devDependencies;
123
- private readonly dependencies;
124
- constructor(compiler: RegistryCompiler, component: Component);
125
- build(): Promise<CompiledComponent>;
126
- private onBuildFile;
127
- private buildFile;
128
- }
129
- declare function resolveFromRemote(r: Registry, component: string, selectFile: (file: ComponentFile) => boolean): Reference | undefined;
130
- //#endregion
131
- //#region src/build/index.d.ts
132
- interface MonoRegistry extends CompiledRegistry {
133
- registries: CompiledRegistry[];
134
- }
135
- declare function combineRegistry(root: CompiledRegistry, ...items: CompiledRegistry[]): MonoRegistry;
136
- declare function writeFumadocsRegistry(out: CompiledRegistry | MonoRegistry, options: {
137
- dir: string;
138
- /**
139
- * Remove previous outputs
140
- *
141
- * @defaultValue false
142
- */
143
- cleanDir?: boolean;
144
- log?: boolean;
145
- }): Promise<void>;
146
- //#endregion
147
- export { CompiledRegistry, Component, ComponentCompiler, ComponentFile, MonoRegistry, OnResolve, PackageJson, Reference, Registry, RegistryCompiler, SourceReference, combineRegistry, resolveFromRemote, writeFumadocsRegistry };
148
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/build/compiler.ts","../../src/build/index.ts"],"mappings":"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"}
@@ -1,289 +0,0 @@
1
- import { a as transformSpecifiers, n as encodeImport } from "../import-CSbSteB3.js";
2
- import { n as isRelative } from "../fs-C3j4H046.js";
3
- import * as fs$1 from "node:fs/promises";
4
- import * as path$1 from "node:path";
5
- import picocolors from "picocolors";
6
- import { parse } from "oxc-parser";
7
- import MagicString from "magic-string";
8
- import { ResolverFactory } from "oxc-resolver";
9
- //#region src/build/compiler.ts
10
- var RegistryCompiler = class {
11
- constructor(registry) {
12
- this.raw = registry;
13
- }
14
- async readPackageJson() {
15
- if (typeof this.raw.packageJson !== "string") return this.raw.packageJson;
16
- return fs$1.readFile(path$1.join(this.raw.dir, this.raw.packageJson)).then((res) => JSON.parse(res.toString())).catch(() => void 0);
17
- }
18
- async compile() {
19
- const registry = this.raw;
20
- this.resolver = new RegistryResolver(this, await this.readPackageJson());
21
- const output = {
22
- name: registry.name,
23
- info: {
24
- indexes: [],
25
- unlistedIndexes: [],
26
- env: registry.env,
27
- variables: registry.variables
28
- },
29
- components: []
30
- };
31
- const builtComps = await Promise.all(registry.components.map(async (component) => {
32
- return [component, await new ComponentCompiler(this, component).build()];
33
- }));
34
- for (const [input, comp] of builtComps) {
35
- (input.unlisted ? output.info.unlistedIndexes : output.info.indexes).push({
36
- name: input.name,
37
- title: input.title,
38
- description: input.description
39
- });
40
- output.components.push(comp);
41
- }
42
- return output;
43
- }
44
- };
45
- var RegistryResolver = class {
46
- constructor(compiler, packageJson = {}) {
47
- this.compiler = compiler;
48
- this.fileToComponent = /* @__PURE__ */ new Map();
49
- const registry = compiler.raw;
50
- for (const comp of registry.components) for (const file of comp.files) {
51
- if (this.fileToComponent.has(file.path)) console.warn(`the same file ${file.path} exists in multiple component, you should make the shared file a separate component.`);
52
- this.fileToComponent.set(file.path, [comp, file]);
53
- }
54
- this.deps = {
55
- ...packageJson?.dependencies,
56
- ...registry.dependencies
57
- };
58
- this.devDeps = {
59
- ...packageJson?.devDependencies,
60
- ...registry.devDependencies
61
- };
62
- this.oxc = new ResolverFactory({
63
- extensions: [
64
- ".js",
65
- ".jsx",
66
- ".ts",
67
- ".tsx",
68
- ".node"
69
- ],
70
- conditionNames: [
71
- "node",
72
- "import",
73
- "require",
74
- "default",
75
- "types"
76
- ],
77
- tsconfig: { configFile: path$1.join(registry.dir, registry.tsconfigPath) }
78
- });
79
- }
80
- getDepFromSpecifier(specifier) {
81
- return specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0];
82
- }
83
- getDepInfo(name) {
84
- if (name in this.deps) return {
85
- name,
86
- type: "runtime",
87
- version: this.deps[name]
88
- };
89
- if (name in this.devDeps) return {
90
- name,
91
- type: "dev",
92
- version: this.devDeps[name]
93
- };
94
- console.warn(`dep info for ${name} cannot be found`);
95
- }
96
- getComponentByName(name) {
97
- return this.compiler.raw.components.find((comp) => comp.name === name);
98
- }
99
- getSubComponent(file) {
100
- const relativeFile = path$1.relative(this.compiler.raw.dir, file);
101
- const comp = this.fileToComponent.get(relativeFile);
102
- if (!comp) return;
103
- return {
104
- component: comp[0],
105
- file: comp[1]
106
- };
107
- }
108
- };
109
- var ComponentCompiler = class {
110
- constructor(compiler, component) {
111
- this.compiler = compiler;
112
- this.component = component;
113
- this.processedFiles = /* @__PURE__ */ new Set();
114
- this.subComponents = /* @__PURE__ */ new Map();
115
- this.devDependencies = /* @__PURE__ */ new Map();
116
- this.dependencies = /* @__PURE__ */ new Map();
117
- this.registry = compiler.raw;
118
- }
119
- async build() {
120
- const files = (await Promise.all(this.component.files.map((file) => this.onBuildFile(file)))).flat();
121
- const dependencies = Object.fromEntries(this.dependencies);
122
- const devDependencies = Object.fromEntries(this.devDependencies);
123
- if (this.component.dependencies) Object.assign(dependencies, this.component.dependencies);
124
- if (this.component.devDependencies) Object.assign(devDependencies, this.component.devDependencies);
125
- return {
126
- name: this.component.name,
127
- title: this.component.title,
128
- description: this.component.description,
129
- files,
130
- subComponents: Array.from(this.subComponents.values()),
131
- dependencies,
132
- devDependencies
133
- };
134
- }
135
- async onBuildFile(file) {
136
- if (this.processedFiles.has(file.path)) return [];
137
- this.processedFiles.add(file.path);
138
- const resolver = this.compiler.resolver;
139
- const queue = [];
140
- return [await this.buildFile(file, (reference) => {
141
- if (reference.type === "dependency" && reference.dep === "@fumadocs/cli") return reference.specifier;
142
- if (reference.type === "unknown-specifier") {
143
- if (!reference.specifier.startsWith("node:")) console.warn(`Unknown specifier ${reference.specifier}, skipping for now`);
144
- return reference.specifier;
145
- }
146
- if (reference.type === "custom") return reference.specifier;
147
- if (reference.type === "file") {
148
- const refFile = this.registry.onUnknownFile?.(reference.file);
149
- if (refFile) {
150
- queue.push(refFile);
151
- return encodeImport(refFile);
152
- }
153
- if (refFile === false) return;
154
- throw new Error(`Unknown file ${reference.file} referenced by ${file.path}`);
155
- }
156
- if (reference.type === "sub-component") {
157
- const resolved = reference.resolved;
158
- if (resolved.component.name === this.component.name) return encodeImport(resolved.file);
159
- if (resolved.type === "remote") this.subComponents.set(`${resolved.registryName}:${resolved.component.name}`, {
160
- type: "http",
161
- baseUrl: resolved.registryName,
162
- component: resolved.component.name
163
- });
164
- else this.subComponents.set(resolved.component.name, resolved.component.name);
165
- return encodeImport(resolved.file);
166
- }
167
- const dep = resolver.getDepInfo(reference.dep);
168
- if (dep) (dep.type === "dev" ? this.devDependencies : this.dependencies).set(dep.name, dep.version);
169
- return reference.specifier;
170
- }), ...(await Promise.all(queue.map((file) => this.onBuildFile(file)))).flat()];
171
- }
172
- async buildFile(file, writeReference) {
173
- const sourceFilePath = path$1.join(this.registry.dir, file.path);
174
- const astType = {
175
- ".ts": "ts",
176
- ".tsx": "ts",
177
- ".js": "js",
178
- ".jsx": "js"
179
- }[path$1.extname(file.path)];
180
- const content = (await fs$1.readFile(sourceFilePath)).toString();
181
- if (!astType) return {
182
- ...file,
183
- content
184
- };
185
- const resolver = this.compiler.resolver;
186
- const ast = await parse(sourceFilePath, content, { astType });
187
- if (ast.errors.length > 0) throw new Error(`failed to parse file ${sourceFilePath}: \n${ast.errors.join("\n")}`);
188
- const s = new MagicString(content);
189
- const ctx = {
190
- component: this.component,
191
- file
192
- };
193
- transformSpecifiers(ast.program, s, (specifier) => {
194
- let resolved = {
195
- type: "unknown-specifier",
196
- specifier
197
- };
198
- const onResolve = this.component.onResolve ?? this.registry.onResolve;
199
- const resolvedSpecifier = resolver.oxc.resolveFileSync(sourceFilePath, specifier);
200
- if (resolvedSpecifier.error || !resolvedSpecifier.path) return writeReference(onResolve ? onResolve(resolved, ctx) : resolved);
201
- resolved = {
202
- type: "file",
203
- file: resolvedSpecifier.path
204
- };
205
- if (!isRelative(this.registry.dir, resolvedSpecifier.path)) resolved = {
206
- type: "dependency",
207
- dep: resolver.getDepFromSpecifier(specifier),
208
- specifier
209
- };
210
- else {
211
- const sub = resolver.getSubComponent(resolvedSpecifier.path);
212
- if (sub) resolved = {
213
- type: "sub-component",
214
- resolved: {
215
- type: "local",
216
- component: sub.component,
217
- file: sub.file
218
- }
219
- };
220
- }
221
- return writeReference(onResolve ? onResolve(resolved, ctx) : resolved);
222
- });
223
- return {
224
- ...file,
225
- content: s.toString()
226
- };
227
- }
228
- };
229
- function resolveFromRemote(r, component, selectFile) {
230
- const comp = r.components.find((comp) => comp.name === component);
231
- if (!comp) return;
232
- const file = comp.files.find(selectFile);
233
- if (!file) return;
234
- return {
235
- type: "sub-component",
236
- resolved: {
237
- type: "remote",
238
- registryName: r.name,
239
- component: comp,
240
- file
241
- }
242
- };
243
- }
244
- //#endregion
245
- //#region src/build/index.ts
246
- function combineRegistry(root, ...items) {
247
- return {
248
- ...root,
249
- info: {
250
- ...root.info,
251
- registries: items.map((item) => item.name)
252
- },
253
- registries: items
254
- };
255
- }
256
- async function writeFumadocsRegistry(out, options) {
257
- const { dir, cleanDir = false, log = true } = options;
258
- if (cleanDir) {
259
- await fs$1.rm(dir, {
260
- recursive: true,
261
- force: true
262
- });
263
- console.log(picocolors.bold(picocolors.greenBright("Cleaned directory")));
264
- }
265
- async function writeInfo() {
266
- await writeFile(path$1.join(dir, "_registry.json"), JSON.stringify(out.info, null, 2), log);
267
- }
268
- const write = out.components.map(async (comp) => {
269
- await writeFile(path$1.join(dir, `${comp.name}.json`), JSON.stringify(comp, null, 2), log);
270
- });
271
- write.push(writeInfo());
272
- if ("registries" in out) for (const child of out.registries) write.push(writeFumadocsRegistry(child, {
273
- dir: path$1.join(dir, child.name),
274
- log: options.log
275
- }));
276
- await Promise.all(write);
277
- }
278
- async function writeFile(file, content, log = true) {
279
- await fs$1.mkdir(path$1.dirname(file), { recursive: true });
280
- await fs$1.writeFile(file, content);
281
- if (log) {
282
- const size = (Buffer.byteLength(content) / 1024).toFixed(2);
283
- console.log(`${picocolors.greenBright("+")} ${path$1.relative(process.cwd(), file)} ${picocolors.dim(`${size} KB`)}`);
284
- }
285
- }
286
- //#endregion
287
- export { ComponentCompiler, RegistryCompiler, combineRegistry, resolveFromRemote, writeFumadocsRegistry };
288
-
289
- //# sourceMappingURL=index.js.map