/** * @fileoverview Precise syntax fix for endpoints.js * Handles specific syntax issues with surgical precision */ import fs from 'fs'; import path from 'path'; /** * Precise fix for syntax issues */ function preciseSyntaxFix() { try { console.log('=== PRECISE SYNTAX FIX FOR ENDPOINTS.JS ==='); console.log(''); const endpointsPath = path.join(process.cwd(), 'src/config/endpoints.js'); let content = fs.readFileSync(endpointsPath, 'utf8'); console.log('📁 Reading endpoints.js...'); console.log(`📊 Original file size: ${content.length} characters`); // Create backup const backupPath = path.join(process.cwd(), `endpoints_precise_backup_${Date.now()}.js`); fs.writeFileSync(backupPath, content); console.log(`💾 Backup created: ${backupPath}`); let fixCount = 0; // Fix 1: Handle bracket notation in parameter names console.log('🔧 Fix 1: Bracket notation in parameter names...'); const bracketFixes = content.match(/\s+[a-zA-Z_][a-zA-Z0-9_]*\[[^\]]+\](\[[^\]]+\])?\s*:/g); if (bracketFixes) { console.log(` Found ${bracketFixes.length} bracket notation issues`); content = content.replace(/(\s+)([a-zA-Z_][a-zA-Z0-9_]*\[[^\]]+\](?:\[[^\]]+\])?)(\s*:\s*\{)/g, '$1"$2"$3'); fixCount += bracketFixes.length; } // Fix 2: Handle malformed parameter definitions with trailing commas console.log('🔧 Fix 2: Malformed parameter definitions...'); const malformedParams = content.match(/description:\s*"[^"]*"\s*,\s*\n\s*[a-zA-Z_]/g); if (malformedParams) { console.log(` Found ${malformedParams.length} malformed parameter definitions`); content = content.replace(/(\w+:\s*\{\s*type:\s*"[^"]*",\s*required:\s*[^,]*,\s*description:\s*"[^"]*")\s*,\s*\n(\s*)([a-zA-Z_])/g, '$1 },\n$2$3'); fixCount += malformedParams.length; } // Fix 3: Handle missing closing braces for parameters console.log('🔧 Fix 3: Missing closing braces...'); content = content.replace(/(\w+:\s*\{\s*type:\s*"[^"]*",\s*required:\s*[^,]*,\s*description:\s*"[^"]*")\s*\n(\s*)(\w+:)/g, '$1 },\n$2$3'); // Fix 4: Handle excessive closing braces console.log('🔧 Fix 4: Excessive closing braces...'); const excessiveBraces = content.match(/\}\}\}+/g); if (excessiveBraces) { console.log(` Found ${excessiveBraces.length} excessive brace sequences`); content = content.replace(/\}\}\}+/g, '}'); fixCount += excessiveBraces.length; } // Fix 5: Remove duplicate parameters in the same block console.log('🔧 Fix 5: Duplicate parameters...'); content = fixDuplicateParametersInBlocks(content); // Fix 6: Ensure proper parameter block structure console.log('🔧 Fix 6: Parameter block structure...'); content = fixParameterBlockStructure(content); // Write the fixed content fs.writeFileSync(endpointsPath, content); console.log(`📊 Fixed file size: ${content.length} characters`); console.log(`🔧 Total fixes applied: ${fixCount}`); console.log(''); console.log('✅ Precise syntax fix completed!'); return { backupPath: backupPath, fixCount: fixCount, success: true }; } catch (error) { console.error('❌ Error in precise syntax fix:', error); throw error; } } /** * Fix duplicate parameters within parameter blocks */ function fixDuplicateParametersInBlocks(content) { console.log(' Processing duplicate parameters in blocks...'); let duplicatesRemoved = 0; // Find all parameter blocks content = content.replace(/parameters:\s*\{([^}]*(?:\{[^}]*\}[^}]*)*)\}/g, (match, paramBlock) => { const lines = paramBlock.split('\n'); const cleanedLines = []; const seenParams = new Set(); for (const line of lines) { // Check if this line starts a parameter definition const paramMatch = line.match(/^\s*(\w+):\s*\{/); if (paramMatch) { const paramName = paramMatch[1]; if (!seenParams.has(paramName)) { seenParams.add(paramName); cleanedLines.push(line); } else { duplicatesRemoved++; // Skip this duplicate parameter and its definition continue; } } else { cleanedLines.push(line); } } return `parameters: {${cleanedLines.join('\n')}}`; }); if (duplicatesRemoved > 0) { console.log(` Removed ${duplicatesRemoved} duplicate parameters`); } return content; } /** * Fix parameter block structure */ function fixParameterBlockStructure(content) { console.log(' Processing parameter block structure...'); // Ensure all parameter definitions end with proper closing brace and comma content = content.replace( /(\w+:\s*\{\s*type:\s*"[^"]*",\s*required:\s*(?:true|false),\s*description:\s*"[^"]*")\s*(?:\})?(?:,)?\s*\n(\s*)(\w+:|"[^"]+":|\})/g, (match, paramDef, indent, nextItem) => { if (nextItem === '}') { return `${paramDef} }\n${indent}${nextItem}`; } else { return `${paramDef} },\n${indent}${nextItem}`; } } ); // Fix trailing commas before closing braces content = content.replace(/,(\s*\})/g, '$1'); return content; } /** * Validate the fixed file */ async function validateFixedFile() { try { console.log('🔍 Validating fixed endpoints.js...'); const endpointsPath = path.join(process.cwd(), 'src/config/endpoints.js'); // Use Node.js syntax check const { spawn } = await import('child_process'); return new Promise((resolve) => { const child = spawn('node', ['-c', endpointsPath], { stdio: ['pipe', 'pipe', 'pipe'] }); let stderr = ''; child.stderr.on('data', (data) => { stderr += data.toString(); }); child.on('close', (code) => { if (code === 0) { console.log('✅ File syntax is valid'); resolve(true); } else { console.error('❌ Syntax errors still exist:'); console.error(stderr); resolve(false); } }); }); } catch (error) { console.error('❌ Error validating file:', error); return false; } } // Run the fix if (import.meta.url === `file://${process.argv[1]}`) { (async () => { try { const result = preciseSyntaxFix(); console.log(''); console.log('=== VALIDATION ==='); const isValid = await validateFixedFile(); if (isValid) { console.log('🎉 Endpoints.js syntax successfully fixed and validated!'); console.log('✅ Ready to test HTTP server startup'); } else { console.log('⚠️ Some syntax errors may remain. Manual review needed.'); } console.log(`💾 Backup saved: ${result.backupPath}`); console.log(`🔧 Total fixes applied: ${result.fixCount}`); } catch (error) { console.error('❌ Failed to fix syntax errors:', error); } })(); } export { preciseSyntaxFix };