@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
204 lines (203 loc) • 6.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.ProgressSpinner = void 0;
exports.createSpinner = createSpinner;
exports.flushOutput = flushOutput;
exports.isInteractiveTerminal = isInteractiveTerminal;
const ora_1 = __importDefault(require("ora"));
const chalk_1 = __importDefault(require("chalk"));
class ProgressSpinner {
constructor(options) {
// Check if we're in an interactive terminal
this.isInteractive = Boolean(process.stdout.isTTY &&
process.env.TERM !== 'dumb' &&
!process.env.CI &&
!process.env.RE_SHELL_NO_SPINNER);
if (this.isInteractive) {
this.spinner = (0, ora_1.default)({
text: options.text,
color: options.color || 'cyan',
stream: options.stream || process.stdout,
// Enhanced configuration for better terminal compatibility
discardStdin: false,
hideCursor: true,
indent: 0,
spinner: 'dots'
});
}
else {
// For non-interactive terminals, just log the message
console.log(chalk_1.default.cyan('⏳'), options.text);
this.spinner = (0, ora_1.default)(); // Create dummy spinner
}
}
start() {
if (this.isInteractive) {
this.spinner.start();
// Force flush the output immediately
this.forceFlush();
}
return this;
}
succeed(text) {
if (this.isInteractive) {
this.spinner.succeed(text);
this.spinner.stop(); // Ensure spinner is fully stopped
}
else {
console.log(chalk_1.default.green('✅'), text || 'Done');
}
// Ensure final output is flushed and terminal is reset
this.finalFlush();
return this;
}
fail(text) {
if (this.isInteractive) {
this.spinner.fail(text);
this.spinner.stop(); // Ensure spinner is fully stopped
}
else {
console.log(chalk_1.default.red('❌'), text || 'Failed');
}
// Ensure final output is flushed and terminal is reset
this.finalFlush();
return this;
}
warn(text) {
if (this.isInteractive) {
this.spinner.warn(text);
}
else {
console.log(chalk_1.default.yellow('⚠️'), text || 'Warning');
}
return this;
}
info(text) {
if (this.isInteractive) {
this.spinner.info(text);
}
else {
console.log(chalk_1.default.blue('ℹ️'), text || 'Info');
}
return this;
}
stop() {
if (this.isInteractive) {
this.spinner.stop();
}
return this;
}
setText(text) {
if (this.isInteractive) {
this.spinner.text = text;
this.forceFlush();
}
else {
console.log(chalk_1.default.cyan('⏳'), text);
}
return this;
}
setColor(color) {
if (this.isInteractive) {
this.spinner.color = color;
}
return this;
}
clear() {
if (this.isInteractive) {
this.spinner.clear();
}
return this;
}
render() {
if (this.isInteractive) {
this.spinner.render();
this.forceFlush();
}
return this;
}
forceFlush() {
try {
// Multiple approaches to ensure output is flushed immediately
if (process.stdout.write('')) {
process.stdout.write('');
}
if (typeof process.stdout._flush === 'function') {
process.stdout._flush();
}
// Force a small delay to ensure output reaches terminal
process.nextTick(() => {
if (process.stdout.isTTY) {
process.stdout.write('\x1b[?25l'); // Hide cursor
process.stdout.write('\x1b[?25h'); // Show cursor
}
});
}
catch (error) {
// Ignore flush errors - they're not critical
}
}
finalFlush() {
try {
// Final flush to ensure all output is displayed immediately
process.stdout.write('');
if (typeof process.stdout._flush === 'function') {
process.stdout._flush();
}
// Ensure cursor is visible and terminal is in proper state
if (process.stdout.isTTY) {
process.stdout.write('\x1b[?25h'); // Show cursor
process.stdout.write('\x1b[0m'); // Reset colors
}
// Force immediate flush with newline
console.log(''); // This ensures a newline and flushes output
}
catch (error) {
// Ignore flush errors - they're not critical
}
}
}
exports.ProgressSpinner = ProgressSpinner;
// Helper function to create a spinner
function createSpinner(text, color) {
return new ProgressSpinner({ text, color });
}
// Helper function to force flush output
function flushOutput() {
try {
// Force immediate output flushing
if (process.stdout.write('')) {
process.stdout.write('');
}
if (process.stderr.write('')) {
process.stderr.write('');
}
// Try additional flush methods if available
if (typeof process.stdout._flush === 'function') {
process.stdout._flush();
}
if (typeof process.stderr._flush === 'function') {
process.stderr._flush();
}
// Ensure output appears immediately in terminal
process.nextTick(() => {
if (process.stdout.isTTY) {
// Force a cursor movement to trigger terminal update
process.stdout.write('\x1b[0G');
}
});
}
catch (error) {
// Ignore flush errors - they're not critical
}
}
// Helper to detect if terminal supports interactive features
function isInteractiveTerminal() {
return Boolean(process.stdout.isTTY &&
process.env.TERM !== 'dumb' &&
!process.env.CI &&
!process.env.RE_SHELL_NO_SPINNER);
}