@re-shell/cli
Version:
Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja
461 lines (460 loc) ⢠17.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.manageConfig = manageConfig;
const chalk_1 = __importDefault(require("chalk"));
const prompts_1 = __importDefault(require("prompts"));
const config_1 = require("../utils/config");
const error_handler_1 = require("../utils/error-handler");
async function manageConfig(options = {}) {
const { spinner, verbose, json } = options;
try {
if (options.backup) {
await backupConfiguration(spinner);
return;
}
if (options.restore) {
await restoreConfiguration(options.restore, spinner);
return;
}
if (options.list) {
await listConfiguration(options, spinner);
return;
}
if (options.get) {
await getConfigValue(options.get, options, spinner);
return;
}
if (options.set && options.value) {
await setConfigValue(options.set, options.value, options, spinner);
return;
}
if (options.save) {
await savePreset(options.save, options, spinner);
return;
}
if (options.load) {
await loadPreset(options.load, options, spinner);
return;
}
if (options.delete) {
await deletePreset(options.delete, options, spinner);
return;
}
if (options.interactive) {
await interactiveConfig(options, spinner);
return;
}
// Default: show current configuration
await showConfiguration(options, spinner);
}
catch (error) {
if (spinner)
spinner.fail(chalk_1.default.red('Configuration operation failed'));
throw error;
}
}
async function backupConfiguration(spinner) {
if (spinner)
spinner.setText('Creating configuration backup...');
const backupPath = await config_1.configManager.backupConfig();
if (spinner) {
spinner.succeed(chalk_1.default.green('Configuration backed up successfully!'));
}
console.log(chalk_1.default.cyan(`Backup saved to: ${backupPath}`));
}
async function restoreConfiguration(backupPath, spinner) {
if (spinner)
spinner.setText(`Restoring configuration from ${backupPath}...`);
await config_1.configManager.restoreConfig(backupPath);
if (spinner) {
spinner.succeed(chalk_1.default.green('Configuration restored successfully!'));
}
console.log(chalk_1.default.cyan('Configuration has been restored from backup'));
}
async function listConfiguration(options, spinner) {
if (spinner)
spinner.setText('Loading configuration...');
const { global: showGlobal, project: showProject, json } = options;
const config = await config_1.configManager.getMergedConfig();
if (spinner)
spinner.stop();
const output = {};
if (showGlobal || (!showProject && !showGlobal)) {
output.global = config.global;
}
if (showProject || (!showProject && !showGlobal)) {
output.project = config.project;
output.merged = config.merged;
}
if (json) {
console.log(JSON.stringify(output, null, 2));
}
else {
if (output.global) {
console.log(chalk_1.default.cyan('\nš Global Configuration:'));
displayConfig(output.global);
}
if (output.project) {
console.log(chalk_1.default.cyan('\nšļø Project Configuration:'));
displayConfig(output.project);
}
else {
console.log(chalk_1.default.yellow('\nā ļø No project configuration found'));
}
if (output.merged && output.project) {
console.log(chalk_1.default.cyan('\nš Merged Configuration:'));
displayConfig(output.merged);
}
}
}
async function getConfigValue(key, options, spinner) {
if (spinner)
spinner.setText(`Getting configuration value: ${key}`);
const config = await config_1.configManager.getMergedConfig();
const value = getNestedValue(config.merged, key) ?? getNestedValue(config.global, key);
if (spinner)
spinner.stop();
if (options.json) {
console.log(JSON.stringify({ [key]: value }, null, 2));
}
else {
if (value !== undefined) {
console.log(chalk_1.default.cyan(`${key}:`), value);
}
else {
console.log(chalk_1.default.yellow(`Configuration key '${key}' not found`));
}
}
}
async function setConfigValue(key, value, options, spinner) {
if (spinner)
spinner.setText(`Setting configuration value: ${key} = ${value}`);
const { global: isGlobal } = options;
// Parse value (try JSON, fallback to string)
let parsedValue;
try {
parsedValue = JSON.parse(value);
}
catch {
parsedValue = value;
}
if (isGlobal) {
const globalConfig = await config_1.configManager.loadGlobalConfig();
setNestedValue(globalConfig, key, parsedValue);
await config_1.configManager.saveGlobalConfig(globalConfig);
}
else {
// Set in project config
const projectConfig = await config_1.configManager.loadProjectConfig();
if (!projectConfig) {
throw new error_handler_1.ValidationError('No project configuration found. Initialize a project first.');
}
setNestedValue(projectConfig, key, parsedValue);
await config_1.configManager.saveProjectConfig(projectConfig);
}
if (spinner) {
spinner.succeed(chalk_1.default.green(`Configuration updated: ${key} = ${value}`));
}
}
async function savePreset(name, options, spinner) {
if (spinner)
spinner.setText(`Saving preset: ${name}`);
const projectConfig = await config_1.configManager.loadProjectConfig();
if (!projectConfig) {
throw new error_handler_1.ValidationError('No project configuration found. Initialize a project first.');
}
await config_1.configManager.savePreset(name, projectConfig);
if (spinner) {
spinner.succeed(chalk_1.default.green(`Preset '${name}' saved successfully!`));
}
}
async function loadPreset(name, options, spinner) {
if (spinner)
spinner.setText(`Loading preset: ${name}`);
const preset = await config_1.configManager.loadPreset(name);
if (!preset) {
throw new error_handler_1.ValidationError(`Preset '${name}' not found`);
}
if (options.json) {
if (spinner)
spinner.stop();
console.log(JSON.stringify(preset, null, 2));
}
else {
if (spinner)
spinner.stop();
console.log(chalk_1.default.cyan(`\nš¦ Preset: ${preset.name}`));
console.log(chalk_1.default.gray(`Description: ${preset.description}`));
console.log(chalk_1.default.gray(`Created: ${new Date(preset.createdAt).toLocaleDateString()}`));
console.log(chalk_1.default.gray(`Updated: ${new Date(preset.updatedAt).toLocaleDateString()}`));
if (preset.tags.length > 0) {
console.log(chalk_1.default.gray(`Tags: ${preset.tags.join(', ')}`));
}
console.log('\nConfiguration:');
displayConfig(preset.config);
}
}
async function deletePreset(name, options, spinner) {
if (spinner)
spinner.setText(`Deleting preset: ${name}`);
const preset = await config_1.configManager.loadPreset(name);
if (!preset) {
throw new error_handler_1.ValidationError(`Preset '${name}' not found`);
}
await config_1.configManager.deletePreset(name);
if (spinner) {
spinner.succeed(chalk_1.default.green(`Preset '${name}' deleted successfully!`));
}
}
async function interactiveConfig(options, spinner) {
if (spinner)
spinner.stop();
const response = await (0, prompts_1.default)([
{
type: 'select',
name: 'action',
message: 'What would you like to do?',
choices: [
{ title: 'š View Configuration', value: 'view' },
{ title: 'āļø Edit Global Settings', value: 'editGlobal' },
{ title: 'šļø Edit Project Settings', value: 'editProject' },
{ title: 'š¦ Manage Presets', value: 'presets' },
{ title: 'š¾ Backup/Restore', value: 'backup' },
{ title: 'š§ Advanced Options', value: 'advanced' }
]
}
]);
if (!response.action)
return;
switch (response.action) {
case 'view':
await showConfiguration(options);
break;
case 'editGlobal':
await interactiveGlobalConfig();
break;
case 'editProject':
await interactiveProjectConfig();
break;
case 'presets':
await interactivePresetManagement();
break;
case 'backup':
await interactiveBackupRestore();
break;
case 'advanced':
await interactiveAdvancedOptions();
break;
}
}
async function interactiveGlobalConfig() {
const globalConfig = await config_1.configManager.loadGlobalConfig();
const response = await (0, prompts_1.default)([
{
type: 'select',
name: 'packageManager',
message: 'Default package manager:',
choices: [
{ title: 'pnpm', value: 'pnpm' },
{ title: 'npm', value: 'npm' },
{ title: 'yarn', value: 'yarn' },
{ title: 'bun', value: 'bun' }
],
initial: ['pnpm', 'npm', 'yarn', 'bun'].indexOf(globalConfig.packageManager)
},
{
type: 'select',
name: 'defaultFramework',
message: 'Default framework:',
choices: [
{ title: 'React with TypeScript', value: 'react-ts' },
{ title: 'React', value: 'react' },
{ title: 'Vue with TypeScript', value: 'vue-ts' },
{ title: 'Vue', value: 'vue' },
{ title: 'Svelte with TypeScript', value: 'svelte-ts' },
{ title: 'Svelte', value: 'svelte' }
]
},
{
type: 'toggle',
name: 'autoUpdate',
message: 'Enable automatic updates?',
initial: globalConfig.cli.autoUpdate,
active: 'yes',
inactive: 'no'
},
{
type: 'toggle',
name: 'telemetry',
message: 'Enable telemetry?',
initial: globalConfig.cli.telemetry,
active: 'yes',
inactive: 'no'
},
{
type: 'select',
name: 'theme',
message: 'CLI theme:',
choices: [
{ title: 'Auto', value: 'auto' },
{ title: 'Light', value: 'light' },
{ title: 'Dark', value: 'dark' }
],
initial: ['auto', 'light', 'dark'].indexOf(globalConfig.cli.theme)
}
]);
if (Object.keys(response).length === 0)
return;
// Update global config
const updates = {
packageManager: response.packageManager || globalConfig.packageManager,
defaultFramework: response.defaultFramework || globalConfig.defaultFramework,
cli: {
...globalConfig.cli,
autoUpdate: response.autoUpdate ?? globalConfig.cli.autoUpdate,
telemetry: response.telemetry ?? globalConfig.cli.telemetry,
theme: response.theme || globalConfig.cli.theme
}
};
await config_1.configManager.updateGlobalConfig(updates);
console.log(chalk_1.default.green('ā
Global configuration updated successfully!'));
}
async function interactiveProjectConfig() {
const projectConfig = await config_1.configManager.loadProjectConfig();
if (!projectConfig) {
console.log(chalk_1.default.yellow('ā ļø No project configuration found. Initialize a project first.'));
return;
}
// Implementation for interactive project config editing
console.log(chalk_1.default.cyan('šļø Interactive project configuration coming soon...'));
}
async function interactivePresetManagement() {
const presets = await config_1.configManager.listPresets();
const response = await (0, prompts_1.default)([
{
type: 'select',
name: 'action',
message: 'Preset management:',
choices: [
{ title: 'š List Presets', value: 'list' },
{ title: 'š¾ Save Current as Preset', value: 'save' },
{ title: 'š„ Load Preset', value: 'load' },
{ title: 'šļø Delete Preset', value: 'delete' }
]
}
]);
if (!response.action)
return;
switch (response.action) {
case 'list':
if (presets.length === 0) {
console.log(chalk_1.default.yellow('No presets found.'));
}
else {
console.log(chalk_1.default.cyan('\nš¦ Available Presets:'));
presets.forEach(preset => {
console.log(` ⢠${preset.name} - ${preset.description}`);
});
}
break;
// Add other preset actions...
}
}
async function interactiveBackupRestore() {
const response = await (0, prompts_1.default)([
{
type: 'select',
name: 'action',
message: 'Backup/Restore:',
choices: [
{ title: 'š¾ Create Backup', value: 'backup' },
{ title: 'š„ Restore from Backup', value: 'restore' }
]
}
]);
if (!response.action)
return;
switch (response.action) {
case 'backup':
await backupConfiguration();
break;
case 'restore':
// Implementation for restore selection
console.log(chalk_1.default.cyan('š Restore functionality coming soon...'));
break;
}
}
async function interactiveAdvancedOptions() {
console.log(chalk_1.default.cyan('š§ Advanced configuration options coming soon...'));
}
async function showConfiguration(options, spinner) {
if (spinner)
spinner.setText('Loading configuration...');
const config = await config_1.configManager.getMergedConfig();
if (spinner)
spinner.stop();
if (options.json) {
console.log(JSON.stringify({
global: config.global,
project: config.project,
merged: config.merged
}, null, 2));
}
else {
console.log(chalk_1.default.cyan('\nš Current Configuration'));
console.log(chalk_1.default.gray('ā'.repeat(50)));
console.log(chalk_1.default.cyan('\nš Global Settings:'));
displayConfig(config.global, 1);
if (config.project) {
console.log(chalk_1.default.cyan('\nšļø Project Settings:'));
displayConfig(config.project, 1);
}
else {
console.log(chalk_1.default.yellow('\nā ļø No project configuration found'));
}
}
}
function displayConfig(config, indent = 0) {
const prefix = ' '.repeat(indent);
for (const [key, value] of Object.entries(config)) {
if (value === null || value === undefined) {
console.log(`${prefix}${chalk_1.default.gray(key)}: ${chalk_1.default.dim('null')}`);
}
else if (typeof value === 'object' && !Array.isArray(value)) {
console.log(`${prefix}${chalk_1.default.cyan(key)}:`);
displayConfig(value, indent + 1);
}
else if (Array.isArray(value)) {
console.log(`${prefix}${chalk_1.default.cyan(key)}: ${chalk_1.default.dim(`[${value.length} items]`)}`);
if (value.length > 0) {
value.slice(0, 3).forEach((item, i) => {
console.log(`${prefix} ${chalk_1.default.gray(`[${i}]`)}: ${item}`);
});
if (value.length > 3) {
console.log(`${prefix} ${chalk_1.default.gray(`... ${value.length - 3} more`)}`);
}
}
}
else {
const displayValue = typeof value === 'string' ? `"${value}"` : value;
console.log(`${prefix}${chalk_1.default.cyan(key)}: ${displayValue}`);
}
}
}
// Utility functions for nested object access
function getNestedValue(obj, path) {
return path.split('.').reduce((current, key) => current?.[key], obj);
}
function setNestedValue(obj, path, value) {
const keys = path.split('.');
const lastKey = keys.pop();
const target = keys.reduce((current, key) => {
if (!(key in current))
current[key] = {};
return current[key];
}, obj);
target[lastKey] = value;
}