UNPKG

vaporwaver-ts

Version:

TypeScript version of the Vaporwaver Python library. Vaporwaver is a Python library for generating vaporwave image art.

125 lines 5.23 kB
import { spawn } from "child_process"; export class DependencyError extends Error { constructor(message, details = {}) { super(message); this.details = details; this.name = 'DependencyError'; } } export class DependencyChecker { static async checkPython(minVersion = '3.7.0') { try { const version = await this.getPythonVersion(); if (!this.isVersionSatisfied(version, minVersion)) { throw new DependencyError(`Python version ${minVersion} or higher is required. Found: ${version}`); } } catch (error) { if (error instanceof DependencyError) throw error; throw new DependencyError('Python is not installed or not accessible'); } } static async checkPythonDependencies() { try { const deps = await this.getInstalledPythonPackages(); const required = ['Pillow', 'glitch-this', 'opencv-python']; const missing = required.filter(dep => !deps.some(installed => installed.toLowerCase().startsWith(dep.toLowerCase()))); if (missing.length > 0) { // Try to install missing dependencies await this.installMissingDependencies(missing); } } catch (error) { throw new DependencyError('Failed to verify Python dependencies', { originalError: error }); } } static async getPythonVersion() { return new Promise((resolve, reject) => { const python = spawn(this.pythonCommand, ['--version']); let output = ''; python.stdout.on('data', (data) => { output += data; }); python.stderr.on('data', (data) => { output += data; }); python.on('close', (code) => { if (code === 0) { const version = output.match(/(\d+\.\d+\.\d+)/); if (version) { resolve(version[1]); } else { reject(new Error('Could not parse Python version')); } } else { reject(new Error(`Python check failed with code ${code}`)); } }); }); } static async getInstalledPythonPackages() { return new Promise((resolve, reject) => { const pip = spawn(this.pipCommand, ['freeze']); let output = ''; pip.stdout.on('data', (data) => { output += data; }); pip.stderr.on('data', () => { }); pip.on('close', (code) => { if (code === 0) { resolve(output.split('\n').filter(Boolean)); } else { reject(new Error('Failed to get installed packages')); } }); }); } static async installMissingDependencies(packages) { // Try different installation methods const methods = [ { cmd: this.pipCommand, args: ['install', '--user'] }, { cmd: this.pipCommand, args: ['install'] }, { cmd: this.pythonCommand, args: ['-m', 'pip', 'install', '--user'] }, { cmd: this.pythonCommand, args: ['-m', 'pip', 'install'] } ]; for (const method of methods) { try { await this.tryInstallMethod(method.cmd, [...method.args, ...packages]); return; // Installation successful } catch (error) { console.warn(`Installation attempt failed with method ${method.cmd}`, error); // Continue to next method } } throw new DependencyError('Failed to install Python dependencies. Please install manually:\n' + `${this.pythonCommand} -m pip install ${packages.join(' ')}`); } static async tryInstallMethod(cmd, args) { return new Promise((resolve, reject) => { const install = spawn(cmd, args); let output = ''; install.stdout.on('data', (data) => { output += data; }); install.stderr.on('data', (data) => { output += data; }); install.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Installation failed with code ${code}\n${output}`)); } }); }); } static isVersionSatisfied(current, required) { const parseVersion = (v) => v.split('.').map(Number); const [currentMajor, currentMinor, currentPatch] = parseVersion(current); const [reqMajor, reqMinor, reqPatch] = parseVersion(required); if (currentMajor !== reqMajor) return currentMajor > reqMajor; if (currentMinor !== reqMinor) return currentMinor > reqMinor; return currentPatch >= reqPatch; } } DependencyChecker.pythonCommand = process.platform === 'win32' ? 'python' : 'python3'; DependencyChecker.pipCommand = process.platform === 'win32' ? 'pip' : 'pip3'; //# sourceMappingURL=dependency-checker.js.map