@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
378 lines (377 loc) ⢠14.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.manageDevMode = manageDevMode;
const chalk_1 = __importDefault(require("chalk"));
const prompts_1 = __importDefault(require("prompts"));
const config_watcher_1 = require("../utils/config-watcher");
async function manageDevMode(options = {}) {
const { spinner, verbose, json } = options;
try {
if (options.start) {
await startDevelopmentMode(options, spinner);
return;
}
if (options.stop) {
await stopDevelopmentMode(options, spinner);
return;
}
if (options.restart) {
await restartDevelopmentMode(options, spinner);
return;
}
if (options.status) {
await showDevModeStatus(options, spinner);
return;
}
if (options.interactive) {
await interactiveDevMode(options, spinner);
return;
}
// Default: show status if already running, otherwise show help
if (config_watcher_1.configWatcher.isActive()) {
await showDevModeStatus(options, spinner);
}
else {
await showDevModeHelp();
}
}
catch (error) {
if (spinner)
spinner.fail(chalk_1.default.red('Development mode operation failed'));
throw error;
}
}
async function startDevelopmentMode(options, spinner) {
if (config_watcher_1.configWatcher.isActive()) {
if (spinner)
spinner.warn(chalk_1.default.yellow('Development mode is already running'));
console.log(chalk_1.default.yellow('ā ļø Development mode is already active'));
return;
}
if (spinner)
spinner.setText('Starting development mode with hot-reloading...');
const hotReloadOptions = {
enabled: true,
verbose: options.verbose || false,
debounceMs: options.debounce || 500,
validateOnChange: !options.noValidation,
autoBackup: !options.noBackup,
restoreOnError: !options.noRestore,
includeWorkspaces: !options.excludeWorkspaces
};
try {
await (0, config_watcher_1.setupConfigHotReload)(hotReloadOptions);
if (spinner) {
spinner.succeed(chalk_1.default.green('Development mode started with hot-reloading'));
}
console.log(chalk_1.default.green('š Development mode active'));
console.log(chalk_1.default.cyan(' Configuration files are now being watched for changes'));
if (hotReloadOptions.verbose) {
console.log(chalk_1.default.gray(' Use --verbose for detailed change notifications'));
}
console.log(chalk_1.default.gray(' Run `re-shell dev stop` to disable hot-reloading\n'));
// Setup event listeners for development feedback
setupDevModeListeners(hotReloadOptions.verbose || false);
}
catch (error) {
if (spinner)
spinner.fail(chalk_1.default.red('Failed to start development mode'));
throw error;
}
}
async function stopDevelopmentMode(options, spinner) {
if (!config_watcher_1.configWatcher.isActive()) {
if (spinner)
spinner.warn(chalk_1.default.yellow('Development mode is not running'));
console.log(chalk_1.default.yellow('ā ļø Development mode is not active'));
return;
}
if (spinner)
spinner.setText('Stopping development mode...');
try {
await config_watcher_1.configWatcher.stopWatching();
if (spinner) {
spinner.succeed(chalk_1.default.green('Development mode stopped'));
}
console.log(chalk_1.default.green('š Development mode deactivated'));
console.log(chalk_1.default.gray(' Configuration hot-reloading has been disabled\n'));
}
catch (error) {
if (spinner)
spinner.fail(chalk_1.default.red('Failed to stop development mode'));
throw error;
}
}
async function restartDevelopmentMode(options, spinner) {
if (spinner)
spinner.setText('Restarting development mode...');
try {
if (config_watcher_1.configWatcher.isActive()) {
await config_watcher_1.configWatcher.stopWatching();
}
// Brief pause to ensure cleanup
await new Promise(resolve => setTimeout(resolve, 100));
await startDevelopmentMode(options, spinner);
if (spinner) {
spinner.succeed(chalk_1.default.green('Development mode restarted'));
}
}
catch (error) {
if (spinner)
spinner.fail(chalk_1.default.red('Failed to restart development mode'));
throw error;
}
}
async function showDevModeStatus(options, spinner) {
if (spinner)
spinner.setText('Checking development mode status...');
const status = config_watcher_1.configWatcher.getStatus();
if (spinner)
spinner.stop();
if (options.json) {
console.log(JSON.stringify(status, null, 2));
return;
}
console.log(chalk_1.default.cyan('\\nš§ Development Mode Status'));
console.log(chalk_1.default.gray('ā'.repeat(40)));
if (status.isWatching) {
console.log(`\\nā
${chalk_1.default.green('Active')} - Configuration hot-reloading enabled`);
if (status.watchedPaths.length > 0) {
console.log(`\\nš Watched paths (${status.watchedPaths.length}):`);
for (const path of status.watchedPaths) {
console.log(` ⢠${chalk_1.default.gray(path)}`);
}
}
console.log(`\\nāļø Options:`);
console.log(` Debounce: ${status.options.debounceMs}ms`);
console.log(` Validation: ${status.options.validateOnChange ? 'ā
' : 'ā'}`);
console.log(` Auto backup: ${status.options.autoBackup ? 'ā
' : 'ā'}`);
console.log(` Error restore: ${status.options.restoreOnError ? 'ā
' : 'ā'}`);
console.log(` Include workspaces: ${status.options.includeWorkspaces ? 'ā
' : 'ā'}`);
console.log(` Verbose logging: ${status.options.verbose ? 'ā
' : 'ā'}`);
}
else {
console.log(`\\nā ${chalk_1.default.red('Inactive')} - Configuration hot-reloading disabled`);
console.log(chalk_1.default.gray(' Run `re-shell dev start` to enable hot-reloading'));
}
console.log(chalk_1.default.cyan('\\nš ļø Available Commands:'));
console.log(' ⢠re-shell dev start [options]');
console.log(' ⢠re-shell dev stop');
console.log(' ⢠re-shell dev restart [options]');
console.log(' ⢠re-shell dev interactive');
}
async function showDevModeHelp() {
console.log(chalk_1.default.cyan('\\nš§ Development Mode - Configuration Hot-Reloading'));
console.log(chalk_1.default.gray('ā'.repeat(60)));
console.log('\\nDevelopment mode enables automatic reloading of configuration files');
console.log('when they change, providing instant feedback during development.');
console.log(chalk_1.default.cyan('\\nš Quick Start:'));
console.log(' re-shell dev start # Start with default settings');
console.log(' re-shell dev start --verbose # Start with detailed logging');
console.log(' re-shell dev interactive # Interactive setup');
console.log(chalk_1.default.cyan('\\nš Features:'));
console.log(' ⢠Real-time configuration file watching');
console.log(' ⢠Automatic validation on changes');
console.log(' ⢠Error recovery with backup/restore');
console.log(' ⢠Debounced change detection');
console.log(' ⢠Support for global, project, and workspace configs');
console.log(chalk_1.default.cyan('\\nāļø Options:'));
console.log(' --verbose Enable detailed change notifications');
console.log(' --debounce <ms> Change detection delay (default: 500ms)');
console.log(' --no-validation Skip configuration validation');
console.log(' --no-backup Disable automatic backups');
console.log(' --no-restore Disable error recovery');
console.log(' --exclude-workspaces Skip workspace configuration watching');
}
async function interactiveDevMode(options, spinner) {
if (spinner)
spinner.stop();
const currentStatus = config_watcher_1.configWatcher.getStatus();
const response = await (0, prompts_1.default)([
{
type: 'select',
name: 'action',
message: 'What would you like to do?',
choices: [
{
title: currentStatus.isWatching ? 'š Stop development mode' : 'š Start development mode',
value: currentStatus.isWatching ? 'stop' : 'start'
},
{ title: 'š Restart development mode', value: 'restart' },
{ title: 'āļø Configure hot-reload options', value: 'configure' },
{ title: 'š Show current status', value: 'status' },
{ title: 'š Force reload configurations', value: 'force-reload' }
]
}
]);
if (!response.action)
return;
switch (response.action) {
case 'start':
await interactiveStart();
break;
case 'stop':
await stopDevelopmentMode(options);
break;
case 'restart':
await restartDevelopmentMode(options);
break;
case 'configure':
await interactiveConfigure();
break;
case 'status':
await showDevModeStatus(options);
break;
case 'force-reload':
await forceReloadConfigs();
break;
}
}
async function interactiveStart() {
const response = await (0, prompts_1.default)([
{
type: 'toggle',
name: 'verbose',
message: 'Enable verbose logging?',
initial: false,
active: 'yes',
inactive: 'no'
},
{
type: 'number',
name: 'debounce',
message: 'Debounce delay (milliseconds):',
initial: 500,
min: 100,
max: 5000
},
{
type: 'toggle',
name: 'validation',
message: 'Validate configurations on change?',
initial: true,
active: 'yes',
inactive: 'no'
},
{
type: 'toggle',
name: 'autoBackup',
message: 'Create automatic backups before changes?',
initial: true,
active: 'yes',
inactive: 'no'
},
{
type: 'toggle',
name: 'restoreOnError',
message: 'Restore from backup on validation errors?',
initial: true,
active: 'yes',
inactive: 'no'
},
{
type: 'toggle',
name: 'includeWorkspaces',
message: 'Watch workspace configurations?',
initial: true,
active: 'yes',
inactive: 'no'
}
]);
const options = {
verbose: response.verbose,
debounce: response.debounce,
noValidation: !response.validation,
noBackup: !response.autoBackup,
noRestore: !response.restoreOnError,
excludeWorkspaces: !response.includeWorkspaces
};
await startDevelopmentMode(options);
}
async function interactiveConfigure() {
const currentOptions = config_watcher_1.configWatcher.getStatus().options;
const response = await (0, prompts_1.default)([
{
type: 'toggle',
name: 'verbose',
message: 'Verbose logging:',
initial: currentOptions.verbose,
active: 'enabled',
inactive: 'disabled'
},
{
type: 'number',
name: 'debounceMs',
message: 'Debounce delay (ms):',
initial: currentOptions.debounceMs,
min: 100,
max: 5000
},
{
type: 'toggle',
name: 'validateOnChange',
message: 'Validate on change:',
initial: currentOptions.validateOnChange,
active: 'enabled',
inactive: 'disabled'
},
{
type: 'toggle',
name: 'autoBackup',
message: 'Auto backup:',
initial: currentOptions.autoBackup,
active: 'enabled',
inactive: 'disabled'
},
{
type: 'toggle',
name: 'restoreOnError',
message: 'Restore on error:',
initial: currentOptions.restoreOnError,
active: 'enabled',
inactive: 'disabled'
},
{
type: 'toggle',
name: 'includeWorkspaces',
message: 'Include workspaces:',
initial: currentOptions.includeWorkspaces,
active: 'enabled',
inactive: 'disabled'
}
]);
config_watcher_1.configWatcher.updateOptions(response);
console.log(chalk_1.default.green('ā
Configuration updated'));
}
async function forceReloadConfigs() {
try {
await config_watcher_1.configWatcher.forceReload();
console.log(chalk_1.default.green('ā
Configurations force-reloaded'));
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to force reload:'), error);
}
}
function setupDevModeListeners(verbose) {
config_watcher_1.configWatcher.on('config-changed', (event) => {
if (verbose) {
console.log(chalk_1.default.green(`š ${event.configType} config updated: ${event.path}`));
}
});
config_watcher_1.configWatcher.on('config-error', (event) => {
console.error(chalk_1.default.red(`ā ${event.configType} config error: ${event.error?.message}`));
});
config_watcher_1.configWatcher.on('watching-started', () => {
if (verbose) {
console.log(chalk_1.default.green('š File watching started'));
}
});
config_watcher_1.configWatcher.on('watching-stopped', () => {
if (verbose) {
console.log(chalk_1.default.gray('šļø File watching stopped'));
}
});
}