@vooodooo/magic
Version:
Vooodooo - AI orchestration platform
248 lines • 10.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginLoader = void 0;
exports.createPluginLoader = createPluginLoader;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
/**
* Loader for Vooodooo plugins
*/
class PluginLoader {
constructor(pluginManager, options) {
this.pluginManager = pluginManager;
// Handle backwards compatibility with string argument
if (typeof options === 'string') {
this.options = { pluginsDir: options };
}
else {
this.options = {
pluginsDir: path_1.default.resolve(process.cwd(), 'plugins'),
autoLoadDependencies: true,
...options,
};
}
}
/**
* Load all plugins from the plugins directory
*/
async loadPlugins() {
// Check if plugins directory exists
const pluginsDir = this.options.pluginsDir;
if (!pluginsDir || !fs_1.default.existsSync(pluginsDir)) {
console.warn(`Plugins directory not found: ${pluginsDir}`);
return;
}
// Get subdirectories (one for each plugin)
const pluginDirs = fs_1.default
.readdirSync(pluginsDir, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => path_1.default.join(pluginsDir, dirent.name));
// Load each plugin
for (const pluginDir of pluginDirs) {
await this.loadPlugin(pluginDir);
}
}
/**
* Load a plugin from a directory
*/
async loadPlugin(pluginDir) {
try {
// Check for manifest
let manifestPath = path_1.default.join(pluginDir, 'manifest.json');
let isPackageJson = false;
// If manifest.json doesn't exist, try package.json
if (!fs_1.default.existsSync(manifestPath)) {
manifestPath = path_1.default.join(pluginDir, 'package.json');
isPackageJson = true;
if (!fs_1.default.existsSync(manifestPath)) {
console.warn(`No manifest found in plugin directory: ${pluginDir}`);
return;
}
}
// Load manifest
const manifestContent = fs_1.default.readFileSync(manifestPath, 'utf8');
const rawManifest = JSON.parse(manifestContent);
// Convert package.json to manifest if needed
const manifest = isPackageJson
? this.convertPackageToManifest(rawManifest, pluginDir)
: rawManifest;
// Check for main entry point
let mainPath;
// Handle different formats for the main field
if (isPackageJson) {
// If it's a package.json, use the main field or look for dist/index.js
const pkgMain = rawManifest.main || 'dist/index.js';
mainPath = path_1.default.join(pluginDir, pkgMain);
}
else {
// If it's a manifest.json, use the main field directly
mainPath = path_1.default.join(pluginDir, manifest.main);
}
if (!fs_1.default.existsSync(mainPath)) {
console.warn(`Main entry point not found: ${mainPath}`);
return;
}
// Load dependencies first if auto-loading is enabled
if (this.options.autoLoadDependencies && manifest.dependencies) {
await this.loadDependencies(manifest.dependencies);
}
// Dynamically import the plugin module
const pluginModule = await Promise.resolve(`${mainPath}`).then(s => __importStar(require(s)));
// Create plugin instance
let pluginInstance;
if (pluginModule.default) {
// If the module exports a class, instantiate it
if (typeof pluginModule.default === 'function') {
pluginInstance = new pluginModule.default();
}
// If the module exports an object, use it directly
else {
pluginInstance = pluginModule.default;
}
}
else {
console.warn(`Plugin module does not export a default: ${mainPath}`);
return;
}
// Ensure plugin has the required manifest
pluginInstance.manifest = manifest;
// Register the plugin
await this.pluginManager.registerPlugin(pluginInstance);
}
catch (error) {
console.error(`Error loading plugin from ${pluginDir}:`, error);
}
}
/**
* Load a plugin from a DiscoveredPlugin object
*/
async loadDiscoveredPlugin(discoveredPlugin) {
try {
const { path: pluginDir, manifest } = discoveredPlugin;
// Check the main entry point
let mainPath;
if (discoveredPlugin.source === 'npm') {
// NPM package - use main from package.json
const pkgMain = manifest.main || 'dist/index.js';
mainPath = path_1.default.join(pluginDir, pkgMain);
}
else {
// Local plugin - use main from manifest
mainPath = path_1.default.join(pluginDir, manifest.main);
}
if (!fs_1.default.existsSync(mainPath)) {
console.warn(`Main entry point not found: ${mainPath}`);
return;
}
// Load dependencies first if auto-loading is enabled
if (this.options.autoLoadDependencies && manifest.dependencies) {
await this.loadDependencies(manifest.dependencies);
}
// Dynamically import the plugin module
const pluginModule = await Promise.resolve(`${mainPath}`).then(s => __importStar(require(s)));
// Create plugin instance
let pluginInstance;
if (pluginModule.default) {
// If the module exports a class, instantiate it
if (typeof pluginModule.default === 'function') {
pluginInstance = new pluginModule.default();
}
// If the module exports an object, use it directly
else {
pluginInstance = pluginModule.default;
}
}
else {
console.warn(`Plugin module does not export a default: ${mainPath}`);
return;
}
// Ensure plugin has the required manifest
pluginInstance.manifest = manifest;
// Register the plugin
await this.pluginManager.registerPlugin(pluginInstance);
}
catch (error) {
console.error(`Error loading discovered plugin ${discoveredPlugin.id}:`, error);
}
}
/**
* Load plugin dependencies
*/
async loadDependencies(dependencies) {
// This is a simplified implementation
// A production system would resolve and load the dependencies
// For now, we just log them
console.log('Plugin dependencies:', dependencies);
}
/**
* Convert a package.json to a plugin manifest
*/
convertPackageToManifest(pkg, pluginDir) {
return {
id: pkg.name,
name: pkg.name.split('/').pop() || pkg.name,
version: pkg.version,
description: pkg.description || '',
author: {
name: typeof pkg.author === 'string'
? pkg.author
: pkg.author?.name || 'Unknown',
email: typeof pkg.author === 'object' ? pkg.author.email : undefined,
url: typeof pkg.author === 'object' ? pkg.author.url : undefined,
},
minPlatformVersion: '0.1.0',
main: pkg.main || 'dist/index.js',
dependencies: pkg.dependencies || {},
homepage: pkg.homepage,
repository: typeof pkg.repository === 'string'
? pkg.repository
: pkg.repository?.url,
license: pkg.license,
keywords: pkg.keywords || [],
};
}
}
exports.PluginLoader = PluginLoader;
/**
* Create a plugin loader instance
*/
function createPluginLoader(pluginManager, options) {
return new PluginLoader(pluginManager, options);
}
//# sourceMappingURL=plugin-loader.js.map