SpaceNinjaServer/scripts/plugin-discovery.js

128 lines
4.0 KiB
JavaScript
Raw Normal View History

/**
* Plugin Discovery Script
* This script runs during build time to discover all plugins and generate a registry
*/
const fs = require('fs');
const path = require('path');
class PluginDiscovery {
constructor(pluginsDir = 'plugins', outputPath = 'build/plugin-registry.json') {
this.pluginsDir = path.resolve(pluginsDir);
this.outputPath = path.resolve(outputPath);
}
/**
* Discover all plugins in the plugins directory
*/
discoverPlugins() {
const registry = {
plugins: [],
manifest: {},
buildTime: new Date().toISOString()
};
console.log(`🔍 Discovering plugins in: ${this.pluginsDir}`);
if (!fs.existsSync(this.pluginsDir)) {
console.log('⚠️ Plugins directory not found, creating empty registry');
return registry;
}
const pluginDirs = fs.readdirSync(this.pluginsDir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
for (const pluginDir of pluginDirs) {
const pluginPath = path.join(this.pluginsDir, pluginDir);
const manifest = this.loadPluginManifest(pluginPath);
if (manifest) {
registry.plugins.push(pluginPath);
registry.manifest[manifest.name] = manifest;
console.log(`✅ Found plugin: ${manifest.name} v${manifest.version}`);
} else {
console.log(`❌ Invalid plugin: ${pluginDir} (missing or invalid plugin.json)`);
}
}
console.log(`📦 Discovered ${registry.plugins.length} plugins`);
return registry;
}
/**
* Load and validate plugin manifest
*/
loadPluginManifest(pluginPath) {
try {
const manifestPath = path.join(pluginPath, 'plugin.json');
if (!fs.existsSync(manifestPath)) {
return null;
}
const manifestContent = fs.readFileSync(manifestPath, 'utf-8');
const manifest = JSON.parse(manifestContent);
// Validate required fields
if (!manifest.name || !manifest.version || !manifest.main) {
console.log(`⚠️ Invalid manifest in ${pluginPath}: missing required fields (name, version, main)`);
return null;
}
// Check if main file exists
const mainFile = path.join(pluginPath, manifest.main);
const mainTsFile = mainFile.replace(/\.js$/, '.ts');
if (!fs.existsSync(mainFile) && !fs.existsSync(mainTsFile)) {
console.log(`⚠️ Main file not found: ${mainFile} or ${mainTsFile}`);
return null;
}
return manifest;
} catch (error) {
console.log(`❌ Failed to load manifest from ${pluginPath}:`, error.message);
return null;
}
}
/**
* Save the plugin registry to file
*/
saveRegistry(registry) {
try {
// Ensure output directory exists
const outputDir = path.dirname(this.outputPath);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
fs.writeFileSync(this.outputPath, JSON.stringify(registry, null, 2));
console.log(`💾 Plugin registry saved to: ${this.outputPath}`);
} catch (error) {
console.error(`❌ Failed to save plugin registry:`, error.message);
process.exit(1);
}
}
/**
* Main execution function
*/
run() {
console.log('🚀 Starting plugin discovery...');
const registry = this.discoverPlugins();
this.saveRegistry(registry);
console.log('✨ Plugin discovery completed!');
}
}
// Run the plugin discovery if this script is executed directly
if (require.main === module) {
const discovery = new PluginDiscovery();
discovery.run();
}
module.exports = { PluginDiscovery };