Rustelo/scripts/build/build-highlight-bundle.js
Jesús Pérez 7cab57b645
Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
chore: update layout and files
2026-02-08 20:18:46 +00:00

172 lines
5.3 KiB
JavaScript

#!/usr/bin/env node
/**
* Build custom highlight.js bundle by downloading and combining CDN files
* This creates a single local file with all required languages
*
* Usage:
* node scripts/build-highlight-bundle.js
*
* This generates a bundle at public/js/highlight-bundle.min.js
*/
const fs = require('fs');
const path = require('path');
const https = require('https');
// Languages we want to include (in addition to core languages)
const additionalLanguages = [
'rust',
'typescript',
'bash',
'yaml',
'dockerfile',
'sql',
'python',
'ini', // For TOML-like syntax
'properties', // Also TOML-like syntax
'markdown'
];
const CDN_BASE = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0';
function downloadFile(url) {
return new Promise((resolve, reject) => {
https.get(url, (response) => {
if (response.statusCode !== 200) {
reject(new Error(`HTTP ${response.statusCode}: ${url}`));
return;
}
let data = '';
response.on('data', (chunk) => data += chunk);
response.on('end', () => resolve(data));
}).on('error', reject);
});
}
async function buildBundle() {
try {
// Ensure output directory exists first
const outputDir = path.join(__dirname, '../public/js');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Check if bundle already exists and is recent (less than 24 hours old)
const outputPath = path.join(outputDir, 'highlight-bundle.min.js');
if (fs.existsSync(outputPath)) {
const stats = fs.statSync(outputPath);
const fileAge = Date.now() - stats.mtime.getTime();
const maxAge = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
if (fileAge < maxAge) {
const fileSizeKB = Math.round(stats.size / 1024);
const ageHours = Math.round(fileAge / (60 * 60 * 1000));
console.log('✅ Highlight.js bundle already exists and is recent!');
console.log(`📁 File: ${outputPath}`);
console.log(`📊 Size: ${fileSizeKB}KB`);
console.log(`⏰ Age: ${ageHours}h (created: ${stats.mtime.toLocaleString()})`);
console.log('🎯 Languages: Core JS/HTML/CSS/JSON/XML + ' + additionalLanguages.join(', '));
console.log('💡 To force rebuild, delete the file or wait 24 hours');
return;
} else {
console.log('🔄 Bundle exists but is older than 24 hours, rebuilding...');
}
}
console.log('🔨 Building highlight.js bundle from CDN...');
console.log(`📦 Including core + ${additionalLanguages.length} additional languages: ${additionalLanguages.join(', ')}`);
// Download core highlight.js
console.log('📥 Downloading core highlight.js...');
const coreJs = await downloadFile(`${CDN_BASE}/highlight.min.js`);
let bundleContent = `/*! Custom Highlight.js Bundle for Rustelo
* Generated on ${new Date().toISOString()}
* Core + Additional Languages: ${additionalLanguages.join(', ')}
* Based on Highlight.js 11.9.0 from CDN
*/
// Core highlight.js
${coreJs}
// Additional language definitions
(function() {
if (typeof hljs === 'undefined') {
console.error('Highlight.js core not available');
return;
}
`;
// Download and add each language
console.log('📝 Downloading language definitions...');
for (const lang of additionalLanguages) {
try {
console.log(` 📥 Downloading: ${lang}`);
const langJs = await downloadFile(`${CDN_BASE}/languages/${lang}.min.js`);
// Wrap the language code to register it properly
bundleContent += `
// Language: ${lang}
(function() {
${langJs}
})();
`;
console.log(` ✅ Added: ${lang}`);
} catch (error) {
console.log(` ❌ Failed to download ${lang}: ${error.message}`);
}
}
// Close the bundle
bundleContent += `
})();
// Auto-initialize when DOM is ready
if (typeof document !== 'undefined') {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
if (typeof hljs !== 'undefined' && hljs.highlightAll) {
hljs.configure({ ignoreUnescapedHTML: true });
hljs.highlightAll();
}
});
} else {
// DOM already ready
if (typeof hljs !== 'undefined' && hljs.highlightAll) {
hljs.configure({ ignoreUnescapedHTML: true });
hljs.highlightAll();
}
}
}
`;
// Write the bundle (directory already created at the start)
fs.writeFileSync(outputPath, bundleContent);
// Get file size
const stats = fs.statSync(outputPath);
const fileSizeKB = Math.round(stats.size / 1024);
console.log(`✅ Highlight.js bundle created successfully!`);
console.log(`📁 Output: ${outputPath}`);
console.log(`📊 Size: ${fileSizeKB}KB`);
console.log(`🎯 Languages: Core JS/HTML/CSS/JSON/XML + ${additionalLanguages.join(', ')}`);
console.log('');
console.log('🚀 Ready to use! The bundle includes:');
console.log(' - Auto-initialization on DOM ready');
console.log(' - All required languages pre-registered');
console.log(' - Single HTTP request instead of multiple CDN calls');
} catch (error) {
console.error('❌ Error building bundle:', error.message);
process.exit(1);
}
}
buildBundle();