UNPKG

accs-cli

Version:

ACCS CLI — Full-featured developer tool for scaffolding, running, building, and managing multi-language projects

430 lines (370 loc) 11.5 kB
/** * Configuration management command */ import chalk from 'chalk'; import inquirer from 'inquirer'; import boxen from 'boxen'; import { logger } from '../utils/logger.js'; import { configManager } from '../config/config-manager.js'; export function configCommand(program) { program .command('config') .argument('[key]', 'Configuration key') .argument('[value]', 'Configuration value') .option('-g, --get <key>', 'Get configuration value') .option('-s, --set <key> <value>', 'Set configuration value') .option('-d, --delete <key>', 'Delete configuration key') .option('-l, --list', 'List all configuration') .option('-r, --reset', 'Reset to defaults') .option('-e, --edit', 'Interactive configuration editor') .option('--export <file>', 'Export configuration to file') .option('--import <file>', 'Import configuration from file') .description('Manage ACCS configuration') .action(async (key, value, options) => { try { await handleConfigAction(key, value, options); } catch (error) { logger.error('Configuration operation failed:', error.message); process.exit(1); } }); } async function handleConfigAction(key, value, options) { // Handle specific options first if (options.get) { return showConfigValue(options.get); } if (options.set) { return setConfigValue(options.set, options.args?.[0]); } if (options.delete) { return deleteConfigKey(options.delete); } if (options.list) { return listConfiguration(); } if (options.reset) { return resetConfiguration(); } if (options.edit) { return interactiveConfigEditor(); } if (options.export) { return exportConfiguration(options.export); } if (options.import) { return importConfiguration(options.import); } // Handle key-value arguments if (key && value !== undefined) { return setConfigValue(key, value); } if (key && value === undefined) { return showConfigValue(key); } // Default: show help return showConfigHelp(); } function showConfigValue(key) { if (!configManager.has(key)) { logger.error(`Configuration key "${key}" not found`); return; } const value = configManager.get(key); logger.info(`${chalk.cyan(key)}: ${chalk.yellow(JSON.stringify(value, null, 2))}`); } function setConfigValue(key, value) { if (!key || value === undefined) { throw new Error('Both key and value are required'); } // Parse value as JSON if possible let parsedValue = value; try { parsedValue = JSON.parse(value); } catch (error) { // Keep as string if not valid JSON } configManager.set(key, parsedValue); logger.success(`Set ${chalk.cyan(key)} = ${chalk.yellow(JSON.stringify(parsedValue))}`); } function deleteConfigKey(key) { if (!configManager.has(key)) { logger.error(`Configuration key "${key}" not found`); return; } configManager.delete(key); logger.success(`Deleted configuration key: ${chalk.cyan(key)}`); } function listConfiguration() { const config = configManager.getAll(); const configPath = configManager.getConfigPath(); console.log(boxen( chalk.blue.bold('🔧 ACCS Configuration'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'blue' } )); logger.info(`Config file: ${chalk.gray(configPath)}`); logger.separator(); if (Object.keys(config).length === 0) { logger.info('No configuration found (using defaults)'); return; } // Group configuration by category const categories = { 'General': ['defaultTemplate', 'verbose', 'autoUpdate', 'theme'], 'Server': ['defaultPort'], 'Build': ['buildDir', 'srcDir'], 'Deploy': ['deployTarget'], 'Plugins': ['plugins'], 'Aliases': ['aliases'], 'Other': [] }; const configEntries = Object.entries(config); // Categorize config entries const categorized = {}; configEntries.forEach(([key, value]) => { let category = 'Other'; for (const [cat, keys] of Object.entries(categories)) { if (keys.includes(key)) { category = cat; break; } } if (!categorized[category]) { categorized[category] = []; } categorized[category].push([key, value]); }); // Display each category Object.entries(categorized).forEach(([category, entries]) => { if (entries.length === 0) return; logger.section(category); entries.forEach(([key, value]) => { displayConfigValue(key, value); }); }); logger.separator(); logger.info('Configuration commands:'); logger.info(` ${chalk.cyan('accs config <key> <value>')} - Set configuration`); logger.info(` ${chalk.cyan('accs config <key>')} - Get configuration`); logger.info(` ${chalk.cyan('accs config --edit')} - Interactive editor`); logger.info(` ${chalk.cyan('accs config --reset')} - Reset to defaults`); } function displayConfigValue(key, value) { let displayValue; if (Array.isArray(value)) { displayValue = value.length > 0 ? value.join(', ') : chalk.gray('(empty array)'); } else if (typeof value === 'object' && value !== null) { displayValue = Object.keys(value).length > 0 ? JSON.stringify(value, null, 2) : chalk.gray('(empty object)'); } else { displayValue = String(value); } console.log(` ${chalk.cyan(key)}: ${chalk.yellow(displayValue)}`); } async function resetConfiguration() { const { confirm } = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: 'Are you sure you want to reset all configuration to defaults?', default: false } ]); if (!confirm) { logger.info('Reset cancelled'); return; } configManager.reset(); logger.success('Configuration reset to defaults'); } async function interactiveConfigEditor() { const config = configManager.getAll(); console.log(boxen( chalk.blue.bold('📝 Interactive Configuration Editor'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'blue' } )); const { action } = await inquirer.prompt([ { type: 'list', name: 'action', message: 'What would you like to do?', choices: [ { name: 'Edit existing configuration', value: 'edit' }, { name: 'Add new configuration', value: 'add' }, { name: 'Remove configuration', value: 'remove' }, { name: 'Reset to defaults', value: 'reset' }, { name: 'Exit', value: 'exit' } ] } ]); switch (action) { case 'edit': await editExistingConfig(config); break; case 'add': await addNewConfig(); break; case 'remove': await removeConfig(config); break; case 'reset': await resetConfiguration(); break; case 'exit': logger.info('Configuration editor closed'); break; } } async function editExistingConfig(config) { if (Object.keys(config).length === 0) { logger.info('No configuration to edit'); return; } const { key } = await inquirer.prompt([ { type: 'list', name: 'key', message: 'Select configuration to edit:', choices: Object.keys(config).map(key => ({ name: `${key}: ${JSON.stringify(config[key])}`, value: key })) } ]); const currentValue = config[key]; const { newValue } = await inquirer.prompt([ { type: 'input', name: 'newValue', message: `New value for ${key}:`, default: JSON.stringify(currentValue), validate: (input) => { if (!input.trim()) return 'Value cannot be empty'; try { JSON.parse(input); return true; } catch (error) { return 'Please enter valid JSON or a simple string'; } } } ]); let parsedValue; try { parsedValue = JSON.parse(newValue); } catch (error) { parsedValue = newValue; } configManager.set(key, parsedValue); logger.success(`Updated ${chalk.cyan(key)} = ${chalk.yellow(JSON.stringify(parsedValue))}`); } async function addNewConfig() { const { key, value } = await inquirer.prompt([ { type: 'input', name: 'key', message: 'Configuration key:', validate: (input) => input.trim() ? true : 'Key cannot be empty' }, { type: 'input', name: 'value', message: 'Configuration value (JSON or string):', validate: (input) => input.trim() ? true : 'Value cannot be empty' } ]); let parsedValue; try { parsedValue = JSON.parse(value); } catch (error) { parsedValue = value; } configManager.set(key, parsedValue); logger.success(`Added ${chalk.cyan(key)} = ${chalk.yellow(JSON.stringify(parsedValue))}`); } async function removeConfig(config) { if (Object.keys(config).length === 0) { logger.info('No configuration to remove'); return; } const { key } = await inquirer.prompt([ { type: 'list', name: 'key', message: 'Select configuration to remove:', choices: Object.keys(config).map(key => ({ name: `${key}: ${JSON.stringify(config[key])}`, value: key })) } ]); const { confirm } = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: `Remove configuration "${key}"?`, default: false } ]); if (confirm) { configManager.delete(key); logger.success(`Removed configuration: ${chalk.cyan(key)}`); } } async function exportConfiguration(filePath) { try { await configManager.exportConfig(filePath); logger.success(`Configuration exported to: ${chalk.cyan(filePath)}`); } catch (error) { throw new Error(`Export failed: ${error.message}`); } } async function importConfiguration(filePath) { try { await configManager.importConfig(filePath); logger.success(`Configuration imported from: ${chalk.cyan(filePath)}`); } catch (error) { throw new Error(`Import failed: ${error.message}`); } } function showConfigHelp() { console.log(boxen( chalk.blue.bold('🔧 ACCS Configuration Help'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'blue' } )); logger.info('Configuration commands:'); logger.info(` ${chalk.cyan('accs config --list')} - Show all configuration`); logger.info(` ${chalk.cyan('accs config <key>')} - Get specific value`); logger.info(` ${chalk.cyan('accs config <key> <value>')} - Set configuration`); logger.info(` ${chalk.cyan('accs config --delete <key>')} - Remove configuration`); logger.info(` ${chalk.cyan('accs config --edit')} - Interactive editor`); logger.info(` ${chalk.cyan('accs config --reset')} - Reset to defaults`); logger.separator(); logger.info('Common configuration keys:'); logger.info(` ${chalk.yellow('defaultTemplate')} - Default project template`); logger.info(` ${chalk.yellow('defaultPort')} - Default server port`); logger.info(` ${chalk.yellow('buildDir')} - Build output directory`); logger.info(` ${chalk.yellow('srcDir')} - Source directory`); logger.info(` ${chalk.yellow('verbose')} - Enable verbose output`); logger.separator(); logger.info('Examples:'); logger.info(` ${chalk.cyan('accs config defaultTemplate react')}`); logger.info(` ${chalk.cyan('accs config defaultPort 8080')}`); logger.info(` ${chalk.cyan('accs config verbose true')}`); }