diff --git a/start.js b/start.js new file mode 100644 index 0000000..fa51a1b --- /dev/null +++ b/start.js @@ -0,0 +1,93 @@ +require('dotenv').config(); +const fs = require('fs'); +const path = require('path'); +const chalk = require('chalk'); + +const clientsDir = path.join(__dirname, 'clients'); +const forcedVersion = process.env.FORCE_CLIENT_VERSION; +const bootLogPath = path.join(__dirname, '.boot'); +const fallbackLogFile = path.join(bootLogPath, 'fallback.log'); + +if (!fs.existsSync(bootLogPath)) fs.mkdirSync(bootLogPath); +fs.writeFileSync(fallbackLogFile, '=== Fallback Log ===\n'); + +function compareVersions(a, b) { + const [aMajor, aMinor, aPatch] = a.split('.').map(Number); + const [bMajor, bMinor, bPatch] = b.split('.').map(Number); + if (aMajor !== bMajor) return bMajor - aMajor; + if (aMinor !== bMinor) return bMinor - aMinor; + return bPatch - aPatch; +} + +function getClientVersions() { + return fs.readdirSync(clientsDir) + .filter(file => file.endsWith('.js')) + .map(f => f.replace(/\.js$/, '')) + .filter(v => /^\d+\.\d+\.\d+$/.test(v)) + .sort(compareVersions); // sort versions in descending order +} + +function logFallback(message) { + const timestamp = new Date().toISOString(); + fs.appendFileSync(fallbackLogFile, `[${timestamp}] ${message}\n`, 'utf8'); +} + +function startClient(version, latest, filePath) { + try { + process.env.CLIENT_VERSION = version; + process.env.LATEST_VERSION = latest; + + console.log(chalk.green(`✅ Launching client version: ${version}`)); + require(filePath); + } catch (err) { + console.log(chalk.red(`❌ Failed to load version ${version}:`)); + logFallback(`Failed to load version ${version}: ${err.message}`); + + if (forcedVersion) { + console.error(chalk.red(`🛑 Forced version failed. No fallback allowed.`)); + process.exit(1); + } + + return false; // allow fallback to prior version + } + + return true; +} + +function boot() { + const versions = getClientVersions(); + + if (versions.length === 0) { + console.error(chalk.red('❌ No valid client versions found in /clients.')); + process.exit(1); + } + + const latest = versions[0]; + + if (forcedVersion) { + const filePath = path.join(clientsDir, `${forcedVersion}.js`); + if (!fs.existsSync(filePath)) { + console.error(chalk.red(`❌ Forced version '${forcedVersion}' not found.`)); + logFallback(`Forced version '${forcedVersion}' not found.`); + process.exit(1); + } + + console.log(chalk.yellow(`⚠ī¸ Forced version detected: ${forcedVersion}`)); + startClient(forcedVersion, latest, filePath); + return; + } + + for (const version of versions) { + const filePath = path.join(clientsDir, `${version}.js`); + const success = startClient(version, latest, filePath); + if (success) return; + + console.log(chalk.yellow(`↩ī¸ Falling back to next available version...`)); + } + + console.log(chalk.red('❌ All client versions failed to load. Giving up.')); + logFallback('All client versions failed to load. Giving up.'); + process.exit(1); +} + +boot();