UNPKG

hextaui

Version:

Build stunning websites effortlessly. HextaUI CLI tool to easily install components for Next.js, Vite, and Astro projects.

110 lines (109 loc) 4.16 kB
import { exec } from "child_process"; import { promisify } from "util"; import { existsSync } from "fs"; import { join } from "path"; import * as p from "@clack/prompts"; import pc from "picocolors"; const execAsync = promisify(exec); export async function checkDependencyManager(projectRoot) { // Check for lock files to determine package manager if (existsSync(join(projectRoot, "pnpm-lock.yaml"))) { return "pnpm"; } if (existsSync(join(projectRoot, "yarn.lock"))) { return "yarn"; } if (existsSync(join(projectRoot, "bun.lock"))) { return "bun"; } return "npm"; } export async function installDependencies(dependencies, projectRoot) { if (dependencies.length === 0) return; const packageManager = await checkDependencyManager(projectRoot); let command; switch (packageManager) { case "pnpm": command = `pnpm add ${dependencies.join(" ")}`; break; case "yarn": command = `yarn add ${dependencies.join(" ")}`; break; case "bun": command = `bun add ${dependencies.join(" ")}`; break; default: command = `npm install ${dependencies.join(" ")}`; break; } try { await execAsync(command, { cwd: projectRoot }); } catch (error) { // If preferred package manager fails, try npm as fallback if (packageManager !== "npm") { const npmCommand = `npm install ${dependencies.join(" ")}`; await execAsync(npmCommand, { cwd: projectRoot }); } else { throw error; } } } export async function installDependenciesWithProgress(dependencies, projectRoot) { if (dependencies.length === 0) return { success: [], failed: [] }; const packageManager = await checkDependencyManager(projectRoot); const success = []; const failed = []; // Show what we're about to install p.log.message(`Installing ${pc.cyan(dependencies.length)} dependencies with ${pc.cyan(packageManager)}:`); p.log.message(`${dependencies.map((dep) => pc.dim(`• ${dep}`)).join("\n")}\n`); const getCommand = (dep) => { switch (packageManager) { case "pnpm": return `pnpm add ${dep}`; case "yarn": return `yarn add ${dep}`; case "bun": return `bun add ${dep}`; default: return `npm install ${dep}`; } }; for (let i = 0; i < dependencies.length; i++) { const dep = dependencies[i]; // Non-null assertion since we know the index is valid const progress = `[${i + 1}/${dependencies.length}]`; const progressBar = `${pc.dim("━".repeat(i))}${pc.cyan("━")}${pc.dim("━".repeat(dependencies.length - i - 1))}`; try { const s = p.spinner(); s.start(`${progress} ${progressBar} Installing ${pc.cyan(dep)}...`); const command = getCommand(dep); await execAsync(command, { cwd: projectRoot }); s.stop(`${progress} ${pc.green("✓")} ${pc.cyan(dep)}`); success.push(dep); } catch (error) { // Try fallback to npm if the preferred package manager fails if (packageManager !== "npm") { try { const s = p.spinner(); s.start(`${progress} ${progressBar} Retrying ${pc.cyan(dep)} with ${pc.yellow("npm")}...`); const npmCommand = `npm install ${dep}`; await execAsync(npmCommand, { cwd: projectRoot }); s.stop(`${progress} ${pc.green("✓")} ${pc.cyan(dep)} ${pc.dim("(npm fallback)")}`); success.push(dep); continue; } catch (npmError) { // Both failed } } const s = p.spinner(); s.stop(`${progress} ${pc.red("✗")} ${pc.cyan(dep)} ${pc.red("failed")}`); failed.push(dep); } } return { success, failed }; }