UNPKG

@api-buddy/plugin-utils

Version:

Shared utilities for API Buddy plugins

136 lines (119 loc) 3.53 kB
import type { Plugin, PluginContext, PluginHook, Logger } from '@api-buddy/types'; export interface PluginManagerOptions { cwd?: string; logger?: Partial<Logger>; pluginsDir?: string | string[]; nodeModulesDirs?: string[]; } /** * A simple plugin manager that handles loading and managing plugins. * Can be extended to add custom plugin functionality. */ export class SimplePluginManager { protected plugins: Map<string, Plugin> = new Map(); protected context: PluginContext; protected options: { pluginsDir: string[]; nodeModulesDirs: string[]; }; private defaultLogger: Logger = { info: console.log, warn: console.warn, error: console.error, debug: console.debug, }; constructor(options: PluginManagerOptions = {}) { this.options = { pluginsDir: Array.isArray(options.pluginsDir) ? options.pluginsDir : options.pluginsDir ? [options.pluginsDir] : [], nodeModulesDirs: options.nodeModulesDirs || [], }; this.context = { cwd: options.cwd || process.cwd(), logger: { ...this.defaultLogger, ...(options.logger || {}) }, config: {}, data: new Map(), utils: { registerHook: () => {}, unregisterHook: () => {}, callHook: async () => undefined, }, }; } /** * Register a plugin */ async registerPlugin(plugin: Plugin): Promise<void> { if (this.plugins.has(plugin.name)) { throw new Error(`Plugin with name '${plugin.name}' is already registered`); } try { // Initialize the plugin if it has an initialize method if (typeof plugin.initialize === 'function') { await plugin.initialize(this.context); } this.plugins.set(plugin.name, plugin); this.context.logger.info(`Registered plugin: ${plugin.name}@${plugin.version}`); } catch (error) { this.context.logger.error(`Failed to initialize plugin ${plugin.name}:`, error); throw error; } } /** * Get a registered plugin by name */ getPlugin<T extends Plugin = Plugin>(name: string): T | undefined { return this.plugins.get(name) as T | undefined; } /** * Get all registered plugins */ getPlugins(): Plugin[] { return Array.from(this.plugins.values()); } /** * Check if a plugin is registered */ hasPlugin(name: string): boolean { return this.plugins.has(name); } /** * Unregister a plugin */ async unregisterPlugin(name: string): Promise<boolean> { const plugin = this.plugins.get(name); if (!plugin) return false; try { // Clean up the plugin if it has a cleanup method if (typeof plugin.cleanup === 'function') { await plugin.cleanup(this.context); } this.plugins.delete(name); this.context.logger.info(`Unregistered plugin: ${name}`); return true; } catch (error) { this.context.logger.error(`Failed to cleanup plugin ${name}:`, error); return false; } } /** * Load plugins from the specified directories */ async loadPlugins(): Promise<void> { // Implementation for loading plugins from directories // This is a simplified version - in a real implementation, you would: // 1. Scan the plugin directories for plugin modules // 2. Import and initialize each plugin // 3. Register them with the plugin manager this.context.logger.info('Loading plugins...'); // Actual implementation would go here } }