harmony-plugin-manager
Version:
A comprehensive TypeScript library for generating harmonious color palettes with WCAG 2.1 accessibility compliance
624 lines • 22.4 kB
TypeScript
/**
* Plugin Manager Builder - Fluent configuration and composition API
*
* The PluginManagerBuilder provides a fluent, expressive API for configuring
* complex plugin arrangements. It's designed to make plugin management more
* readable and maintainable, especially for large applications with many plugins.
*
* ## Key Benefits
*
* - **Fluent Interface**: Method chaining for readable configuration
* - **Conditional Logic**: Runtime decisions about plugin inclusion
* - **Grouping**: Organize related plugins with shared tags
* - **Priority Management**: Easy priority assignment and ordering
* - **Validation**: Pre-build validation of plugin configuration
* - **Cloning**: Create variations of plugin configurations
*
* ## Usage Patterns
*
* ### Basic Building
* ```typescript
* const manager = createPluginBuilder<string, string>()
* .plugin(validationPlugin)
* .plugin(transformPlugin)
* .plugin(outputPlugin)
* .build();
* ```
*
* ### Environment-Specific Configuration
* ```typescript
* const builder = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugin(corePlugin)
* .when(isDevelopment, debugPlugin)
* .when(isProduction, monitoringPlugin)
* .group({
* tag: 'validation',
* items: [
* { plugin: authPlugin, settings: { priority: 100 } },
* { plugin: inputValidationPlugin, settings: { priority: 90 } }
* ]
* });
* ```
*/
import type { IPlugin } from '../core/interfaces';
import type { PluginContext, PluginSettings } from '../core/types';
import { PluginManager } from '../manager';
export declare class PluginManagerBuilder<TInput = unknown, TOutput = unknown, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
private readonly manager;
/**
* Registers a single plugin with optional settings
*
* This is the fundamental building block for plugin registration.
* Each call adds one plugin to the manager's execution pipeline.
*
* @param plugin - Plugin instance to register
* @param settings - Optional plugin configuration settings
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Simple plugin registration
* const builder = createPluginBuilder<string, string>()
* .plugin(uppercasePlugin)
* .plugin(trimPlugin);
* ```
*
* @example
* ```typescript
* // Plugin registration with detailed settings
* const builder = createPluginBuilder<UserData, ProcessedUser>()
* .plugin(validationPlugin, {
* enabled: true,
* priority: 100,
* config: {
* strictMode: true,
* requiredFields: ['id', 'email'],
* customValidators: ['email-format', 'phone-format']
* }
* })
* .plugin(enrichmentPlugin, {
* priority: 50,
* config: {
* dataSources: ['user-preferences', 'activity-history'],
* cacheEnabled: true,
* cacheTtl: 300000 // 5 minutes
* }
* });
* ```
*
* @example
* ```typescript
* // Chained registration with different plugin types
* const apiBuilder = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugin(rateLimitingPlugin, {
* priority: 100,
* config: { maxRequests: 1000, windowMs: 60000 }
* })
* .plugin(authenticationPlugin, {
* priority: 90,
* config: { tokenExpiry: 3600, refreshEnabled: true }
* })
* .plugin(businessLogicPlugin, {
* priority: 50,
* config: { enableCaching: true, enableAudit: true }
* })
* .plugin(responseFormatterPlugin, {
* priority: 10,
* config: { includeMetadata: true, compression: 'gzip' }
* });
* ```
*/
plugin(plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>, settings?: Partial<PluginSettings>): this;
/**
* Registers multiple plugins with their respective settings
*
* Convenient method for bulk plugin registration when you have
* multiple plugins to register at once. Particularly useful for
* plugin suites or when loading plugins from configuration.
*
* @param plugins - Array of plugin configurations
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Bulk registration of related plugins
* const validationSuite = [
* { plugin: schemaValidationPlugin, settings: { priority: 100 } },
* { plugin: businessRuleValidationPlugin, settings: { priority: 90 } },
* { plugin: securityValidationPlugin, settings: { priority: 80 } }
* ];
*
* const builder = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugins(validationSuite)
* .plugin(mainBusinessLogicPlugin);
* ```
*
* @example
* ```typescript
* // Configuration-driven plugin loading
* const pluginConfigs = await loadPluginConfiguration();
*
* const pluginRegistrations = pluginConfigs.map(config => ({
* plugin: pluginRegistry.get(config.name),
* settings: {
* enabled: config.enabled,
* priority: config.priority,
* config: config.parameters
* }
* }));
*
* const builder = createPluginBuilder<DataRecord, ProcessedRecord>()
* .plugins(pluginRegistrations)
* .plugin(outputPlugin); // Always include output plugin
* ```
*
* @example
* ```typescript
* // Environment-specific plugin suites
* const developmentPlugins = [
* { plugin: debugPlugin, settings: { priority: 200 } },
* { plugin: performanceMonitorPlugin, settings: { priority: 190 } },
* { plugin: requestLoggerPlugin, settings: { priority: 180 } }
* ];
*
* const productionPlugins = [
* { plugin: metricsPlugin, settings: { priority: 200 } },
* { plugin: alertingPlugin, settings: { priority: 190 } },
* { plugin: auditPlugin, settings: { priority: 180 } }
* ];
*
* const builder = createPluginBuilder<UserRequest, UserResponse>()
* .plugin(corePlugin) // Always include core functionality
* .plugins(isDevelopment ? developmentPlugins : productionPlugins);
* ```
*/
plugins(plugins: Array<{
plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>;
settings?: Partial<PluginSettings>;
}>): this;
/**
* Conditionally registers a plugin based on a boolean condition
*
* Conditional registration allows you to include or exclude plugins
* based on runtime conditions such as environment variables,
* feature flags, configuration settings, or user preferences.
*
* @param condition - Whether to register the plugin (true = register)
* @param plugin - Plugin to register if condition is true
* @param settings - Optional plugin settings
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Environment-based conditional registration
* const isDevelopment = process.env.NODE_ENV === 'development';
* const isProduction = process.env.NODE_ENV === 'production';
* const enableDebug = process.env.DEBUG === 'true';
*
* const builder = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugin(corePlugin) // Always include
*
* // Development-only plugins
* .when(isDevelopment, debugPlugin)
* .when(isDevelopment, mockDataPlugin)
* .when(isDevelopment && enableDebug, verboseLoggingPlugin)
*
* // Production-only plugins
* .when(isProduction, performanceMonitoringPlugin)
* .when(isProduction, alertingPlugin)
* .when(isProduction, compressionPlugin);
* ```
*
* @example
* ```typescript
* // Feature flag-driven registration
* const featureFlags = await loadFeatureFlags();
*
* const builder = createPluginBuilder<UserData, ProcessedUser>()
* .plugin(basicProcessingPlugin)
*
* // Feature-specific plugins
* .when(featureFlags.enableRecommendations, recommendationPlugin)
* .when(featureFlags.enableAnalytics, analyticsPlugin)
* .when(featureFlags.enablePersonalization, personalizationPlugin, {
* config: {
* algorithm: featureFlags.personalizationAlgorithm,
* maxRecommendations: featureFlags.maxRecommendations
* }
* })
*
* // Beta features
* .when(featureFlags.betaFeatures && featureFlags.enableAI, aiProcessingPlugin);
* ```
*
* @example
* ```typescript
* // User preference-based registration
* const userPreferences = await loadUserPreferences(userId);
* const subscription = await getUserSubscription(userId);
*
* const builder = createPluginBuilder<UserContent, ProcessedContent>()
* .plugin(basicContentPlugin)
*
* // Preference-based plugins
* .when(userPreferences.enablePersonalization, personalizationPlugin)
* .when(userPreferences.enableNotifications, notificationPlugin)
* .when(userPreferences.privacyMode === false, analyticsPlugin)
*
* // Subscription-based features
* .when(subscription.tier === 'premium', premiumFeaturesPlugin)
* .when(subscription.tier === 'enterprise', enterpriseFeaturesPlugin)
* .when(subscription.addOns.includes('advanced-analytics'), advancedAnalyticsPlugin);
* ```
*/
when(condition: boolean, plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>, settings?: Partial<PluginSettings>): this;
/**
* Registers a group of plugins with a common tag
*
* Plugin grouping helps organize related plugins and makes it easier
* to manage plugin suites that work together. All plugins in a group
* will be tagged with the group's tag, making them easy to query and
* manage as a unit.
*
* @param plugins - Group configuration with tag and plugin items
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Validation plugin group
* const builder = createPluginBuilder<UserData, ProcessedUser>()
* .group({
* tag: 'validation',
* items: [
* {
* plugin: schemaValidationPlugin,
* settings: {
* priority: 100,
* config: { strictMode: true }
* }
* },
* {
* plugin: businessRuleValidationPlugin,
* settings: {
* priority: 90,
* config: { enableCustomRules: true }
* }
* },
* {
* plugin: securityValidationPlugin,
* settings: {
* priority: 80,
* config: { enableThreatDetection: true }
* }
* }
* ]
* });
*
* // Later, you can query validation plugins:
* // const validationPlugins = manager.getPluginsByTag('validation');
* ```
*
* @example
* ```typescript
* // Multiple functional groups
* const apiBuilder = createPluginBuilder<ApiRequest, ApiResponse>()
*
* // Security group
* .group({
* tag: 'security',
* items: [
* { plugin: authenticationPlugin, settings: { priority: 100 } },
* { plugin: authorizationPlugin, settings: { priority: 90 } },
* { plugin: rateLimitingPlugin, settings: { priority: 80 } }
* ]
* })
*
* // Processing group
* .group({
* tag: 'processing',
* items: [
* { plugin: validationPlugin, settings: { priority: 70 } },
* { plugin: transformationPlugin, settings: { priority: 60 } },
* { plugin: businessLogicPlugin, settings: { priority: 50 } }
* ]
* })
*
* // Output group
* .group({
* tag: 'output',
* items: [
* { plugin: formattingPlugin, settings: { priority: 20 } },
* { plugin: compressionPlugin, settings: { priority: 10 } },
* { plugin: cachePlugin, settings: { priority: 5 } }
* ]
* });
* ```
*
* @example
* ```typescript
* // Environment-specific groups
* const monitoringPlugins = isDevelopment
* ? [
* { plugin: debugPlugin, settings: { priority: 200 } },
* { plugin: performancePlugin, settings: { priority: 190 } }
* ]
* : [
* { plugin: metricsPlugin, settings: { priority: 200 } },
* { plugin: alertingPlugin, settings: { priority: 190 } },
* { plugin: auditPlugin, settings: { priority: 180 } }
* ];
*
* const builder = createPluginBuilder<DataRecord, ProcessedRecord>()
* .plugin(corePlugin)
* .group({
* tag: 'monitoring',
* items: monitoringPlugins
* });
* ```
*/
group(plugins: {
tag: string;
items: Array<{
plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>;
settings?: Partial<PluginSettings>;
}>;
}): this;
/**
* Registers a plugin with a specific priority
*
* Priority assignment determines the order of plugin execution within
* dependency levels. Higher priority plugins execute before lower priority
* ones. This method provides a convenient way to set priority without
* manually constructing settings objects.
*
* @param priority - Execution priority (higher = earlier execution)
* @param plugin - Plugin to register
* @param settings - Optional additional settings
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Clear priority-based ordering
* const builder = createPluginBuilder<ApiRequest, ApiResponse>()
* // Critical early processing (100-90)
* .withPriority(100, authenticationPlugin)
* .withPriority(95, rateLimitingPlugin)
* .withPriority(90, authorizationPlugin)
*
* // Validation and preprocessing (80-60)
* .withPriority(80, inputValidationPlugin)
* .withPriority(70, sanitizationPlugin)
* .withPriority(60, normalizationPlugin)
*
* // Core business logic (50-30)
* .withPriority(50, businessLogicPlugin)
* .withPriority(40, dataEnrichmentPlugin)
* .withPriority(30, calculationPlugin)
*
* // Output processing (20-10)
* .withPriority(20, responseFormattingPlugin)
* .withPriority(15, compressionPlugin)
* .withPriority(10, cachePlugin);
* ```
*
* @example
* ```typescript
* // Priority with additional configuration
* const builder = createPluginBuilder<UserData, ProcessedUser>()
* .withPriority(100, validationPlugin, {
* config: {
* strictMode: true,
* failFast: true,
* requiredFields: ['id', 'email']
* }
* })
* .withPriority(50, enrichmentPlugin, {
* config: {
* sources: ['database', 'cache', 'external-api'],
* timeout: 5000,
* fallbackEnabled: true
* }
* })
* .withPriority(10, outputPlugin, {
* config: {
* format: 'json',
* includeMetadata: true,
* compression: 'gzip'
* }
* });
* ```
*
* @example
* ```typescript
* // Dynamic priority assignment
* const config = await loadConfiguration();
*
* const builder = createPluginBuilder<DataRecord, ProcessedRecord>()
* .plugin(corePlugin); // Default priority (0)
*
* // Add plugins with computed priorities
* config.plugins.forEach((pluginConfig, index) => {
* const plugin = pluginRegistry.get(pluginConfig.name);
* const priority = config.basePriority + (config.plugins.length - index) * 10;
*
* builder.withPriority(priority, plugin, {
* enabled: pluginConfig.enabled,
* config: pluginConfig.settings
* });
* });
* ```
*/
withPriority(priority: number, plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>, settings?: Partial<PluginSettings>): this;
/**
* Registers a plugin in disabled state
*
* Disabled plugins are registered but won't execute until explicitly enabled.
* This is useful for plugins that you want to configure but activate later,
* or for plugins that should only run under specific conditions.
*
* @param plugin - Plugin to register as disabled
* @param settings - Optional additional settings
*
* @returns Builder instance for method chaining
*
* @example
* ```typescript
* // Register plugins that will be enabled conditionally later
* const builder = createPluginBuilder<UserRequest, UserResponse>()
* .plugin(corePlugin) // Always enabled
*
* // Disabled by default, enabled based on user tier
* .disabled(premiumFeaturesPlugin, {
* priority: 50,
* config: { featureSet: 'premium' }
* })
* .disabled(enterpriseFeaturesPlugin, {
* priority: 40,
* config: { featureSet: 'enterprise' }
* });
*
* // Later, before building, conditionally enable
* const userTier = await getUserTier(userId);
* if (userTier === 'premium') {
* manager.configure('premium-features-plugin', { enabled: true });
* } else if (userTier === 'enterprise') {
* manager.configure('enterprise-features-plugin', { enabled: true });
* }
* ```
*
* @example
* ```typescript
* // Feature flags with disabled plugins
* const builder = createPluginBuilder<DataRecord, ProcessedRecord>()
* .plugin(basicProcessingPlugin)
*
* // Register experimental features as disabled
* .disabled(experimentalAlgorithmPlugin, {
* priority: 60,
* config: { algorithm: 'ml-enhanced', version: 'beta' }
* })
* .disabled(advancedAnalyticsPlugin, {
* priority: 30,
* config: { realTimeProcessing: true }
* });
*
* // Enable based on feature flags
* const featureFlags = await loadFeatureFlags();
* const manager = builder.build();
*
* if (featureFlags.enableExperimental) {
* manager.configure('experimental-algorithm-plugin', { enabled: true });
* }
* if (featureFlags.enableAdvancedAnalytics) {
* manager.configure('advanced-analytics-plugin', { enabled: true });
* }
* ```
*/
disabled(plugin: IPlugin<TInput, TOutput, PluginContext<TMetadata>>, settings?: Partial<PluginSettings>): this;
/**
* Builds and returns the configured plugin manager
*
* Building finalizes the plugin configuration and creates a ready-to-use
* plugin manager. This process includes dependency resolution, execution
* order determination, and pipeline construction. After building, the
* manager cannot be reconfigured.
*
* @returns Built plugin manager ready for execution
*
* @throws {Error} When dependency resolution fails
* @throws {Error} When circular dependencies are detected
*
* @example
* ```typescript
* // Basic build
* const manager = createPluginBuilder<string, string>()
* .plugin(validationPlugin)
* .plugin(transformPlugin)
* .plugin(outputPlugin)
* .build(); // Now ready for execution
*
* const result = await manager.execute('input data', {});
* ```
*
* @example
* ```typescript
* // Build with error handling
* try {
* const manager = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugin(authPlugin)
* .plugin(businessLogicPlugin, { dependencies: ['auth-plugin'] })
* .plugin(responsePlugin, { dependencies: ['business-logic-plugin'] })
* .validate() // Optional: validate before building
* .build();
*
* console.log('Manager built successfully');
*
* } catch (error) {
* console.error('Build failed:', error.message);
* // Handle build failure
* }
* ```
*/
build(): PluginManager<TInput, TOutput, TMetadata>;
/**
* Validates the current builder configuration
*
* Validation checks the current plugin configuration for common issues
* before building. This can help catch configuration problems early
* and provide better error messages.
*
* @returns Builder instance for method chaining
*
* @throws {Error} When validation fails
*
* @example
* ```typescript
* // Validate before building
* const manager = createPluginBuilder<UserData, ProcessedUser>()
* .plugin(validationPlugin)
* .plugin(transformPlugin)
* .validate() // Throws if no plugins or other issues
* .build();
* ```
*/
validate(): this;
/**
* Creates a deep copy of the current builder configuration
*
* Cloning allows you to create variations of plugin configurations
* without modifying the original builder. This is useful for creating
* different configurations for different environments or use cases.
*
* @returns New builder instance with identical configuration
*
* @example
* ```typescript
* // Base configuration
* const baseBuilder = createPluginBuilder<ApiRequest, ApiResponse>()
* .plugin(authPlugin)
* .plugin(validationPlugin)
* .plugin(businessLogicPlugin);
*
* // Development variant
* const devBuilder = baseBuilder.clone()
* .plugin(debugPlugin)
* .plugin(mockDataPlugin);
*
* // Production variant
* const prodBuilder = baseBuilder.clone()
* .plugin(monitoringPlugin)
* .plugin(alertingPlugin)
* .plugin(compressionPlugin);
*
* const devManager = devBuilder.build();
* const prodManager = prodBuilder.build();
* ```
*/
clone(): PluginManagerBuilder<TInput, TOutput, TMetadata>;
}
//# sourceMappingURL=plugin-builder.d.ts.map