129 lines
4.0 KiB
JavaScript
129 lines
4.0 KiB
JavaScript
/**
|
|
* 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 };
|