UNPKG

@invisiblecities/sidequest-cqo

Version:

Configuration-agnostic TypeScript and ESLint orchestrator with real-time watch mode, SQLite persistence, and intelligent terminal detection

152 lines 4.6 kB
/** * @fileoverview Base audit engine abstract class * * Provides the common interface and utilities that all audit engines must implement. * Handles error recovery, timing, and standardized result formatting. */ /** * Abstract base class for all audit engines * * Each engine is responsible for: * - Analyzing code for specific types of violations * - Handling errors gracefully without breaking the orchestrator * - Providing consistent violation format * - Implementing timeout and cancellation support */ export class BaseAuditEngine { engineName; source; config; abortController; constructor(engineName, source, config) { this.engineName = engineName; this.source = source; this.config = config; } /** * Execute the audit engine analysis * * @param targetPath - Directory or file to analyze * @param options - Engine-specific options * @returns Promise resolving to engine results */ async execute(targetPath, options = {}) { const startTime = Date.now(); this.abortController = new AbortController(); try { // Set up timeout if configured let timeoutId; if (this.config.timeout) { timeoutId = setTimeout(() => { this.abortController?.abort(); }, this.config.timeout); } // Execute the actual analysis const violations = await this.analyze(targetPath, options); // Clear timeout if analysis completed if (timeoutId) { clearTimeout(timeoutId); } const executionTime = Date.now() - startTime; return { engineName: this.engineName, violations, executionTime, success: true, metadata: { targetPath, violationsFound: violations.length, config: this.config, }, }; } catch (error) { const executionTime = Date.now() - startTime; const errorMessage = error instanceof Error ? error.message : String(error); // Log the error but don't throw if allowFailure is true console.warn(`[${this.engineName}] Analysis failed: ${errorMessage}`); if (!this.config.allowFailure) { throw error; } return { engineName: this.engineName, violations: [], executionTime, success: false, error: errorMessage, metadata: { targetPath, failureRecovery: true, }, }; } finally { this.abortController = undefined; } } /** * Check if the engine can be aborted */ get canAbort() { return this.abortController !== undefined; } /** * Abort the current analysis */ abort() { this.abortController?.abort(); } /** * Helper method to create standardized violations */ createViolation(file, line, code, category, severity, rule, message, column) { const violation = { file, line, code: code.trim(), category, severity, source: this.source, }; if (column !== undefined) { violation.column = column; } if (rule !== undefined) { violation.rule = rule; } if (message !== undefined) { violation.message = message; } const fixSuggestion = this.generateFixSuggestion?.(category, rule, code); if (fixSuggestion !== undefined) { violation.fixSuggestion = fixSuggestion; } return violation; } /** * Update engine configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } /** * Get current engine configuration */ getConfig() { return { ...this.config }; } /** * Get engine metadata */ getMetadata() { return { name: this.engineName, source: this.source, enabled: this.config.enabled, priority: this.config.priority, allowFailure: this.config.allowFailure, timeout: this.config.timeout, }; } } //# sourceMappingURL=base-engine.js.map