@fumadocs/cli 1.3.3 → 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 (43) hide show
  1. package/dist/config.d.ts +53 -2
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +9 -6
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.js +87 -157
  6. package/dist/index.js.map +1 -1
  7. package/dist/installer-zD4jTQWp.js +128 -0
  8. package/dist/installer-zD4jTQWp.js.map +1 -0
  9. package/dist/registry/installer.d.ts +13 -0
  10. package/dist/registry/installer.d.ts.map +1 -0
  11. package/dist/registry/installer.js +2 -0
  12. package/package.json +7 -15
  13. package/dist/build/index.d.ts +0 -148
  14. package/dist/build/index.d.ts.map +0 -1
  15. package/dist/build/index.js +0 -289
  16. package/dist/build/index.js.map +0 -1
  17. package/dist/client-C2A4Jf2w.js +0 -102
  18. package/dist/client-C2A4Jf2w.js.map +0 -1
  19. package/dist/config-Bx-m6awG.d.ts +0 -53
  20. package/dist/config-Bx-m6awG.d.ts.map +0 -1
  21. package/dist/fs-C3j4H046.js +0 -18
  22. package/dist/fs-C3j4H046.js.map +0 -1
  23. package/dist/import-CSbSteB3.js +0 -124
  24. package/dist/import-CSbSteB3.js.map +0 -1
  25. package/dist/installer-BWoLnsXE.js +0 -673
  26. package/dist/installer-BWoLnsXE.js.map +0 -1
  27. package/dist/registry/client.d.ts +0 -112
  28. package/dist/registry/client.d.ts.map +0 -1
  29. package/dist/registry/client.js +0 -2
  30. package/dist/registry/installer/index.d.ts +0 -96
  31. package/dist/registry/installer/index.d.ts.map +0 -1
  32. package/dist/registry/installer/index.js +0 -2
  33. package/dist/registry/macros/route-handler.d.ts +0 -21
  34. package/dist/registry/macros/route-handler.d.ts.map +0 -1
  35. package/dist/registry/macros/route-handler.js +0 -11
  36. package/dist/registry/macros/route-handler.js.map +0 -1
  37. package/dist/registry/schema.d.ts +0 -2
  38. package/dist/registry/schema.js +0 -50
  39. package/dist/registry/schema.js.map +0 -1
  40. package/dist/schema-BAaUX4uu.d.ts +0 -77
  41. package/dist/schema-BAaUX4uu.d.ts.map +0 -1
  42. package/dist/types-79PW0lgM.d.ts +0 -6
  43. package/dist/types-79PW0lgM.d.ts.map +0 -1
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["fs","path","fs","path"],"sources":["../../src/build/compiler.ts","../../src/build/index.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n CompiledComponent,\n CompiledFile,\n httpSubComponent,\n registryInfoSchema,\n} from '@/registry/schema';\nimport type { z } from 'zod';\nimport { parse } from 'oxc-parser';\nimport { ResolverFactory } from 'oxc-resolver';\nimport MagicString from 'magic-string';\nimport { transformSpecifiers } from '@/utils/ast';\nimport { isRelative } from '@/utils/fs';\nimport type { DistributiveOmit } from '@/types';\nimport { encodeImport } from '@/registry/protocols/import';\n\nexport type OnResolve = (\n reference: SourceReference,\n from: { component: Component; file: ComponentFile },\n) => Reference;\n\nexport interface CompiledRegistry {\n name: string;\n components: CompiledComponent[];\n info: z.output<typeof registryInfoSchema>;\n}\n\nexport type ComponentFile = DistributiveOmit<CompiledFile, 'content'> & {\n path: string;\n};\n\nexport interface Component {\n name: string;\n title?: string;\n description?: string;\n files: ComponentFile[];\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n\n /**\n * Don't list the component in registry index file\n */\n unlisted?: boolean;\n\n /**\n * Map imported file paths, inherit from registry if not defined.\n */\n onResolve?: OnResolve;\n}\n\nexport interface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nexport interface Registry extends Omit<z.input<typeof registryInfoSchema>, 'indexes'> {\n name: string;\n packageJson: string | PackageJson;\n tsconfigPath: string;\n components: Component[];\n\n /**\n * The directory of registry, used to resolve relative paths\n */\n dir: string;\n\n /**\n * Map import paths of components\n */\n onResolve?: OnResolve;\n /**\n * When a referenced file is not found in component files, this function is called.\n * @returns file, or `false` to mark as external.\n */\n onUnknownFile?: (absolutePath: string) => ComponentFile | false | undefined;\n\n dependencies?: Record<string, string | null>;\n devDependencies?: Record<string, string | null>;\n}\n\nexport class RegistryCompiler {\n readonly raw: Registry;\n resolver!: RegistryResolver;\n\n constructor(registry: Registry) {\n this.raw = registry;\n }\n\n private async readPackageJson(): Promise<PackageJson | undefined> {\n if (typeof this.raw.packageJson !== 'string') return this.raw.packageJson;\n\n return fs\n .readFile(path.join(this.raw.dir, this.raw.packageJson))\n .then((res) => JSON.parse(res.toString()) as PackageJson)\n .catch(() => undefined);\n }\n\n async compile(): Promise<CompiledRegistry> {\n const registry = this.raw;\n this.resolver = new RegistryResolver(this, await this.readPackageJson());\n const output: CompiledRegistry = {\n name: registry.name,\n info: {\n indexes: [],\n unlistedIndexes: [],\n env: registry.env,\n variables: registry.variables,\n },\n components: [],\n };\n\n const builtComps = await Promise.all(\n registry.components.map(async (component) => {\n const compiler = new ComponentCompiler(this, component);\n\n return [component, await compiler.build()] as [Component, CompiledComponent];\n }),\n );\n\n for (const [input, comp] of builtComps) {\n const arr = input.unlisted ? output.info.unlistedIndexes : output.info.indexes;\n\n arr.push({\n name: input.name,\n title: input.title,\n description: input.description,\n });\n output.components.push(comp);\n }\n\n return output;\n }\n}\n\nclass RegistryResolver {\n private readonly deps: Record<string, string | null>;\n private readonly devDeps: Record<string, string | null>;\n private readonly fileToComponent = new Map<string, [Component, ComponentFile]>();\n readonly oxc: ResolverFactory;\n\n constructor(\n private readonly compiler: RegistryCompiler,\n packageJson: PackageJson = {},\n ) {\n const registry = compiler.raw;\n\n for (const comp of registry.components) {\n for (const file of comp.files) {\n if (this.fileToComponent.has(file.path))\n console.warn(\n `the same file ${file.path} exists in multiple component, you should make the shared file a separate component.`,\n );\n this.fileToComponent.set(file.path, [comp, file]);\n }\n }\n\n this.deps = {\n ...packageJson?.dependencies,\n ...registry.dependencies,\n };\n\n this.devDeps = {\n ...packageJson?.devDependencies,\n ...registry.devDependencies,\n };\n\n // resolve anything possible\n this.oxc = new ResolverFactory({\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.node'],\n conditionNames: ['node', 'import', 'require', 'default', 'types'],\n tsconfig: {\n configFile: path.join(registry.dir, registry.tsconfigPath),\n },\n });\n }\n\n getDepFromSpecifier(specifier: string) {\n return specifier.startsWith('@')\n ? specifier.split('/').slice(0, 2).join('/')\n : specifier.split('/')[0];\n }\n\n getDepInfo(name: string):\n | {\n type: 'runtime' | 'dev';\n name: string;\n version: string | null;\n }\n | undefined {\n if (name in this.deps)\n return {\n name,\n type: 'runtime',\n version: this.deps[name],\n };\n\n if (name in this.devDeps)\n return {\n name,\n type: 'dev',\n version: this.devDeps[name],\n };\n\n console.warn(`dep info for ${name} cannot be found`);\n }\n\n getComponentByName(name: string): Component | undefined {\n return this.compiler.raw.components.find((comp) => comp.name === name);\n }\n\n getSubComponent(file: string) {\n const relativeFile = path.relative(this.compiler.raw.dir, file);\n const comp = this.fileToComponent.get(relativeFile);\n\n if (!comp) return;\n return {\n component: comp[0],\n file: comp[1],\n };\n }\n}\n\nexport type SourceReference =\n | {\n type: 'file';\n /**\n * Absolute path\n */\n file: string;\n }\n | {\n type: 'dependency';\n dep: string;\n specifier: string;\n }\n | {\n type: 'sub-component';\n resolved:\n | {\n type: 'local';\n component: Component;\n file: ComponentFile;\n }\n | {\n type: 'remote';\n component: Component;\n file: ComponentFile;\n registryName: string;\n };\n }\n | {\n type: 'unknown-specifier';\n specifier: string;\n };\n\nexport type Reference =\n | SourceReference\n | {\n type: 'custom';\n specifier: string;\n };\n\nexport class ComponentCompiler {\n private readonly processedFiles = new Set<string>();\n private readonly registry: Registry;\n private readonly subComponents = new Map<string, string | z.input<typeof httpSubComponent>>();\n private readonly devDependencies = new Map<string, string | null>();\n private readonly dependencies = new Map<string, string | null>();\n\n constructor(\n private readonly compiler: RegistryCompiler,\n private readonly component: Component,\n ) {\n this.registry = compiler.raw;\n }\n\n async build(): Promise<CompiledComponent> {\n const files = (\n await Promise.all(this.component.files.map((file) => this.onBuildFile(file)))\n ).flat();\n const dependencies = Object.fromEntries(this.dependencies);\n const devDependencies = Object.fromEntries(this.devDependencies);\n\n if (this.component.dependencies) {\n Object.assign(dependencies, this.component.dependencies);\n }\n if (this.component.devDependencies) {\n Object.assign(devDependencies, this.component.devDependencies);\n }\n\n return {\n name: this.component.name,\n title: this.component.title,\n description: this.component.description,\n files,\n subComponents: Array.from(this.subComponents.values()),\n dependencies,\n devDependencies,\n };\n }\n\n private async onBuildFile(file: ComponentFile): Promise<CompiledFile[]> {\n if (this.processedFiles.has(file.path)) return [];\n this.processedFiles.add(file.path);\n const resolver = this.compiler.resolver;\n\n const queue: ComponentFile[] = [];\n const result = await this.buildFile(file, (reference) => {\n const external = reference.type === 'dependency' && reference.dep === '@fumadocs/cli';\n\n if (external) {\n return reference.specifier;\n }\n\n if (reference.type === 'unknown-specifier') {\n if (!reference.specifier.startsWith('node:')) {\n console.warn(`Unknown specifier ${reference.specifier}, skipping for now`);\n }\n\n return reference.specifier;\n }\n\n if (reference.type === 'custom') return reference.specifier;\n\n if (reference.type === 'file') {\n const refFile = this.registry.onUnknownFile?.(reference.file);\n if (refFile) {\n queue.push(refFile);\n return encodeImport(refFile);\n }\n\n if (refFile === false) return;\n\n throw new Error(`Unknown file ${reference.file} referenced by ${file.path}`);\n }\n\n if (reference.type === 'sub-component') {\n const resolved = reference.resolved;\n if (resolved.component.name === this.component.name) return encodeImport(resolved.file);\n\n if (resolved.type === 'remote') {\n this.subComponents.set(`${resolved.registryName}:${resolved.component.name}`, {\n type: 'http',\n baseUrl: resolved.registryName,\n component: resolved.component.name,\n });\n } else {\n this.subComponents.set(resolved.component.name, resolved.component.name);\n }\n\n return encodeImport(resolved.file);\n }\n\n const dep = resolver.getDepInfo(reference.dep);\n if (dep) {\n const map = dep.type === 'dev' ? this.devDependencies : this.dependencies;\n map.set(dep.name, dep.version);\n }\n\n return reference.specifier;\n });\n\n return [result, ...(await Promise.all(queue.map((file) => this.onBuildFile(file)))).flat()];\n }\n\n private async buildFile(\n file: ComponentFile,\n /**\n * write references back to import specifiers\n *\n * keep original one if `undefined`\n */\n writeReference: (reference: Reference) => string | undefined,\n ): Promise<CompiledFile> {\n const sourceFilePath = path.join(this.registry.dir, file.path);\n const astTypes: Record<string, 'js' | 'ts' | undefined> = {\n '.ts': 'ts',\n '.tsx': 'ts',\n '.js': 'js',\n '.jsx': 'js',\n };\n const astType = astTypes[path.extname(file.path)];\n const content = (await fs.readFile(sourceFilePath)).toString();\n\n if (!astType) {\n return {\n ...file,\n content,\n };\n }\n\n const resolver = this.compiler.resolver;\n\n const ast = await parse(sourceFilePath, content, {\n astType,\n });\n\n if (ast.errors.length > 0) {\n throw new Error(`failed to parse file ${sourceFilePath}: \\n${ast.errors.join('\\n')}`);\n }\n\n const s = new MagicString(content);\n const ctx = { component: this.component, file };\n // Process import paths\n transformSpecifiers(ast.program, s, (specifier) => {\n let resolved: Reference = {\n type: 'unknown-specifier',\n specifier: specifier,\n };\n const onResolve = this.component.onResolve ?? this.registry.onResolve;\n const resolvedSpecifier = resolver.oxc.resolveFileSync(sourceFilePath, specifier);\n if (resolvedSpecifier.error || !resolvedSpecifier.path) {\n return writeReference(onResolve ? onResolve(resolved, ctx) : resolved);\n }\n\n resolved = {\n type: 'file',\n file: resolvedSpecifier.path,\n };\n\n // outside of registry dir\n if (!isRelative(this.registry.dir, resolvedSpecifier.path)) {\n resolved = {\n type: 'dependency',\n dep: resolver.getDepFromSpecifier(specifier),\n specifier,\n };\n } else {\n const sub = resolver.getSubComponent(resolvedSpecifier.path);\n if (sub) {\n resolved = {\n type: 'sub-component',\n resolved: {\n type: 'local',\n component: sub.component,\n file: sub.file,\n },\n };\n }\n }\n\n return writeReference(onResolve ? onResolve(resolved, ctx) : resolved);\n });\n\n return {\n ...file,\n content: s.toString(),\n };\n }\n}\n\nexport function resolveFromRemote(\n r: Registry,\n component: string,\n selectFile: (file: ComponentFile) => boolean,\n): Reference | undefined {\n const comp = r.components.find((comp) => comp.name === component);\n if (!comp) return;\n const file = comp.files.find(selectFile);\n if (!file) return;\n\n return {\n type: 'sub-component',\n resolved: {\n type: 'remote',\n registryName: r.name,\n component: comp,\n file,\n },\n };\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport picocolors from 'picocolors';\nimport type { CompiledRegistry } from '@/build/compiler';\n\nexport * from './compiler';\n\nexport interface MonoRegistry extends CompiledRegistry {\n registries: CompiledRegistry[];\n}\n\nexport function combineRegistry(\n root: CompiledRegistry,\n ...items: CompiledRegistry[]\n): MonoRegistry {\n return {\n ...root,\n info: {\n ...root.info,\n registries: items.map((item) => item.name),\n },\n registries: items,\n };\n}\n\nexport async function writeFumadocsRegistry(\n out: CompiledRegistry | MonoRegistry,\n options: {\n dir: string;\n\n /**\n * Remove previous outputs\n *\n * @defaultValue false\n */\n cleanDir?: boolean;\n\n log?: boolean;\n },\n): Promise<void> {\n const { dir, cleanDir = false, log = true } = options;\n\n if (cleanDir) {\n await fs.rm(dir, {\n recursive: true,\n force: true,\n });\n console.log(picocolors.bold(picocolors.greenBright('Cleaned directory')));\n }\n\n async function writeInfo() {\n const file = path.join(dir, '_registry.json');\n const json = JSON.stringify(out.info, null, 2);\n\n await writeFile(file, json, log);\n }\n\n const write = out.components.map(async (comp) => {\n const file = path.join(dir, `${comp.name}.json`);\n const json = JSON.stringify(comp, null, 2);\n\n await writeFile(file, json, log);\n });\n\n write.push(writeInfo());\n if ('registries' in out) {\n for (const child of out.registries) {\n write.push(\n writeFumadocsRegistry(child, {\n dir: path.join(dir, child.name),\n log: options.log,\n }),\n );\n }\n }\n\n await Promise.all(write);\n}\n\nasync function writeFile(file: string, content: string, log = true): Promise<void> {\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, content);\n\n if (log) {\n const size = (Buffer.byteLength(content) / 1024).toFixed(2);\n\n console.log(\n `${picocolors.greenBright('+')} ${path.relative(process.cwd(), file)} ${picocolors.dim(`${size} KB`)}`,\n );\n }\n}\n"],"mappings":"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"}
@@ -1,102 +0,0 @@
1
- import { componentSchema, registryInfoSchema } from "./registry/schema.js";
2
- import fs from "node:fs/promises";
3
- import path from "node:path";
4
- //#region src/utils/cache.ts
5
- /**
6
- * cache for async resources, finished promises will be resolved into original value, otherwise wrapped with a promise.
7
- */
8
- function createCache(store = /* @__PURE__ */ new Map()) {
9
- return {
10
- cached(key, fn) {
11
- let cached = store.get(key);
12
- if (cached) return cached;
13
- cached = fn((v) => store.set(key, v));
14
- if (cached instanceof Promise) cached = cached.then((out) => {
15
- if (store.has(key)) store.set(key, out);
16
- return out;
17
- });
18
- store.set(key, cached);
19
- return cached;
20
- },
21
- invalidate(key) {
22
- store.delete(key);
23
- },
24
- $value() {
25
- return this;
26
- }
27
- };
28
- }
29
- //#endregion
30
- //#region src/registry/client.ts
31
- const fetchCache = createCache();
32
- var HttpRegistryClient = class HttpRegistryClient {
33
- constructor(baseUrl, config) {
34
- this.baseUrl = baseUrl;
35
- this.config = config;
36
- this.registryId = baseUrl;
37
- }
38
- async fetchRegistryInfo(baseUrl = this.baseUrl) {
39
- const url = new URL("_registry.json", `${baseUrl}/`);
40
- return fetchCache.$value().cached(url.href, async () => {
41
- const res = await fetch(url);
42
- if (!res.ok) throw new Error(`failed to fetch ${url.href}: ${res.statusText}`);
43
- return registryInfoSchema.parse(await res.json());
44
- });
45
- }
46
- async fetchComponent(name) {
47
- const url = new URL(`${name}.json`, `${this.baseUrl}/`);
48
- return fetchCache.$value().cached(url.href, async () => {
49
- const res = await fetch(`${this.baseUrl}/${name}.json`);
50
- if (!res.ok) {
51
- if (res.status === 404) throw new Error(`component ${name} not found at ${url.href}`);
52
- throw new Error(await res.text());
53
- }
54
- return componentSchema.parse(await res.json());
55
- });
56
- }
57
- async hasComponent(name) {
58
- const url = new URL(`${name}.json`, `${this.baseUrl}/`);
59
- return (await fetch(url, { method: "HEAD" })).ok;
60
- }
61
- createLinkedRegistryClient(name) {
62
- return new HttpRegistryClient(`${this.baseUrl}/${name}`, this.config);
63
- }
64
- };
65
- var LocalRegistryClient = class LocalRegistryClient {
66
- constructor(dir, config) {
67
- this.dir = dir;
68
- this.config = config;
69
- this.registryId = dir;
70
- }
71
- async fetchRegistryInfo(dir = this.dir) {
72
- if (this.registryInfo) return this.registryInfo;
73
- const filePath = path.join(dir, "_registry.json");
74
- const out = await fs.readFile(filePath).then((res) => JSON.parse(res.toString())).catch((e) => {
75
- throw new Error(`failed to resolve local file "${filePath}"`, { cause: e });
76
- });
77
- return this.registryInfo = registryInfoSchema.parse(out);
78
- }
79
- async fetchComponent(name) {
80
- const filePath = path.join(this.dir, `${name}.json`);
81
- const out = await fs.readFile(filePath).then((res) => JSON.parse(res.toString())).catch((e) => {
82
- throw new Error(`component ${name} not found at ${filePath}`, { cause: e });
83
- });
84
- return componentSchema.parse(out);
85
- }
86
- async hasComponent(name) {
87
- const filePath = path.join(this.dir, `${name}.json`);
88
- try {
89
- await fs.stat(filePath);
90
- return true;
91
- } catch {
92
- return false;
93
- }
94
- }
95
- createLinkedRegistryClient(name) {
96
- return new LocalRegistryClient(path.join(this.dir, name), this.config);
97
- }
98
- };
99
- //#endregion
100
- export { LocalRegistryClient as n, createCache as r, HttpRegistryClient as t };
101
-
102
- //# sourceMappingURL=client-C2A4Jf2w.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-C2A4Jf2w.js","names":[],"sources":["../src/utils/cache.ts","../src/registry/client.ts"],"sourcesContent":["export interface AsyncCache<V> {\n cached: (\n key: string,\n fn: (\n /**\n * set a cache value before the compute function completes.\n *\n * useful to handle recursive access.\n */\n presolve: (v: V) => void,\n ) => V | Promise<V>,\n ) => V | Promise<V>;\n $value: <T>() => AsyncCache<T>;\n invalidate: (key: string) => void;\n}\n\n/**\n * cache for async resources, finished promises will be resolved into original value, otherwise wrapped with a promise.\n */\nexport function createCache<V>(store = new Map<string, V | Promise<V>>()): AsyncCache<V> {\n return {\n cached(key, fn) {\n let cached = store.get(key);\n if (cached) return cached;\n\n cached = fn((v) => store.set(key, v));\n if (cached instanceof Promise) {\n cached = cached.then((out) => {\n // replace with resolved if still exists\n if (store.has(key)) {\n store.set(key, out);\n }\n\n return out;\n });\n }\n store.set(key, cached);\n return cached;\n },\n invalidate(key) {\n store.delete(key);\n },\n $value<T>() {\n return this as unknown as AsyncCache<T>;\n },\n };\n}\n","import {\n type DownloadedRegistryInfo,\n type Component,\n componentSchema,\n registryInfoSchema,\n} from '@/registry/schema';\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport type { LoadedConfig } from '@/config';\nimport { createCache } from '@/utils/cache';\n\nexport interface RegistryClient {\n readonly registryId: string;\n readonly config: LoadedConfig;\n fetchRegistryInfo: () => Promise<DownloadedRegistryInfo>;\n fetchComponent: (name: string) => Promise<Component>;\n hasComponent: (name: string) => Promise<boolean>;\n createLinkedRegistryClient: (registryName: string) => RegistryClient;\n}\n\nconst fetchCache = createCache<unknown>();\n\nexport class HttpRegistryClient implements RegistryClient {\n readonly registryId: string;\n\n constructor(\n readonly baseUrl: string,\n readonly config: LoadedConfig,\n ) {\n this.registryId = baseUrl;\n }\n\n async fetchRegistryInfo(baseUrl = this.baseUrl) {\n const url = new URL('_registry.json', `${baseUrl}/`);\n\n return fetchCache.$value<DownloadedRegistryInfo>().cached(url.href, async () => {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`failed to fetch ${url.href}: ${res.statusText}`);\n }\n\n return registryInfoSchema.parse(await res.json());\n });\n }\n\n async fetchComponent(name: string) {\n const url = new URL(`${name}.json`, `${this.baseUrl}/`);\n\n return fetchCache.$value<Component>().cached(url.href, async () => {\n const res = await fetch(`${this.baseUrl}/${name}.json`);\n if (!res.ok) {\n if (res.status === 404) {\n throw new Error(`component ${name} not found at ${url.href}`);\n }\n throw new Error(await res.text());\n }\n\n return componentSchema.parse(await res.json());\n });\n }\n\n async hasComponent(name: string) {\n const url = new URL(`${name}.json`, `${this.baseUrl}/`);\n const res = await fetch(url, { method: 'HEAD' });\n return res.ok;\n }\n\n createLinkedRegistryClient(name: string) {\n return new HttpRegistryClient(`${this.baseUrl}/${name}`, this.config);\n }\n}\n\nexport class LocalRegistryClient implements RegistryClient {\n readonly registryId: string;\n private registryInfo: DownloadedRegistryInfo | undefined;\n\n constructor(\n private readonly dir: string,\n readonly config: LoadedConfig,\n ) {\n this.registryId = dir;\n }\n\n async fetchRegistryInfo(dir = this.dir) {\n if (this.registryInfo) return this.registryInfo;\n\n const filePath = path.join(dir, '_registry.json');\n const out = await fs\n .readFile(filePath)\n .then((res) => JSON.parse(res.toString()))\n .catch((e) => {\n throw new Error(`failed to resolve local file \"${filePath}\"`, {\n cause: e,\n });\n });\n\n return (this.registryInfo = registryInfoSchema.parse(out));\n }\n\n async fetchComponent(name: string) {\n const filePath = path.join(this.dir, `${name}.json`);\n const out = await fs\n .readFile(filePath)\n .then((res) => JSON.parse(res.toString()))\n .catch((e) => {\n throw new Error(`component ${name} not found at ${filePath}`, { cause: e });\n });\n\n return componentSchema.parse(out);\n }\n\n async hasComponent(name: string) {\n const filePath = path.join(this.dir, `${name}.json`);\n try {\n await fs.stat(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n createLinkedRegistryClient(name: string) {\n return new LocalRegistryClient(path.join(this.dir, name), this.config);\n }\n}\n"],"mappings":"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"}
@@ -1,53 +0,0 @@
1
- import { z } from "zod";
2
-
3
- //#region src/config.d.ts
4
- declare const frameworks: readonly ["next", "waku", "react-router", "tanstack-start"];
5
- type Framework = (typeof frameworks)[number];
6
- declare function createConfigSchema(): z.ZodObject<{
7
- $schema: z.ZodOptional<z.ZodDefault<z.ZodString>>;
8
- aliases: z.ZodDefault<z.ZodObject<{
9
- uiDir: z.ZodDefault<z.ZodString>;
10
- componentsDir: z.ZodDefault<z.ZodString>;
11
- layoutDir: z.ZodDefault<z.ZodString>;
12
- cssDir: z.ZodDefault<z.ZodString>;
13
- libDir: z.ZodDefault<z.ZodString>;
14
- }, z.core.$strip>>;
15
- baseDir: z.ZodDefault<z.ZodString>;
16
- uiLibrary: z.ZodDefault<z.ZodEnum<{
17
- "radix-ui": "radix-ui";
18
- "base-ui": "base-ui";
19
- }>>;
20
- framework: z.ZodDefault<z.ZodLiteral<"next" | "waku" | "react-router" | "tanstack-start">>;
21
- commands: z.ZodDefault<z.ZodObject<{
22
- format: z.ZodOptional<z.ZodString>;
23
- }, z.core.$strip>>;
24
- }, z.core.$strip>;
25
- type ConfigSchema = ReturnType<typeof createConfigSchema>;
26
- type ConfigInput = z.input<ConfigSchema>;
27
- type LoadedConfig = z.output<ConfigSchema>;
28
- declare function createOrLoadConfig(file?: string): Promise<LoadedConfig>;
29
- /**
30
- * Write new config, skip if a config already exists
31
- *
32
- * @returns the created config, `undefined` if not created
33
- */
34
- declare function initConfig(file?: string): Promise<LoadedConfig | undefined>;
35
- declare function getDefaultConfig(): Promise<{
36
- aliases: {
37
- uiDir: string;
38
- componentsDir: string;
39
- layoutDir: string;
40
- cssDir: string;
41
- libDir: string;
42
- };
43
- baseDir: string;
44
- uiLibrary: "radix-ui" | "base-ui";
45
- framework: "next" | "waku" | "react-router" | "tanstack-start";
46
- commands: {
47
- format?: string | undefined;
48
- };
49
- $schema?: string | undefined;
50
- }>;
51
- //#endregion
52
- export { createOrLoadConfig as a, createConfigSchema as i, Framework as n, getDefaultConfig as o, LoadedConfig as r, initConfig as s, ConfigInput as t };
53
- //# sourceMappingURL=config-Bx-m6awG.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-Bx-m6awG.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;cAIM,UAAA;AAAA,KACM,SAAA,WAAoB,UAAA;AAAA,iBAEhB,kBAAA,CAAA,GAAkB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;KAyD7B,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,CAAA,GAAgB,OAAA"}
@@ -1,18 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- //#region src/utils/fs.ts
4
- async function exists(pathLike) {
5
- try {
6
- await fs.access(pathLike);
7
- return true;
8
- } catch {
9
- return false;
10
- }
11
- }
12
- function isRelative(from, to) {
13
- return !path.relative(from, to).startsWith(`..${path.sep}`);
14
- }
15
- //#endregion
16
- export { isRelative as n, exists as t };
17
-
18
- //# sourceMappingURL=fs-C3j4H046.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fs-C3j4H046.js","names":[],"sources":["../src/utils/fs.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport async function exists(pathLike: string): Promise<boolean> {\n try {\n await fs.access(pathLike);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isRelative(from: string, to: string): boolean {\n return !path.relative(from, to).startsWith(`..${path.sep}`);\n}\n"],"mappings":";;;AAGA,eAAsB,OAAO,UAAoC;AAC/D,KAAI;AACF,QAAM,GAAG,OAAO,SAAS;AACzB,SAAO;SACD;AACN,SAAO;;;AAIX,SAAgB,WAAW,MAAc,IAAqB;AAC5D,QAAO,CAAC,KAAK,SAAS,MAAM,GAAG,CAAC,WAAW,KAAK,KAAK,MAAM"}
@@ -1,124 +0,0 @@
1
- import path from "node:path";
2
- import { Visitor } from "oxc-parser";
3
- //#region src/constants.ts
4
- const typescriptExtensions = [
5
- ".ts",
6
- ".tsx",
7
- ".js",
8
- ".jsx"
9
- ];
10
- //#endregion
11
- //#region src/utils/ast.ts
12
- /**
13
- * Return the import modifier for `sourceFile` to import `referenceFile`
14
- *
15
- * @example
16
- * ```ts
17
- * toReferencePath('index.ts', 'dir/hello.ts')
18
- * // should output './dir/hello'
19
- * ```
20
- */
21
- function toImportSpecifier(sourceFile, referenceFile) {
22
- const extname = path.extname(referenceFile);
23
- const removeExt = typescriptExtensions.includes(extname);
24
- let importPath = path.relative(path.dirname(sourceFile), removeExt ? referenceFile.substring(0, referenceFile.length - extname.length) : referenceFile).replaceAll(path.sep, "/");
25
- if (removeExt && importPath.endsWith("/index")) importPath = importPath.slice(0, -6);
26
- return importPath.startsWith("../") ? importPath : `./${importPath}`;
27
- }
28
- function transformSpecifiers(program, s, transformSpecifier) {
29
- new Visitor({
30
- ImportDeclaration(node) {
31
- const source = node.source;
32
- const out = transformSpecifier(source.value);
33
- if (out) {
34
- s.update(source.start + 1, source.end - 1, out);
35
- source.value = out;
36
- }
37
- },
38
- ImportExpression(node) {
39
- if (node.source.type === "Literal") {
40
- const source = node.source;
41
- const out = transformSpecifier(source.value);
42
- if (out) {
43
- s.update(source.start + 1, source.end - 1, out);
44
- source.value = out;
45
- }
46
- }
47
- },
48
- ExportAllDeclaration(node) {
49
- const source = node.source;
50
- const out = transformSpecifier(source.value);
51
- if (out) {
52
- s.update(source.start + 1, source.end - 1, out);
53
- source.value = out;
54
- }
55
- },
56
- ExportNamedDeclaration(node) {
57
- const source = node.source;
58
- if (!source) return;
59
- const out = transformSpecifier(source.value);
60
- if (out) {
61
- s.update(source.start + 1, source.end - 1, out);
62
- source.value = out;
63
- }
64
- }
65
- }).visit(program);
66
- }
67
- function getImportedBinding(spec) {
68
- if (spec.type === "ImportSpecifier") {
69
- let imported;
70
- switch (spec.imported.type) {
71
- case "Identifier":
72
- imported = spec.imported.name;
73
- break;
74
- case "Literal":
75
- imported = spec.imported.value;
76
- break;
77
- }
78
- return {
79
- imported,
80
- local: spec.local.name
81
- };
82
- }
83
- if (spec.type === "ImportDefaultSpecifier") return {
84
- imported: "default",
85
- local: spec.local.name
86
- };
87
- return null;
88
- }
89
- function collectMacroBindings(program, name) {
90
- const locals = /* @__PURE__ */ new Set();
91
- const importDecls = [];
92
- const seenDecl = /* @__PURE__ */ new Set();
93
- new Visitor({ ImportDeclaration(node) {
94
- for (const spec of node.specifiers) {
95
- const b = getImportedBinding(spec);
96
- if (!b || b.imported !== name) continue;
97
- locals.add(b.local);
98
- if (!seenDecl.has(node)) {
99
- seenDecl.add(node);
100
- importDecls.push(node);
101
- }
102
- }
103
- } }).visit(program);
104
- if (locals.size === 0) return null;
105
- return {
106
- importDecls,
107
- locals
108
- };
109
- }
110
- //#endregion
111
- //#region src/registry/protocols/import.ts
112
- function encodeImport(file) {
113
- if (file.type === "route-handler") return `route-handler:${file.route}`;
114
- return `:${file.target ?? file.path}`;
115
- }
116
- function decodeImport(s) {
117
- if (s.startsWith(":")) return { target: s.slice(1) };
118
- if (s.startsWith("route-handler:")) return { route: s.slice(14) };
119
- return { raw: s };
120
- }
121
- //#endregion
122
- export { transformSpecifiers as a, toImportSpecifier as i, encodeImport as n, typescriptExtensions as o, collectMacroBindings as r, decodeImport as t };
123
-
124
- //# sourceMappingURL=import-CSbSteB3.js.map