@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.
- package/dist/build/index.d.ts +2 -2
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +3 -3
- package/dist/build/index.js.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
- package/LICENSE +0 -21
package/dist/build/index.d.ts
CHANGED
|
@@ -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
|
|
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,
|
|
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,
|
|
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"}
|
package/dist/build/index.js
CHANGED
|
@@ -237,7 +237,7 @@ function combineRegistry(root, ...items) {
|
|
|
237
237
|
registries: items
|
|
238
238
|
};
|
|
239
239
|
}
|
|
240
|
-
async function
|
|
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(
|
|
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,
|
|
272
|
+
export { ComponentCompiler, RegistryCompiler, combineRegistry, resolveFromRemote, writeDocsRegistry };
|
|
273
273
|
//# sourceMappingURL=index.js.map
|
package/dist/build/index.js.map
CHANGED
|
@@ -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.
|
|
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": "
|
|
474
|
-
"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
|
|
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("
|
|
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.
|
|
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://
|
|
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":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/docs-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "The CLI tool for
|
|
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://
|
|
9
|
+
"homepage": "https://hanzo.ai/docs",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"author": "Fuma Nama",
|
|
12
|
-
"repository": "github:
|
|
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
|
-
"
|
|
43
|
-
"
|
|
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.
|