@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
172 lines (147 loc) ⢠5.94 kB
JavaScript
import { execSync } from 'child_process';
import { createRequire } from 'module';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
const require = createRequire(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Colors for console output
const colors = {
reset: '\x1b[0m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
cyan: '\x1b[36m'
};
function log(message, color = 'reset') {
console.log(`${colors[color]}${message}${colors.reset}`);
}
async function checkAndRebuildSqlite() {
try {
// Try to load better-sqlite3
const Database = require('better-sqlite3');
// Try to create a test database to ensure it's fully functional
const testDb = new Database(':memory:');
testDb.exec('CREATE TABLE test (id INTEGER)');
testDb.close();
log('ā
better-sqlite3 is compatible with your Node.js version', 'green');
return true;
} catch (error) {
if (error.message.includes('NODE_MODULE_VERSION') ||
error.message.includes('was compiled against a different Node.js version') ||
error.message.includes('The module') && error.message.includes('was compiled')) {
log('ā ļø better-sqlite3 needs to be rebuilt for your Node.js version', 'yellow');
log(`Current Node.js version: ${process.version}`, 'cyan');
// Check if we're in a global npm install or local
const isGlobal = process.env.npm_config_global === 'true';
const npmPrefix = process.env.npm_config_prefix;
if (isGlobal) {
log('š¦ Detected global installation', 'cyan');
}
// Try to find better-sqlite3 location
const possiblePaths = [
path.join(__dirname, '..', 'node_modules', 'better-sqlite3'),
path.join(process.cwd(), 'node_modules', 'better-sqlite3'),
];
if (npmPrefix) {
possiblePaths.push(
path.join(npmPrefix, 'node_modules', '@simonecoelhosfo', 'optimizely-mcp-server', 'node_modules', 'better-sqlite3'),
path.join(npmPrefix, 'node_modules', 'better-sqlite3')
);
}
let sqlitePath = null;
for (const p of possiblePaths) {
if (fs.existsSync(p)) {
sqlitePath = p;
break;
}
}
if (!sqlitePath) {
log('ā Could not locate better-sqlite3 module', 'red');
log('Please manually rebuild with: npm rebuild better-sqlite3', 'yellow');
return false;
}
log(`š Found better-sqlite3 at: ${sqlitePath}`, 'cyan');
// Check if node-gyp is available
try {
execSync('node-gyp --version', { stdio: 'pipe' });
} catch (e) {
log('š¦ Installing node-gyp for rebuild...', 'cyan');
try {
execSync('npm install -g node-gyp', { stdio: 'inherit' });
} catch (installError) {
log('ā Failed to install node-gyp. Trying npm rebuild instead...', 'yellow');
// Try npm rebuild as fallback
try {
log('šØ Attempting npm rebuild better-sqlite3...', 'cyan');
execSync('npm rebuild better-sqlite3', {
stdio: 'inherit',
cwd: path.join(__dirname, '..'),
timeout: 120000 // 2 minutes timeout
});
log('ā
Successfully rebuilt better-sqlite3!', 'green');
return true;
} catch (rebuildError) {
log('ā npm rebuild failed', 'red');
return false;
}
}
}
// Try to rebuild with node-gyp
try {
log('šØ Rebuilding better-sqlite3 for your Node.js version...', 'cyan');
execSync('node-gyp rebuild', {
cwd: sqlitePath,
stdio: 'inherit',
timeout: 120000 // 2 minutes timeout
});
log('ā
Successfully rebuilt better-sqlite3!', 'green');
// Verify it works now
const Database = require('better-sqlite3');
const testDb = new Database(':memory:');
testDb.close();
return true;
} catch (rebuildError) {
log('ā Rebuild failed. Trying npm rebuild as fallback...', 'yellow');
// Try npm rebuild as last resort
try {
execSync('npm rebuild better-sqlite3', {
stdio: 'inherit',
cwd: path.join(__dirname, '..'),
timeout: 120000
});
log('ā
Successfully rebuilt better-sqlite3 using npm!', 'green');
return true;
} catch (npmRebuildError) {
log('ā All rebuild attempts failed', 'red');
log('Please try manually:', 'yellow');
log(' 1. npm rebuild better-sqlite3', 'cyan');
log(' 2. Or reinstall: npm uninstall better-sqlite3 && npm install better-sqlite3', 'cyan');
log(' 3. See docs: https://github.com/WiseLibs/better-sqlite3/blob/master/docs/troubleshooting.md', 'cyan');
return false;
}
}
} else {
// Some other error
log(`ā Error loading better-sqlite3: ${error.message}`, 'red');
return false;
}
}
}
// Don't run during npm install if silent
const npmLogLevel = process.env.npm_config_loglevel;
const isSilent = npmLogLevel === 'silent' ||
npmLogLevel === 'error' ||
process.env.npm_config_silent === 'true';
if (!isSilent) {
checkAndRebuildSqlite().then(success => {
if (!success) {
// Don't exit with error during install - just warn
log('\nā ļø The MCP server may not work properly until better-sqlite3 is rebuilt', 'yellow');
log('š See: docs/BETTER-SQLITE3-REBUILD-GUIDE.md for manual instructions\n', 'cyan');
}
}).catch(err => {
log(`\nā ļø Unexpected error during SQLite check: ${err.message}`, 'yellow');
});
}