"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pluginRegistry = void 0; const logger_1 = require("../config/logger"); /** * Registry central dos plugins. * Gerencia o lifecycle (activate/deactivate) e expõe metadados para a API admin. */ class PluginRegistry { entries = new Map(); ctx; /** Deve ser chamado uma vez no bootstrap com o contexto completo */ setContext(ctx) { this.ctx = ctx; } /** Registra plugins carregados (sem ativar ainda) */ register(plugins) { for (const { instance, manifest, dir } of plugins) { this.entries.set(manifest.name, { instance, manifest, active: false, dir }); } } /** Ativa todos os plugins marcados como enabled no manifest. * Plugins com dependências faltando são pulados com warning (não crasham o servidor). */ async activateAll() { for (const [name, entry] of this.entries) { if (!entry.manifest.enabled) continue; try { await this.activate(name); } catch (err) { logger_1.logger.warn({ name, err: err.message }, '[PluginRegistry] Plugin pulado na inicialização'); } } } async activate(name) { const entry = this.entries.get(name); if (!entry) throw new Error(`Plugin "${name}" não encontrado`); if (entry.active) return; // Verifica dependências for (const dep of entry.manifest.dependencies) { const depEntry = this.entries.get(dep); if (!depEntry?.active) { throw new Error(`Dependência "${dep}" do plugin "${name}" não está ativa`); } } try { await entry.instance.activate(this.ctx); entry.active = true; entry.manifest.enabled = true; logger_1.logger.info({ name }, '[PluginRegistry] Plugin ativado'); } catch (err) { logger_1.logger.error({ err, name }, '[PluginRegistry] Falha ao ativar plugin'); throw err; } } async deactivate(name) { const entry = this.entries.get(name); if (!entry) throw new Error(`Plugin "${name}" não encontrado`); if (!entry.active) return; if (!entry.manifest.canDisable) throw new Error(`Plugin "${name}" não pode ser desativado`); // Verifica se algum plugin ativo depende deste for (const [depName, depEntry] of this.entries) { if (depEntry.active && depEntry.manifest.dependencies.includes(name)) { throw new Error(`Plugin "${depName}" depende de "${name}". Desative-o primeiro.`); } } try { await entry.instance.deactivate(this.ctx); entry.active = false; entry.manifest.enabled = false; logger_1.logger.info({ name }, '[PluginRegistry] Plugin desativado'); } catch (err) { logger_1.logger.error({ err, name }, '[PluginRegistry] Falha ao desativar plugin'); throw err; } } /** Retorna lista de todos os plugins com status para a API admin */ list() { return Array.from(this.entries.entries()).map(([name, entry]) => ({ name, ...entry })); } getEntry(name) { return this.entries.get(name); } /** * Força reativação de um plugin sem passar pelo deactivate. * Útil quando canDisable=false mas a config foi atualizada e precisa ser relida. */ async reactivate(name) { const entry = this.entries.get(name); if (!entry) throw new Error(`Plugin "${name}" não encontrado`); entry.active = false; await this.activate(name); logger_1.logger.info({ name }, '[PluginRegistry] Plugin reativado com nova config'); } /** Retorna menu items de todos os plugins ativos */ getActiveMenuItems() { return Array.from(this.entries.values()) .filter((e) => e.active && e.manifest.frontend?.menuItems?.length) .map((e) => ({ pluginName: e.manifest.name, items: e.manifest.frontend })); } } exports.pluginRegistry = new PluginRegistry();