@fumadocs/cli 1.0.0 → 1.0.2

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.
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import * as ts_morph from 'ts-morph';
3
- import { Registry as Registry$1 } from 'shadcn/registry';
3
+ import { Registry as Registry$1 } from 'shadcn/schema';
4
4
 
5
5
  type Output = z.infer<typeof rootSchema>;
6
6
  type NamespaceType = (typeof namespaces)[number];
@@ -117,14 +117,18 @@ interface Registry {
117
117
  onResolve?: OnResolve;
118
118
  /**
119
119
  * When a referenced file is not found in component files, this function is called.
120
+ * @returns file, or `false` to mark as external.
120
121
  */
121
- onUnknownFile?: (absolutePath: string) => ComponentFile | undefined;
122
+ onUnknownFile?: (absolutePath: string) => ComponentFile | false | undefined;
122
123
  dependencies?: Record<string, string | null>;
123
124
  devDependencies?: Record<string, string | null>;
124
125
  }
125
126
  declare function build(registry: Registry): Promise<Output>;
126
127
 
127
- declare function toShadcnRegistry(out: Output, baseUrl: string): Registry$1;
128
+ declare function toShadcnRegistry(out: Output, baseUrl: string): {
129
+ registry: Registry$1;
130
+ index: Registry$1;
131
+ };
128
132
 
129
133
  declare function combineRegistry(...items: Output[]): Output;
