UNPKG

supa-seed

Version:

A constraint-aware, framework-agnostic database seeding framework with deep PostgreSQL business logic discovery and MakerKit integration support

229 lines 7.97 kB
"use strict"; /** * Framework Strategy Registry * Manages registration and selection of framework strategies */ Object.defineProperty(exports, "__esModule", { value: true }); exports.StrategyRegistry = void 0; const logger_1 = require("../../core/utils/logger"); class StrategyRegistry { constructor(client, options = {}) { this.strategies = new Map(); this.client = client; this.options = { enableFallback: true, minimumConfidence: 0.3, debug: false, ...options }; } /** * Register a seeding strategy */ async register(strategy) { try { await strategy.initialize(this.client); this.strategies.set(strategy.name, strategy); if (this.options.debug) { logger_1.Logger.debug(`Registered strategy: ${strategy.name}`); } } catch (error) { logger_1.Logger.error(`Failed to register strategy ${strategy.name}:`, error); throw error; } } /** * Register multiple strategies */ async registerAll(strategies) { for (const strategy of strategies) { await this.register(strategy); } } /** * Unregister a strategy */ unregister(strategyName) { this.strategies.delete(strategyName); if (this.options.debug) { logger_1.Logger.debug(`Unregistered strategy: ${strategyName}`); } } /** * Get all registered strategies */ getStrategies() { return Array.from(this.strategies.values()); } /** * Get a specific strategy by name */ getStrategy(name) { return this.strategies.get(name); } /** * Select the best strategy for the given schema */ async selectStrategy(schema) { if (this.strategies.size === 0) { throw new Error('No strategies registered'); } const detectionResults = []; // Run detection on all strategies for (const strategy of this.strategies.values()) { try { const detection = await strategy.detect(schema); detectionResults.push({ strategy, detection }); if (this.options.debug) { logger_1.Logger.debug(`Strategy ${strategy.name} confidence: ${detection.confidence}`); } } catch (error) { logger_1.Logger.warn(`Strategy ${strategy.name} detection failed:`, error); } } if (detectionResults.length === 0) { throw new Error('No strategies could analyze the schema'); } // Sort by confidence and priority detectionResults.sort((a, b) => { const confidenceDiff = b.detection.confidence - a.detection.confidence; if (Math.abs(confidenceDiff) > 0.1) { return confidenceDiff; } return b.strategy.getPriority() - a.strategy.getPriority(); }); const bestResult = detectionResults[0]; // Check minimum confidence threshold if (bestResult.detection.confidence < this.options.minimumConfidence) { if (this.options.enableFallback) { const fallbackStrategy = this.findFallbackStrategy(); if (fallbackStrategy) { logger_1.Logger.warn(`Low confidence (${bestResult.detection.confidence}), using fallback strategy`); return { strategy: fallbackStrategy, detection: { framework: 'generic', confidence: 0.1, detectedFeatures: [], recommendations: ['Consider manual framework specification'] }, reason: 'fallback_low_confidence' }; } } throw new Error(`No strategy meets minimum confidence threshold (${this.options.minimumConfidence})`); } return { strategy: bestResult.strategy, detection: bestResult.detection, reason: 'best_match' }; } /** * Select strategy with manual override */ async selectStrategyWithOverride(schema, frameworkOverride) { if (frameworkOverride) { const strategy = this.strategies.get(frameworkOverride); if (strategy) { const detection = await strategy.detect(schema); return { strategy, detection, reason: 'manual_override' }; } else { logger_1.Logger.warn(`Override strategy '${frameworkOverride}' not found, falling back to auto-detection`); } } return this.selectStrategy(schema); } /** * Find the fallback strategy (typically generic) */ findFallbackStrategy() { // Look for strategies with 'generic' in the name first for (const [name, strategy] of this.strategies) { if (name.toLowerCase().includes('generic')) { return strategy; } } // Fall back to the strategy with lowest priority const strategies = Array.from(this.strategies.values()); if (strategies.length === 0) return undefined; strategies.sort((a, b) => a.getPriority() - b.getPriority()); return strategies[0]; } /** * Get detection results for all strategies */ async getAllDetectionResults(schema) { const results = []; for (const strategy of this.strategies.values()) { try { const detection = await strategy.detect(schema); results.push({ strategy: strategy.name, detection }); } catch (error) { logger_1.Logger.warn(`Detection failed for strategy ${strategy.name}:`, error); results.push({ strategy: strategy.name, detection: { framework: 'unknown', confidence: 0, detectedFeatures: [], recommendations: [`Detection failed: ${error.message}`] } }); } } return results; } /** * Validate that a strategy works with the current schema */ async validateStrategy(strategyName, schema) { const strategy = this.strategies.get(strategyName); if (!strategy) { return { valid: false, issues: [`Strategy '${strategyName}' not found`], recommendations: ['Register the strategy first'] }; } try { const detection = await strategy.detect(schema); const recommendations = strategy.getRecommendations(); return { valid: detection.confidence > 0, issues: detection.confidence === 0 ? ['Strategy not compatible with schema'] : [], recommendations }; } catch (error) { return { valid: false, issues: [`Strategy validation failed: ${error.message}`], recommendations: ['Check strategy implementation and schema compatibility'] }; } } /** * Clear all registered strategies */ clear() { this.strategies.clear(); if (this.options.debug) { logger_1.Logger.debug('Cleared all registered strategies'); } } } exports.StrategyRegistry = StrategyRegistry; //# sourceMappingURL=strategy-registry.js.map