UNPKG

kist

Version:

Package Pipeline Processor

181 lines (180 loc) 6.87 kB
"use strict"; // ============================================================================ // Import // ============================================================================ Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionRegistry = void 0; const fs_1 = require("fs"); const path_1 = require("path"); const CoreActions_1 = require("../../actions/CoreActions"); const AbstractProcess_1 = require("../abstract/AbstractProcess"); // ============================================================================ // Class // ============================================================================ /** * ActionRegistry is a singleton registry for step actions, mapping action * names to their corresponding classes. This registry allows dynamic * resolution of step actions within the pipeline and supports custom * developer integrations. */ class ActionRegistry extends AbstractProcess_1.AbstractProcess { // Constructor // ======================================================================== /** * Constructs an ActionRegistry instance and automatically registers core * actions. The constructor is private to enforce the singleton pattern. */ constructor() { // Initialize logging through AbstractProcess super(); this.registry = new Map(); // Automatically register core actions this.registerCoreActions(); this.discoverPlugins(); this.logInfo("ActionRegistry initialized."); } // Singleton Methods // ======================================================================== /** * Initializes the singleton instance of ActionRegistry. * Should only be called once during application startup. * * @throws Error if the registry has already been initialized. */ static initialize() { if (ActionRegistry.instance) { throw new Error("ActionRegistry has already been initialized."); } ActionRegistry.instance = new ActionRegistry(); } /** * Retrieves the singleton instance of ActionRegistry, initializing it if * necessary. * * @returns The ActionRegistry instance. */ static getInstance() { if (!ActionRegistry.instance) { ActionRegistry.instance = new ActionRegistry(); } return ActionRegistry.instance; } /** * Resets the singleton instance of ActionRegistry. * This is useful for testing or resetting the registry state during * runtime. */ static resetInstance() { ActionRegistry.instance = null; } // Instance Methods // ======================================================================== /** * Registers a new action in the registry. * * @param actionClass - The class implementing `ActionInterface`. * @throws Error if the action name is already registered or missing. */ registerAction(actionClass) { const actionInstance = new actionClass(); const name = actionInstance.name; if (!name || typeof name !== "string") { throw new Error(`[ActionRegistry] Action class must have a valid 'name' property.`); } if (this.registry.has(name)) { throw new Error(`[ActionRegistry] Action "${name}" is already registered.`); } this.registry.set(name, actionClass); this.logInfo(`Action "${name}" registered successfully.`); } /** * Retrieves a step action class from the registry. * This method looks up an action by name and returns the corresponding * class that implements the ActionInterface. * * @param name - The name of the action to retrieve. * @returns The action class constructor if found, or undefined if no such * action is registered. */ getAction(name) { // Validate the input name if (!name || typeof name !== "string") { this.logWarn(`Invalid action name requested: "${name}".`); return undefined; } // Retrieve the action from the registry const action = this.registry.get(name); // Log a warning if the action is not found if (!action) { this.logWarn(`Action "${name}" not found in the registry.`); } else { this.logDebug(`Retrieved action "${name}" from the registry.`); } return action; } /** * Lists all registered step actions. * Provides a utility to view currently registered actions, useful for * debugging and validation. * * @returns An array of registered action names. */ listRegisteredActions() { this.logDebug("Listing all registered actions."); return Array.from(this.registry.keys()); } /** * Pre-registers core actions that are included with the pipeline by * default. Developers can extend this by registering additional custom * actions as needed. */ registerCoreActions() { Object.values(CoreActions_1.coreActions).forEach((actionClass) => { this.registerAction(actionClass); }); this.logInfo("Core actions registered successfully."); } discoverPlugins() { this.logInfo("Discovering external plugins..."); const nodeModulesPath = (0, path_1.join)(process.cwd(), "node_modules"); const pluginPrefix = "@kist/plugin-"; try { const directories = (0, fs_1.readdirSync)(nodeModulesPath, { withFileTypes: true, }); for (const dir of directories) { if (dir.isDirectory() && dir.name.startsWith(pluginPrefix)) { const pluginPath = (0, path_1.join)(nodeModulesPath, dir.name); const plugin = require(pluginPath).default; if (plugin && typeof plugin.registerActions === "function") { const actions = plugin.registerActions(); for (const [name, actionClass] of Object.entries(actions)) { this.registerAction(actionClass); } } } } this.logInfo("Plugins loaded successfully."); } catch (error) { this.logError("Failed to discover plugins.", error); } } /** * Clears all registered actions in the registry. * Useful for testing or resetting the pipeline. */ clearRegistry() { this.registry.clear(); this.logInfo("Registry cleared."); } } exports.ActionRegistry = ActionRegistry; // Parameters // ======================================================================== /** * Singleton instance */ ActionRegistry.instance = null;