/** * Automation configuration module for environment-based adapter selection. * * This module provides configuration types and loaders for the automation system, * allowing switching between different adapters based on environment variables. */ export type AutomationMode = 'dev' | 'production' | 'mock'; export interface AutomationEnvironmentConfig { mode: AutomationMode; /** Dev mode configuration (Browser DevTools) */ devTools?: { browserWSEndpoint?: string; debuggingPort?: number; }; /** Production mode configuration (nut.js) */ nutJs?: { mouseSpeed?: number; keyboardDelay?: number; windowTitle?: string; templatePath?: string; confidence?: number; }; /** Default timeout for automation operations in milliseconds */ defaultTimeout?: number; /** Number of retry attempts for failed operations */ retryAttempts?: number; /** Whether to capture screenshots on error */ screenshotOnError?: boolean; } /** * Load automation configuration from environment variables. * * Environment variables: * - AUTOMATION_MODE: 'dev' | 'production' | 'mock' (default: 'mock') * - CHROME_DEBUG_PORT: Chrome debugging port (default: 9222) * - CHROME_WS_ENDPOINT: WebSocket endpoint for Chrome DevTools * - IRACING_WINDOW_TITLE: Window title for nut.js (default: 'iRacing') * - TEMPLATE_PATH: Path to template images (default: './resources/templates') * - OCR_CONFIDENCE: OCR confidence threshold (default: 0.9) * - AUTOMATION_TIMEOUT: Default timeout in ms (default: 30000) * - RETRY_ATTEMPTS: Number of retry attempts (default: 3) * - SCREENSHOT_ON_ERROR: Capture screenshots on error (default: true) * * @returns AutomationEnvironmentConfig with parsed environment values */ export function loadAutomationConfig(): AutomationEnvironmentConfig { const modeEnv = process.env.AUTOMATION_MODE; const mode: AutomationMode = isValidAutomationMode(modeEnv) ? modeEnv : 'mock'; return { mode, devTools: { debuggingPort: parseIntSafe(process.env.CHROME_DEBUG_PORT, 9222), browserWSEndpoint: process.env.CHROME_WS_ENDPOINT, }, nutJs: { mouseSpeed: parseIntSafe(process.env.NUTJS_MOUSE_SPEED, 1000), keyboardDelay: parseIntSafe(process.env.NUTJS_KEYBOARD_DELAY, 50), windowTitle: process.env.IRACING_WINDOW_TITLE || 'iRacing', templatePath: process.env.TEMPLATE_PATH || './resources/templates', confidence: parseFloatSafe(process.env.OCR_CONFIDENCE, 0.9), }, defaultTimeout: parseIntSafe(process.env.AUTOMATION_TIMEOUT, 30000), retryAttempts: parseIntSafe(process.env.RETRY_ATTEMPTS, 3), screenshotOnError: process.env.SCREENSHOT_ON_ERROR !== 'false', }; } /** * Type guard to validate automation mode string. */ function isValidAutomationMode(value: string | undefined): value is AutomationMode { return value === 'dev' || value === 'production' || value === 'mock'; } /** * Safely parse an integer with a default fallback. */ function parseIntSafe(value: string | undefined, defaultValue: number): number { if (value === undefined || value === '') { return defaultValue; } const parsed = parseInt(value, 10); return isNaN(parsed) ? defaultValue : parsed; } /** * Safely parse a float with a default fallback. */ function parseFloatSafe(value: string | undefined, defaultValue: number): number { if (value === undefined || value === '') { return defaultValue; } const parsed = parseFloat(value); return isNaN(parsed) ? defaultValue : parsed; }