@fumadocs/cli 1.6.2 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{all-BBf7I8hG.js → all-BVSylqu2.js} +2 -2
- package/dist/{all-BBf7I8hG.js.map → all-BVSylqu2.js.map} +1 -1
- package/dist/features/all.js +1 -1
- package/dist/features/index.js +1 -1
- package/dist/features/search.d.ts +55 -10
- package/dist/features/search.d.ts.map +1 -1
- package/dist/features/search.js +2 -2
- package/dist/{features-CXFCgOWD.js → features-Do6x9Tsz.js} +6 -12
- package/dist/features-Do6x9Tsz.js.map +1 -0
- package/dist/index.js +65 -66
- package/dist/index.js.map +1 -1
- package/dist/installer-C4662Woc.js +33 -0
- package/dist/installer-C4662Woc.js.map +1 -0
- package/dist/registry/installer.d.ts +3 -4
- package/dist/registry/installer.d.ts.map +1 -1
- package/dist/registry/installer.js +1 -1
- package/dist/{search-WfSdiGx-.js → search-BbzvfJal.js} +134 -77
- package/dist/search-BbzvfJal.js.map +1 -0
- package/package.json +3 -2
- package/dist/features-CXFCgOWD.js.map +0 -1
- package/dist/installer-CzhVfs7i.js +0 -204
- package/dist/installer-CzhVfs7i.js.map +0 -1
- package/dist/search-WfSdiGx-.js.map +0 -1
|
@@ -2,7 +2,7 @@ import { t as docs } from "./docs--WqEHTyl.js";
|
|
|
2
2
|
import { t as ai } from "./ai-C19ZOP53.js";
|
|
3
3
|
import { r as llms } from "./llms-Br0RJXXg.js";
|
|
4
4
|
import { t as og } from "./og-LFlX1Bl4.js";
|
|
5
|
-
import { t as search } from "./search-
|
|
5
|
+
import { t as search } from "./search-BbzvfJal.js";
|
|
6
6
|
import { t as mcp } from "./mcp-Ce_W93we.js";
|
|
7
7
|
import { n as webmcp } from "./webmcp-DyTLrsXL.js";
|
|
8
8
|
import { t as feedback } from "./feedback-Brj092vC.js";
|
|
@@ -24,4 +24,4 @@ const features = [
|
|
|
24
24
|
//#endregion
|
|
25
25
|
export { features as t };
|
|
26
26
|
|
|
27
|
-
//# sourceMappingURL=all-
|
|
27
|
+
//# sourceMappingURL=all-BVSylqu2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all-
|
|
1
|
+
{"version":3,"file":"all-BVSylqu2.js","names":[],"sources":["../src/features/all.ts"],"sourcesContent":["import type { AnyFeature } from '.';\nimport { docs } from './docs';\nimport { ai } from './ai';\nimport { llms } from './llms';\nimport { og } from './og';\nimport { search } from './search';\nimport { mcp } from './mcp';\nimport { webmcp } from './webmcp';\nimport { feedback } from './feedback';\nimport { epub } from './epub';\nimport { lint } from './lint';\n\nexport const features: AnyFeature[] = [\n docs,\n ai,\n llms,\n mcp,\n webmcp,\n og,\n search,\n feedback,\n epub,\n lint,\n];\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,WAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
|
package/dist/features/all.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as features } from "../all-
|
|
1
|
+
import { t as features } from "../all-BVSylqu2.js";
|
|
2
2
|
export { features };
|
package/dist/features/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runFeature } from "../features-
|
|
1
|
+
import { t as runFeature } from "../features-Do6x9Tsz.js";
|
|
2
2
|
export { runFeature };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { o as ReactFramework, s as SourceInfo } from "../index-DI66DoV8.js";
|
|
1
2
|
import { r as Feature } from "../index-Cs7hw2un.js";
|
|
2
|
-
import { t as SourceRef } from "../utils-CxJ7kw39.js";
|
|
3
|
+
import { p as FormattedRoute, t as SourceRef } from "../utils-CxJ7kw39.js";
|
|
3
4
|
//#region src/features/search.d.ts
|
|
4
5
|
/** how client code reads public env variables */
|
|
5
6
|
interface Env {
|
|
6
7
|
prefix: string;
|
|
7
8
|
read: string;
|
|
8
9
|
}
|
|
10
|
+
/** `scripts/sync-content.ts`, syncing the search indexes pre-rendered to `output` */
|
|
11
|
+
export declare const syncScript: (output: string, imports: string, body: string) => string;
|
|
9
12
|
declare const providers: {
|
|
10
13
|
'orama-cloud': {
|
|
11
14
|
label: string;
|
|
@@ -18,10 +21,13 @@ declare const providers: {
|
|
|
18
21
|
static: true;
|
|
19
22
|
dialog: (env: Env) => string;
|
|
20
23
|
exportIndexes: ({ ref }: SourceRef) => {
|
|
21
|
-
|
|
24
|
+
head: string;
|
|
22
25
|
documents: string;
|
|
23
26
|
};
|
|
24
|
-
sync: (env: Env
|
|
27
|
+
sync: (env: Env, { output }: {
|
|
28
|
+
dir: string;
|
|
29
|
+
output: string;
|
|
30
|
+
}) => string;
|
|
25
31
|
};
|
|
26
32
|
algolia: {
|
|
27
33
|
label: string;
|
|
@@ -34,10 +40,32 @@ declare const providers: {
|
|
|
34
40
|
static: true;
|
|
35
41
|
dialog: (env: Env) => string;
|
|
36
42
|
exportIndexes: ({ ref }: SourceRef) => {
|
|
37
|
-
|
|
43
|
+
head: string;
|
|
38
44
|
documents: string;
|
|
39
45
|
};
|
|
40
|
-
sync: (env: Env
|
|
46
|
+
sync: (env: Env, { output }: {
|
|
47
|
+
dir: string;
|
|
48
|
+
output: string;
|
|
49
|
+
}) => string;
|
|
50
|
+
};
|
|
51
|
+
meilisearch: {
|
|
52
|
+
label: string;
|
|
53
|
+
hint: string;
|
|
54
|
+
dependencies: {
|
|
55
|
+
meilisearch: null;
|
|
56
|
+
};
|
|
57
|
+
publicEnv: string[];
|
|
58
|
+
privateEnv: string[];
|
|
59
|
+
static: true;
|
|
60
|
+
dialog: (env: Env) => string;
|
|
61
|
+
exportIndexes: ({ ref }: SourceRef) => {
|
|
62
|
+
head: string;
|
|
63
|
+
documents: string;
|
|
64
|
+
};
|
|
65
|
+
sync: (env: Env, { output }: {
|
|
66
|
+
dir: string;
|
|
67
|
+
output: string;
|
|
68
|
+
}) => string;
|
|
41
69
|
};
|
|
42
70
|
typesense: {
|
|
43
71
|
label: string;
|
|
@@ -50,12 +78,14 @@ declare const providers: {
|
|
|
50
78
|
privateEnv: string[];
|
|
51
79
|
static: true;
|
|
52
80
|
dialog: (env: Env) => string;
|
|
53
|
-
exportIndexes: (src: SourceRef) => {
|
|
54
|
-
|
|
81
|
+
exportIndexes: (src: SourceRef, async: boolean) => {
|
|
82
|
+
head: string;
|
|
55
83
|
documents: string;
|
|
56
|
-
file: (async: boolean) => string;
|
|
57
84
|
};
|
|
58
|
-
sync: (env: Env
|
|
85
|
+
sync: (env: Env, { output }: {
|
|
86
|
+
dir: string;
|
|
87
|
+
output: string;
|
|
88
|
+
}) => string;
|
|
59
89
|
};
|
|
60
90
|
mixedbread: {
|
|
61
91
|
label: string;
|
|
@@ -67,7 +97,10 @@ declare const providers: {
|
|
|
67
97
|
privateEnv: string[];
|
|
68
98
|
static: false;
|
|
69
99
|
dialog: () => string;
|
|
70
|
-
sync: (_env: Env, dir:
|
|
100
|
+
sync: (_env: Env, { dir }: {
|
|
101
|
+
dir: string;
|
|
102
|
+
output: string;
|
|
103
|
+
}) => string;
|
|
71
104
|
searchRoute: {
|
|
72
105
|
next: string;
|
|
73
106
|
'react-router': string;
|
|
@@ -77,6 +110,18 @@ declare const providers: {
|
|
|
77
110
|
};
|
|
78
111
|
};
|
|
79
112
|
export type SearchProvider = keyof typeof providers;
|
|
113
|
+
/** pre-rendered on build to export the search indexes */
|
|
114
|
+
export declare const staticJson: (framework: ReactFramework) => FormattedRoute;
|
|
115
|
+
export declare const staticRoute: (framework: ReactFramework, head: string, documents: string) => string;
|
|
116
|
+
/** where `static.json` is pre-rendered on build, `config` is the Vite config of TanStack Start */
|
|
117
|
+
export declare function staticOutput(framework: ReactFramework, config?: string): string;
|
|
118
|
+
/** runs the sync script after build */
|
|
119
|
+
export declare const syncCommand = "node --env-file-if-exists=.env.local scripts/sync-content.ts";
|
|
120
|
+
/** the files written by a provider, relative to the project, `output` is where `static.json` is pre-rendered */
|
|
121
|
+
export declare function templates(name: SearchProvider, framework: ReactFramework, { baseDir, source }: {
|
|
122
|
+
baseDir: string;
|
|
123
|
+
source: Pick<SourceInfo, 'dynamic' | 'async' | 'dir'>;
|
|
124
|
+
}, output: string): [file: string, content: string][];
|
|
80
125
|
export declare const search: Feature<{
|
|
81
126
|
provider: SearchProvider;
|
|
82
127
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","names":[],"sources":["../../src/features/search.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"search.d.ts","names":[],"sources":["../../src/features/search.ts"],"mappings":";;;;;UAyBU;EACR;EACA;;;qBAsEW,aAAU,gBACP,iBACC;cAqCX;;;;;MAIc;;;;;;;;;;;MATc;MAAgB;;;;;;;MAyD9B;;;;;;;;;;;MAzDc;MAAgB;;;;;;;MAyG9B;;;;;;;;;;;MAzGc;MAAgB;;;;;;;MA4J9B;MAAiB;;;;;;;;;;;MA5JH;MAAgB;;;;;;;MA4M9B;;;;;;;MA5Mc;MAAgB;;;;;;;;;;YAiRtC,8BAA8B;;qBAG7B,aAAU,WAAe,mBAAA;qBAGzB,cAAW,WAAe,gBAAc,cAAc;;wBASnD,aAAa,WAAW,gBAAgB;;qBAgB3C;;wBAGG,UACd,MAAM,gBACN,WAAW,kBACT,SAAS;EAAY;EAAiB,QAAQ,KAAK;GACrD,kBACE,cAAc;qBAmBL,QAAQ;EAAU,UAAU"}
|
package/dist/features/search.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as search } from "../search-
|
|
2
|
-
export { search };
|
|
1
|
+
import { a as syncCommand, i as staticRoute, n as staticJson, o as syncScript, r as staticOutput, s as templates, t as search } from "../search-BbzvfJal.js";
|
|
2
|
+
export { search, staticJson, staticOutput, staticRoute, syncCommand, syncScript, templates };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { g as createSourceFile } from "./codemod-auol-p4R.js";
|
|
2
2
|
import { t as exists } from "./fs-D6J9dOEx.js";
|
|
3
|
-
import { t as FumadocsComponentInstaller } from "./installer-
|
|
3
|
+
import { t as FumadocsComponentInstaller } from "./installer-C4662Woc.js";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { x } from "tinyexec";
|
|
@@ -15,9 +15,8 @@ async function runFeature(feature, options, { project, connector, io, versions }
|
|
|
15
15
|
const env = [];
|
|
16
16
|
const notes = [];
|
|
17
17
|
const installer = new FumadocsComponentInstaller(connector, project.config, cwd, {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
onFileDownloaded: ({ path: file }) => io.log(`installed ${path.relative(cwd, file)}`)
|
|
18
|
+
confirmFileOverride: (file) => io.confirmOverwrite(path.relative(cwd, file.output)),
|
|
19
|
+
onFileWritten: (file) => io.log(`installed ${path.relative(cwd, file.output)}`)
|
|
21
20
|
});
|
|
22
21
|
const ctx = {
|
|
23
22
|
project,
|
|
@@ -72,13 +71,8 @@ async function runFeature(feature, options, { project, connector, io, versions }
|
|
|
72
71
|
},
|
|
73
72
|
async install(name, subRegistry) {
|
|
74
73
|
const manager = await (await installer.install(name, subRegistry)).deps();
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (at === -1) target[dep] = null;
|
|
78
|
-
else target[dep.slice(0, at)] = dep.slice(at + 1);
|
|
79
|
-
};
|
|
80
|
-
for (const dep of manager.dependencies) decode(deps, dep);
|
|
81
|
-
for (const dep of manager.devDependencies) decode(devDeps, dep);
|
|
74
|
+
Object.assign(deps, manager.required);
|
|
75
|
+
Object.assign(devDeps, manager.requiredDev);
|
|
82
76
|
}
|
|
83
77
|
};
|
|
84
78
|
await feature.apply(ctx, options);
|
|
@@ -129,4 +123,4 @@ async function installDependencies(project, deps, devDeps, io, versions = {}) {
|
|
|
129
123
|
//#endregion
|
|
130
124
|
export { runFeature as t };
|
|
131
125
|
|
|
132
|
-
//# sourceMappingURL=features-
|
|
126
|
+
//# sourceMappingURL=features-Do6x9Tsz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features-Do6x9Tsz.js","names":[],"sources":["../src/features/index.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { x } from 'tinyexec';\nimport type { RegistryConnector } from 'fuma-cli/registry/connector';\nimport type { Project } from '@/project';\nimport { createSourceFile, type SourceFile } from '@/codemod';\nimport { FumadocsComponentInstaller } from '@/registry/installer';\nimport { exists } from '@/utils/fs';\n\nexport interface SelectOption<T> {\n message: string;\n choices: { value: T; label: string; hint?: string }[];\n}\n\nexport interface ConfirmOption {\n message: string;\n initialValue?: boolean;\n}\n\nexport type FeatureOption<T> = [T] extends [boolean] ? ConfirmOption : SelectOption<T>;\n\nexport interface Feature<Options extends object = Record<never, never>> {\n id: string;\n title: string;\n description: string;\n options?: { [K in keyof Options]: FeatureOption<Options[K]> };\n /** features that must be applied first */\n requires?: AnyFeature[];\n /** whether the feature is already applied to the project */\n detect?: (project: Project) => Promise<boolean>;\n /** @returns `true` if supported, otherwise the reason */\n supports?: (project: Project) => true | string;\n apply(ctx: FeatureContext, options: Options): Promise<void>;\n}\n\nexport type AnyFeature = Omit<Feature<Record<string, unknown>>, 'options'> & {\n options?: Record<string, SelectOption<unknown> | ConfirmOption>;\n};\n\nexport interface PackageJson {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nexport interface FeatureContext {\n project: Project;\n /** write a file (relative to project root), asks before overwriting */\n write: (file: string, content: string) => Promise<void>;\n /** edit a file with codemods, `false` if the file doesn't exist */\n source: (file: string, edit: (file: SourceFile) => void) => Promise<boolean>;\n /** append lines to a text file, skip lines already present */\n append: (file: string, lines: string[]) => Promise<void>;\n remove: (file: string) => Promise<void>;\n packageJson: (edit: (data: PackageJson) => void) => Promise<void>;\n /** install a registry component */\n install: (name: string, subRegistry?: string) => Promise<void>;\n /** `null` to install the latest version */\n addDependencies: (deps: Record<string, string | null>, dev?: boolean) => void;\n env: (key: string, value: string) => void;\n /** instructions to show after the feature is applied */\n note: (text: string) => void;\n log: (message: string) => void;\n}\n\nexport interface FeatureIO {\n log: (message: string) => void;\n confirmOverwrite: (file: string) => Promise<boolean>;\n /** run package manager to install dependencies, otherwise only write them into `package.json` */\n installDependencies: boolean;\n}\n\nexport interface RunOptions {\n project: Project;\n connector: RegistryConnector;\n io: FeatureIO;\n /** preferred versions of dependencies, when a feature doesn't specify one */\n versions?: Record<string, string>;\n}\n\nexport async function runFeature<O extends object>(\n feature: Omit<Feature<O>, 'options'>,\n options: O,\n { project, connector, io, versions }: RunOptions,\n): Promise<{ notes: string[] }> {\n for (const dep of feature.requires ?? []) {\n if (dep.detect && !(await dep.detect(project)))\n throw new Error(\n `\"${feature.id}\" requires \"${dep.id}\", run \\`fumadocs feature ${dep.id}\\` first.`,\n );\n }\n const supported = feature.supports?.(project) ?? true;\n if (supported !== true) throw new Error(`\"${feature.id}\" is unavailable: ${supported}`);\n\n const { cwd } = project;\n const deps: Record<string, string | null> = {};\n const devDeps: Record<string, string | null> = {};\n const env: string[] = [];\n const notes: string[] = [];\n const installer = new FumadocsComponentInstaller(connector, project.config, cwd, {\n confirmFileOverride: (file) => io.confirmOverwrite(path.relative(cwd, file.output)),\n onFileWritten: (file) => io.log(`installed ${path.relative(cwd, file.output)}`),\n });\n\n const ctx: FeatureContext = {\n project,\n log: io.log,\n note: (text) => notes.push(text),\n env: (key, value) => env.push(`${key}=${value}`),\n addDependencies(input, dev) {\n Object.assign(dev ? devDeps : deps, input);\n },\n async write(file, content) {\n const target = path.join(cwd, file);\n const current = await fs.readFile(target, 'utf-8').catch(() => null);\n if (current !== null) {\n if (current.trim() === content.trim()) return;\n if (!(await io.confirmOverwrite(file))) return;\n }\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, content);\n io.log(`${current === null ? 'created' : 'updated'} ${file}`);\n },\n async source(file, edit) {\n const target = path.join(cwd, file);\n if (!(await exists(target))) return false;\n const source = await createSourceFile(target);\n edit(source);\n if (source.s.hasChanged()) {\n await source.save();\n io.log(`updated ${file}`);\n }\n return true;\n },\n async append(file, lines) {\n const target = path.join(cwd, file);\n const current = await fs.readFile(target, 'utf-8').catch(() => '');\n const missing = lines.filter((line) => !current.includes(line));\n if (missing.length === 0) return;\n const separator = current.length === 0 || current.endsWith('\\n') ? '' : '\\n';\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, `${current}${separator}${missing.join('\\n')}\\n`);\n io.log(`updated ${file}`);\n },\n async remove(file) {\n await fs.rm(path.join(cwd, file), { force: true });\n io.log(`removed ${file}`);\n },\n async packageJson(edit) {\n const target = path.join(cwd, 'package.json');\n const data = JSON.parse(await fs.readFile(target, 'utf-8'));\n edit(data);\n await fs.writeFile(target, `${JSON.stringify(data, null, 2)}\\n`);\n io.log('updated package.json');\n },\n async install(name, subRegistry) {\n const result = await installer.install(name, subRegistry);\n const manager = await result.deps();\n Object.assign(deps, manager.required);\n Object.assign(devDeps, manager.requiredDev);\n },\n };\n\n await feature.apply(ctx, options);\n\n if (env.length > 0) await ctx.append('.env.local', env);\n await installDependencies(project, deps, devDeps, io, versions);\n return { notes };\n}\n\nasync function installDependencies(\n project: Project,\n deps: Record<string, string | null>,\n devDeps: Record<string, string | null>,\n io: FeatureIO,\n versions: Record<string, string> = {},\n) {\n const { dependencies = {}, devDependencies = {} } = project.packageJson;\n const filter = (input: Record<string, string | null>) =>\n Object.entries(input).filter(([name]) => !(name in dependencies) && !(name in devDependencies));\n const missing = filter(deps);\n const missingDev = filter(devDeps);\n if (missing.length === 0 && missingDev.length === 0) return;\n\n if (io.installDependencies) {\n const pm = project.packageManager;\n const run = async (flags: string[], entries: [string, string | null][]) => {\n if (entries.length === 0) return;\n const args = [\n 'add',\n ...flags,\n ...entries.map(([name, version]) => (version ? `${name}@${version}` : name)),\n ];\n io.log(`${pm} ${args.join(' ')}`);\n await x(pm, args, {\n nodeOptions: { cwd: project.cwd, stdio: 'inherit' },\n throwOnError: true,\n });\n };\n await run([], missing);\n await run(['-D'], missingDev);\n return;\n }\n\n const file = path.join(project.cwd, 'package.json');\n const json = JSON.parse(await fs.readFile(file, 'utf-8'));\n const write = (field: string, entries: [string, string | null][]) => {\n if (entries.length === 0) return;\n const target = (json[field] ??= {});\n for (const [name, version] of entries) target[name] = version ?? versions[name] ?? 'latest';\n };\n write('dependencies', missing);\n write('devDependencies', missingDev);\n await fs.writeFile(file, `${JSON.stringify(json, null, 2)}\\n`);\n io.log('updated package.json');\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,15 +3,15 @@ import { i as initConfig, n as createOrLoadConfig } from "./config-Bw0kmF01.js";
|
|
|
3
3
|
import { T as parseSourceFile } from "./codemod-auol-p4R.js";
|
|
4
4
|
import { t as exists } from "./fs-D6J9dOEx.js";
|
|
5
5
|
import { i as loadProject, n as frameworks } from "./project-DwRVTm4p.js";
|
|
6
|
-
import { n as
|
|
7
|
-
import { t as runFeature } from "./features-
|
|
8
|
-
import { t as features } from "./all-
|
|
6
|
+
import { n as UIRegistries, t as FumadocsComponentInstaller } from "./installer-C4662Woc.js";
|
|
7
|
+
import { t as runFeature } from "./features-Do6x9Tsz.js";
|
|
8
|
+
import { t as features } from "./all-BVSylqu2.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { cac } from "cac";
|
|
12
12
|
import picocolors from "picocolors";
|
|
13
13
|
import { x } from "tinyexec";
|
|
14
|
-
import { autocompleteMultiselect, cancel, confirm, group, intro, log, note, outro, select, spinner } from "@clack/prompts";
|
|
14
|
+
import { autocompleteMultiselect, cancel, confirm, group, intro, isCancel, log, note, outro, select, spinner } from "@clack/prompts";
|
|
15
15
|
import { exec } from "node:child_process";
|
|
16
16
|
import { promisify } from "node:util";
|
|
17
17
|
import { HttpRegistryConnector, LocalRegistryConnector } from "fuma-cli/registry/connector";
|
|
@@ -66,14 +66,14 @@ async function runTree(args) {
|
|
|
66
66
|
}
|
|
67
67
|
//#endregion
|
|
68
68
|
//#region package.json
|
|
69
|
-
var version = "1.
|
|
69
|
+
var version = "1.7.1";
|
|
70
70
|
//#endregion
|
|
71
71
|
//#region src/commands/customise.ts
|
|
72
72
|
async function customise(config, connector) {
|
|
73
73
|
intro(picocolors.bgBlack(picocolors.whiteBright("Customize Fumadocs UI")));
|
|
74
74
|
const installer = new FumadocsComponentInstaller(connector, config);
|
|
75
75
|
const subRegistry = UIRegistries[config.uiLibrary];
|
|
76
|
-
const
|
|
76
|
+
const manifest = await installer.fetchManifest(subRegistry);
|
|
77
77
|
const targetInfo = (await group({
|
|
78
78
|
layout: () => select({
|
|
79
79
|
message: "What do you want to customize?",
|
|
@@ -143,6 +143,33 @@ async function customise(config, connector) {
|
|
|
143
143
|
target: (v) => {
|
|
144
144
|
const selected = v.results.layout;
|
|
145
145
|
if (selected.id === "home") return Promise.resolve(selected);
|
|
146
|
+
const slots = [];
|
|
147
|
+
const prefix = `layouts/${selected.id}/`;
|
|
148
|
+
for (const { name: id } of manifest.components) {
|
|
149
|
+
const [dir, name] = id.startsWith(prefix) ? id.slice(prefix.length).split("slots/") : [];
|
|
150
|
+
if (name === void 0) continue;
|
|
151
|
+
const isPage = dir === "page/";
|
|
152
|
+
slots.push({
|
|
153
|
+
label: `${isPage ? "Page" : "Layout"}: ${name}`,
|
|
154
|
+
hint: `only replace a part of layout${isPage ? "'s page" : ""}, useful for adjusting details`,
|
|
155
|
+
value: {
|
|
156
|
+
id,
|
|
157
|
+
targets: [{
|
|
158
|
+
subRegistry,
|
|
159
|
+
name: id
|
|
160
|
+
}],
|
|
161
|
+
print() {
|
|
162
|
+
printSlot({
|
|
163
|
+
at: `@/${id}`,
|
|
164
|
+
layoutId: selected.id,
|
|
165
|
+
name,
|
|
166
|
+
isPage,
|
|
167
|
+
uiLibrary: config.uiLibrary
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
146
173
|
return select({
|
|
147
174
|
message: "Which part do you want to customize?",
|
|
148
175
|
options: [
|
|
@@ -160,54 +187,7 @@ async function customise(config, connector) {
|
|
|
160
187
|
print: () => printLayout(config, ["fumadocs-ui/layouts/docs", "@/layouts/docs"], ["fumadocs-ui/layouts/docs/page", "@/layouts/docs/page"])
|
|
161
188
|
}
|
|
162
189
|
},
|
|
163
|
-
...
|
|
164
|
-
const prefix = `slots/${selected.id}`;
|
|
165
|
-
if (!index.name.startsWith(prefix)) return [];
|
|
166
|
-
let name = index.name.slice(prefix.length + 1);
|
|
167
|
-
if (name.startsWith("page/")) {
|
|
168
|
-
name = name.slice(5);
|
|
169
|
-
return {
|
|
170
|
-
label: `Page: ${name}`,
|
|
171
|
-
hint: "only replace a part of layout's page, useful for adjusting details",
|
|
172
|
-
value: {
|
|
173
|
-
id: index.name,
|
|
174
|
-
targets: [{
|
|
175
|
-
subRegistry,
|
|
176
|
-
name: index.name
|
|
177
|
-
}],
|
|
178
|
-
print() {
|
|
179
|
-
printSlot({
|
|
180
|
-
at: `@/layouts/${selected.id}/page/slots/${name}`,
|
|
181
|
-
layoutId: selected.id,
|
|
182
|
-
name,
|
|
183
|
-
isPage: true,
|
|
184
|
-
uiLibrary: config.uiLibrary
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
label: `Layout: ${name}`,
|
|
192
|
-
hint: "only replace a part of layout, useful for adjusting details",
|
|
193
|
-
value: {
|
|
194
|
-
id: index.name,
|
|
195
|
-
targets: [{
|
|
196
|
-
subRegistry,
|
|
197
|
-
name: index.name
|
|
198
|
-
}],
|
|
199
|
-
print() {
|
|
200
|
-
printSlot({
|
|
201
|
-
at: `@/layouts/${selected.id}/slots/${name}`,
|
|
202
|
-
layoutId: selected.id,
|
|
203
|
-
name,
|
|
204
|
-
isPage: false,
|
|
205
|
-
uiLibrary: config.uiLibrary
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
})
|
|
190
|
+
...slots
|
|
211
191
|
]
|
|
212
192
|
});
|
|
213
193
|
}
|
|
@@ -455,6 +435,15 @@ return (
|
|
|
455
435
|
}
|
|
456
436
|
}
|
|
457
437
|
//#endregion
|
|
438
|
+
//#region src/utils/prompt.ts
|
|
439
|
+
/**
|
|
440
|
+
* `@clack/core` narrows to its own `unique symbol`, which can't exclude the wider `symbol` that
|
|
441
|
+
* `@clack/prompts` returns, so a prompt result never narrows without this.
|
|
442
|
+
*/
|
|
443
|
+
function isCancel$1(value) {
|
|
444
|
+
return isCancel(value);
|
|
445
|
+
}
|
|
446
|
+
//#endregion
|
|
458
447
|
//#region src/commands/add.ts
|
|
459
448
|
async function add(input, connector, config) {
|
|
460
449
|
let targets;
|
|
@@ -464,14 +453,20 @@ async function add(input, connector, config) {
|
|
|
464
453
|
const spin = spinner();
|
|
465
454
|
spin.start("fetching registry");
|
|
466
455
|
async function scan(subRegistry, prefix) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
456
|
+
const manifest = await installer.fetchManifest(subRegistry);
|
|
457
|
+
const options = [];
|
|
458
|
+
for (const item of manifest.components) {
|
|
459
|
+
if (item.unlisted) continue;
|
|
460
|
+
options.push({
|
|
461
|
+
label: `${prefix ? `${picocolors.bold(prefix)} - ` : ""}${item.title ?? item.name}`,
|
|
462
|
+
value: {
|
|
463
|
+
name: item.name,
|
|
464
|
+
subRegistry
|
|
465
|
+
},
|
|
466
|
+
hint: item.description
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
return options;
|
|
475
470
|
}
|
|
476
471
|
const groups = await Promise.all([
|
|
477
472
|
scan(void 0, "common"),
|
|
@@ -490,10 +485,14 @@ async function add(input, connector, config) {
|
|
|
490
485
|
return;
|
|
491
486
|
}
|
|
492
487
|
targets = value;
|
|
493
|
-
} else
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
488
|
+
} else {
|
|
489
|
+
const root = /* @__PURE__ */ new Set();
|
|
490
|
+
for (const item of (await installer.fetchManifest()).components) root.add(item.name);
|
|
491
|
+
targets = input.map((name) => root.has(name) ? { name } : {
|
|
492
|
+
subRegistry,
|
|
493
|
+
name
|
|
494
|
+
});
|
|
495
|
+
}
|
|
497
496
|
for (const target of targets) await installer.installInteractive(target.name, target.subRegistry);
|
|
498
497
|
outro(picocolors.bold(picocolors.greenBright("Successful")));
|
|
499
498
|
}
|