130
134
  declare function writeShadcnRegistry(out: Output, options: {
@@ -14,13 +14,38 @@ function escapeName(name) {
14
14
  return name;
15
15
  }
16
16
  function toShadcnRegistry(out, baseUrl) {
17
- return {
17
+ const registry = {
18
18
  homepage: baseUrl,
19
19
  name: out.name,
20
20
  items: out.components.map((comp) => componentToShadcn(comp, baseUrl))
21
21
  };
22
+ return {
23
+ registry,
24
+ index: {
25
+ ...registry,
26
+ items: out.components.map(
27
+ (comp) => componentToShadcn(comp, baseUrl, true)
28
+ )
29
+ }
30
+ };
22
31
  }
23
- function componentToShadcn(comp, baseUrl) {
32
+ function componentToShadcn(comp, baseUrl, noFile = false) {
33
+ const FileType = {
34
+ components: "registry:component",
35
+ lib: "registry:lib",
36
+ css: "registry:style",
37
+ route: "registry:page",
38
+ ui: "registry:ui",
39
+ block: "registry:block"
40
+ };
41
+ function onFile(file) {
42
+ return {
43
+ type: FileType[file.type],
44
+ content: file.content,
45
+ path: file.path,
46
+ target: file.target
47
+ };
48
+ }
24
49
  return {
25
50
  extends: "none",
26
51
  type: "registry:block",
@@ -34,21 +59,7 @@ function componentToShadcn(comp, baseUrl) {
34
59
  return comp2;
35
60
  return new URL(`/r/${escapeName(comp2)}.json`, baseUrl).toString();
36
61
  }),
37
- files: comp.files.map((file) => {
38
- return {
39
- type: {
40
- components: "registry:component",
41
- lib: "registry:lib",
42
- css: "registry:style",
43
- route: "registry:page",
44
- ui: "registry:ui",
45
- block: "registry:block"
46
- }[file.type],
47
- content: file.content,
48
- path: file.path,
49
- target: file.target
50
- };
51
- })
62
+ files: noFile ? [] : comp.files.map(onFile)
52
63
  };
53
64
  }
54
65
 
@@ -108,7 +119,9 @@ async function buildFile(file, builder, comp, writeReference) {
108
119
  } else if (specifier.startsWith("./") || specifier.startsWith("../")) {
109
120
  filePath = path.join(path.dirname(sourceFilePath), specifier);
110
121
  } else {
111
- throw new Error("Unknown specifier " + specifier);
122
+ if (!specifier.startsWith("node:"))
123
+ console.warn(`Unknown specifier ${specifier}, skipping for now`);
124
+ return;
112
125
  }
113
126
  if (path.relative(builder.registryDir, filePath).startsWith("../")) {
114
127
  return {
@@ -133,27 +146,25 @@ async function buildFile(file, builder, comp, writeReference) {
133
146
  file: filePath
134
147
  };
135
148
  };
136
- function process2(specifier, getSpecifiedFile) {
149
+ function process2(specifier, specifiedFile) {
137
150
  const onResolve = comp.onResolve ?? builder.registry.onResolve;
138
151
  let resolved = defaultResolve(
139
152
  specifier.getLiteralValue(),
140
- getSpecifiedFile()
153
+ specifiedFile
141
154
  );
155
+ if (!resolved) return;
142
156
  if (onResolve) resolved = onResolve(resolved);
143
157
  const out = writeReference(resolved);
144
158
  if (out) specifier.setLiteralValue(out);
145
159
  }
146
160
  const sourceFile = await builder.createSourceFile(sourceFilePath);
147
161
  for (const item of sourceFile.getImportDeclarations()) {
148
- process2(
149
- item.getModuleSpecifier(),
150
- () => item.getModuleSpecifierSourceFile()
151
- );
162
+ process2(item.getModuleSpecifier(), item.getModuleSpecifierSourceFile());
152
163
  }
153
164
  for (const item of sourceFile.getExportDeclarations()) {
154
165
  const specifier = item.getModuleSpecifier();
155
166
  if (!specifier) continue;
156
- process2(specifier, () => item.getModuleSpecifierSourceFile());
167
+ process2(specifier, item.getModuleSpecifierSourceFile());
157
168
  }
158
169
  const calls = sourceFile.getDescendantsOfKind(ts.SyntaxKind.CallExpression);
159
170
  for (const expression of calls) {
@@ -162,7 +173,7 @@ async function buildFile(file, builder, comp, writeReference) {
162
173
  if (!argument.isKind(ts.SyntaxKind.StringLiteral)) continue;
163
174
  process2(
164
175
  argument,
165
- () => argument.getSymbol()?.getDeclarations()[0].getSourceFile()
176
+ argument.getSymbol()?.getDeclarations()[0].getSourceFile()
166
177
  );
167
178
  }
168
179
  }
@@ -293,6 +304,7 @@ async function buildComponent(component, builder) {
293
304
  queue.push(refFile);
294
305
  return toImportPath(refFile);
295
306
  }
307
+ if (refFile === false) return;
296
308
  throw new Error(
297
309
  `Unknown file ${reference.file} referenced by ${file.path}`
298
310
  );
@@ -349,12 +361,15 @@ async function writeShadcnRegistry(out, options) {
349
361
  });
350
362
  console.log(picocolors.bold(picocolors.greenBright("Cleaned directory")));
351
363
  }
352
- await Promise.all(
353
- toShadcnRegistry(out, baseUrl).items.map(async (item) => {
354
- const file = path4.join(dir, `${item.name}.json`);
355
- await writeFile2(file, JSON.stringify(item, null, 2));
356
- })
364
+ const { registry, index } = toShadcnRegistry(out, baseUrl);
365
+ const write = registry.items.map(async (item) => {
366
+ const file = path4.join(dir, `${item.name}.json`);
367
+ await writeFile2(file, JSON.stringify(item, null, 2));
368
+ });
369
+ write.push(
370
+ writeFile2(path4.join(dir, "registry.json"), JSON.stringify(index, null, 2))
357
371
  );
372
+ await Promise.all(write);
358
373
  }
359
374
  async function writeFumadocsRegistry(out, options) {
360
375
  const { dir, cleanDir = false, log = true } = options;
package/dist/index.js CHANGED
@@ -343,14 +343,14 @@ async function runTree(args) {
343
343
  // package.json
344
344
  var package_default = {
345
345
  name: "@fumadocs/cli",
346
- version: "1.0.0",
346
+ version: "1.0.2",
347
347
  description: "The CLI tool for Fumadocs",
348
348
  keywords: [
349
349
  "NextJs",
350
350
  "Docs",
351
351
  "Fumadocs"
352
352
  ],
353
- homepage: "https://fumadocs.vercel.app",
353
+ homepage: "https://fumadocs.dev",
354
354
  repository: "github:fuma-nama/fumadocs",
355
355
  license: "MIT",
356
356
  author: "Fuma Nama",
@@ -373,24 +373,22 @@ var package_default = {
373
373
  clean: "rimraf dist",
374
374
  dev: "tsup --watch",
375
375
  lint: "eslint .",
376
- sync: "tsx ./scripts/sync.ts",
377
376
  "types:check": "tsc --noEmit"
378
377
  },
379
378
  dependencies: {
380
379
  "@clack/prompts": "^0.11.0",
381
- commander: "^14.0.0",
380
+ commander: "^14.0.1",
382
381
  "package-manager-detector": "^1.3.0",
383
382
  picocolors: "^1.1.1",
384
383
  tinyexec: "^1.0.1",
385
- "ts-morph": "^26.0.0",
386
- zod: "^4.0.17"
384
+ "ts-morph": "^27.0.0",
385
+ zod: "^4.1.11"
387
386
  },
388
387
  devDependencies: {
389
- shadcn: "2.9.3-canary.0",
390
- "@types/node": "24.2.1",
388
+ "@types/node": "24.6.2",
391
389
  "eslint-config-custom": "workspace:*",
392
- tsconfig: "workspace:*",
393
- tsx: "^4.20.3"
390
+ shadcn: "3.3.1",
391
+ tsconfig: "workspace:*"
394
392
  },
395
393
  publishConfig: {
396
394
  access: "public"
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@fumadocs/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "The CLI tool for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
7
7
  "Docs",
8
8
  "Fumadocs"
9
9
  ],
10
- "homepage": "https://fumadocs.vercel.app",
10
+ "homepage": "https://fumadocs.dev",
11
11
  "repository": "github:fuma-nama/fumadocs",
12
12
  "license": "MIT",
13
13
  "author": "Fuma Nama",
@@ -27,17 +27,16 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@clack/prompts": "^0.11.0",
30
- "commander": "^14.0.0",
30
+ "commander": "^14.0.1",
31
31
  "package-manager-detector": "^1.3.0",
32
32
  "picocolors": "^1.1.1",
33
33
  "tinyexec": "^1.0.1",
34
- "ts-morph": "^26.0.0",
35
- "zod": "^4.0.17"
34
+ "ts-morph": "^27.0.0",
35
+ "zod": "^4.1.11"
36
36
  },
37
37
  "devDependencies": {
38
- "shadcn": "2.9.3-canary.0",
39
- "@types/node": "24.2.1",
40
- "tsx": "^4.20.3",
38
+ "@types/node": "24.6.2",
39
+ "shadcn": "3.3.1",
41
40
  "eslint-config-custom": "0.0.0",
42
41
  "tsconfig": "0.0.0"
43
42
  },
@@ -49,7 +48,6 @@
49
48
  "clean": "rimraf dist",
50
49
  "dev": "tsup --watch",
51
50
  "lint": "eslint .",
52
- "sync": "tsx ./scripts/sync.ts",
53
51
  "types:check": "tsc --noEmit"
54
52
  }
55
53
  }