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

254 lines (253 loc) 11.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkForUpdates = checkForUpdates; exports.runUpdateCommand = runUpdateCommand; const https = __importStar(require("https")); const semver = __importStar(require("semver")); const chalk_1 = __importDefault(require("chalk")); const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const child_process_1 = require("child_process"); async function checkForUpdates(currentVersion) { try { // Check if we should skip the update check (e.g., in CI environments) if (process.env.CI || process.env.RE_SHELL_SKIP_UPDATE_CHECK) { return; } // Check if we've recently checked for updates (within last 24 hours) const cacheFile = path.join(process.env.HOME || process.env.USERPROFILE || '', '.re-shell-update-check'); if (await fs.pathExists(cacheFile)) { const lastCheck = await fs.readJson(cacheFile).catch(() => null); if (lastCheck && Date.now() - lastCheck.timestamp < 86400000) { // 24 hours // If there was a cached update notification, show it if (lastCheck.hasUpdate) { showUpdateNotification(currentVersion, lastCheck.latestVersion); } return; } } // Fetch latest version from npm registry const latestVersion = await fetchLatestVersion('@re-shell/cli'); if (latestVersion && semver.gt(latestVersion, currentVersion)) { // Cache the update check result await fs.writeJson(cacheFile, { timestamp: Date.now(), hasUpdate: true, latestVersion }).catch(() => { }); showUpdateNotification(currentVersion, latestVersion); } else { // Cache that no update is needed await fs.writeJson(cacheFile, { timestamp: Date.now(), hasUpdate: false, latestVersion }).catch(() => { }); } } catch (error) { // Silently ignore update check errors to not disrupt the CLI usage } } function fetchLatestVersion(packageName) { return new Promise((resolve) => { const options = { hostname: 'registry.npmjs.org', path: `/${packageName}`, method: 'GET', timeout: 3000 // 3 second timeout }; const req = https.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { const packageInfo = JSON.parse(data); resolve(packageInfo['dist-tags'].latest); } catch { resolve(null); } }); }); req.on('error', () => resolve(null)); req.on('timeout', () => { req.destroy(); resolve(null); }); req.end(); }); } function showUpdateNotification(currentVersion, latestVersion) { console.log(); console.log(chalk_1.default.yellow('╔════════════════════════════════════════════════════════════════╗')); console.log(chalk_1.default.yellow('║') + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + chalk_1.default.bold.white(' Update available! ') + chalk_1.default.gray(`${currentVersion} → `) + chalk_1.default.green.bold(latestVersion) + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + ' Run ' + chalk_1.default.cyan.bold('npm install -g @re-shell/cli@latest') + ' to update ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + chalk_1.default.gray(' Changelog: https://github.com/Re-Shell/cli/releases') + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('║') + ' ' + chalk_1.default.yellow('║')); console.log(chalk_1.default.yellow('╚════════════════════════════════════════════════════════════════╝')); console.log(); // Force flush output process.stdout.write(''); process.stderr.write(''); } async function runUpdateCommand() { const { createSpinner, flushOutput } = await Promise.resolve().then(() => __importStar(require('./spinner'))); const prompts = await Promise.resolve().then(() => __importStar(require('prompts'))); const spinner = createSpinner('Checking for updates...').start(); flushOutput(); try { const packageJsonPath = path.resolve(__dirname, '../../package.json'); const packageJson = await fs.readJson(packageJsonPath); const currentVersion = packageJson.version; const latestVersion = await fetchLatestVersion('@re-shell/cli'); if (!latestVersion) { spinner.fail(chalk_1.default.red('Unable to check for updates. Please check your internet connection.')); return; } if (semver.gt(latestVersion, currentVersion)) { spinner.succeed(chalk_1.default.green(`Update available: ${currentVersion}${latestVersion}`)); console.log(); // Ask user if they want to update automatically const response = await prompts.default({ type: 'confirm', name: 'shouldUpdate', message: `Do you want to update to version ${latestVersion} now?`, initial: true }); if (response.shouldUpdate) { // Detect package manager const packageManager = detectPackageManager(); const updateSpinner = createSpinner(`Updating @re-shell/cli using ${packageManager}...`).start(); try { await performUpdate(packageManager); updateSpinner.succeed(chalk_1.default.green(`Successfully updated to @re-shell/cli@${latestVersion}!`)); console.log(); console.log(chalk_1.default.green('🎉 Update completed! You can now use the latest features.')); } catch (error) { updateSpinner.fail(chalk_1.default.red('Update failed')); console.log(); console.log(chalk_1.default.yellow('Please update manually using one of these commands:')); console.log(chalk_1.default.bold(' npm install -g @re-shell/cli@latest')); console.log(' yarn global add @re-shell/cli@latest'); console.log(' pnpm add -g @re-shell/cli@latest'); } } else { console.log(); console.log(chalk_1.default.yellow('Update skipped. To update later, run:')); console.log(chalk_1.default.bold(' re-shell update')); } } else { spinner.succeed(chalk_1.default.green(`You're using the latest version (${currentVersion})`)); } } catch (error) { spinner.fail(chalk_1.default.red('Error checking for updates')); console.error(error); } } function detectPackageManager() { // Try to detect which package manager was used to install re-shell const execPath = process.env._ || ''; if (execPath.includes('pnpm')) return 'pnpm'; if (execPath.includes('yarn')) return 'yarn'; // Check if pnpm is available try { require('child_process').execSync('pnpm --version', { stdio: 'ignore' }); return 'pnpm'; } catch { // pnpm not available } // Check if yarn is available try { require('child_process').execSync('yarn --version', { stdio: 'ignore' }); return 'yarn'; } catch { // yarn not available } // Default to npm return 'npm'; } function performUpdate(packageManager) { return new Promise((resolve, reject) => { let command; let args; switch (packageManager) { case 'pnpm': command = 'pnpm'; args = ['add', '-g', '@re-shell/cli@latest']; break; case 'yarn': command = 'yarn'; args = ['global', 'add', '@re-shell/cli@latest']; break; default: command = 'npm'; args = ['install', '-g', '@re-shell/cli@latest']; } const child = (0, child_process_1.spawn)(command, args, { stdio: 'pipe', shell: true }); child.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Update process exited with code ${code}`)); } }); child.on('error', (error) => { reject(error); }); }); }