@hanzo/docs-cli 1.2.1 → 1.2.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.
package/dist/index.js CHANGED
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import { n as transformSpecifiers, r as typescriptExtensions, t as toImportSpecifier } from "./ast-BS3xj9uY.js";
2
3
  import fs from "node:fs/promises";
3
4
  import path from "node:path";
4
5
  import { Command } from "commander";
5
6
  import picocolors from "picocolors";
6
7
  import { z } from "zod";
7
8
  import { x } from "tinyexec";
8
- import { cancel, confirm, group, intro, isCancel, log, multiselect, outro, select, spinner } from "@clack/prompts";
9
- import { Project } from "ts-morph";
9
+ import { autocompleteMultiselect, box, cancel, confirm, group, intro, isCancel, log, outro, select, spinner } from "@clack/prompts";
10
+ import { parse } from "oxc-parser";
10
11
  import { detect } from "package-manager-detector";
12
+ import MagicString from "magic-string";
11
13
 
12
14
  //#region src/utils/fs.ts
13
15
  async function exists(pathLike) {
@@ -27,7 +29,7 @@ async function isSrc() {
27
29
 
28
30
  //#endregion
29
31
  //#region src/config.ts
30
- function createConfigSchema(isSrc$1) {
32
+ function createConfigSchema(isSrc) {
31
33
  const defaultAliases = {
32
34
  uiDir: "./components/ui",
33
35
  componentsDir: "./components",
@@ -36,7 +38,7 @@ function createConfigSchema(isSrc$1) {
36
38
  libDir: "./lib"
37
39
  };
38
40
  return z.object({
39
- $schema: z.string().default(isSrc$1 ? "node_modules/@hanzo/docs-cli/dist/schema/src.json" : "node_modules/@hanzo/docs-cli/dist/schema/default.json").optional(),
41
+ $schema: z.string().default(isSrc ? "node_modules/@hanzo/docs-cli/dist/schema/src.json" : "node_modules/@hanzo/docs-cli/dist/schema/default.json").optional(),
40
42
  aliases: z.object({
41
43
  uiDir: z.string().default(defaultAliases.uiDir),
42
44
  componentsDir: z.string().default(defaultAliases.uiDir),
@@ -44,7 +46,7 @@ function createConfigSchema(isSrc$1) {
44
46
  cssDir: z.string().default(defaultAliases.componentsDir),
45
47
  libDir: z.string().default(defaultAliases.libDir)
46
48
  }).default(defaultAliases),
47
- baseDir: z.string().default(isSrc$1 ? "src" : ""),
49
+ baseDir: z.string().default(isSrc ? "src" : ""),
48
50
  uiLibrary: z.enum(["radix-ui", "base-ui"]).default("radix-ui"),
49
51
  commands: z.object({ format: z.string().optional() }).default({})
50
52
  });
@@ -97,7 +99,7 @@ ${item.contents.map(toNode).filter(Boolean).join("\n")}
97
99
  ${children.map(toNode).filter(Boolean).join("\n")}
98
100
  </Files>`;
99
101
  }
100
- function treeToJavaScript(input, noRoot, importName = "@hanzo/docs-ui/components/files") {
102
+ function treeToJavaScript(input, noRoot, importName = "@hanzo/docs-base-ui/components/files") {
101
103
  return `import { File, Files, Folder } from ${JSON.stringify(importName)}
102
104
 
103
105
  export default (${treeToMdx(input, noRoot)})`;
@@ -121,41 +123,7 @@ async function runTree(args) {
121
123
 
122
124
  //#endregion
123
125
  //#region package.json
124
- var version = "1.2.1";
125
-
126
- //#endregion
127
- //#region src/utils/typescript.ts
128
- function createEmptyProject() {
129
- return new Project({ compilerOptions: {} });
130
- }
131
-
132
- //#endregion
133
- //#region src/constants.ts
134
- const typescriptExtensions = [
135
- ".ts",
136
- ".tsx",
137
- ".js",
138
- ".jsx"
139
- ];
140
-
141
- //#endregion
142
- //#region src/utils/ast.ts
143
- /**
144
- * Return the import modifier for `sourceFile` to import `referenceFile`
145
- *
146
- * @example
147
- * ```ts
148
- * toReferencePath('index.ts', 'dir/hello.ts')
149
- * // should output './dir/hello'
150
- * ```
151
- */
152
- function toImportSpecifier(sourceFile, referenceFile) {
153
- const extname = path.extname(referenceFile);
154
- const removeExt = typescriptExtensions.includes(extname);
155
- let importPath = path.relative(path.dirname(sourceFile), removeExt ? referenceFile.substring(0, referenceFile.length - extname.length) : referenceFile).replaceAll(path.sep, "/");
156
- if (removeExt && importPath.endsWith("/index")) importPath = importPath.slice(0, -6);
157
- return importPath.startsWith("../") ? importPath : `./${importPath}`;
158
- }
126
+ var version = "1.2.5";
159
127
 
160
128
  //#endregion
161
129
  //#region src/registry/schema.ts
@@ -204,22 +172,34 @@ const registryInfoSchema = z.object({
204
172
 
205
173
  //#endregion
206
174
  //#region src/utils/cache.ts
207
- var AsyncCache = class {
208
- constructor() {
209
- this.store = /* @__PURE__ */ new Map();
210
- }
211
- cached(key, fn) {
212
- let cached = this.store.get(key);
213
- if (cached !== void 0) return cached;
214
- cached = fn();
215
- this.store.set(key, cached);
216
- return cached;
217
- }
218
- };
175
+ /**
176
+ * cache for async resources, finished promises will be resolved into original value, otherwise wrapped with a promise.
177
+ */
178
+ function createCache(store = /* @__PURE__ */ new Map()) {
179
+ return {
180
+ cached(key, fn) {
181
+ let cached = store.get(key);
182
+ if (cached) return cached;
183
+ cached = fn((v) => store.set(key, v));
184
+ if (cached instanceof Promise) cached = cached.then((out) => {
185
+ if (store.has(key)) store.set(key, out);
186
+ return out;
187
+ });
188
+ store.set(key, cached);
189
+ return cached;
190
+ },
191
+ invalidate(key) {
192
+ store.delete(key);
193
+ },
194
+ $value() {
195
+ return this;
196
+ }
197
+ };
198
+ }
219
199
 
220
200
  //#endregion
221
201
  //#region src/registry/client.ts
222
- const fetchCache = new AsyncCache();
202
+ const fetchCache = createCache();
223
203
  var HttpRegistryClient = class HttpRegistryClient {
224
204
  constructor(baseUrl, config) {
225
205
  this.baseUrl = baseUrl;
@@ -228,7 +208,7 @@ var HttpRegistryClient = class HttpRegistryClient {
228
208
  }
229
209
  async fetchRegistryInfo(baseUrl = this.baseUrl) {
230
210
  const url = new URL("_registry.json", `${baseUrl}/`);
231
- return fetchCache.cached(url.href, async () => {
211
+ return fetchCache.$value().cached(url.href, async () => {
232
212
  const res = await fetch(url);
233
213
  if (!res.ok) throw new Error(`failed to fetch ${url.href}: ${res.statusText}`);
234
214
  return registryInfoSchema.parse(await res.json());
@@ -236,10 +216,10 @@ var HttpRegistryClient = class HttpRegistryClient {
236
216
  }
237
217
  async fetchComponent(name) {
238
218
  const url = new URL(`${name}.json`, `${this.baseUrl}/`);
239
- return fetchCache.cached(url.href, async () => {
219
+ return fetchCache.$value().cached(url.href, async () => {
240
220
  const res = await fetch(`${this.baseUrl}/${name}.json`);
241
221
  if (!res.ok) {
242
- log.error(`component ${name} not found at ${url.href}`);
222
+ if (res.status === 404) throw new Error(`component ${name} not found at ${url.href}`);
243
223
  throw new Error(await res.text());
244
224
  }
245
225
  return componentSchema.parse(await res.json());
@@ -270,8 +250,7 @@ var LocalRegistryClient = class LocalRegistryClient {
270
250
  async fetchComponent(name) {
271
251
  const filePath = path.join(this.dir, `${name}.json`);
272
252
  const out = await fs.readFile(filePath).then((res) => JSON.parse(res.toString())).catch((e) => {
273
- log.error(`component ${name} not found at ${filePath}`);
274
- throw e;
253
+ throw new Error(`component ${name} not found at ${filePath}`, { cause: e });
275
254
  });
276
255
  return componentSchema.parse(out);
277
256
  }
@@ -298,46 +277,43 @@ async function getPackageManager() {
298
277
  //#endregion
299
278
  //#region src/registry/installer/dep-manager.ts
300
279
  var DependencyManager = class {
301
- /**
302
- * Get dependencies from `package.json`
303
- */
304
- async getDeps() {
305
- if (this.cachedInstalledDeps) return this.cachedInstalledDeps;
306
- const dependencies = /* @__PURE__ */ new Map();
307
- if (!await exists("package.json")) return dependencies;
308
- const content = await fs.readFile("package.json");
309
- const parsed = JSON.parse(content.toString());
310
- if ("dependencies" in parsed && typeof parsed.dependencies === "object") {
311
- const records = parsed.dependencies;
312
- for (const [k, v] of Object.entries(records)) dependencies.set(k, v);
313
- }
314
- if ("devDependencies" in parsed && typeof parsed.devDependencies === "object") {
315
- const records = parsed.devDependencies;
316
- for (const [k, v] of Object.entries(records)) dependencies.set(k, v);
280
+ constructor() {
281
+ this.installedDeps = /* @__PURE__ */ new Map();
282
+ this.dependencies = [];
283
+ this.devDependencies = [];
284
+ this.packageManager = "npm";
285
+ }
286
+ async init(deps, devDeps) {
287
+ this.installedDeps.clear();
288
+ if (await exists("package.json")) {
289
+ const content = await fs.readFile("package.json");
290
+ const parsed = JSON.parse(content.toString());
291
+ if ("dependencies" in parsed && typeof parsed.dependencies === "object") {
292
+ const records = parsed.dependencies;
293
+ for (const [k, v] of Object.entries(records)) this.installedDeps.set(k, v);
294
+ }
295
+ if ("devDependencies" in parsed && typeof parsed.devDependencies === "object") {
296
+ const records = parsed.devDependencies;
297
+ for (const [k, v] of Object.entries(records)) this.installedDeps.set(k, v);
298
+ }
317
299
  }
318
- return this.cachedInstalledDeps = dependencies;
300
+ this.dependencies = this.resolveRequiredDependencies(deps);
301
+ this.devDependencies = this.resolveRequiredDependencies(devDeps);
302
+ this.packageManager = await getPackageManager();
319
303
  }
320
- async resolveInstallDependencies(deps) {
321
- const cachedInstalledDeps = await this.getDeps();
322
- return Object.entries(deps).filter(([k]) => !cachedInstalledDeps.has(k)).map(([k, v]) => v === null || v.length === 0 ? k : `${k}@${v}`);
304
+ resolveRequiredDependencies(deps) {
305
+ return Object.entries(deps).filter(([k]) => !this.installedDeps.has(k)).map(([k, v]) => v === null || v.length === 0 ? k : `${k}@${v}`);
323
306
  }
324
- async installDeps(deps, devDeps) {
325
- const items = await this.resolveInstallDependencies(deps);
326
- const devItems = await this.resolveInstallDependencies(devDeps);
327
- if (items.length === 0 && devItems.length === 0) return;
328
- const manager = await getPackageManager();
329
- const value = await confirm({ message: `Do you want to install with ${manager}?
330
- ${[...items, ...devItems].map((v) => `- ${v}`).join("\n")}` });
331
- if (isCancel(value) || !value) return;
332
- const spin = spinner();
333
- spin.start("Installing dependencies...");
334
- if (items.length > 0) await x(manager, ["install", ...items]);
335
- if (devItems.length > 0) await x(manager, [
307
+ hasRequired() {
308
+ return this.dependencies.length > 0 || this.devDependencies.length > 0;
309
+ }
310
+ async installRequired() {
311
+ if (this.dependencies.length > 0) await x(this.packageManager, ["install", ...this.dependencies]);
312
+ if (this.devDependencies.length > 0) await x(this.packageManager, [
336
313
  "install",
337
- ...devItems,
314
+ ...this.devDependencies,
338
315
  "-D"
339
316
  ]);
340
- spin.stop("Dependencies installed.");
341
317
  }
342
318
  };
343
319
 
@@ -347,14 +323,13 @@ var ComponentInstaller = class {
347
323
  constructor(rootClient, plugins = []) {
348
324
  this.rootClient = rootClient;
349
325
  this.plugins = plugins;
350
- this.project = createEmptyProject();
351
326
  this.installedFiles = /* @__PURE__ */ new Set();
352
- this.downloadCache = new AsyncCache();
327
+ this.downloadCache = createCache();
353
328
  this.dependencies = {};
354
329
  this.devDependencies = {};
355
- this.pathToFileCache = new AsyncCache();
330
+ this.pathToFileCache = createCache();
356
331
  }
357
- async install(name) {
332
+ async install(name, io) {
358
333
  let downloaded;
359
334
  const info = await this.rootClient.fetchRegistryInfo();
360
335
  for (const registry of info.registries ?? []) if (name.startsWith(`${registry}/`)) {
@@ -370,30 +345,28 @@ var ComponentInstaller = class {
370
345
  const outPath = this.resolveOutputPath(file);
371
346
  if (this.installedFiles.has(outPath)) continue;
372
347
  this.installedFiles.add(outPath);
373
- const output = typescriptExtensions.includes(path.extname(outPath)) ? await this.transform(name, file, comp, downloaded) : file.content;
348
+ const output = typescriptExtensions.includes(path.extname(outPath)) ? await this.transform(io, name, file, comp, downloaded) : file.content;
374
349
  const status = await fs.readFile(outPath).then((res) => {
375
350
  if (res.toString() === output) return "ignore";
376
351
  return "need-update";
377
352
  }).catch(() => "write");
378
353
  if (status === "ignore") continue;
379
354
  if (status === "need-update") {
380
- const override = await confirm({
381
- message: `Do you want to override ${outPath}?`,
382
- initialValue: false
383
- });
384
- if (isCancel(override)) {
385
- outro("Ended");
386
- process.exit(0);
387
- }
388
- if (!override) continue;
355
+ if (!await io.confirmFileOverride({ path: outPath })) continue;
389
356
  }
390
357
  await fs.mkdir(path.dirname(outPath), { recursive: true });
391
358
  await fs.writeFile(outPath, output);
392
- log.step(`downloaded ${outPath}`);
359
+ io.onFileDownloaded({
360
+ path: outPath,
361
+ file,
362
+ component: comp
363
+ });
393
364
  }
394
365
  }
395
- async installDeps() {
396
- await new DependencyManager().installDeps(this.dependencies, this.devDependencies);
366
+ async deps() {
367
+ const manager = new DependencyManager();
368
+ await manager.init(this.dependencies, this.devDependencies);
369
+ return manager;
397
370
  }
398
371
  async onEnd() {
399
372
  const config = this.rootClient.config;
@@ -410,10 +383,10 @@ var ComponentInstaller = class {
410
383
  ...info.env
411
384
  };
412
385
  for (const [k, v] of Object.entries(info.variables ?? {})) variables[k] ??= v.default;
413
- return (await this.downloadCache.cached(hash, async () => {
386
+ return (await this.downloadCache.cached(hash, async (presolve) => {
414
387
  const comp = await client.fetchComponent(name);
415
388
  const result = [comp];
416
- this.downloadCache.store.set(hash, result);
389
+ presolve(result);
417
390
  const child = await Promise.all(comp.subComponents.map((sub) => {
418
391
  if (typeof sub === "string") return this.download(sub, client);
419
392
  const baseUrl = this.rootClient instanceof HttpRegistryClient ? new URL(sub.baseUrl, `${this.rootClient.baseUrl}/`).href : sub.baseUrl;
@@ -426,31 +399,34 @@ var ComponentInstaller = class {
426
399
  variables
427
400
  }));
428
401
  }
429
- async transform(taskId, file, component, allComponents) {
402
+ async transform(io, taskId, file, component, allComponents) {
430
403
  const filePath = this.resolveOutputPath(file);
431
- const sourceFile = this.project.createSourceFile(filePath, file.content, { overwrite: true });
404
+ const parsed = await parse(filePath, file.content);
405
+ const s = new MagicString(file.content);
432
406
  const prefix = "@/";
433
407
  const variables = Object.entries(component.variables ?? {});
434
408
  const pathToFile = await this.pathToFileCache.cached(taskId, () => {
435
409
  const map = /* @__PURE__ */ new Map();
436
- for (const comp of allComponents) for (const file$1 of comp.files) map.set(file$1.target ?? file$1.path, file$1);
410
+ for (const comp of allComponents) for (const file of comp.files) map.set(file.target ?? file.path, file);
437
411
  return map;
438
412
  });
439
- for (const specifier of sourceFile.getImportStringLiterals()) {
440
- for (const [k, v] of variables) specifier.setLiteralValue(specifier.getLiteralValue().replaceAll(`<${k}>`, v));
441
- if (specifier.getLiteralValue().startsWith(prefix)) {
442
- const lookup = specifier.getLiteralValue().substring(2);
413
+ transformSpecifiers(parsed.program, s, (specifier) => {
414
+ for (const [k, v] of variables) specifier = specifier.replaceAll(`<${k}>`, v);
415
+ if (specifier.startsWith(prefix)) {
416
+ const lookup = specifier.substring(2);
443
417
  const target = pathToFile.get(lookup);
444
- if (target) specifier.setLiteralValue(toImportSpecifier(filePath, this.resolveOutputPath(target)));
445
- else console.warn(`cannot find the referenced file of ${specifier}`);
418
+ if (target) specifier = toImportSpecifier(filePath, this.resolveOutputPath(target));
419
+ else io.onWarn(`cannot find the referenced file of ${specifier}`);
446
420
  }
447
- }
448
- for (const plugin of this.plugins) await plugin.transform?.({
449
- file: sourceFile,
450
- componentFile: file,
421
+ return specifier;
422
+ });
423
+ for (const plugin of this.plugins) await plugin.transformFile?.({
424
+ s,
425
+ parsed,
426
+ file,
451
427
  component
452
428
  });
453
- return sourceFile.getFullText();
429
+ return s.toString();
454
430
  }
455
431
  resolveOutputPath(file) {
456
432
  const config = this.rootClient.config;
@@ -470,8 +446,8 @@ var ComponentInstaller = class {
470
446
  //#endregion
471
447
  //#region src/commands/shared.ts
472
448
  const UIRegistries = {
473
- "base-ui": "fumadocs/base-ui",
474
- "radix-ui": "fumadocs/radix-ui"
449
+ "base-ui": "hanzo-docs/base-ui",
450
+ "radix-ui": "hanzo-docs/radix-ui"
475
451
  };
476
452
 
477
453
  //#endregion
@@ -498,7 +474,7 @@ async function add(input, client) {
498
474
  hint: item.description
499
475
  });
500
476
  spin.stop(picocolors.bold(picocolors.greenBright("registry fetched")));
501
- const value = await multiselect({
477
+ const value = await autocompleteMultiselect({
502
478
  message: "Select components to install",
503
479
  options
504
480
  });
@@ -512,17 +488,52 @@ async function add(input, client) {
512
488
  }
513
489
  async function install(target, installer) {
514
490
  for (const name of target) {
515
- intro(picocolors.bold(picocolors.inverse(picocolors.cyanBright(`Add Component: ${name}`))));
491
+ const spin = spinner();
492
+ spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));
516
493
  try {
517
- await installer.install(name);
518
- outro(picocolors.bold(picocolors.greenBright(`${name} installed`)));
494
+ await installer.install(name, {
495
+ onWarn(message) {
496
+ spin.message(message);
497
+ },
498
+ async confirmFileOverride(options) {
499
+ spin.clear();
500
+ const value = await confirm({
501
+ message: `Do you want to override ${options.path}?`,
502
+ initialValue: false
503
+ });
504
+ if (isCancel(value)) {
505
+ outro("Installation terminated");
506
+ process.exit(0);
507
+ }
508
+ spin.start(picocolors.bold(picocolors.cyanBright(`Installing ${name}`)));
509
+ return value;
510
+ },
511
+ onFileDownloaded(options) {
512
+ spin.message(options.path);
513
+ }
514
+ });
515
+ spin.stop(picocolors.bold(picocolors.greenBright(`${name} installed`)));
519
516
  } catch (e) {
520
- log.error(String(e));
521
- throw e;
517
+ spin.error(e instanceof Error ? e.message : String(e));
518
+ process.exit(-1);
519
+ }
520
+ }
521
+ const deps = await installer.deps();
522
+ if (deps.hasRequired()) {
523
+ log.message();
524
+ box([...deps.dependencies, ...deps.devDependencies].join("\n"), "New Dependencies");
525
+ const value = await confirm({ message: `Do you want to install with ${deps.packageManager}?` });
526
+ if (isCancel(value)) {
527
+ outro("Installation terminated");
528
+ process.exit(0);
529
+ }
530
+ if (value) {
531
+ const spin = spinner({ errorMessage: "Failed to install dependencies" });
532
+ spin.start("Installing dependencies");
533
+ await deps.installRequired();
534
+ spin.stop("Dependencies installed");
522
535
  }
523
536
  }
524
- intro(picocolors.bold("New Dependencies"));
525
- await installer.installDeps();
526
537
  await installer.onEnd();
527
538
  outro(picocolors.bold(picocolors.greenBright("Successful")));
528
539
  }
@@ -530,11 +541,12 @@ async function install(target, installer) {
530
541
  //#endregion
531
542
  //#region src/commands/customise.ts
532
543
  async function customise(client) {
533
- intro(picocolors.bgBlack(picocolors.whiteBright("Customise Fumadocs UI")));
544
+ intro(picocolors.bgBlack(picocolors.whiteBright("Customise Hanzo Docs UI")));
534
545
  const config = client.config;
535
546
  const installer = new ComponentInstaller(client);
536
- const result = await group({
537
- target: () => select({
547
+ const registry = UIRegistries[config.uiLibrary];
548
+ const target = (await group({
549
+ layout: () => select({
538
550
  message: "What do you want to customise?",
539
551
  options: [{
540
552
  label: "Docs Layout",
@@ -546,24 +558,44 @@ async function customise(client) {
546
558
  hint: "the navbar for your other pages"
547
559
  }]
548
560
  }),
549
- mode: (v) => {
550
- if (v.results.target !== "docs") return;
561
+ target: (v) => {
562
+ if (v.results.layout !== "docs") return Promise.resolve({
563
+ target: [`${registry}/layouts/home`],
564
+ replace: [["@hanzo/docs-base-ui/layouts/home", `@/components/layout/home`]]
565
+ });
551
566
  return select({
552
567
  message: "Which variant do you want to start from?",
553
568
  options: [
554
569
  {
555
570
  label: "Start from minimal styles",
556
- value: "minimal",
557
- hint: "for those who want to build their own variant from ground up."
571
+ hint: "for those who want to build their own variant from ground up.",
572
+ value: {
573
+ target: ["hanzo-docs/ui/layouts/docs-min"],
574
+ replace: [["@hanzo/docs-base-ui/layouts/docs", "@/components/layout/docs"], ["@hanzo/docs-base-ui/layouts/docs/page", "@/components/layout/docs/page"]]
575
+ }
558
576
  },
559
577
  {
560
578
  label: "Start from default layout",
561
- value: "full-default",
579
+ value: {
580
+ target: [`${registry}/layouts/docs`],
581
+ replace: [["@hanzo/docs-base-ui/layouts/docs", "@/components/layout/docs"], ["@hanzo/docs-base-ui/layouts/docs/page", "@/components/layout/docs/page"]]
582
+ },
562
583
  hint: "useful for adjusting small details."
563
584
  },
564
585
  {
565
586
  label: "Start from Notebook layout",
566
- value: "full-notebook",
587
+ value: {
588
+ target: [`${registry}/layouts/notebook`],
589
+ replace: [["@hanzo/docs-base-ui/layouts/notebook", "@/components/layout/notebook"], ["@hanzo/docs-base-ui/layouts/notebook/page", "@/components/layout/notebook/page"]]
590
+ },
591
+ hint: "useful for adjusting small details."
592
+ },
593
+ {
594
+ label: "Start from Flux layout",
595
+ value: {
596
+ target: [`${registry}/layouts/flux`],
597
+ replace: [["@hanzo/docs-base-ui/layouts/flux", "@/components/layout/flux"], ["@hanzo/docs-base-ui/layouts/flux/page", "@/components/layout/flux/page"]]
598
+ },
567
599
  hint: "useful for adjusting small details."
568
600
  }
569
601
  ]
@@ -572,19 +604,9 @@ async function customise(client) {
572
604
  }, { onCancel: () => {
573
605
  cancel("Installation Stopped.");
574
606
  process.exit(0);
575
- } });
576
- const registry = UIRegistries[config.uiLibrary];
577
- if (result.target === "docs") {
578
- const targets = [];
579
- if (result.mode === "minimal") targets.push("fumadocs/ui/layouts/docs-min");
580
- else targets.push(result.mode === "full-default" ? `${registry}/layouts/docs` : `${registry}/layouts/notebook`);
581
- await install(targets, installer);
582
- printNext(...result.mode === "full-notebook" ? [["@hanzo/docs-ui/layouts/notebook", "@/components/layout/notebook"], ["@hanzo/docs-ui/layouts/notebook/page", "@/components/layout/notebook/page"]] : [["@hanzo/docs-ui/layouts/docs", "@/components/layout/docs"], ["@hanzo/docs-ui/layouts/docs/page", "@/components/layout/docs/page"]]);
583
- }
584
- if (result.target === "home") {
585
- await install([`${registry}/layouts/home`], installer);
586
- printNext(["@hanzo/docs-ui/layouts/home", `@/components/layout/home`]);
587
- }
607
+ } })).target;
608
+ await install(target.target, installer);
609
+ printNext(...target.replace);
588
610
  outro(picocolors.bold("Have fun!"));
589
611
  }
590
612
  function printNext(...maps) {
@@ -608,7 +630,7 @@ program.command("customise").alias("customize").description("simple way to custo
608
630
  await customise(createClientFromDir(options.dir, await createOrLoadConfig(options.config)));
609
631
  });
610
632
  const dirShortcuts = {
611
- ":preview": "https://preview.fumadocs.dev/registry",
633
+ ":preview": "https://preview.hanzo.ai/docs/registry",
612
634
  ":dev": "http://localhost:3000/registry"
613
635
  };
614
636
  program.command("add").description("add a new component to your docs").argument("[components...]", "components to download").option("--dir <string>", "the root url or directory to resolve registry").action(async (input, options) => {
@@ -633,7 +655,7 @@ program.command("tree").argument("[json_or_args]", "JSON output of `tree` comman
633
655
  await fs.writeFile(output, out);
634
656
  } else console.log(out);
635
657
  });
636
- function createClientFromDir(dir = "https://fumadocs.dev/registry", config) {
658
+ function createClientFromDir(dir = "https://hanzo.ai/docs/registry", config) {
637
659
  if (dir in dirShortcuts) dir = dirShortcuts[dir];
638
660
  return dir.startsWith("http://") || dir.startsWith("https://") ? new HttpRegistryClient(dir, config) : new LocalRegistryClient(dir, config);
639
661
  }