selah-cli
Version:
Zero-setup AWS deployment for Bolt.new apps. Build in Bolt, deploy to production in 3 minutes with AI guidance.
133 lines (110 loc) • 4.19 kB
JavaScript
const JavaScriptObfuscator = require('javascript-obfuscator');
const fs = require('fs');
const path = require('path');
console.log('🔒 Obfuscating CLI code for production...');
// Obfuscation configuration for maximum protection while maintaining functionality
const obfuscationOptions = {
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: true,
debugProtectionInterval: 2000,
disableConsoleOutput: false, // Keep console for CLI feedback
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false, // Preserve global Node.js APIs
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true,
unicodeEscapeSequence: false
};
// Function to obfuscate a single file
function obfuscateFile(filePath) {
try {
const code = fs.readFileSync(filePath, 'utf8');
// Skip already obfuscated files
if (code.includes('_0x')) {
console.log(`⏭️ Skipping already obfuscated: ${filePath}`);
return;
}
console.log(`🔄 Obfuscating: ${filePath}`);
const obfuscated = JavaScriptObfuscator.obfuscate(code, obfuscationOptions);
// Add header comment to obfuscated file
const header = `#!/usr/bin/env node
// Selah CLI - Production build (obfuscated)
// Original source protected - Generated ${new Date().toISOString()}
`;
const finalCode = header + obfuscated.getObfuscatedCode();
// Create backup
const backupPath = filePath + '.original';
if (!fs.existsSync(backupPath)) {
fs.copyFileSync(filePath, backupPath);
}
fs.writeFileSync(filePath, finalCode);
console.log(`✅ Obfuscated: ${filePath}`);
} catch (error) {
console.error(`❌ Error obfuscating ${filePath}:`, error.message);
}
}
// Function to recursively find and obfuscate JS files
function obfuscateDirectory(dirPath, excludePatterns = []) {
if (!fs.existsSync(dirPath)) {
console.log(`⚠️ Directory does not exist: ${dirPath}`);
return;
}
const items = fs.readdirSync(dirPath);
for (const item of items) {
const itemPath = path.join(dirPath, item);
const stat = fs.statSync(itemPath);
// Skip excluded patterns
if (excludePatterns.some(pattern => itemPath.includes(pattern))) {
continue;
}
if (stat.isDirectory()) {
obfuscateDirectory(itemPath, excludePatterns);
} else if (item.endsWith('.js') && !item.endsWith('.original') && !item.endsWith('.min.js')) {
obfuscateFile(itemPath);
}
}
}
// Main obfuscation process
try {
const distPath = path.join(__dirname, '..', 'dist');
if (!fs.existsSync(distPath)) {
console.error('❌ Dist directory not found. Run npm run build:cli first.');
process.exit(1);
}
console.log('🔒 Starting code obfuscation...');
console.log(`📁 Target directory: ${distPath}`);
// Obfuscate all CLI files
obfuscateDirectory(distPath, [
'node_modules',
'.git',
'test',
'spec'
]);
console.log('');
console.log('✅ Code obfuscation complete!');
console.log('🔐 Your source code is now protected for NPM publication');
console.log('💡 Original files backed up with .original extension');
} catch (error) {
console.error('❌ Obfuscation failed:', error.message);
process.exit(1);
}