@hanzo/docs-cli 1.2.1 → 1.3.0

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.
@@ -164,7 +164,7 @@ interface MonoRegistry extends CompiledRegistry {
164
164
  registries: CompiledRegistry[];
165
165
  }
166
166
  declare function combineRegistry(root: CompiledRegistry, ...items: CompiledRegistry[]): MonoRegistry;
167
- declare function writeFumadocsRegistry(out: CompiledRegistry | MonoRegistry, options: {
167
+ declare function writeDocsRegistry(out: CompiledRegistry | MonoRegistry, options: {
168
168
  dir: string;
169
169
  /**
170
170
  * Remove previous outputs
@@ -175,5 +175,5 @@ declare function writeFumadocsRegistry(out: CompiledRegistry | MonoRegistry, opt
175
175
  log?: boolean;
176
176
  }): Promise<void>;
177
177
  //#endregion
178
- export { CompiledRegistry, Component, ComponentCompiler, ComponentFile, MonoRegistry, OnResolve, PackageJson, Reference, Registry, RegistryCompiler, SourceReference, combineRegistry, resolveFromRemote, writeFumadocsRegistry };
178
+ export { CompiledRegistry, Component, ComponentCompiler, ComponentFile, MonoRegistry, OnResolve, PackageJson, Reference, Registry, RegistryCompiler, SourceReference, combineRegistry, resolveFromRemote, writeDocsRegistry };
179
179
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/registry/schema.ts","../../src/build/compiler.ts","../../src/build/index.ts"],"sourcesContent":[],"mappings":";;;;KAEY,aAAA,WAAwB;KAExB,iBAAA,GAAoB,CAAA,CAAE,aAAa;cAMlC;cAqBA,iBAAe,CAAA,CAAA;;;;;;;;;;;;;;;;EAAA,CAAA,eAAA,CAAA,CAAA,CAAA,CAAA,CAAA;CAAA,eAAA,CAAA;AAaf,cAAA,kBAoBX,EApB6B,CAAA,CAAA,SAoB7B,CAAA;;;;;;;;;;;;;;;KCpDU,SAAA,eAAwB,oBAAoB;ADV5C,UCYK,gBAAA,CDZmB;EAExB,IAAA,EAAA,MAAA;EAMC,UAAA,ECMC,iBDNyE,EAAA;EAqB1E,IAAA,ECdL,CAAA,CAAE,MDcG,CAAA,OCdW,kBDyBtB,CAAA;;UCtBe,aAAA;QACT;;;;UAKS,SAAA;;;;SAIR;;;;;;;;cAUK;;UAGG,WAAA;iBACA;oBACG;;UAGH,QAAA,SAAiB,KAAK,CAAA,CAAE,aAAa;;wBAE9B;;cAEV;;;;;EDrBc;;AAa5B;cCkBc;;;;;4CAK8B;iBAE3B;oBACG;;cAGP,gBAAA;gBACG;oBACI;YACP;wBAEW;;kCAgBa,QAAA;aAOlB,QAAQ;;cAqCrB,gBAAA;;;;;wBAMyB,gCACd;;;IDrGc,IAAA,EAAA,SAAA,GAAA,KAAA;IAAA,IAAA,EAAA,MAAA;;;oCC4JK;EA5LxB,eAAS,CAAA,IAAA,EAAA,MAAe,CAAA,EAAA;IAEnB,SAAA,WAAgB;IAEnB,IAAA,eAAA;EACU,CAAA,GAAA,SAAA;;AAAR,KAuMJ,eAAA,GAvMI;EAGC,IAAA,EAAA,MAAA;EAMA;AAiBjB;AAKA;EAAsD,IAAA,EAAA,MAAA;CAAf,GAAE;EAEjB,IAAA,EAAA,YAAA;EAEV,GAAA,EAAA,MAAA;EAUA,SAAA,EAAA,MAAA;CAK8B,GAAA;EAE3B,IAAA,EAAA,eAAA;EACG,QAAA,EAAA;IAtBc,IAAA,EAAA,OAAA;IAAI,SAAA,EA0Lf,SA1Le;IAyBzB,IAAA,EAkKK,aAlKW;EACb,CAAA,GAAA;IACI,IAAA,EAAA,QAAA;IACP,SAAA,EAmKU,SAnKV;IAEW,IAAA,EAkKN,aAlKM;IAgBa,YAAA,EAAA,MAAA;EAAA,CAAA;CAOV;AAAR,KAgJP,SAAA,GACR,eAjJe,GAAA;EAAO,IAAA,EAAA,QAAA;EAqCpB,SAAA,EAAA,MAAA;CAMyB;AACd,cA2GJ,iBAAA,CA3GI;EAuDmB,iBAAA,QAAA;;;;EAgBxB,iBAAA,aAAe;EAkBJ,iBAAA,eAAA;EACL,iBAAA,YAAA;EAIK,WAAA,CAAA,QAAA,EAqBQ,gBArBR,EAAA,SAAA,EAsBS,SAtBT;EACL,QAAA,YAAA;EAAa,KAAA,CAAA,CAAA,EAoCd,OApCc,CAoCN,iBApCM,CAAA;EAKnB,QAAA,gBACR;EAMS,QAAA,aAAiB;EAQC,QAAA,SAAA;;AAgBN,iBAiLT,iBAAA,CAjLS,CAAA,EAkLpB,QAlLoB,EAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,CAAA,IAAA,EAoLJ,aApLI,EAAA,GAAA,OAAA,CAAA,EAqLtB,SArLsB,GAAA,SAAA;;;UC7QR,YAAA,SAAqB;cACxB;AFNd;AAEY,iBEOI,eAAA,CFP+B,IAAA,EEQvC,gBFR+B,EAAA,GAAA,KAAA,EES3B,gBFT2B,EAAA,CAAA,EEUpC,YFVoC;AAM1B,iBEeS,qBAAA,CFfiE,GAAA,EEgBhF,gBFhBgF,GEgB7D,YFhB6D,EAAA,OAAA,EAAA;EAqB1E,GAAA,EAAA,MAAA;;;;;;;;IEQV"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/registry/schema.ts","../../src/build/compiler.ts","../../src/build/index.ts"],"sourcesContent":[],"mappings":";;;;KAEY,aAAA,WAAwB;KAExB,iBAAA,GAAoB,CAAA,CAAE,aAAa;cAMlC;cAqBA,iBAAe,CAAA,CAAA;;;;;;;;;;;;;;;;EAAA,CAAA,eAAA,CAAA,CAAA,CAAA,CAAA,CAAA;CAAA,eAAA,CAAA;AAaf,cAAA,kBAoBX,EApB6B,CAAA,CAAA,SAoB7B,CAAA;;;;;;;;;;;;;;;KCpDU,SAAA,eAAwB,oBAAoB;ADV5C,UCYK,gBAAA,CDZmB;EAExB,IAAA,EAAA,MAAA;EAMC,UAAA,ECMC,iBDNyE,EAAA;EAqB1E,IAAA,ECdL,CAAA,CAAE,MDcG,CAAA,OCdW,kBDyBtB,CAAA;;UCtBe,aAAA;QACT;;;;UAKS,SAAA;;;;SAIR;;;;;;;;cAUK;;UAGG,WAAA;iBACA;oBACG;;UAGH,QAAA,SAAiB,KAAK,CAAA,CAAE,aAAa;;wBAE9B;;cAEV;;;;;EDrBc;;AAa5B;cCkBc;;;;;4CAK8B;iBAE3B;oBACG;;cAGP,gBAAA;gBACG;oBACI;YACP;wBAEW;;kCAgBa,QAAA;aAOlB,QAAQ;;cAqCrB,gBAAA;;;;;wBAMyB,gCACd;;;IDrGc,IAAA,EAAA,SAAA,GAAA,KAAA;IAAA,IAAA,EAAA,MAAA;;;oCC4JK;EA5LxB,eAAS,CAAA,IAAA,EAAA,MAAe,CAAA,EAAA;IAEnB,SAAA,WAAgB;IAEnB,IAAA,eAAA;EACU,CAAA,GAAA,SAAA;;AAAR,KAuMJ,eAAA,GAvMI;EAGC,IAAA,EAAA,MAAA;EAMA;AAiBjB;AAKA;EAAsD,IAAA,EAAA,MAAA;CAAf,GAAE;EAEjB,IAAA,EAAA,YAAA;EAEV,GAAA,EAAA,MAAA;EAUA,SAAA,EAAA,MAAA;CAK8B,GAAA;EAE3B,IAAA,EAAA,eAAA;EACG,QAAA,EAAA;IAtBc,IAAA,EAAA,OAAA;IAAI,SAAA,EA0Lf,SA1Le;IAyBzB,IAAA,EAkKK,aAlKW;EACb,CAAA,GAAA;IACI,IAAA,EAAA,QAAA;IACP,SAAA,EAmKU,SAnKV;IAEW,IAAA,EAkKN,aAlKM;IAgBa,YAAA,EAAA,MAAA;EAAA,CAAA;CAOV;AAAR,KAgJP,SAAA,GACR,eAjJe,GAAA;EAAO,IAAA,EAAA,QAAA;EAqCpB,SAAA,EAAA,MAAA;CAMyB;AACd,cA2GJ,iBAAA,CA3GI;EAuDmB,iBAAA,QAAA;;;;EAgBxB,iBAAA,aAAe;EAkBJ,iBAAA,eAAA;EACL,iBAAA,YAAA;EAIK,WAAA,CAAA,QAAA,EAqBQ,gBArBR,EAAA,SAAA,EAsBS,SAtBT;EACL,QAAA,YAAA;EAAa,KAAA,CAAA,CAAA,EAoCd,OApCc,CAoCN,iBApCM,CAAA;EAKnB,QAAA,gBACR;EAMS,QAAA,aAAiB;EAQC,QAAA,SAAA;;AAgBN,iBAiLT,iBAAA,CAjLS,CAAA,EAkLpB,QAlLoB,EAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,CAAA,IAAA,EAoLJ,aApLI,EAAA,GAAA,OAAA,CAAA,EAqLtB,SArLsB,GAAA,SAAA;;;UC7QR,YAAA,SAAqB;cACxB;AFNd;AAEY,iBEOI,eAAA,CFP+B,IAAA,EEQvC,gBFR+B,EAAA,GAAA,KAAA,EES3B,gBFT2B,EAAA,CAAA,EEUpC,YFVoC;AAM1B,iBEeS,iBAAA,CFfiE,GAAA,EEgBhF,gBFhBgF,GEgB7D,YFhB6D,EAAA,OAAA,EAAA;EAqB1E,GAAA,EAAA,MAAA;;;;;;;;IEQV"}
@@ -237,7 +237,7 @@ function combineRegistry(root, ...items) {
237
237
  registries: items
238
238
  };
239
239
  }
240
- async function writeFumadocsRegistry(out, options) {
240
+ async function writeDocsRegistry(out, options) {
241
241
  const { dir, cleanDir = false, log = true } = options;
242
242
  if (cleanDir) {
243
243
  await fs$1.rm(dir, {
@@ -253,7 +253,7 @@ async function writeFumadocsRegistry(out, options) {
253
253
  await writeFile(path$1.join(dir, `${comp.name}.json`), JSON.stringify(comp, null, 2), log);
254
254
  });
255
255
  write.push(writeInfo());
256
- if ("registries" in out) for (const child of out.registries) write.push(writeFumadocsRegistry(child, {
256
+ if ("registries" in out) for (const child of out.registries) write.push(writeDocsRegistry(child, {
257
257
  dir: path$1.join(dir, child.name),
258
258
  log: options.log
259
259
  }));
@@ -269,5 +269,5 @@ async function writeFile(file, content, log = true) {
269
269
  }
270
270
 
271
271
  //#endregion
272
- export { ComponentCompiler, RegistryCompiler, combineRegistry, resolveFromRemote, writeFumadocsRegistry };
272
+ export { ComponentCompiler, RegistryCompiler, combineRegistry, resolveFromRemote, writeDocsRegistry };
273
273
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["path","fs","output: CompiledRegistry","compiler: RegistryCompiler","component: Component","queue: ComponentFile[]","file","filePath: string","process","resolved: Reference | undefined","comp","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 NamespaceType,\n registryInfoSchema,\n} from '@/registry/schema';\nimport type { z } from 'zod';\nimport { Project, SourceFile, StringLiteral, ts } from 'ts-morph';\n\nexport type OnResolve = (reference: SourceReference) => Reference;\n\nexport interface CompiledRegistry {\n name: string;\n components: CompiledComponent[];\n info: z.output<typeof registryInfoSchema>;\n}\n\nexport interface ComponentFile {\n type: NamespaceType;\n path: string;\n target?: string;\n}\n\nexport interface Component {\n name: string;\n title?: string;\n description?: string;\n files: ComponentFile[];\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 readonly project: Project;\n resolver!: RegistryResolver;\n\n constructor(registry: Registry) {\n this.raw = registry;\n this.project = new Project({\n tsConfigFilePath: path.join(registry.dir, registry.tsconfigPath),\n });\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 createSourceFile(file: string) {\n const content = await fs.readFile(file);\n return this.project.createSourceFile(file, content.toString(), {\n overwrite: true,\n });\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 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 if (!input.unlisted) {\n output.info.indexes.push({\n name: input.name,\n title: input.title,\n description: input.description,\n });\n }\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\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\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\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 Set<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 // see https://github.com/shadcn-ui/ui/blob/396275e46a58333caa1fa0a991bd9bc5237d2ee3/packages/shadcn/src/utils/updaters/update-files.ts#L585\n // to hit the fast-path step, we need to import `target` path first because it's detected from `fileSet`, a set of output file paths\n private toImportPath(file: ComponentFile): string {\n let filePath = file.target ?? file.path;\n\n if (filePath.startsWith('./')) filePath = filePath.slice(2);\n\n return `@/${filePath.replaceAll(path.sep, '/')}`;\n }\n\n async build(): Promise<CompiledComponent> {\n return {\n name: this.component.name,\n title: this.component.title,\n description: this.component.description,\n files: (\n await Promise.all(this.component.files.map((file) => this.buildFileAndDeps(file)))\n ).flat(),\n subComponents: Array.from(this.subComponents),\n dependencies: Object.fromEntries(this.dependencies),\n devDependencies: Object.fromEntries(this.devDependencies),\n };\n }\n\n private async buildFileAndDeps(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 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 this.toImportPath(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) {\n if (resolved.type === 'remote') {\n this.subComponents.add({\n type: 'http',\n baseUrl: resolved.registryName,\n component: resolved.component.name,\n });\n } else {\n this.subComponents.add(resolved.component.name);\n }\n }\n\n return this.toImportPath(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 [\n result,\n ...(await Promise.all(queue.map((file) => this.buildFileAndDeps(file)))).flat(),\n ];\n }\n\n private resolveImport(\n sourceFilePath: string,\n specifier: string,\n specified: SourceFile | undefined,\n ): SourceReference | undefined {\n let filePath: string;\n if (specified) {\n filePath = specified.getFilePath();\n } else if (specifier.startsWith('./') || specifier.startsWith('../')) {\n filePath = path.join(path.dirname(sourceFilePath), specifier);\n } else {\n if (!specifier.startsWith('node:'))\n console.warn(`Unknown specifier ${specifier}, skipping for now`);\n return;\n }\n\n const resolver = this.compiler.resolver;\n // outside of registry dir\n if (path.relative(this.registry.dir, filePath).startsWith('../')) {\n return {\n type: 'dependency',\n dep: resolver.getDepFromSpecifier(specifier),\n specifier,\n };\n }\n\n const sub = resolver.getSubComponent(filePath);\n if (sub) {\n return {\n type: 'sub-component',\n resolved: {\n type: 'local',\n component: sub.component,\n file: sub.file,\n },\n };\n }\n\n return {\n type: 'file',\n file: filePath,\n };\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\n /**\n * Process import paths\n */\n const process = (specifier: StringLiteral, specifiedFile: SourceFile | undefined) => {\n const onResolve = this.component.onResolve ?? this.registry.onResolve;\n let resolved: Reference | undefined = this.resolveImport(\n sourceFilePath,\n specifier.getLiteralValue(),\n specifiedFile,\n );\n\n if (!resolved) return;\n if (onResolve) resolved = onResolve(resolved);\n const out = writeReference(resolved);\n if (out) specifier.setLiteralValue(out);\n };\n\n const sourceFile = await this.compiler.createSourceFile(sourceFilePath);\n\n for (const item of sourceFile.getImportDeclarations()) {\n process(item.getModuleSpecifier(), item.getModuleSpecifierSourceFile());\n }\n\n for (const item of sourceFile.getExportDeclarations()) {\n const specifier = item.getModuleSpecifier();\n if (!specifier) continue;\n\n process(specifier, item.getModuleSpecifierSourceFile());\n }\n\n // transform async imports\n const calls = sourceFile.getDescendantsOfKind(ts.SyntaxKind.CallExpression);\n\n for (const expression of calls) {\n if (\n expression.getExpression().isKind(ts.SyntaxKind.ImportKeyword) &&\n expression.getArguments().length === 1\n ) {\n const argument = expression.getArguments()[0];\n\n if (!argument.isKind(ts.SyntaxKind.StringLiteral)) continue;\n\n process(argument, argument.getSymbol()?.getDeclarations()[0].getSourceFile());\n }\n }\n\n return {\n content: sourceFile.getFullText(),\n type: file.type,\n path: file.path,\n target: file.target,\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
+ {"version":3,"file":"index.js","names":["path","fs","output: CompiledRegistry","compiler: RegistryCompiler","component: Component","queue: ComponentFile[]","file","filePath: string","process","resolved: Reference | undefined","comp","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 NamespaceType,\n registryInfoSchema,\n} from '@/registry/schema';\nimport type { z } from 'zod';\nimport { Project, SourceFile, StringLiteral, ts } from 'ts-morph';\n\nexport type OnResolve = (reference: SourceReference) => Reference;\n\nexport interface CompiledRegistry {\n name: string;\n components: CompiledComponent[];\n info: z.output<typeof registryInfoSchema>;\n}\n\nexport interface ComponentFile {\n type: NamespaceType;\n path: string;\n target?: string;\n}\n\nexport interface Component {\n name: string;\n title?: string;\n description?: string;\n files: ComponentFile[];\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 readonly project: Project;\n resolver!: RegistryResolver;\n\n constructor(registry: Registry) {\n this.raw = registry;\n this.project = new Project({\n tsConfigFilePath: path.join(registry.dir, registry.tsconfigPath),\n });\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 createSourceFile(file: string) {\n const content = await fs.readFile(file);\n return this.project.createSourceFile(file, content.toString(), {\n overwrite: true,\n });\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 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 if (!input.unlisted) {\n output.info.indexes.push({\n name: input.name,\n title: input.title,\n description: input.description,\n });\n }\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\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\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\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 Set<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 // see https://github.com/shadcn-ui/ui/blob/396275e46a58333caa1fa0a991bd9bc5237d2ee3/packages/shadcn/src/utils/updaters/update-files.ts#L585\n // to hit the fast-path step, we need to import `target` path first because it's detected from `fileSet`, a set of output file paths\n private toImportPath(file: ComponentFile): string {\n let filePath = file.target ?? file.path;\n\n if (filePath.startsWith('./')) filePath = filePath.slice(2);\n\n return `@/${filePath.replaceAll(path.sep, '/')}`;\n }\n\n async build(): Promise<CompiledComponent> {\n return {\n name: this.component.name,\n title: this.component.title,\n description: this.component.description,\n files: (\n await Promise.all(this.component.files.map((file) => this.buildFileAndDeps(file)))\n ).flat(),\n subComponents: Array.from(this.subComponents),\n dependencies: Object.fromEntries(this.dependencies),\n devDependencies: Object.fromEntries(this.devDependencies),\n };\n }\n\n private async buildFileAndDeps(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 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 this.toImportPath(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) {\n if (resolved.type === 'remote') {\n this.subComponents.add({\n type: 'http',\n baseUrl: resolved.registryName,\n component: resolved.component.name,\n });\n } else {\n this.subComponents.add(resolved.component.name);\n }\n }\n\n return this.toImportPath(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 [\n result,\n ...(await Promise.all(queue.map((file) => this.buildFileAndDeps(file)))).flat(),\n ];\n }\n\n private resolveImport(\n sourceFilePath: string,\n specifier: string,\n specified: SourceFile | undefined,\n ): SourceReference | undefined {\n let filePath: string;\n if (specified) {\n filePath = specified.getFilePath();\n } else if (specifier.startsWith('./') || specifier.startsWith('../')) {\n filePath = path.join(path.dirname(sourceFilePath), specifier);\n } else {\n if (!specifier.startsWith('node:'))\n console.warn(`Unknown specifier ${specifier}, skipping for now`);\n return;\n }\n\n const resolver = this.compiler.resolver;\n // outside of registry dir\n if (path.relative(this.registry.dir, filePath).startsWith('../')) {\n return {\n type: 'dependency',\n dep: resolver.getDepFromSpecifier(specifier),\n specifier,\n };\n }\n\n const sub = resolver.getSubComponent(filePath);\n if (sub) {\n return {\n type: 'sub-component',\n resolved: {\n type: 'local',\n component: sub.component,\n file: sub.file,\n },\n };\n }\n\n return {\n type: 'file',\n file: filePath,\n };\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\n /**\n * Process import paths\n */\n const process = (specifier: StringLiteral, specifiedFile: SourceFile | undefined) => {\n const onResolve = this.component.onResolve ?? this.registry.onResolve;\n let resolved: Reference | undefined = this.resolveImport(\n sourceFilePath,\n specifier.getLiteralValue(),\n specifiedFile,\n );\n\n if (!resolved) return;\n if (onResolve) resolved = onResolve(resolved);\n const out = writeReference(resolved);\n if (out) specifier.setLiteralValue(out);\n };\n\n const sourceFile = await this.compiler.createSourceFile(sourceFilePath);\n\n for (const item of sourceFile.getImportDeclarations()) {\n process(item.getModuleSpecifier(), item.getModuleSpecifierSourceFile());\n }\n\n for (const item of sourceFile.getExportDeclarations()) {\n const specifier = item.getModuleSpecifier();\n if (!specifier) continue;\n\n process(specifier, item.getModuleSpecifierSourceFile());\n }\n\n // transform async imports\n const calls = sourceFile.getDescendantsOfKind(ts.SyntaxKind.CallExpression);\n\n for (const expression of calls) {\n if (\n expression.getExpression().isKind(ts.SyntaxKind.ImportKeyword) &&\n expression.getArguments().length === 1\n ) {\n const argument = expression.getArguments()[0];\n\n if (!argument.isKind(ts.SyntaxKind.StringLiteral)) continue;\n\n process(argument, argument.getSymbol()?.getDeclarations()[0].getSourceFile());\n }\n }\n\n return {\n content: sourceFile.getFullText(),\n type: file.type,\n path: file.path,\n target: file.target,\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 writeDocsRegistry(\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 writeDocsRegistry(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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"}
package/dist/index.js CHANGED
@@ -121,7 +121,7 @@ async function runTree(args) {
121
121
 
122
122
  //#endregion
123
123
  //#region package.json
124
- var version = "1.2.1";
124
+ var version = "1.3.0";
125
125
 
126
126
  //#endregion
127
127
  //#region src/utils/typescript.ts
@@ -470,8 +470,8 @@ var ComponentInstaller = class {
470
470
  //#endregion
471
471
  //#region src/commands/shared.ts
472
472
  const UIRegistries = {
473
- "base-ui": "fumadocs/base-ui",
474
- "radix-ui": "fumadocs/radix-ui"
473
+ "base-ui": "hanzo-docs/base-ui",
474
+ "radix-ui": "hanzo-docs/radix-ui"
475
475
  };
476
476
 
477
477
  //#endregion
@@ -530,7 +530,7 @@ async function install(target, installer) {
530
530
  //#endregion
531
531
  //#region src/commands/customise.ts
532
532
  async function customise(client) {
533
- intro(picocolors.bgBlack(picocolors.whiteBright("Customise Fumadocs UI")));
533
+ intro(picocolors.bgBlack(picocolors.whiteBright("Customise Hanzo Docs UI")));
534
534
  const config = client.config;
535
535
  const installer = new ComponentInstaller(client);
536
536
  const result = await group({
@@ -576,7 +576,7 @@ async function customise(client) {
576
576
  const registry = UIRegistries[config.uiLibrary];
577
577
  if (result.target === "docs") {
578
578
  const targets = [];
579
- if (result.mode === "minimal") targets.push("fumadocs/ui/layouts/docs-min");
579
+ if (result.mode === "minimal") targets.push("hanzo-docs/ui/layouts/docs-min");
580
580
  else targets.push(result.mode === "full-default" ? `${registry}/layouts/docs` : `${registry}/layouts/notebook`);
581
581
  await install(targets, installer);
582
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"]]);
@@ -608,7 +608,7 @@ program.command("customise").alias("customize").description("simple way to custo
608
608
  await customise(createClientFromDir(options.dir, await createOrLoadConfig(options.config)));
609
609
  });
610
610
  const dirShortcuts = {
611
- ":preview": "https://preview.fumadocs.dev/registry",
611
+ ":preview": "https://preview.hanzo.ai/docs/registry",
612
612
  ":dev": "http://localhost:3000/registry"
613
613
  };
614
614
  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 +633,7 @@ program.command("tree").argument("[json_or_args]", "JSON output of `tree` comman
633
633
  await fs.writeFile(output, out);
634
634
  } else console.log(out);
635
635
  });
636
- function createClientFromDir(dir = "https://fumadocs.dev/registry", config) {
636
+ function createClientFromDir(dir = "https://hanzo.ai/docs/registry", config) {
637
637
  if (dir in dirShortcuts) dir = dirShortcuts[dir];
638
638
  return dir.startsWith("http://") || dir.startsWith("https://") ? new HttpRegistryClient(dir, config) : new LocalRegistryClient(dir, config);
639
639
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["isSrc","baseUrl: string","config: LoadedConfig","dir: string","rootClient: RegistryClient","plugins: ComponentInstallerPlugin[]","downloaded: DownloadedComponent[]","result: DownloadedComponent[]","file","target: string[]","options: {\n label: string;\n value: string;\n hint?: string;\n }[]","packageJson.version","dirShortcuts: Record<string, string>","nodes: JsonTreeNode[]"],"sources":["../src/utils/fs.ts","../src/utils/is-src.ts","../src/config.ts","../src/commands/file-tree.ts","../src/utils/file-tree/run-tree.ts","../package.json","../src/utils/typescript.ts","../src/constants.ts","../src/utils/ast.ts","../src/registry/schema.ts","../src/utils/cache.ts","../src/registry/client.ts","../src/utils/get-package-manager.ts","../src/registry/installer/dep-manager.ts","../src/registry/installer/index.ts","../src/commands/shared.ts","../src/commands/add.ts","../src/commands/customise.ts","../src/index.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","import { exists } from '@/utils/fs';\n\nexport async function isSrc(): Promise<boolean> {\n return exists('./src');\n}\n","import fs from 'node:fs/promises';\nimport { isSrc } from '@/utils/is-src';\nimport { z } from 'zod';\n\nexport function createConfigSchema(isSrc: boolean) {\n const defaultAliases = {\n uiDir: './components/ui',\n componentsDir: './components',\n blockDir: './components',\n cssDir: './styles',\n libDir: './lib',\n };\n\n return z.object({\n $schema: z\n .string()\n .default(\n isSrc\n ? 'node_modules/@hanzo/docs-cli/dist/schema/src.json'\n : 'node_modules/@hanzo/docs-cli/dist/schema/default.json',\n )\n .optional(),\n aliases: z\n .object({\n uiDir: z.string().default(defaultAliases.uiDir),\n componentsDir: z.string().default(defaultAliases.uiDir),\n blockDir: z.string().default(defaultAliases.blockDir),\n cssDir: z.string().default(defaultAliases.componentsDir),\n libDir: z.string().default(defaultAliases.libDir),\n })\n .default(defaultAliases),\n\n baseDir: z.string().default(isSrc ? 'src' : ''),\n uiLibrary: z.enum(['radix-ui', 'base-ui']).default('radix-ui'),\n\n commands: z\n .object({\n /**\n * command to format output code automatically\n */\n format: z.string().optional(),\n })\n .default({}),\n });\n}\n\ntype ConfigSchema = ReturnType<typeof createConfigSchema>;\n\nexport type ConfigInput = z.input<ConfigSchema>;\nexport type LoadedConfig = z.output<ConfigSchema>;\n\nexport async function createOrLoadConfig(file = './cli.json'): Promise<LoadedConfig> {\n const inited = await initConfig(file);\n if (inited) return inited;\n\n const content = (await fs.readFile(file)).toString();\n const src = await isSrc();\n const configSchema = createConfigSchema(src);\n\n return configSchema.parse(JSON.parse(content));\n}\n\n/**\n * Write new config, skip if a config already exists\n *\n * @returns the created config, `undefined` if not created\n */\nexport async function initConfig(\n file = './cli.json',\n src?: boolean,\n): Promise<LoadedConfig | undefined> {\n if (\n await fs\n .stat(file)\n .then(() => true)\n .catch(() => false)\n ) {\n return;\n }\n\n const defaultConfig = createConfigSchema(src ?? (await isSrc())).parse({} satisfies ConfigInput);\n await fs.writeFile(file, JSON.stringify(defaultConfig, null, 2));\n return defaultConfig;\n}\n","export type JsonTreeNode =\n | {\n type: 'file';\n name: string;\n }\n | {\n type: 'directory';\n name: string;\n contents: JsonTreeNode[];\n }\n | {\n type: 'report';\n }\n | {\n type: 'link';\n name: string;\n };\n\nconst scanned = ['file', 'directory', 'link'];\n\nexport function treeToMdx(input: JsonTreeNode[], noRoot = false): string {\n function toNode(item: JsonTreeNode): string {\n if (item.type === 'file' || item.type === 'link') {\n return `<File name=${JSON.stringify(item.name)} />`;\n }\n\n if (item.type === 'directory') {\n if (item.contents.length === 1 && 'name' in item.contents[0]) {\n const child = item.contents[0];\n\n return toNode({\n ...child,\n name: `${item.name}/${child.name}`,\n });\n }\n\n return `<Folder name=${JSON.stringify(item.name)}>\n${item.contents.map(toNode).filter(Boolean).join('\\n')}\n</Folder>`;\n }\n\n return '';\n }\n\n let children = input.filter((v) => scanned.includes(v.type));\n\n if (noRoot && children.length === 1 && input[0].type === 'directory') {\n children = input[0].contents;\n }\n\n return `<Files>\n${children.map(toNode).filter(Boolean).join('\\n')}\n</Files>`;\n}\n\nexport function treeToJavaScript(\n input: JsonTreeNode[],\n noRoot?: boolean,\n importName = '@hanzo/docs-ui/components/files',\n): string {\n return `import { File, Files, Folder } from ${JSON.stringify(importName)}\n\nexport default (${treeToMdx(input, noRoot)})`;\n}\n","import { x } from 'tinyexec';\nimport type { JsonTreeNode } from '@/commands/file-tree';\n\nexport async function runTree(args: string): Promise<JsonTreeNode[]> {\n const out = await x('tree', [args, '--gitignore', '--prune', '-J']);\n\n try {\n return JSON.parse(out.stdout) as JsonTreeNode[];\n } catch (e) {\n throw new Error('failed to run `tree` command', {\n cause: e,\n });\n }\n}\n","","import { Project } from 'ts-morph';\n\nexport function createEmptyProject(): Project {\n return new Project({\n compilerOptions: {},\n });\n}\n","export const typescriptExtensions = ['.ts', '.tsx', '.js', '.jsx'];\n","import path from 'node:path';\nimport { typescriptExtensions } from '@/constants';\n\n/**\n * Return the import modifier for `sourceFile` to import `referenceFile`\n *\n * @example\n * ```ts\n * toReferencePath('index.ts', 'dir/hello.ts')\n * // should output './dir/hello'\n * ```\n */\nexport function toImportSpecifier(sourceFile: string, referenceFile: string): string {\n const extname = path.extname(referenceFile);\n const removeExt = typescriptExtensions.includes(extname);\n\n let importPath = path\n .relative(\n path.dirname(sourceFile),\n removeExt ? referenceFile.substring(0, referenceFile.length - extname.length) : referenceFile,\n )\n .replaceAll(path.sep, '/');\n\n if (removeExt && importPath.endsWith('/index')) {\n importPath = importPath.slice(0, -'/index'.length);\n }\n\n return importPath.startsWith('../') ? importPath : `./${importPath}`;\n}\n","import { z } from 'zod';\n\nexport type NamespaceType = (typeof namespaces)[number];\nexport type CompiledFile = z.input<typeof fileSchema>;\nexport type CompiledComponent = z.input<typeof componentSchema>;\nexport type CompiledRegistryInfo = z.input<typeof registryInfoSchema>;\nexport type DownloadedRegistryInfo = z.output<typeof registryInfoSchema>;\nexport type File = z.output<typeof fileSchema>;\nexport type Component = z.output<typeof componentSchema>;\n\nexport const namespaces = ['components', 'lib', 'css', 'route', 'ui', 'block'] as const;\n\nexport const indexSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport const fileSchema = z.object({\n type: z.literal(namespaces),\n path: z.string(),\n target: z.string().optional(),\n content: z.string(),\n});\n\nexport const httpSubComponent = z.object({\n type: z.literal('http'),\n baseUrl: z.string(),\n component: z.string(),\n});\n\nexport const componentSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n files: z.array(fileSchema),\n dependencies: z.record(z.string(), z.string().or(z.null())),\n devDependencies: z.record(z.string(), z.string().or(z.null())),\n /**\n * list of sub components, either local (component name) or remote (registry info & component name)\n */\n subComponents: z.array(z.string().or(httpSubComponent)).default([]),\n});\n\nexport const registryInfoSchema = z.object({\n /**\n * define used variables, variables can be referenced in the import specifiers of component files.\n */\n variables: z\n .record(\n z.string(),\n z.object({\n description: z.string().optional(),\n default: z.unknown().optional(),\n }),\n )\n .optional(),\n /**\n * provide variables to sub components\n */\n env: z.record(z.string(), z.unknown()).optional(),\n indexes: z.array(indexSchema).default([]),\n\n registries: z.array(z.string()).optional(),\n});\n","export class AsyncCache<V> {\n readonly store = new Map<string, V | Promise<V>>();\n\n cached<V1 extends V = V>(key: string, fn: () => V1 | Promise<V1>): V1 | Promise<V1> {\n let cached = this.store.get(key);\n if (cached !== undefined) return cached as V1;\n\n cached = fn();\n this.store.set(key, cached);\n return cached as V1;\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 { log } from '@clack/prompts';\nimport { AsyncCache } 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 = new AsyncCache<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.cached<DownloadedRegistryInfo>(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.cached<Component>(url.href, async () => {\n const res = await fetch(`${this.baseUrl}/${name}.json`);\n if (!res.ok) {\n log.error(`component ${name} not found at ${url.href}`);\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 log.error(`component ${name} not found at ${filePath}`);\n throw 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","import { detect, type AgentName } from 'package-manager-detector';\n\nexport type PackageManager = AgentName;\n\nexport async function getPackageManager(): Promise<PackageManager> {\n const result = await detect();\n\n return result?.name ?? 'npm';\n}\n","import { exists } from '@/utils/fs';\nimport fs from 'node:fs/promises';\nimport { getPackageManager } from '@/utils/get-package-manager';\nimport { confirm, isCancel, spinner } from '@clack/prompts';\nimport { x } from 'tinyexec';\n\nexport class DependencyManager {\n private cachedInstalledDeps: Map<string, string> | undefined;\n\n /**\n * Get dependencies from `package.json`\n */\n async getDeps(): Promise<Map<string, string>> {\n if (this.cachedInstalledDeps) return this.cachedInstalledDeps;\n const dependencies = new Map<string, string>();\n\n if (!(await exists('package.json'))) return dependencies;\n\n const content = await fs.readFile('package.json');\n const parsed = JSON.parse(content.toString()) as object;\n\n if ('dependencies' in parsed && typeof parsed.dependencies === 'object') {\n const records = parsed.dependencies as Record<string, string>;\n\n for (const [k, v] of Object.entries(records)) {\n dependencies.set(k, v);\n }\n }\n\n if ('devDependencies' in parsed && typeof parsed.devDependencies === 'object') {\n const records = parsed.devDependencies as Record<string, string>;\n\n for (const [k, v] of Object.entries(records)) {\n dependencies.set(k, v);\n }\n }\n\n return (this.cachedInstalledDeps = dependencies);\n }\n\n private async resolveInstallDependencies(deps: Record<string, string | null>): Promise<string[]> {\n const cachedInstalledDeps = await this.getDeps();\n\n return Object.entries(deps)\n .filter(([k]) => !cachedInstalledDeps.has(k))\n .map(([k, v]) => (v === null || v.length === 0 ? k : `${k}@${v}`));\n }\n\n async installDeps(deps: Record<string, string | null>, devDeps: Record<string, string | null>) {\n const items = await this.resolveInstallDependencies(deps);\n const devItems = await this.resolveInstallDependencies(devDeps);\n if (items.length === 0 && devItems.length === 0) return;\n\n const manager = await getPackageManager();\n const value = await confirm({\n message: `Do you want to install with ${manager}?\n${[...items, ...devItems].map((v) => `- ${v}`).join('\\n')}`,\n });\n\n if (isCancel(value) || !value) {\n return;\n }\n\n const spin = spinner();\n spin.start('Installing dependencies...');\n if (items.length > 0) await x(manager, ['install', ...items]);\n if (devItems.length > 0) await x(manager, ['install', ...devItems, '-D']);\n spin.stop('Dependencies installed.');\n }\n}\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { confirm, isCancel, log, outro } from '@clack/prompts';\nimport { createEmptyProject } from '@/utils/typescript';\nimport { typescriptExtensions } from '@/constants';\nimport { toImportSpecifier } from '@/utils/ast';\nimport type { Component, File } from '@/registry/schema';\nimport { HttpRegistryClient, type RegistryClient } from '@/registry/client';\nimport { x } from 'tinyexec';\nimport { DependencyManager } from '@/registry/installer/dep-manager';\nimport { AsyncCache } from '@/utils/cache';\nimport type { SourceFile } from 'ts-morph';\n\ninterface DownloadedComponent extends Omit<Component, 'subComponents'> {\n variables?: Record<string, unknown>;\n}\n\nexport interface ComponentInstallerPlugin {\n transform?: (context: {\n file: SourceFile;\n componentFile: File;\n component: DownloadedComponent;\n }) => void | Promise<void>;\n}\n\nexport class ComponentInstaller {\n private readonly project = createEmptyProject();\n private readonly installedFiles = new Set<string>();\n private readonly downloadCache = new AsyncCache<DownloadedComponent[]>();\n readonly dependencies: Record<string, string | null> = {};\n readonly devDependencies: Record<string, string | null> = {};\n\n constructor(\n private readonly rootClient: RegistryClient,\n private readonly plugins: ComponentInstallerPlugin[] = [],\n ) {}\n\n async install(name: string) {\n let downloaded: DownloadedComponent[];\n // detect linked registry\n const info = await this.rootClient.fetchRegistryInfo();\n\n for (const registry of info.registries ?? []) {\n if (name.startsWith(`${registry}/`)) {\n downloaded = await this.download(\n name.slice(registry.length + 1),\n this.rootClient.createLinkedRegistryClient(registry),\n );\n break;\n }\n }\n\n downloaded ??= await this.download(name, this.rootClient);\n\n for (const item of downloaded) {\n Object.assign(this.dependencies, item.dependencies);\n Object.assign(this.devDependencies, item.devDependencies);\n }\n\n for (const comp of downloaded) {\n for (const file of comp.files) {\n const outPath = this.resolveOutputPath(file);\n if (this.installedFiles.has(outPath)) continue;\n this.installedFiles.add(outPath);\n\n const output = typescriptExtensions.includes(path.extname(outPath))\n ? await this.transform(name, file, comp, downloaded)\n : file.content;\n\n const status = await fs\n .readFile(outPath)\n .then((res) => {\n if (res.toString() === output) return 'ignore';\n return 'need-update';\n })\n .catch(() => 'write');\n\n if (status === 'ignore') continue;\n\n if (status === 'need-update') {\n const override = await confirm({\n message: `Do you want to override ${outPath}?`,\n initialValue: false,\n });\n\n if (isCancel(override)) {\n outro('Ended');\n process.exit(0);\n }\n\n if (!override) continue;\n }\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, output);\n log.step(`downloaded ${outPath}`);\n }\n }\n }\n\n async installDeps() {\n await new DependencyManager().installDeps(this.dependencies, this.devDependencies);\n }\n\n async onEnd() {\n const config = this.rootClient.config;\n if (config.commands.format) {\n await x(config.commands.format);\n }\n }\n\n /**\n * return a list of components, merged with child components & variables.\n */\n private async download(\n name: string,\n client: RegistryClient,\n contextVariables?: Record<string, unknown>,\n ): Promise<DownloadedComponent[]> {\n const hash = `${client.registryId} ${name}`;\n const info = await client.fetchRegistryInfo();\n const variables = { ...contextVariables, ...info.env };\n for (const [k, v] of Object.entries(info.variables ?? {})) {\n variables[k] ??= v.default;\n }\n\n const out = await this.downloadCache.cached(hash, async () => {\n const comp = await client.fetchComponent(name);\n const result: DownloadedComponent[] = [comp];\n // place it before downloading child components to avoid recursive downloads\n this.downloadCache.store.set(hash, result);\n\n const child = await Promise.all(\n comp.subComponents.map((sub) => {\n if (typeof sub === 'string') return this.download(sub, client);\n const baseUrl =\n this.rootClient instanceof HttpRegistryClient\n ? new URL(sub.baseUrl, `${this.rootClient.baseUrl}/`).href\n : sub.baseUrl;\n\n return this.download(\n sub.component,\n new HttpRegistryClient(baseUrl, client.config),\n variables,\n );\n }),\n );\n for (const sub of child) result.push(...sub);\n return result;\n });\n\n return out.map((file) => ({ ...file, variables }));\n }\n\n private readonly pathToFileCache = new AsyncCache<Map<string, File>>();\n private async transform(\n taskId: string,\n file: File,\n component: DownloadedComponent,\n allComponents: DownloadedComponent[],\n ): Promise<string> {\n const filePath = this.resolveOutputPath(file);\n const sourceFile = this.project.createSourceFile(filePath, file.content, {\n overwrite: true,\n });\n\n // transform alias\n const prefix = '@/';\n const variables = Object.entries(component.variables ?? {});\n const pathToFile = await this.pathToFileCache.cached(taskId, () => {\n const map = new Map<string, File>();\n for (const comp of allComponents) {\n for (const file of comp.files) map.set(file.target ?? file.path, file);\n }\n return map;\n });\n for (const specifier of sourceFile.getImportStringLiterals()) {\n for (const [k, v] of variables) {\n specifier.setLiteralValue(specifier.getLiteralValue().replaceAll(`<${k}>`, v as string));\n }\n\n if (specifier.getLiteralValue().startsWith(prefix)) {\n const lookup = specifier.getLiteralValue().substring(prefix.length);\n const target = pathToFile.get(lookup);\n\n if (target) {\n specifier.setLiteralValue(toImportSpecifier(filePath, this.resolveOutputPath(target)));\n } else {\n console.warn(`cannot find the referenced file of ${specifier}`);\n }\n }\n }\n\n for (const plugin of this.plugins) {\n await plugin.transform?.({\n file: sourceFile,\n componentFile: file,\n component,\n });\n }\n\n return sourceFile.getFullText();\n }\n\n private resolveOutputPath(file: File): string {\n const config = this.rootClient.config;\n const dir = (\n {\n components: config.aliases.componentsDir,\n block: config.aliases.blockDir,\n ui: config.aliases.uiDir,\n css: config.aliases.cssDir,\n lib: config.aliases.libDir,\n route: './',\n } as const\n )[file.type];\n if (file.target) {\n return path.join(config.baseDir, file.target.replace('<dir>', dir));\n }\n\n return path.join(config.baseDir, dir, path.basename(file.path));\n }\n}\n","export const UIRegistries = {\n 'base-ui': 'fumadocs/base-ui',\n 'radix-ui': 'fumadocs/radix-ui',\n};\n","import { intro, isCancel, log, multiselect, outro, spinner } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { ComponentInstaller } from '@/registry/installer';\nimport type { RegistryClient } from '@/registry/client';\nimport { UIRegistries } from '@/commands/shared';\n\nexport async function add(input: string[], client: RegistryClient) {\n const config = client.config;\n let target: string[];\n const installer = new ComponentInstaller(client);\n const registry = UIRegistries[config.uiLibrary];\n\n if (input.length === 0) {\n const spin = spinner();\n spin.start('fetching registry');\n const info = await client.fetchRegistryInfo();\n const options: {\n label: string;\n value: string;\n hint?: string;\n }[] = [];\n\n for (const item of info.indexes) {\n options.push({\n label: item.title ?? item.name,\n value: item.name,\n hint: item.description,\n });\n }\n const { indexes } = await client.createLinkedRegistryClient(registry).fetchRegistryInfo();\n\n for (const item of indexes) {\n options.push({\n label: item.title ?? item.name,\n value: `${registry}/${item.name}`,\n hint: item.description,\n });\n }\n\n spin.stop(picocolors.bold(picocolors.greenBright('registry fetched')));\n const value = await multiselect({\n message: 'Select components to install',\n options,\n });\n\n if (isCancel(value)) {\n outro('Ended');\n return;\n }\n\n target = value;\n } else {\n target = await Promise.all(\n input.map(async (item) => ((await client.hasComponent(item)) ? item : `${registry}/${item}`)),\n );\n }\n\n await install(target, installer);\n}\n\nexport async function install(target: string[], installer: ComponentInstaller) {\n for (const name of target) {\n intro(picocolors.bold(picocolors.inverse(picocolors.cyanBright(`Add Component: ${name}`))));\n\n try {\n await installer.install(name);\n outro(picocolors.bold(picocolors.greenBright(`${name} installed`)));\n } catch (e) {\n log.error(String(e));\n throw e;\n }\n }\n\n intro(picocolors.bold('New Dependencies'));\n\n await installer.installDeps();\n await installer.onEnd();\n\n outro(picocolors.bold(picocolors.greenBright('Successful')));\n}\n","import { cancel, group, intro, log, outro, select } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { install } from '@/commands/add';\nimport type { RegistryClient } from '@/registry/client';\nimport { ComponentInstaller } from '@/registry/installer';\nimport { UIRegistries } from '@/commands/shared';\n\nexport async function customise(client: RegistryClient) {\n intro(picocolors.bgBlack(picocolors.whiteBright('Customise Fumadocs UI')));\n const config = client.config;\n const installer = new ComponentInstaller(client);\n\n const result = await group(\n {\n target: () =>\n select({\n message: 'What do you want to customise?',\n options: [\n {\n label: 'Docs Layout',\n value: 'docs',\n hint: 'main UI of your docs',\n },\n {\n label: 'Home Layout',\n value: 'home',\n hint: 'the navbar for your other pages',\n },\n ],\n }),\n mode: (v) => {\n if (v.results.target !== 'docs') return;\n\n return select({\n message: 'Which variant do you want to start from?',\n options: [\n {\n label: 'Start from minimal styles',\n value: 'minimal',\n hint: 'for those who want to build their own variant from ground up.',\n },\n {\n label: 'Start from default layout',\n value: 'full-default',\n hint: 'useful for adjusting small details.',\n },\n {\n label: 'Start from Notebook layout',\n value: 'full-notebook',\n hint: 'useful for adjusting small details.',\n },\n ],\n });\n },\n },\n {\n onCancel: () => {\n cancel('Installation Stopped.');\n process.exit(0);\n },\n },\n );\n\n const registry = UIRegistries[config.uiLibrary];\n if (result.target === 'docs') {\n const targets = [];\n if (result.mode === 'minimal') {\n targets.push('fumadocs/ui/layouts/docs-min');\n } else {\n targets.push(\n result.mode === 'full-default'\n ? `${registry}/layouts/docs`\n : `${registry}/layouts/notebook`,\n );\n }\n\n await install(targets, installer);\n const maps: [string, string][] =\n result.mode === 'full-notebook'\n ? [\n ['@hanzo/docs-ui/layouts/notebook', '@/components/layout/notebook'],\n ['@hanzo/docs-ui/layouts/notebook/page', '@/components/layout/notebook/page'],\n ]\n : [\n ['@hanzo/docs-ui/layouts/docs', '@/components/layout/docs'],\n ['@hanzo/docs-ui/layouts/docs/page', '@/components/layout/docs/page'],\n ];\n\n printNext(...maps);\n }\n\n if (result.target === 'home') {\n await install([`${registry}/layouts/home`], installer);\n printNext(['@hanzo/docs-ui/layouts/home', `@/components/layout/home`]);\n }\n\n outro(picocolors.bold('Have fun!'));\n}\n\nfunction printNext(...maps: [from: string, to: string][]) {\n intro(picocolors.bold('What is Next?'));\n\n log.info(\n [\n 'You can check the installed components in `components`.',\n picocolors.dim('---'),\n 'Open your `layout.tsx` files, replace the imports of components:',\n ...maps.map(([from, to]) => picocolors.greenBright(`\"${from}\" -> \"${to}\"`)),\n ].join('\\n'),\n );\n}\n","#!/usr/bin/env node\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport picocolors from 'picocolors';\nimport { createOrLoadConfig, initConfig, type LoadedConfig } from '@/config';\nimport { type JsonTreeNode, treeToJavaScript, treeToMdx } from '@/commands/file-tree';\nimport { runTree } from '@/utils/file-tree/run-tree';\nimport packageJson from '../package.json';\nimport { customise } from '@/commands/customise';\nimport { add } from '@/commands/add';\nimport { HttpRegistryClient, LocalRegistryClient } from '@/registry/client';\n\nconst program = new Command().option('--config <string>');\n\nprogram\n .name('hanzo-docs')\n .description('CLI to setup Hanzo Docs, init a config')\n .version(packageJson.version)\n .action(async () => {\n if (await initConfig()) {\n console.log(picocolors.green('Initialized a `./cli.json` config file.'));\n } else {\n console.log(picocolors.redBright('A config file already exists.'));\n }\n });\n\nprogram\n .command('customise')\n .alias('customize')\n .description('simple way to customise layouts with Hanzo Docs UI')\n .option('--dir <string>', 'the root url or directory to resolve registry')\n .action(async (options: { config?: string; dir?: string }) => {\n await customise(createClientFromDir(options.dir, await createOrLoadConfig(options.config)));\n });\n\nconst dirShortcuts: Record<string, string> = {\n ':preview': 'https://preview.fumadocs.dev/registry',\n ':dev': 'http://localhost:3000/registry',\n};\n\nprogram\n .command('add')\n .description('add a new component to your docs')\n .argument('[components...]', 'components to download')\n .option('--dir <string>', 'the root url or directory to resolve registry')\n .action(async (input: string[], options: { config?: string; dir?: string }) => {\n const client = createClientFromDir(options.dir, await createOrLoadConfig(options.config));\n await add(input, client);\n });\n\nprogram\n .command('tree')\n .argument('[json_or_args]', 'JSON output of `tree` command or arguments for the `tree` command')\n .argument('[output]', 'output path of file')\n .option('--js', 'output as JavaScript file')\n .option('--no-root', 'remove the root node')\n .option('--import-name <name>', 'where to import components (JS only)')\n .action(\n async (\n str: string | undefined,\n output: string | undefined,\n { js, root, importName }: { js: boolean; root: boolean; importName?: string },\n ) => {\n const jsExtensions = ['.js', '.tsx', '.jsx'];\n const noRoot = !root;\n let nodes: JsonTreeNode[];\n\n try {\n nodes = JSON.parse(str ?? '') as JsonTreeNode[];\n } catch {\n nodes = await runTree(str ?? './');\n }\n\n const out =\n js || (output && jsExtensions.includes(path.extname(output)))\n ? treeToJavaScript(nodes, noRoot, importName)\n : treeToMdx(nodes, noRoot);\n\n if (output) {\n await fs.mkdir(path.dirname(output), { recursive: true });\n await fs.writeFile(output, out);\n } else {\n console.log(out);\n }\n },\n );\n\nfunction createClientFromDir(dir = 'https://fumadocs.dev/registry', config: LoadedConfig) {\n if (dir in dirShortcuts) dir = dirShortcuts[dir];\n\n return dir.startsWith('http://') || dir.startsWith('https://')\n ? new HttpRegistryClient(dir, config)\n : new LocalRegistryClient(dir, config);\n}\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["isSrc","baseUrl: string","config: LoadedConfig","dir: string","rootClient: RegistryClient","plugins: ComponentInstallerPlugin[]","downloaded: DownloadedComponent[]","result: DownloadedComponent[]","file","target: string[]","options: {\n label: string;\n value: string;\n hint?: string;\n }[]","packageJson.version","dirShortcuts: Record<string, string>","nodes: JsonTreeNode[]"],"sources":["../src/utils/fs.ts","../src/utils/is-src.ts","../src/config.ts","../src/commands/file-tree.ts","../src/utils/file-tree/run-tree.ts","../package.json","../src/utils/typescript.ts","../src/constants.ts","../src/utils/ast.ts","../src/registry/schema.ts","../src/utils/cache.ts","../src/registry/client.ts","../src/utils/get-package-manager.ts","../src/registry/installer/dep-manager.ts","../src/registry/installer/index.ts","../src/commands/shared.ts","../src/commands/add.ts","../src/commands/customise.ts","../src/index.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","import { exists } from '@/utils/fs';\n\nexport async function isSrc(): Promise<boolean> {\n return exists('./src');\n}\n","import fs from 'node:fs/promises';\nimport { isSrc } from '@/utils/is-src';\nimport { z } from 'zod';\n\nexport function createConfigSchema(isSrc: boolean) {\n const defaultAliases = {\n uiDir: './components/ui',\n componentsDir: './components',\n blockDir: './components',\n cssDir: './styles',\n libDir: './lib',\n };\n\n return z.object({\n $schema: z\n .string()\n .default(\n isSrc\n ? 'node_modules/@hanzo/docs-cli/dist/schema/src.json'\n : 'node_modules/@hanzo/docs-cli/dist/schema/default.json',\n )\n .optional(),\n aliases: z\n .object({\n uiDir: z.string().default(defaultAliases.uiDir),\n componentsDir: z.string().default(defaultAliases.uiDir),\n blockDir: z.string().default(defaultAliases.blockDir),\n cssDir: z.string().default(defaultAliases.componentsDir),\n libDir: z.string().default(defaultAliases.libDir),\n })\n .default(defaultAliases),\n\n baseDir: z.string().default(isSrc ? 'src' : ''),\n uiLibrary: z.enum(['radix-ui', 'base-ui']).default('radix-ui'),\n\n commands: z\n .object({\n /**\n * command to format output code automatically\n */\n format: z.string().optional(),\n })\n .default({}),\n });\n}\n\ntype ConfigSchema = ReturnType<typeof createConfigSchema>;\n\nexport type ConfigInput = z.input<ConfigSchema>;\nexport type LoadedConfig = z.output<ConfigSchema>;\n\nexport async function createOrLoadConfig(file = './cli.json'): Promise<LoadedConfig> {\n const inited = await initConfig(file);\n if (inited) return inited;\n\n const content = (await fs.readFile(file)).toString();\n const src = await isSrc();\n const configSchema = createConfigSchema(src);\n\n return configSchema.parse(JSON.parse(content));\n}\n\n/**\n * Write new config, skip if a config already exists\n *\n * @returns the created config, `undefined` if not created\n */\nexport async function initConfig(\n file = './cli.json',\n src?: boolean,\n): Promise<LoadedConfig | undefined> {\n if (\n await fs\n .stat(file)\n .then(() => true)\n .catch(() => false)\n ) {\n return;\n }\n\n const defaultConfig = createConfigSchema(src ?? (await isSrc())).parse({} satisfies ConfigInput);\n await fs.writeFile(file, JSON.stringify(defaultConfig, null, 2));\n return defaultConfig;\n}\n","export type JsonTreeNode =\n | {\n type: 'file';\n name: string;\n }\n | {\n type: 'directory';\n name: string;\n contents: JsonTreeNode[];\n }\n | {\n type: 'report';\n }\n | {\n type: 'link';\n name: string;\n };\n\nconst scanned = ['file', 'directory', 'link'];\n\nexport function treeToMdx(input: JsonTreeNode[], noRoot = false): string {\n function toNode(item: JsonTreeNode): string {\n if (item.type === 'file' || item.type === 'link') {\n return `<File name=${JSON.stringify(item.name)} />`;\n }\n\n if (item.type === 'directory') {\n if (item.contents.length === 1 && 'name' in item.contents[0]) {\n const child = item.contents[0];\n\n return toNode({\n ...child,\n name: `${item.name}/${child.name}`,\n });\n }\n\n return `<Folder name=${JSON.stringify(item.name)}>\n${item.contents.map(toNode).filter(Boolean).join('\\n')}\n</Folder>`;\n }\n\n return '';\n }\n\n let children = input.filter((v) => scanned.includes(v.type));\n\n if (noRoot && children.length === 1 && input[0].type === 'directory') {\n children = input[0].contents;\n }\n\n return `<Files>\n${children.map(toNode).filter(Boolean).join('\\n')}\n</Files>`;\n}\n\nexport function treeToJavaScript(\n input: JsonTreeNode[],\n noRoot?: boolean,\n importName = '@hanzo/docs-ui/components/files',\n): string {\n return `import { File, Files, Folder } from ${JSON.stringify(importName)}\n\nexport default (${treeToMdx(input, noRoot)})`;\n}\n","import { x } from 'tinyexec';\nimport type { JsonTreeNode } from '@/commands/file-tree';\n\nexport async function runTree(args: string): Promise<JsonTreeNode[]> {\n const out = await x('tree', [args, '--gitignore', '--prune', '-J']);\n\n try {\n return JSON.parse(out.stdout) as JsonTreeNode[];\n } catch (e) {\n throw new Error('failed to run `tree` command', {\n cause: e,\n });\n }\n}\n","","import { Project } from 'ts-morph';\n\nexport function createEmptyProject(): Project {\n return new Project({\n compilerOptions: {},\n });\n}\n","export const typescriptExtensions = ['.ts', '.tsx', '.js', '.jsx'];\n","import path from 'node:path';\nimport { typescriptExtensions } from '@/constants';\n\n/**\n * Return the import modifier for `sourceFile` to import `referenceFile`\n *\n * @example\n * ```ts\n * toReferencePath('index.ts', 'dir/hello.ts')\n * // should output './dir/hello'\n * ```\n */\nexport function toImportSpecifier(sourceFile: string, referenceFile: string): string {\n const extname = path.extname(referenceFile);\n const removeExt = typescriptExtensions.includes(extname);\n\n let importPath = path\n .relative(\n path.dirname(sourceFile),\n removeExt ? referenceFile.substring(0, referenceFile.length - extname.length) : referenceFile,\n )\n .replaceAll(path.sep, '/');\n\n if (removeExt && importPath.endsWith('/index')) {\n importPath = importPath.slice(0, -'/index'.length);\n }\n\n return importPath.startsWith('../') ? importPath : `./${importPath}`;\n}\n","import { z } from 'zod';\n\nexport type NamespaceType = (typeof namespaces)[number];\nexport type CompiledFile = z.input<typeof fileSchema>;\nexport type CompiledComponent = z.input<typeof componentSchema>;\nexport type CompiledRegistryInfo = z.input<typeof registryInfoSchema>;\nexport type DownloadedRegistryInfo = z.output<typeof registryInfoSchema>;\nexport type File = z.output<typeof fileSchema>;\nexport type Component = z.output<typeof componentSchema>;\n\nexport const namespaces = ['components', 'lib', 'css', 'route', 'ui', 'block'] as const;\n\nexport const indexSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport const fileSchema = z.object({\n type: z.literal(namespaces),\n path: z.string(),\n target: z.string().optional(),\n content: z.string(),\n});\n\nexport const httpSubComponent = z.object({\n type: z.literal('http'),\n baseUrl: z.string(),\n component: z.string(),\n});\n\nexport const componentSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n files: z.array(fileSchema),\n dependencies: z.record(z.string(), z.string().or(z.null())),\n devDependencies: z.record(z.string(), z.string().or(z.null())),\n /**\n * list of sub components, either local (component name) or remote (registry info & component name)\n */\n subComponents: z.array(z.string().or(httpSubComponent)).default([]),\n});\n\nexport const registryInfoSchema = z.object({\n /**\n * define used variables, variables can be referenced in the import specifiers of component files.\n */\n variables: z\n .record(\n z.string(),\n z.object({\n description: z.string().optional(),\n default: z.unknown().optional(),\n }),\n )\n .optional(),\n /**\n * provide variables to sub components\n */\n env: z.record(z.string(), z.unknown()).optional(),\n indexes: z.array(indexSchema).default([]),\n\n registries: z.array(z.string()).optional(),\n});\n","export class AsyncCache<V> {\n readonly store = new Map<string, V | Promise<V>>();\n\n cached<V1 extends V = V>(key: string, fn: () => V1 | Promise<V1>): V1 | Promise<V1> {\n let cached = this.store.get(key);\n if (cached !== undefined) return cached as V1;\n\n cached = fn();\n this.store.set(key, cached);\n return cached as V1;\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 { log } from '@clack/prompts';\nimport { AsyncCache } 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 = new AsyncCache<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.cached<DownloadedRegistryInfo>(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.cached<Component>(url.href, async () => {\n const res = await fetch(`${this.baseUrl}/${name}.json`);\n if (!res.ok) {\n log.error(`component ${name} not found at ${url.href}`);\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 log.error(`component ${name} not found at ${filePath}`);\n throw 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","import { detect, type AgentName } from 'package-manager-detector';\n\nexport type PackageManager = AgentName;\n\nexport async function getPackageManager(): Promise<PackageManager> {\n const result = await detect();\n\n return result?.name ?? 'npm';\n}\n","import { exists } from '@/utils/fs';\nimport fs from 'node:fs/promises';\nimport { getPackageManager } from '@/utils/get-package-manager';\nimport { confirm, isCancel, spinner } from '@clack/prompts';\nimport { x } from 'tinyexec';\n\nexport class DependencyManager {\n private cachedInstalledDeps: Map<string, string> | undefined;\n\n /**\n * Get dependencies from `package.json`\n */\n async getDeps(): Promise<Map<string, string>> {\n if (this.cachedInstalledDeps) return this.cachedInstalledDeps;\n const dependencies = new Map<string, string>();\n\n if (!(await exists('package.json'))) return dependencies;\n\n const content = await fs.readFile('package.json');\n const parsed = JSON.parse(content.toString()) as object;\n\n if ('dependencies' in parsed && typeof parsed.dependencies === 'object') {\n const records = parsed.dependencies as Record<string, string>;\n\n for (const [k, v] of Object.entries(records)) {\n dependencies.set(k, v);\n }\n }\n\n if ('devDependencies' in parsed && typeof parsed.devDependencies === 'object') {\n const records = parsed.devDependencies as Record<string, string>;\n\n for (const [k, v] of Object.entries(records)) {\n dependencies.set(k, v);\n }\n }\n\n return (this.cachedInstalledDeps = dependencies);\n }\n\n private async resolveInstallDependencies(deps: Record<string, string | null>): Promise<string[]> {\n const cachedInstalledDeps = await this.getDeps();\n\n return Object.entries(deps)\n .filter(([k]) => !cachedInstalledDeps.has(k))\n .map(([k, v]) => (v === null || v.length === 0 ? k : `${k}@${v}`));\n }\n\n async installDeps(deps: Record<string, string | null>, devDeps: Record<string, string | null>) {\n const items = await this.resolveInstallDependencies(deps);\n const devItems = await this.resolveInstallDependencies(devDeps);\n if (items.length === 0 && devItems.length === 0) return;\n\n const manager = await getPackageManager();\n const value = await confirm({\n message: `Do you want to install with ${manager}?\n${[...items, ...devItems].map((v) => `- ${v}`).join('\\n')}`,\n });\n\n if (isCancel(value) || !value) {\n return;\n }\n\n const spin = spinner();\n spin.start('Installing dependencies...');\n if (items.length > 0) await x(manager, ['install', ...items]);\n if (devItems.length > 0) await x(manager, ['install', ...devItems, '-D']);\n spin.stop('Dependencies installed.');\n }\n}\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { confirm, isCancel, log, outro } from '@clack/prompts';\nimport { createEmptyProject } from '@/utils/typescript';\nimport { typescriptExtensions } from '@/constants';\nimport { toImportSpecifier } from '@/utils/ast';\nimport type { Component, File } from '@/registry/schema';\nimport { HttpRegistryClient, type RegistryClient } from '@/registry/client';\nimport { x } from 'tinyexec';\nimport { DependencyManager } from '@/registry/installer/dep-manager';\nimport { AsyncCache } from '@/utils/cache';\nimport type { SourceFile } from 'ts-morph';\n\ninterface DownloadedComponent extends Omit<Component, 'subComponents'> {\n variables?: Record<string, unknown>;\n}\n\nexport interface ComponentInstallerPlugin {\n transform?: (context: {\n file: SourceFile;\n componentFile: File;\n component: DownloadedComponent;\n }) => void | Promise<void>;\n}\n\nexport class ComponentInstaller {\n private readonly project = createEmptyProject();\n private readonly installedFiles = new Set<string>();\n private readonly downloadCache = new AsyncCache<DownloadedComponent[]>();\n readonly dependencies: Record<string, string | null> = {};\n readonly devDependencies: Record<string, string | null> = {};\n\n constructor(\n private readonly rootClient: RegistryClient,\n private readonly plugins: ComponentInstallerPlugin[] = [],\n ) {}\n\n async install(name: string) {\n let downloaded: DownloadedComponent[];\n // detect linked registry\n const info = await this.rootClient.fetchRegistryInfo();\n\n for (const registry of info.registries ?? []) {\n if (name.startsWith(`${registry}/`)) {\n downloaded = await this.download(\n name.slice(registry.length + 1),\n this.rootClient.createLinkedRegistryClient(registry),\n );\n break;\n }\n }\n\n downloaded ??= await this.download(name, this.rootClient);\n\n for (const item of downloaded) {\n Object.assign(this.dependencies, item.dependencies);\n Object.assign(this.devDependencies, item.devDependencies);\n }\n\n for (const comp of downloaded) {\n for (const file of comp.files) {\n const outPath = this.resolveOutputPath(file);\n if (this.installedFiles.has(outPath)) continue;\n this.installedFiles.add(outPath);\n\n const output = typescriptExtensions.includes(path.extname(outPath))\n ? await this.transform(name, file, comp, downloaded)\n : file.content;\n\n const status = await fs\n .readFile(outPath)\n .then((res) => {\n if (res.toString() === output) return 'ignore';\n return 'need-update';\n })\n .catch(() => 'write');\n\n if (status === 'ignore') continue;\n\n if (status === 'need-update') {\n const override = await confirm({\n message: `Do you want to override ${outPath}?`,\n initialValue: false,\n });\n\n if (isCancel(override)) {\n outro('Ended');\n process.exit(0);\n }\n\n if (!override) continue;\n }\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, output);\n log.step(`downloaded ${outPath}`);\n }\n }\n }\n\n async installDeps() {\n await new DependencyManager().installDeps(this.dependencies, this.devDependencies);\n }\n\n async onEnd() {\n const config = this.rootClient.config;\n if (config.commands.format) {\n await x(config.commands.format);\n }\n }\n\n /**\n * return a list of components, merged with child components & variables.\n */\n private async download(\n name: string,\n client: RegistryClient,\n contextVariables?: Record<string, unknown>,\n ): Promise<DownloadedComponent[]> {\n const hash = `${client.registryId} ${name}`;\n const info = await client.fetchRegistryInfo();\n const variables = { ...contextVariables, ...info.env };\n for (const [k, v] of Object.entries(info.variables ?? {})) {\n variables[k] ??= v.default;\n }\n\n const out = await this.downloadCache.cached(hash, async () => {\n const comp = await client.fetchComponent(name);\n const result: DownloadedComponent[] = [comp];\n // place it before downloading child components to avoid recursive downloads\n this.downloadCache.store.set(hash, result);\n\n const child = await Promise.all(\n comp.subComponents.map((sub) => {\n if (typeof sub === 'string') return this.download(sub, client);\n const baseUrl =\n this.rootClient instanceof HttpRegistryClient\n ? new URL(sub.baseUrl, `${this.rootClient.baseUrl}/`).href\n : sub.baseUrl;\n\n return this.download(\n sub.component,\n new HttpRegistryClient(baseUrl, client.config),\n variables,\n );\n }),\n );\n for (const sub of child) result.push(...sub);\n return result;\n });\n\n return out.map((file) => ({ ...file, variables }));\n }\n\n private readonly pathToFileCache = new AsyncCache<Map<string, File>>();\n private async transform(\n taskId: string,\n file: File,\n component: DownloadedComponent,\n allComponents: DownloadedComponent[],\n ): Promise<string> {\n const filePath = this.resolveOutputPath(file);\n const sourceFile = this.project.createSourceFile(filePath, file.content, {\n overwrite: true,\n });\n\n // transform alias\n const prefix = '@/';\n const variables = Object.entries(component.variables ?? {});\n const pathToFile = await this.pathToFileCache.cached(taskId, () => {\n const map = new Map<string, File>();\n for (const comp of allComponents) {\n for (const file of comp.files) map.set(file.target ?? file.path, file);\n }\n return map;\n });\n for (const specifier of sourceFile.getImportStringLiterals()) {\n for (const [k, v] of variables) {\n specifier.setLiteralValue(specifier.getLiteralValue().replaceAll(`<${k}>`, v as string));\n }\n\n if (specifier.getLiteralValue().startsWith(prefix)) {\n const lookup = specifier.getLiteralValue().substring(prefix.length);\n const target = pathToFile.get(lookup);\n\n if (target) {\n specifier.setLiteralValue(toImportSpecifier(filePath, this.resolveOutputPath(target)));\n } else {\n console.warn(`cannot find the referenced file of ${specifier}`);\n }\n }\n }\n\n for (const plugin of this.plugins) {\n await plugin.transform?.({\n file: sourceFile,\n componentFile: file,\n component,\n });\n }\n\n return sourceFile.getFullText();\n }\n\n private resolveOutputPath(file: File): string {\n const config = this.rootClient.config;\n const dir = (\n {\n components: config.aliases.componentsDir,\n block: config.aliases.blockDir,\n ui: config.aliases.uiDir,\n css: config.aliases.cssDir,\n lib: config.aliases.libDir,\n route: './',\n } as const\n )[file.type];\n if (file.target) {\n return path.join(config.baseDir, file.target.replace('<dir>', dir));\n }\n\n return path.join(config.baseDir, dir, path.basename(file.path));\n }\n}\n","export const UIRegistries = {\n 'base-ui': 'hanzo-docs/base-ui',\n 'radix-ui': 'hanzo-docs/radix-ui',\n};\n","import { intro, isCancel, log, multiselect, outro, spinner } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { ComponentInstaller } from '@/registry/installer';\nimport type { RegistryClient } from '@/registry/client';\nimport { UIRegistries } from '@/commands/shared';\n\nexport async function add(input: string[], client: RegistryClient) {\n const config = client.config;\n let target: string[];\n const installer = new ComponentInstaller(client);\n const registry = UIRegistries[config.uiLibrary];\n\n if (input.length === 0) {\n const spin = spinner();\n spin.start('fetching registry');\n const info = await client.fetchRegistryInfo();\n const options: {\n label: string;\n value: string;\n hint?: string;\n }[] = [];\n\n for (const item of info.indexes) {\n options.push({\n label: item.title ?? item.name,\n value: item.name,\n hint: item.description,\n });\n }\n const { indexes } = await client.createLinkedRegistryClient(registry).fetchRegistryInfo();\n\n for (const item of indexes) {\n options.push({\n label: item.title ?? item.name,\n value: `${registry}/${item.name}`,\n hint: item.description,\n });\n }\n\n spin.stop(picocolors.bold(picocolors.greenBright('registry fetched')));\n const value = await multiselect({\n message: 'Select components to install',\n options,\n });\n\n if (isCancel(value)) {\n outro('Ended');\n return;\n }\n\n target = value;\n } else {\n target = await Promise.all(\n input.map(async (item) => ((await client.hasComponent(item)) ? item : `${registry}/${item}`)),\n );\n }\n\n await install(target, installer);\n}\n\nexport async function install(target: string[], installer: ComponentInstaller) {\n for (const name of target) {\n intro(picocolors.bold(picocolors.inverse(picocolors.cyanBright(`Add Component: ${name}`))));\n\n try {\n await installer.install(name);\n outro(picocolors.bold(picocolors.greenBright(`${name} installed`)));\n } catch (e) {\n log.error(String(e));\n throw e;\n }\n }\n\n intro(picocolors.bold('New Dependencies'));\n\n await installer.installDeps();\n await installer.onEnd();\n\n outro(picocolors.bold(picocolors.greenBright('Successful')));\n}\n","import { cancel, group, intro, log, outro, select } from '@clack/prompts';\nimport picocolors from 'picocolors';\nimport { install } from '@/commands/add';\nimport type { RegistryClient } from '@/registry/client';\nimport { ComponentInstaller } from '@/registry/installer';\nimport { UIRegistries } from '@/commands/shared';\n\nexport async function customise(client: RegistryClient) {\n intro(picocolors.bgBlack(picocolors.whiteBright('Customise Hanzo Docs UI')));\n const config = client.config;\n const installer = new ComponentInstaller(client);\n\n const result = await group(\n {\n target: () =>\n select({\n message: 'What do you want to customise?',\n options: [\n {\n label: 'Docs Layout',\n value: 'docs',\n hint: 'main UI of your docs',\n },\n {\n label: 'Home Layout',\n value: 'home',\n hint: 'the navbar for your other pages',\n },\n ],\n }),\n mode: (v) => {\n if (v.results.target !== 'docs') return;\n\n return select({\n message: 'Which variant do you want to start from?',\n options: [\n {\n label: 'Start from minimal styles',\n value: 'minimal',\n hint: 'for those who want to build their own variant from ground up.',\n },\n {\n label: 'Start from default layout',\n value: 'full-default',\n hint: 'useful for adjusting small details.',\n },\n {\n label: 'Start from Notebook layout',\n value: 'full-notebook',\n hint: 'useful for adjusting small details.',\n },\n ],\n });\n },\n },\n {\n onCancel: () => {\n cancel('Installation Stopped.');\n process.exit(0);\n },\n },\n );\n\n const registry = UIRegistries[config.uiLibrary];\n if (result.target === 'docs') {\n const targets = [];\n if (result.mode === 'minimal') {\n targets.push('hanzo-docs/ui/layouts/docs-min');\n } else {\n targets.push(\n result.mode === 'full-default'\n ? `${registry}/layouts/docs`\n : `${registry}/layouts/notebook`,\n );\n }\n\n await install(targets, installer);\n const maps: [string, string][] =\n result.mode === 'full-notebook'\n ? [\n ['@hanzo/docs-ui/layouts/notebook', '@/components/layout/notebook'],\n ['@hanzo/docs-ui/layouts/notebook/page', '@/components/layout/notebook/page'],\n ]\n : [\n ['@hanzo/docs-ui/layouts/docs', '@/components/layout/docs'],\n ['@hanzo/docs-ui/layouts/docs/page', '@/components/layout/docs/page'],\n ];\n\n printNext(...maps);\n }\n\n if (result.target === 'home') {\n await install([`${registry}/layouts/home`], installer);\n printNext(['@hanzo/docs-ui/layouts/home', `@/components/layout/home`]);\n }\n\n outro(picocolors.bold('Have fun!'));\n}\n\nfunction printNext(...maps: [from: string, to: string][]) {\n intro(picocolors.bold('What is Next?'));\n\n log.info(\n [\n 'You can check the installed components in `components`.',\n picocolors.dim('---'),\n 'Open your `layout.tsx` files, replace the imports of components:',\n ...maps.map(([from, to]) => picocolors.greenBright(`\"${from}\" -> \"${to}\"`)),\n ].join('\\n'),\n );\n}\n","#!/usr/bin/env node\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport picocolors from 'picocolors';\nimport { createOrLoadConfig, initConfig, type LoadedConfig } from '@/config';\nimport { type JsonTreeNode, treeToJavaScript, treeToMdx } from '@/commands/file-tree';\nimport { runTree } from '@/utils/file-tree/run-tree';\nimport packageJson from '../package.json';\nimport { customise } from '@/commands/customise';\nimport { add } from '@/commands/add';\nimport { HttpRegistryClient, LocalRegistryClient } from '@/registry/client';\n\nconst program = new Command().option('--config <string>');\n\nprogram\n .name('hanzo-docs')\n .description('CLI to setup Hanzo Docs, init a config')\n .version(packageJson.version)\n .action(async () => {\n if (await initConfig()) {\n console.log(picocolors.green('Initialized a `./cli.json` config file.'));\n } else {\n console.log(picocolors.redBright('A config file already exists.'));\n }\n });\n\nprogram\n .command('customise')\n .alias('customize')\n .description('simple way to customise layouts with Hanzo Docs UI')\n .option('--dir <string>', 'the root url or directory to resolve registry')\n .action(async (options: { config?: string; dir?: string }) => {\n await customise(createClientFromDir(options.dir, await createOrLoadConfig(options.config)));\n });\n\nconst dirShortcuts: Record<string, string> = {\n ':preview': 'https://preview.hanzo.ai/docs/registry',\n ':dev': 'http://localhost:3000/registry',\n};\n\nprogram\n .command('add')\n .description('add a new component to your docs')\n .argument('[components...]', 'components to download')\n .option('--dir <string>', 'the root url or directory to resolve registry')\n .action(async (input: string[], options: { config?: string; dir?: string }) => {\n const client = createClientFromDir(options.dir, await createOrLoadConfig(options.config));\n await add(input, client);\n });\n\nprogram\n .command('tree')\n .argument('[json_or_args]', 'JSON output of `tree` command or arguments for the `tree` command')\n .argument('[output]', 'output path of file')\n .option('--js', 'output as JavaScript file')\n .option('--no-root', 'remove the root node')\n .option('--import-name <name>', 'where to import components (JS only)')\n .action(\n async (\n str: string | undefined,\n output: string | undefined,\n { js, root, importName }: { js: boolean; root: boolean; importName?: string },\n ) => {\n const jsExtensions = ['.js', '.tsx', '.jsx'];\n const noRoot = !root;\n let nodes: JsonTreeNode[];\n\n try {\n nodes = JSON.parse(str ?? '') as JsonTreeNode[];\n } catch {\n nodes = await runTree(str ?? './');\n }\n\n const out =\n js || (output && jsExtensions.includes(path.extname(output)))\n ? treeToJavaScript(nodes, noRoot, importName)\n : treeToMdx(nodes, noRoot);\n\n if (output) {\n await fs.mkdir(path.dirname(output), { recursive: true });\n await fs.writeFile(output, out);\n } else {\n console.log(out);\n }\n },\n );\n\nfunction createClientFromDir(dir = 'https://hanzo.ai/docs/registry', config: LoadedConfig) {\n if (dir in dirShortcuts) dir = dirShortcuts[dir];\n\n return dir.startsWith('http://') || dir.startsWith('https://')\n ? new HttpRegistryClient(dir, config)\n : new LocalRegistryClient(dir, config);\n}\n\nprogram.parse();\n"],"mappings":";;;;;;;;;;;;AAGA,eAAsB,OAAO,UAAoC;AAC/D,KAAI;AACF,QAAM,GAAG,OAAO,SAAS;AACzB,SAAO;SACD;AACN,SAAO;;;;;;ACNX,eAAsB,QAA0B;AAC9C,QAAO,OAAO,QAAQ;;;;;ACCxB,SAAgB,mBAAmB,SAAgB;CACjD,MAAM,iBAAiB;EACrB,OAAO;EACP,eAAe;EACf,UAAU;EACV,QAAQ;EACR,QAAQ;EACT;AAED,QAAO,EAAE,OAAO;EACd,SAAS,EACN,QAAQ,CACR,QACCA,UACI,sDACA,wDACL,CACA,UAAU;EACb,SAAS,EACN,OAAO;GACN,OAAO,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GAC/C,eAAe,EAAE,QAAQ,CAAC,QAAQ,eAAe,MAAM;GACvD,UAAU,EAAE,QAAQ,CAAC,QAAQ,eAAe,SAAS;GACrD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,cAAc;GACxD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,eAAe,OAAO;GAClD,CAAC,CACD,QAAQ,eAAe;EAE1B,SAAS,EAAE,QAAQ,CAAC,QAAQA,UAAQ,QAAQ,GAAG;EAC/C,WAAW,EAAE,KAAK,CAAC,YAAY,UAAU,CAAC,CAAC,QAAQ,WAAW;EAE9D,UAAU,EACP,OAAO,EAIN,QAAQ,EAAE,QAAQ,CAAC,UAAU,EAC9B,CAAC,CACD,QAAQ,EAAE,CAAC;EACf,CAAC;;AAQJ,eAAsB,mBAAmB,OAAO,cAAqC;CACnF,MAAM,SAAS,MAAM,WAAW,KAAK;AACrC,KAAI,OAAQ,QAAO;CAEnB,MAAM,WAAW,MAAM,GAAG,SAAS,KAAK,EAAE,UAAU;AAIpD,QAFqB,mBADT,MAAM,OAAO,CACmB,CAExB,MAAM,KAAK,MAAM,QAAQ,CAAC;;;;;;;AAQhD,eAAsB,WACpB,OAAO,cACP,KACmC;AACnC,KACE,MAAM,GACH,KAAK,KAAK,CACV,WAAW,KAAK,CAChB,YAAY,MAAM,CAErB;CAGF,MAAM,gBAAgB,mBAAmB,OAAQ,MAAM,OAAO,CAAE,CAAC,MAAM,EAAE,CAAuB;AAChG,OAAM,GAAG,UAAU,MAAM,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAChE,QAAO;;;;;AChET,MAAM,UAAU;CAAC;CAAQ;CAAa;CAAO;AAE7C,SAAgB,UAAU,OAAuB,SAAS,OAAe;CACvE,SAAS,OAAO,MAA4B;AAC1C,MAAI,KAAK,SAAS,UAAU,KAAK,SAAS,OACxC,QAAO,cAAc,KAAK,UAAU,KAAK,KAAK,CAAC;AAGjD,MAAI,KAAK,SAAS,aAAa;AAC7B,OAAI,KAAK,SAAS,WAAW,KAAK,UAAU,KAAK,SAAS,IAAI;IAC5D,MAAM,QAAQ,KAAK,SAAS;AAE5B,WAAO,OAAO;KACZ,GAAG;KACH,MAAM,GAAG,KAAK,KAAK,GAAG,MAAM;KAC7B,CAAC;;AAGJ,UAAO,gBAAgB,KAAK,UAAU,KAAK,KAAK,CAAC;EACrD,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK,CAAC;;;AAInD,SAAO;;CAGT,IAAI,WAAW,MAAM,QAAQ,MAAM,QAAQ,SAAS,EAAE,KAAK,CAAC;AAE5D,KAAI,UAAU,SAAS,WAAW,KAAK,MAAM,GAAG,SAAS,YACvD,YAAW,MAAM,GAAG;AAGtB,QAAO;EACP,SAAS,IAAI,OAAO,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK,CAAC;;;AAIlD,SAAgB,iBACd,OACA,QACA,aAAa,mCACL;AACR,QAAO,uCAAuC,KAAK,UAAU,WAAW,CAAC;;kBAEzD,UAAU,OAAO,OAAO,CAAC;;;;;AC3D3C,eAAsB,QAAQ,MAAuC;CACnE,MAAM,MAAM,MAAM,EAAE,QAAQ;EAAC;EAAM;EAAe;EAAW;EAAK,CAAC;AAEnE,KAAI;AACF,SAAO,KAAK,MAAM,IAAI,OAAO;UACtB,GAAG;AACV,QAAM,IAAI,MAAM,gCAAgC,EAC9C,OAAO,GACR,CAAC;;;;;;;;;;AETN,SAAgB,qBAA8B;AAC5C,QAAO,IAAI,QAAQ,EACjB,iBAAiB,EAAE,EACpB,CAAC;;;;;ACLJ,MAAa,uBAAuB;CAAC;CAAO;CAAQ;CAAO;CAAO;;;;;;;;;;;;;ACYlE,SAAgB,kBAAkB,YAAoB,eAA+B;CACnF,MAAM,UAAU,KAAK,QAAQ,cAAc;CAC3C,MAAM,YAAY,qBAAqB,SAAS,QAAQ;CAExD,IAAI,aAAa,KACd,SACC,KAAK,QAAQ,WAAW,EACxB,YAAY,cAAc,UAAU,GAAG,cAAc,SAAS,QAAQ,OAAO,GAAG,cACjF,CACA,WAAW,KAAK,KAAK,IAAI;AAE5B,KAAI,aAAa,WAAW,SAAS,SAAS,CAC5C,cAAa,WAAW,MAAM,GAAG,GAAiB;AAGpD,QAAO,WAAW,WAAW,MAAM,GAAG,aAAa,KAAK;;;;;ACjB1D,MAAa,aAAa;CAAC;CAAc;CAAO;CAAO;CAAS;CAAM;CAAQ;AAE9E,MAAa,cAAc,EAAE,OAAO;CAClC,MAAM,EAAE,QAAQ;CAChB,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,aAAa,EAAE,QAAQ,CAAC,UAAU;CACnC,CAAC;AAEF,MAAa,aAAa,EAAE,OAAO;CACjC,MAAM,EAAE,QAAQ,WAAW;CAC3B,MAAM,EAAE,QAAQ;CAChB,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,SAAS,EAAE,QAAQ;CACpB,CAAC;AAEF,MAAa,mBAAmB,EAAE,OAAO;CACvC,MAAM,EAAE,QAAQ,OAAO;CACvB,SAAS,EAAE,QAAQ;CACnB,WAAW,EAAE,QAAQ;CACtB,CAAC;AAEF,MAAa,kBAAkB,EAAE,OAAO;CACtC,MAAM,EAAE,QAAQ;CAChB,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,aAAa,EAAE,QAAQ,CAAC,UAAU;CAClC,OAAO,EAAE,MAAM,WAAW;CAC1B,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;CAC3D,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;CAI9D,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;CACpE,CAAC;AAEF,MAAa,qBAAqB,EAAE,OAAO;CAIzC,WAAW,EACR,OACC,EAAE,QAAQ,EACV,EAAE,OAAO;EACP,aAAa,EAAE,QAAQ,CAAC,UAAU;EAClC,SAAS,EAAE,SAAS,CAAC,UAAU;EAChC,CAAC,CACH,CACA,UAAU;CAIb,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACjD,SAAS,EAAE,MAAM,YAAY,CAAC,QAAQ,EAAE,CAAC;CAEzC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAC3C,CAAC;;;;AChEF,IAAa,aAAb,MAA2B;;+BACR,IAAI,KAA6B;;CAElD,OAAyB,KAAa,IAA8C;EAClF,IAAI,SAAS,KAAK,MAAM,IAAI,IAAI;AAChC,MAAI,WAAW,OAAW,QAAO;AAEjC,WAAS,IAAI;AACb,OAAK,MAAM,IAAI,KAAK,OAAO;AAC3B,SAAO;;;;;;ACYX,MAAM,aAAa,IAAI,YAAqB;AAE5C,IAAa,qBAAb,MAAa,mBAA6C;CAGxD,YACE,AAASC,SACT,AAASC,QACT;EAFS;EACA;AAET,OAAK,aAAa;;CAGpB,MAAM,kBAAkB,UAAU,KAAK,SAAS;EAC9C,MAAM,MAAM,IAAI,IAAI,kBAAkB,GAAG,QAAQ,GAAG;AAEpD,SAAO,WAAW,OAA+B,IAAI,MAAM,YAAY;GACrE,MAAM,MAAM,MAAM,MAAM,IAAI;AAC5B,OAAI,CAAC,IAAI,GACP,OAAM,IAAI,MAAM,mBAAmB,IAAI,KAAK,IAAI,IAAI,aAAa;AAGnE,UAAO,mBAAmB,MAAM,MAAM,IAAI,MAAM,CAAC;IACjD;;CAGJ,MAAM,eAAe,MAAc;EACjC,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,KAAK,QAAQ,GAAG;AAEvD,SAAO,WAAW,OAAkB,IAAI,MAAM,YAAY;GACxD,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO;AACvD,OAAI,CAAC,IAAI,IAAI;AACX,QAAI,MAAM,aAAa,KAAK,gBAAgB,IAAI,OAAO;AACvD,UAAM,IAAI,MAAM,MAAM,IAAI,MAAM,CAAC;;AAGnC,UAAO,gBAAgB,MAAM,MAAM,IAAI,MAAM,CAAC;IAC9C;;CAGJ,MAAM,aAAa,MAAc;EAC/B,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,KAAK,QAAQ,GAAG;AAEvD,UADY,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,CAAC,EACrC;;CAGb,2BAA2B,MAAc;AACvC,SAAO,IAAI,mBAAmB,GAAG,KAAK,QAAQ,GAAG,QAAQ,KAAK,OAAO;;;AAIzE,IAAa,sBAAb,MAAa,oBAA8C;CAIzD,YACE,AAAiBC,KACjB,AAASD,QACT;EAFiB;EACR;AAET,OAAK,aAAa;;CAGpB,MAAM,kBAAkB,MAAM,KAAK,KAAK;AACtC,MAAI,KAAK,aAAc,QAAO,KAAK;EAEnC,MAAM,WAAW,KAAK,KAAK,KAAK,iBAAiB;EACjD,MAAM,MAAM,MAAM,GACf,SAAS,SAAS,CAClB,MAAM,QAAQ,KAAK,MAAM,IAAI,UAAU,CAAC,CAAC,CACzC,OAAO,MAAM;AACZ,SAAM,IAAI,MAAM,iCAAiC,SAAS,IAAI,EAC5D,OAAO,GACR,CAAC;IACF;AAEJ,SAAQ,KAAK,eAAe,mBAAmB,MAAM,IAAI;;CAG3D,MAAM,eAAe,MAAc;EACjC,MAAM,WAAW,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,OAAO;EACpD,MAAM,MAAM,MAAM,GACf,SAAS,SAAS,CAClB,MAAM,QAAQ,KAAK,MAAM,IAAI,UAAU,CAAC,CAAC,CACzC,OAAO,MAAM;AACZ,OAAI,MAAM,aAAa,KAAK,gBAAgB,WAAW;AACvD,SAAM;IACN;AAEJ,SAAO,gBAAgB,MAAM,IAAI;;CAGnC,MAAM,aAAa,MAAc;EAC/B,MAAM,WAAW,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,OAAO;AACpD,MAAI;AACF,SAAM,GAAG,KAAK,SAAS;AACvB,UAAO;UACD;AACN,UAAO;;;CAIX,2BAA2B,MAAc;AACvC,SAAO,IAAI,oBAAoB,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,KAAK,OAAO;;;;;;ACtH1E,eAAsB,oBAA6C;AAGjE,SAFe,MAAM,QAAQ,GAEd,QAAQ;;;;;ACDzB,IAAa,oBAAb,MAA+B;;;;CAM7B,MAAM,UAAwC;AAC5C,MAAI,KAAK,oBAAqB,QAAO,KAAK;EAC1C,MAAM,+BAAe,IAAI,KAAqB;AAE9C,MAAI,CAAE,MAAM,OAAO,eAAe,CAAG,QAAO;EAE5C,MAAM,UAAU,MAAM,GAAG,SAAS,eAAe;EACjD,MAAM,SAAS,KAAK,MAAM,QAAQ,UAAU,CAAC;AAE7C,MAAI,kBAAkB,UAAU,OAAO,OAAO,iBAAiB,UAAU;GACvE,MAAM,UAAU,OAAO;AAEvB,QAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAC1C,cAAa,IAAI,GAAG,EAAE;;AAI1B,MAAI,qBAAqB,UAAU,OAAO,OAAO,oBAAoB,UAAU;GAC7E,MAAM,UAAU,OAAO;AAEvB,QAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAC1C,cAAa,IAAI,GAAG,EAAE;;AAI1B,SAAQ,KAAK,sBAAsB;;CAGrC,MAAc,2BAA2B,MAAwD;EAC/F,MAAM,sBAAsB,MAAM,KAAK,SAAS;AAEhD,SAAO,OAAO,QAAQ,KAAK,CACxB,QAAQ,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAC5C,KAAK,CAAC,GAAG,OAAQ,MAAM,QAAQ,EAAE,WAAW,IAAI,IAAI,GAAG,EAAE,GAAG,IAAK;;CAGtE,MAAM,YAAY,MAAqC,SAAwC;EAC7F,MAAM,QAAQ,MAAM,KAAK,2BAA2B,KAAK;EACzD,MAAM,WAAW,MAAM,KAAK,2BAA2B,QAAQ;AAC/D,MAAI,MAAM,WAAW,KAAK,SAAS,WAAW,EAAG;EAEjD,MAAM,UAAU,MAAM,mBAAmB;EACzC,MAAM,QAAQ,MAAM,QAAQ,EAC1B,SAAS,+BAA+B,QAAQ;EACpD,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,IACpD,CAAC;AAEF,MAAI,SAAS,MAAM,IAAI,CAAC,MACtB;EAGF,MAAM,OAAO,SAAS;AACtB,OAAK,MAAM,6BAA6B;AACxC,MAAI,MAAM,SAAS,EAAG,OAAM,EAAE,SAAS,CAAC,WAAW,GAAG,MAAM,CAAC;AAC7D,MAAI,SAAS,SAAS,EAAG,OAAM,EAAE,SAAS;GAAC;GAAW,GAAG;GAAU;GAAK,CAAC;AACzE,OAAK,KAAK,0BAA0B;;;;;;AC1CxC,IAAa,qBAAb,MAAgC;CAO9B,YACE,AAAiBE,YACjB,AAAiBC,UAAsC,EAAE,EACzD;EAFiB;EACA;iBARQ,oBAAoB;wCACb,IAAI,KAAa;uBAClB,IAAI,YAAmC;sBACjB,EAAE;yBACC,EAAE;yBA4HzB,IAAI,YAA+B;;CArHtE,MAAM,QAAQ,MAAc;EAC1B,IAAIC;EAEJ,MAAM,OAAO,MAAM,KAAK,WAAW,mBAAmB;AAEtD,OAAK,MAAM,YAAY,KAAK,cAAc,EAAE,CAC1C,KAAI,KAAK,WAAW,GAAG,SAAS,GAAG,EAAE;AACnC,gBAAa,MAAM,KAAK,SACtB,KAAK,MAAM,SAAS,SAAS,EAAE,EAC/B,KAAK,WAAW,2BAA2B,SAAS,CACrD;AACD;;AAIJ,iBAAe,MAAM,KAAK,SAAS,MAAM,KAAK,WAAW;AAEzD,OAAK,MAAM,QAAQ,YAAY;AAC7B,UAAO,OAAO,KAAK,cAAc,KAAK,aAAa;AACnD,UAAO,OAAO,KAAK,iBAAiB,KAAK,gBAAgB;;AAG3D,OAAK,MAAM,QAAQ,WACjB,MAAK,MAAM,QAAQ,KAAK,OAAO;GAC7B,MAAM,UAAU,KAAK,kBAAkB,KAAK;AAC5C,OAAI,KAAK,eAAe,IAAI,QAAQ,CAAE;AACtC,QAAK,eAAe,IAAI,QAAQ;GAEhC,MAAM,SAAS,qBAAqB,SAAS,KAAK,QAAQ,QAAQ,CAAC,GAC/D,MAAM,KAAK,UAAU,MAAM,MAAM,MAAM,WAAW,GAClD,KAAK;GAET,MAAM,SAAS,MAAM,GAClB,SAAS,QAAQ,CACjB,MAAM,QAAQ;AACb,QAAI,IAAI,UAAU,KAAK,OAAQ,QAAO;AACtC,WAAO;KACP,CACD,YAAY,QAAQ;AAEvB,OAAI,WAAW,SAAU;AAEzB,OAAI,WAAW,eAAe;IAC5B,MAAM,WAAW,MAAM,QAAQ;KAC7B,SAAS,2BAA2B,QAAQ;KAC5C,cAAc;KACf,CAAC;AAEF,QAAI,SAAS,SAAS,EAAE;AACtB,WAAM,QAAQ;AACd,aAAQ,KAAK,EAAE;;AAGjB,QAAI,CAAC,SAAU;;AAGjB,SAAM,GAAG,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAC1D,SAAM,GAAG,UAAU,SAAS,OAAO;AACnC,OAAI,KAAK,cAAc,UAAU;;;CAKvC,MAAM,cAAc;AAClB,QAAM,IAAI,mBAAmB,CAAC,YAAY,KAAK,cAAc,KAAK,gBAAgB;;CAGpF,MAAM,QAAQ;EACZ,MAAM,SAAS,KAAK,WAAW;AAC/B,MAAI,OAAO,SAAS,OAClB,OAAM,EAAE,OAAO,SAAS,OAAO;;;;;CAOnC,MAAc,SACZ,MACA,QACA,kBACgC;EAChC,MAAM,OAAO,GAAG,OAAO,WAAW,GAAG;EACrC,MAAM,OAAO,MAAM,OAAO,mBAAmB;EAC7C,MAAM,YAAY;GAAE,GAAG;GAAkB,GAAG,KAAK;GAAK;AACtD,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,aAAa,EAAE,CAAC,CACvD,WAAU,OAAO,EAAE;AA4BrB,UAzBY,MAAM,KAAK,cAAc,OAAO,MAAM,YAAY;GAC5D,MAAM,OAAO,MAAM,OAAO,eAAe,KAAK;GAC9C,MAAMC,SAAgC,CAAC,KAAK;AAE5C,QAAK,cAAc,MAAM,IAAI,MAAM,OAAO;GAE1C,MAAM,QAAQ,MAAM,QAAQ,IAC1B,KAAK,cAAc,KAAK,QAAQ;AAC9B,QAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,SAAS,KAAK,OAAO;IAC9D,MAAM,UACJ,KAAK,sBAAsB,qBACvB,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,WAAW,QAAQ,GAAG,CAAC,OACpD,IAAI;AAEV,WAAO,KAAK,SACV,IAAI,WACJ,IAAI,mBAAmB,SAAS,OAAO,OAAO,EAC9C,UACD;KACD,CACH;AACD,QAAK,MAAM,OAAO,MAAO,QAAO,KAAK,GAAG,IAAI;AAC5C,UAAO;IACP,EAES,KAAK,UAAU;GAAE,GAAG;GAAM;GAAW,EAAE;;CAIpD,MAAc,UACZ,QACA,MACA,WACA,eACiB;EACjB,MAAM,WAAW,KAAK,kBAAkB,KAAK;EAC7C,MAAM,aAAa,KAAK,QAAQ,iBAAiB,UAAU,KAAK,SAAS,EACvE,WAAW,MACZ,CAAC;EAGF,MAAM,SAAS;EACf,MAAM,YAAY,OAAO,QAAQ,UAAU,aAAa,EAAE,CAAC;EAC3D,MAAM,aAAa,MAAM,KAAK,gBAAgB,OAAO,cAAc;GACjE,MAAM,sBAAM,IAAI,KAAmB;AACnC,QAAK,MAAM,QAAQ,cACjB,MAAK,MAAMC,UAAQ,KAAK,MAAO,KAAI,IAAIA,OAAK,UAAUA,OAAK,MAAMA,OAAK;AAExE,UAAO;IACP;AACF,OAAK,MAAM,aAAa,WAAW,yBAAyB,EAAE;AAC5D,QAAK,MAAM,CAAC,GAAG,MAAM,UACnB,WAAU,gBAAgB,UAAU,iBAAiB,CAAC,WAAW,IAAI,EAAE,IAAI,EAAY,CAAC;AAG1F,OAAI,UAAU,iBAAiB,CAAC,WAAW,OAAO,EAAE;IAClD,MAAM,SAAS,UAAU,iBAAiB,CAAC,UAAU,EAAc;IACnE,MAAM,SAAS,WAAW,IAAI,OAAO;AAErC,QAAI,OACF,WAAU,gBAAgB,kBAAkB,UAAU,KAAK,kBAAkB,OAAO,CAAC,CAAC;QAEtF,SAAQ,KAAK,sCAAsC,YAAY;;;AAKrE,OAAK,MAAM,UAAU,KAAK,QACxB,OAAM,OAAO,YAAY;GACvB,MAAM;GACN,eAAe;GACf;GACD,CAAC;AAGJ,SAAO,WAAW,aAAa;;CAGjC,AAAQ,kBAAkB,MAAoB;EAC5C,MAAM,SAAS,KAAK,WAAW;EAC/B,MAAM,MACJ;GACE,YAAY,OAAO,QAAQ;GAC3B,OAAO,OAAO,QAAQ;GACtB,IAAI,OAAO,QAAQ;GACnB,KAAK,OAAO,QAAQ;GACpB,KAAK,OAAO,QAAQ;GACpB,OAAO;GACR,CACD,KAAK;AACP,MAAI,KAAK,OACP,QAAO,KAAK,KAAK,OAAO,SAAS,KAAK,OAAO,QAAQ,SAAS,IAAI,CAAC;AAGrE,SAAO,KAAK,KAAK,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,KAAK,CAAC;;;;;;AC5NnE,MAAa,eAAe;CAC1B,WAAW;CACX,YAAY;CACb;;;;ACGD,eAAsB,IAAI,OAAiB,QAAwB;CACjE,MAAM,SAAS,OAAO;CACtB,IAAIC;CACJ,MAAM,YAAY,IAAI,mBAAmB,OAAO;CAChD,MAAM,WAAW,aAAa,OAAO;AAErC,KAAI,MAAM,WAAW,GAAG;EACtB,MAAM,OAAO,SAAS;AACtB,OAAK,MAAM,oBAAoB;EAC/B,MAAM,OAAO,MAAM,OAAO,mBAAmB;EAC7C,MAAMC,UAIA,EAAE;AAER,OAAK,MAAM,QAAQ,KAAK,QACtB,SAAQ,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,OAAO,KAAK;GACZ,MAAM,KAAK;GACZ,CAAC;EAEJ,MAAM,EAAE,YAAY,MAAM,OAAO,2BAA2B,SAAS,CAAC,mBAAmB;AAEzF,OAAK,MAAM,QAAQ,QACjB,SAAQ,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,OAAO,GAAG,SAAS,GAAG,KAAK;GAC3B,MAAM,KAAK;GACZ,CAAC;AAGJ,OAAK,KAAK,WAAW,KAAK,WAAW,YAAY,mBAAmB,CAAC,CAAC;EACtE,MAAM,QAAQ,MAAM,YAAY;GAC9B,SAAS;GACT;GACD,CAAC;AAEF,MAAI,SAAS,MAAM,EAAE;AACnB,SAAM,QAAQ;AACd;;AAGF,WAAS;OAET,UAAS,MAAM,QAAQ,IACrB,MAAM,IAAI,OAAO,SAAW,MAAM,OAAO,aAAa,KAAK,GAAI,OAAO,GAAG,SAAS,GAAG,OAAQ,CAC9F;AAGH,OAAM,QAAQ,QAAQ,UAAU;;AAGlC,eAAsB,QAAQ,QAAkB,WAA+B;AAC7E,MAAK,MAAM,QAAQ,QAAQ;AACzB,QAAM,WAAW,KAAK,WAAW,QAAQ,WAAW,WAAW,kBAAkB,OAAO,CAAC,CAAC,CAAC;AAE3F,MAAI;AACF,SAAM,UAAU,QAAQ,KAAK;AAC7B,SAAM,WAAW,KAAK,WAAW,YAAY,GAAG,KAAK,YAAY,CAAC,CAAC;WAC5D,GAAG;AACV,OAAI,MAAM,OAAO,EAAE,CAAC;AACpB,SAAM;;;AAIV,OAAM,WAAW,KAAK,mBAAmB,CAAC;AAE1C,OAAM,UAAU,aAAa;AAC7B,OAAM,UAAU,OAAO;AAEvB,OAAM,WAAW,KAAK,WAAW,YAAY,aAAa,CAAC,CAAC;;;;;ACvE9D,eAAsB,UAAU,QAAwB;AACtD,OAAM,WAAW,QAAQ,WAAW,YAAY,0BAA0B,CAAC,CAAC;CAC5E,MAAM,SAAS,OAAO;CACtB,MAAM,YAAY,IAAI,mBAAmB,OAAO;CAEhD,MAAM,SAAS,MAAM,MACnB;EACE,cACE,OAAO;GACL,SAAS;GACT,SAAS,CACP;IACE,OAAO;IACP,OAAO;IACP,MAAM;IACP,EACD;IACE,OAAO;IACP,OAAO;IACP,MAAM;IACP,CACF;GACF,CAAC;EACJ,OAAO,MAAM;AACX,OAAI,EAAE,QAAQ,WAAW,OAAQ;AAEjC,UAAO,OAAO;IACZ,SAAS;IACT,SAAS;KACP;MACE,OAAO;MACP,OAAO;MACP,MAAM;MACP;KACD;MACE,OAAO;MACP,OAAO;MACP,MAAM;MACP;KACD;MACE,OAAO;MACP,OAAO;MACP,MAAM;MACP;KACF;IACF,CAAC;;EAEL,EACD,EACE,gBAAgB;AACd,SAAO,wBAAwB;AAC/B,UAAQ,KAAK,EAAE;IAElB,CACF;CAED,MAAM,WAAW,aAAa,OAAO;AACrC,KAAI,OAAO,WAAW,QAAQ;EAC5B,MAAM,UAAU,EAAE;AAClB,MAAI,OAAO,SAAS,UAClB,SAAQ,KAAK,iCAAiC;MAE9C,SAAQ,KACN,OAAO,SAAS,iBACZ,GAAG,SAAS,iBACZ,GAAG,SAAS,mBACjB;AAGH,QAAM,QAAQ,SAAS,UAAU;AAYjC,YAAU,GAVR,OAAO,SAAS,kBACZ,CACE,CAAC,mCAAmC,+BAA+B,EACnE,CAAC,wCAAwC,oCAAoC,CAC9E,GACD,CACE,CAAC,+BAA+B,2BAA2B,EAC3D,CAAC,oCAAoC,gCAAgC,CACtE,CAEW;;AAGpB,KAAI,OAAO,WAAW,QAAQ;AAC5B,QAAM,QAAQ,CAAC,GAAG,SAAS,eAAe,EAAE,UAAU;AACtD,YAAU,CAAC,+BAA+B,2BAA2B,CAAC;;AAGxE,OAAM,WAAW,KAAK,YAAY,CAAC;;AAGrC,SAAS,UAAU,GAAG,MAAoC;AACxD,OAAM,WAAW,KAAK,gBAAgB,CAAC;AAEvC,KAAI,KACF;EACE;EACA,WAAW,IAAI,MAAM;EACrB;EACA,GAAG,KAAK,KAAK,CAAC,MAAM,QAAQ,WAAW,YAAY,IAAI,KAAK,QAAQ,GAAG,GAAG,CAAC;EAC5E,CAAC,KAAK,KAAK,CACb;;;;;AChGH,MAAM,UAAU,IAAI,SAAS,CAAC,OAAO,oBAAoB;AAEzD,QACG,KAAK,aAAa,CAClB,YAAY,yCAAyC,CACrD,QAAQC,QAAoB,CAC5B,OAAO,YAAY;AAClB,KAAI,MAAM,YAAY,CACpB,SAAQ,IAAI,WAAW,MAAM,0CAA0C,CAAC;KAExE,SAAQ,IAAI,WAAW,UAAU,gCAAgC,CAAC;EAEpE;AAEJ,QACG,QAAQ,YAAY,CACpB,MAAM,YAAY,CAClB,YAAY,qDAAqD,CACjE,OAAO,kBAAkB,gDAAgD,CACzE,OAAO,OAAO,YAA+C;AAC5D,OAAM,UAAU,oBAAoB,QAAQ,KAAK,MAAM,mBAAmB,QAAQ,OAAO,CAAC,CAAC;EAC3F;AAEJ,MAAMC,eAAuC;CAC3C,YAAY;CACZ,QAAQ;CACT;AAED,QACG,QAAQ,MAAM,CACd,YAAY,mCAAmC,CAC/C,SAAS,mBAAmB,yBAAyB,CACrD,OAAO,kBAAkB,gDAAgD,CACzE,OAAO,OAAO,OAAiB,YAA+C;AAE7E,OAAM,IAAI,OADK,oBAAoB,QAAQ,KAAK,MAAM,mBAAmB,QAAQ,OAAO,CAAC,CACjE;EACxB;AAEJ,QACG,QAAQ,OAAO,CACf,SAAS,kBAAkB,oEAAoE,CAC/F,SAAS,YAAY,sBAAsB,CAC3C,OAAO,QAAQ,4BAA4B,CAC3C,OAAO,aAAa,uBAAuB,CAC3C,OAAO,wBAAwB,uCAAuC,CACtE,OACC,OACE,KACA,QACA,EAAE,IAAI,MAAM,iBACT;CACH,MAAM,eAAe;EAAC;EAAO;EAAQ;EAAO;CAC5C,MAAM,SAAS,CAAC;CAChB,IAAIC;AAEJ,KAAI;AACF,UAAQ,KAAK,MAAM,OAAO,GAAG;SACvB;AACN,UAAQ,MAAM,QAAQ,OAAO,KAAK;;CAGpC,MAAM,MACJ,MAAO,UAAU,aAAa,SAAS,KAAK,QAAQ,OAAO,CAAC,GACxD,iBAAiB,OAAO,QAAQ,WAAW,GAC3C,UAAU,OAAO,OAAO;AAE9B,KAAI,QAAQ;AACV,QAAM,GAAG,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,WAAW,MAAM,CAAC;AACzD,QAAM,GAAG,UAAU,QAAQ,IAAI;OAE/B,SAAQ,IAAI,IAAI;EAGrB;AAEH,SAAS,oBAAoB,MAAM,kCAAkC,QAAsB;AACzF,KAAI,OAAO,aAAc,OAAM,aAAa;AAE5C,QAAO,IAAI,WAAW,UAAU,IAAI,IAAI,WAAW,WAAW,GAC1D,IAAI,mBAAmB,KAAK,OAAO,GACnC,IAAI,oBAAoB,KAAK,OAAO;;AAG1C,QAAQ,OAAO"}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@hanzo/docs-cli",
3
- "version": "1.2.1",
4
- "description": "The CLI tool for Fumadocs",
3
+ "version": "1.3.0",
4
+ "description": "The CLI tool for Hanzo Docs",
5
5
  "keywords": [
6
6
  "Docs",
7
7
  "CLI"
8
8
  ],
9
- "homepage": "https://fumadocs.dev",
9
+ "homepage": "https://hanzo.ai/docs",
10
10
  "license": "MIT",
11
11
  "author": "Fuma Nama",
12
- "repository": "github:fuma-nama/fumadocs",
12
+ "repository": "github:hanzoai/docs",
13
13
  "bin": {
14
14
  "hanzo-docs": "./dist/index.js"
15
15
  },
@@ -27,6 +27,13 @@
27
27
  "publishConfig": {
28
28
  "access": "public"
29
29
  },
30
+ "scripts": {
31
+ "build": "tsdown --config-loader unrun",
32
+ "clean": "rimraf dist",
33
+ "dev": "tsdown --watch --config-loader unrun",
34
+ "lint": "eslint .",
35
+ "types:check": "tsc --noEmit"
36
+ },
30
37
  "dependencies": {
31
38
  "@clack/prompts": "^0.11.0",
32
39
  "commander": "^14.0.2",
@@ -38,16 +45,9 @@
38
45
  },
39
46
  "devDependencies": {
40
47
  "@types/node": "24.10.2",
48
+ "eslint-config-custom": "workspace:*",
41
49
  "shadcn": "3.6.2",
42
- "tsdown": "^0.18.3",
43
- "tsconfig": "0.0.0",
44
- "eslint-config-custom": "0.0.0"
45
- },
46
- "scripts": {
47
- "build": "tsdown --config-loader unrun",
48
- "clean": "rimraf dist",
49
- "dev": "tsdown --watch --config-loader unrun",
50
- "lint": "eslint .",
51
- "types:check": "tsc --noEmit"
50
+ "tsconfig": "workspace:*",
51
+ "tsdown": "^0.18.3"
52
52
  }
53
- }
53
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Fuma
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.