UNPKG

leshi-ui

Version:

Modern CLI for building and managing React Native UI components with copy-paste simplicity, custom theming, and open source design system support

100 lines (99 loc) 4.49 kB
import { Command } from 'commander'; import inquirer from 'inquirer'; import ora from 'ora'; import { Logger } from '../utils/logger.js'; import { FileUtils } from '../utils/file-utils.js'; import { ProjectService } from '../services/project-service.js'; import { GitHubProjectService } from '../services/github-project-service.js'; import { colors, icons } from '../utils/colors.js'; export function createInitCommand() { return new Command('init') .description('Initialize leshi-ui in your React Native project') .option('--rn', 'Use React Native StyleSheet implementation (default)') .option('--unistyles', 'Use Unistyles implementation') .option('-y, --yes', 'Skip confirmation prompts') .option('-c, --cwd <path>', 'Working directory', process.cwd()) .action(async (options) => { try { await initProject(options); } catch (error) { Logger.error(`Failed to initialize project: ${error instanceof Error ? error.message : 'Unknown error'}`); process.exit(1); } }); } async function initProject(options) { const cwd = options.cwd || process.cwd(); let framework = 'rn'; if (options.unistyles) { framework = 'unistyles'; } else if (options.rn) { framework = 'rn'; } Logger.title(`${icons.rocket} Initializing leshi-ui`); Logger.subtitle(`Framework: ${framework === 'rn' ? 'React Native StyleSheet' : 'Unistyles'}`); Logger.break(); const isRNProject = await ProjectService.isReactNativeProject(cwd); if (!isRNProject) { Logger.warning('This doesn\'t appear to be a React Native project.'); if (!options.yes) { const { proceed } = await inquirer.prompt([ { type: 'confirm', name: 'proceed', message: 'Continue anyway?', default: false, }, ]); if (!proceed) { Logger.info('Initialization cancelled.'); return; } } } const spinner = ora('Setting up project structure...').start(); try { const config = await ProjectService.getProjectConfig(cwd); await FileUtils.ensureDir(config.componentsDir); await FileUtils.ensureDir(config.stylesDir); await FileUtils.ensureDir(config.libDir); spinner.text = 'Downloading theme files from GitHub...'; const targetStylesPath = config.stylesDir; const { success: styleSuccess, files: downloadedStyleFiles } = await GitHubProjectService.downloadStyleFiles(framework, targetStylesPath, true); if (!styleSuccess) { spinner.fail('Failed to download style files from GitHub'); throw new Error('Failed to download style files'); } spinner.text = 'Downloading basic themes...'; const themesTargetPath = FileUtils.join(targetStylesPath, 'themes'); await FileUtils.ensureDir(themesTargetPath); const basicThemes = ['light', 'dark', 'common', 'index']; for (const themeName of basicThemes) { const targetPath = FileUtils.join(themesTargetPath, `${themeName}.ts`); await GitHubProjectService.downloadTheme(framework, themeName, targetPath, true); } spinner.succeed('Project initialized successfully!'); Logger.break(); Logger.success('Styling system initialized successfully!'); Logger.break(); Logger.log(`${icons.folder} Created directories:`); Logger.log(` • ${colors.dim('components/ui/')} - UI components`); Logger.log(` • ${colors.dim('styles/')} - Theme system`); Logger.log(` • ${colors.dim('lib/')} - Utility functions`); Logger.break(); Logger.log(`${icons.theme} Themes included:`); Logger.log(` • ${colors.dim('light.ts')} - Light theme`); Logger.log(` • ${colors.dim('dark.ts')} - Dark theme`); Logger.break(); Logger.tip('Next steps:'); Logger.log(` 1. Wrap your app with ${colors.primary('<ThemeProvider>')}`); Logger.log(` 2. Add components: ${colors.primary('npx leshi-ui@latest add component button')}`); Logger.log(` 3. View available components: ${colors.primary('npx leshi-ui@latest list component')}`); } catch (error) { spinner.fail('Failed to initialize project'); throw error; } }