UNPKG

tools.xsh

Version:

Enhanced terminal with auto-completion, encryption/decryption, and automatic package management

308 lines (273 loc) 11.8 kB
#!/usr/bin/env node const readline = require('readline'); const chalk = require('chalk'); const fs = require('fs-extra'); const path = require('path'); const { spawn, exec } = require('child_process'); const crypto = require('crypto'); const glob = require('glob'); class XSHTerminal { constructor() { this.rl = null; this.currentPath = process.cwd(); this.commandHistory = []; this.autoCompleteCommands = [ 'npm install', 'npm i', 'npm start', 'npm run', 'npm test', 'pip install', 'pip list', 'pip show', 'pip uninstall', 'python', 'python3', 'node', 'git', 'cd', 'ls', 'dir', 'mkdir', 'rmdir', 'touch', 'rm', 'cp', 'mv' ]; this.init(); } init() { console.clear(); this.showHeader(); this.checkAndInstallPackages(); this.createInterface(); } showHeader() { const header = chalk.bgMagenta.white.bold(' XSH ') + ' Enhanced Terminal'; console.log(header); console.log(chalk.gray('─'.repeat(50))); console.log(chalk.cyan('Welcome to XSH Terminal!')); console.log(chalk.gray('Type "help" for available commands\n')); } createInterface() { this.rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: this.getPrompt(), completer: this.autoComplete.bind(this) }); this.rl.on('line', (input) => { this.handleCommand(input.trim()); }); this.rl.on('close', () => { console.log(chalk.yellow('\nGoodbye!')); process.exit(0); }); this.rl.prompt(); } getPrompt() { const pathDisplay = this.currentPath.length > 30 ? '...' + this.currentPath.slice(-27) : this.currentPath; return chalk.bgMagenta.white(' XSH ') + chalk.cyan(` ${pathDisplay} `) + chalk.white('> '); } autoComplete(line) { const hits = this.autoCompleteCommands.filter((cmd) => cmd.startsWith(line)); // Package.json tabanlı otomatik tamamlama if (line.startsWith('npm i') || line.startsWith('npm install')) { const packageSuggestions = this.getPackageSuggestions(); hits.push(...packageSuggestions.filter(pkg => pkg.startsWith(line))); } return [hits.length ? hits : this.autoCompleteCommands, line]; } getPackageSuggestions() { const packageJsonPath = path.join(this.currentPath, 'package.json'); const suggestions = []; if (fs.existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }; Object.keys(dependencies).forEach(pkg => { suggestions.push(`npm install ${pkg}`); suggestions.push(`npm i ${pkg}`); }); } catch (error) { // Ignore JSON parse errors } } return suggestions; } async handleCommand(input) { if (!input) { this.rl.prompt(); return; } this.commandHistory.push(input); // XSH özel komutları if (input.includes('xsh.encrypt')) { this.handleEncryption(input); } else if (input.includes('xsh.decrypt')) { this.handleDecryption(input); } else if (input === 'help') { this.showHelp(); } else if (input === 'clear') { console.clear(); this.showHeader(); } else if (input.startsWith('cd ')) { this.changeDirectory(input.slice(3)); } else if (input === 'exit' || input === 'quit') { this.rl.close(); return; } else { // Normal komutları çalıştır await this.executeCommand(input); } this.rl.setPrompt(this.getPrompt()); this.rl.prompt(); } handleEncryption(input) { const match = input.match(/xsh\.encrypt\s*\{\s*type\s*:\s*(\w+)\s*,\s*text\s*:\s*\(([^)]+)\)\s*\}/); if (match) { const [, type, text] = match; const encrypted = this.encrypt(text, type); console.log(chalk.green(`Encrypted (${type}): ${encrypted}`)); } else { console.log(chalk.red('Invalid encryption syntax. Use: xsh.encrypt{type:sha256, text:(your text)}')); } } handleDecryption(input) { const match = input.match(/xsh\.decrypt\s*\(\s*([^)]+)\s*\)/); if (match) { const [, encryptedText] = match; console.log(chalk.yellow('Note: Decryption of hashed values (like SHA256) is not possible.')); console.log(chalk.yellow('Only reversible encryption methods can be decrypted.')); } else { console.log(chalk.red('Invalid decryption syntax. Use: xsh.decrypt(encrypted_text)')); } } encrypt(text, type = 'sha256') { try { switch (type.toLowerCase()) { case 'sha256': return crypto.createHash('sha256').update(text).digest('hex'); case 'md5': return crypto.createHash('md5').update(text).digest('hex'); case 'base64': return Buffer.from(text).toString('base64'); case 'aes256': // Basit XOR tabanlı şifreleme (AES256 yerine) const keyStr = 'default-xsh-key-for-encryption-32'; let result = ''; for (let i = 0; i < text.length; i++) { const keyChar = keyStr.charCodeAt(i % keyStr.length); const textChar = text.charCodeAt(i); result += String.fromCharCode(textChar ^ keyChar); } return Buffer.from(result).toString('base64'); case 'rot13': return text.replace(/[a-zA-Z]/g, function(c) { return String.fromCharCode( (c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26 ); }); default: return crypto.createHash('sha256').update(text).digest('hex'); } } catch (error) { console.log(chalk.red(`Encryption error: ${error.message}`)); return null; } } decrypt(encryptedText, type = 'base64') { try { switch (type.toLowerCase()) { case 'base64': return Buffer.from(encryptedText, 'base64').toString('utf8'); case 'aes256': // Basit XOR tabanlı şifre çözme const keyStr = 'default-xsh-key-for-encryption-32'; const decoded = Buffer.from(encryptedText, 'base64').toString(); let result = ''; for (let i = 0; i < decoded.length; i++) { const keyChar = keyStr.charCodeAt(i % keyStr.length); const encChar = decoded.charCodeAt(i); result += String.fromCharCode(encChar ^ keyChar); } return result; case 'rot13': // ROT13 kendi tersini alır return encryptedText.replace(/[a-zA-Z]/g, function(c) { return String.fromCharCode( (c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26 ); }); case 'sha256': case 'md5': throw new Error(`${type.toUpperCase()} is a one-way hash and cannot be decrypted`); default: throw new Error(`Unsupported decryption type: ${type}`); } } catch (error) { console.log(chalk.red(`Decryption error: ${error.message}`)); return null; } } changeDirectory(newPath) { try { const targetPath = path.resolve(this.currentPath, newPath); if (fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory()) { this.currentPath = targetPath; process.chdir(targetPath); console.log(chalk.green(`Changed directory to: ${this.currentPath}`)); } else { console.log(chalk.red(`Directory not found: ${newPath}`)); } } catch (error) { console.log(chalk.red(`Error changing directory: ${error.message}`)); } } async executeCommand(command) { return new Promise((resolve) => { const child = spawn(command, [], { shell: true, cwd: this.currentPath, stdio: 'inherit' }); child.on('close', (code) => { if (code !== 0) { console.log(chalk.red(`Command exited with code ${code}`)); } resolve(); }); child.on('error', (error) => { console.log(chalk.red(`Error executing command: ${error.message}`)); resolve(); }); }); } async checkAndInstallPackages() { const packageJsonPath = path.join(this.currentPath, 'package.json'); const nodeModulesPath = path.join(this.currentPath, 'node_modules'); if (fs.existsSync(packageJsonPath) && !fs.existsSync(nodeModulesPath)) { console.log(chalk.yellow('📦 Package.json found but node_modules missing. Installing packages...')); await this.executeCommand('npm install'); } // Python requirements.txt kontrolü const requirementsPath = path.join(this.currentPath, 'requirements.txt'); if (fs.existsSync(requirementsPath)) { console.log(chalk.yellow('🐍 Requirements.txt found. Checking Python packages...')); // Python paketlerini kontrol et ve güncelle await this.executeCommand('pip install -r requirements.txt'); } } showHelp() { console.log(chalk.cyan('\n📖 XSH Terminal Help:')); console.log(chalk.white('─'.repeat(40))); console.log(chalk.green('🔐 Encryption:')); console.log(' xsh.encrypt{type:sha256, text:(your text)}'); console.log(' xsh.encrypt{type:md5, text:(your text)}'); console.log(' xsh.encrypt{type:base64, text:(your text)}'); console.log(' xsh.encrypt{type:aes256, text:(your text)}'); console.log(' xsh.encrypt{type:rot13, text:(your text)}'); console.log(chalk.green('\n🔓 Decryption:')); console.log(' xsh.decrypt(encrypted_text) - For base64, aes256, rot13'); console.log(' Note: SHA256 and MD5 are one-way hashes'); console.log(chalk.green('\n📁 Navigation:')); console.log(' cd <directory> - Change directory'); console.log(' clear - Clear screen'); console.log(' exit/quit - Exit XSH'); console.log(chalk.green('\n✨ Features:')); console.log(' • Auto-completion with TAB'); console.log(' • Automatic package installation'); console.log(' • Smart command suggestions'); console.log(' • Package.json dependency detection\n'); } } // XSH Terminal'i başlat if (require.main === module) { new XSHTerminal(); } module.exports = XSHTerminal;