UNPKG

@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

205 lines (204 loc) 7.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProgressBar = exports.MultiStepProgress = exports.ProgressTracker = void 0; exports.createProgressTracker = createProgressTracker; exports.createMultiStepProgress = createMultiStepProgress; exports.createProgressBar = createProgressBar; const chalk_1 = __importDefault(require("chalk")); const spinner_1 = require("./spinner"); // Enhanced progress tracker with substeps class ProgressTracker { constructor(title, totalSteps) { this.currentStep = 0; this.stepName = ''; this.totalSteps = totalSteps; this.spinner = new spinner_1.ProgressSpinner({ text: this.formatText(title) }); } start() { this.spinner.start(); return this; } nextStep(stepName) { this.currentStep++; this.stepName = stepName; this.spinner.setText(this.formatText(stepName)); return this; } updateStep(message) { this.spinner.setText(this.formatText(message)); return this; } succeed(message) { this.spinner.succeed(message || `✅ All ${this.totalSteps} steps completed successfully!`); return this; } fail(message) { this.spinner.fail(message || `❌ Failed at step ${this.currentStep}/${this.totalSteps}: ${this.stepName}`); return this; } stop() { this.spinner.stop(); return this; } formatText(text) { if (this.totalSteps > 1) { const progress = this.currentStep > 0 ? ` (${this.currentStep}/${this.totalSteps})` : ''; return `${text}${progress}`; } return text; } } exports.ProgressTracker = ProgressTracker; // Enhanced multi-step operations with better UX class MultiStepProgress { constructor(title, steps) { this.steps = []; this.steps = steps.map(name => ({ name, status: 'pending' })); this.isInteractive = Boolean(process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.CI && !process.env.RE_SHELL_NO_SPINNER); this.spinner = new spinner_1.ProgressSpinner({ text: title }); } start() { if (this.isInteractive) { this.spinner.start(); this.updateDisplay(); } else { console.log(chalk_1.default.cyan('⏳ Starting multi-step process...')); this.steps.forEach((step, index) => { console.log(chalk_1.default.gray(` ${index + 1}. ${step.name}`)); }); } return this; } startStep(stepIndex) { if (stepIndex >= 0 && stepIndex < this.steps.length) { this.steps[stepIndex].status = 'running'; this.updateDisplay(); } return this; } completeStep(stepIndex) { if (stepIndex >= 0 && stepIndex < this.steps.length) { this.steps[stepIndex].status = 'completed'; this.updateDisplay(); } return this; } failStep(stepIndex) { if (stepIndex >= 0 && stepIndex < this.steps.length) { this.steps[stepIndex].status = 'failed'; this.updateDisplay(); } return this; } succeed(message) { if (this.isInteractive) { this.spinner.succeed(message || 'All steps completed successfully!'); } else { console.log(chalk_1.default.green('✅'), message || 'All steps completed successfully!'); } return this; } fail(message) { if (this.isInteractive) { this.spinner.fail(message || 'Process failed'); } else { console.log(chalk_1.default.red('❌'), message || 'Process failed'); } return this; } stop() { this.spinner.stop(); return this; } updateDisplay() { if (!this.isInteractive) { // For non-interactive, just log the current step const runningStep = this.steps.find(s => s.status === 'running'); const completedCount = this.steps.filter(s => s.status === 'completed').length; if (runningStep) { console.log(chalk_1.default.cyan(`⏳ [${completedCount}/${this.steps.length}] ${runningStep.name}`)); } return; } const completedCount = this.steps.filter(s => s.status === 'completed').length; const runningStep = this.steps.find(s => s.status === 'running'); const failedStep = this.steps.find(s => s.status === 'failed'); let text = ''; if (failedStep) { text = `❌ Failed: ${failedStep.name}`; } else if (runningStep) { text = `[${completedCount}/${this.steps.length}] ${runningStep.name}`; } else if (completedCount === this.steps.length) { text = `✅ All ${this.steps.length} steps completed`; } else { text = `Preparing... (${completedCount}/${this.steps.length})`; } this.spinner.setText(text); } } exports.MultiStepProgress = MultiStepProgress; // Simple progress bar for file operations class ProgressBar { constructor(title, total) { this.current = 0; this.total = total; this.title = title; this.spinner = new spinner_1.ProgressSpinner({ text: this.formatText() }); } start() { this.spinner.start(); return this; } increment(amount = 1) { this.current = Math.min(this.current + amount, this.total); this.spinner.setText(this.formatText()); return this; } setProgress(current) { this.current = Math.min(Math.max(current, 0), this.total); this.spinner.setText(this.formatText()); return this; } succeed(message) { this.spinner.succeed(message || `${this.title} completed`); return this; } fail(message) { this.spinner.fail(message || `${this.title} failed`); return this; } formatText() { const percentage = Math.round((this.current / this.total) * 100); const progressBar = this.createProgressBar(percentage); return `${this.title} ${progressBar} ${this.current}/${this.total} (${percentage}%)`; } createProgressBar(percentage) { const width = 20; const filled = Math.round((percentage / 100) * width); const empty = width - filled; return `[${'█'.repeat(filled)}${'░'.repeat(empty)}]`; } } exports.ProgressBar = ProgressBar; // Factory functions for common progress patterns function createProgressTracker(title, steps) { return new ProgressTracker(title, steps); } function createMultiStepProgress(title, steps) { return new MultiStepProgress(title, steps); } function createProgressBar(title, total) { return new ProgressBar(title, total); }