fix add tool
This commit is contained in:
310
phase3-integration.js
Normal file
310
phase3-integration.js
Normal file
@@ -0,0 +1,310 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Phase 3: Integration and Syntax Validation
|
||||
* Safely integrate new tools into endpoints.js with proper syntax validation
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
class Phase3Integration {
|
||||
constructor() {
|
||||
this.auditResults = null;
|
||||
this.newToolsByAuthType = {};
|
||||
this.parameterUpdates = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load audit results
|
||||
*/
|
||||
loadAuditResults() {
|
||||
try {
|
||||
console.log('📖 Loading audit results...');
|
||||
const resultsPath = path.join(process.cwd(), 'comprehensive-audit-results.json');
|
||||
const resultsContent = fs.readFileSync(resultsPath, 'utf8');
|
||||
this.auditResults = JSON.parse(resultsContent);
|
||||
|
||||
console.log(`✅ Loaded audit results: ${this.auditResults.newTools.length} new tools`);
|
||||
|
||||
// Group new tools by auth type
|
||||
this.auditResults.newTools.forEach(tool => {
|
||||
if (!this.newToolsByAuthType[tool.authType]) {
|
||||
this.newToolsByAuthType[tool.authType] = [];
|
||||
}
|
||||
this.newToolsByAuthType[tool.authType].push(tool);
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ Error loading audit results:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert tool to properly formatted endpoint string
|
||||
*/
|
||||
toolToEndpointString(tool) {
|
||||
const paramEntries = Object.entries(tool.parameters);
|
||||
|
||||
let paramString = '{}';
|
||||
if (paramEntries.length > 0) {
|
||||
const paramLines = paramEntries.map(([name, param]) => {
|
||||
return ` ${name}: {
|
||||
type: "${param.type}",
|
||||
required: ${param.required},
|
||||
description: "${param.description}",
|
||||
}`;
|
||||
});
|
||||
paramString = `{
|
||||
${paramLines.join(',\n')}
|
||||
}`;
|
||||
}
|
||||
|
||||
return ` {
|
||||
path: "${tool.path}",
|
||||
method: "${tool.method}",
|
||||
controller: "${tool.controller}",
|
||||
category: ${tool.category},
|
||||
description: "${tool.description}",
|
||||
parameters: ${paramString},
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new endpoints to specific auth type section
|
||||
*/
|
||||
addEndpointsToSection(content, sectionName, newTools) {
|
||||
if (newTools.length === 0) return content;
|
||||
|
||||
console.log(`📋 Adding ${newTools.length} endpoints to ${sectionName}`);
|
||||
|
||||
// Generate endpoint strings
|
||||
const endpointStrings = newTools.map(tool => this.toolToEndpointString(tool));
|
||||
|
||||
// Find the section
|
||||
const sectionRegex = new RegExp(`(export const ${sectionName}\\s*=\\s*\\[)([\\s\\S]*?)(\\];)`, 'g');
|
||||
const match = sectionRegex.exec(content);
|
||||
|
||||
if (match) {
|
||||
const beforeSection = match[1];
|
||||
const sectionContent = match[2];
|
||||
const afterSection = match[3];
|
||||
|
||||
// Add new endpoints at the end of the section
|
||||
const newSection = `
|
||||
// ===== NEW ENDPOINTS FROM API-DOCS.JSON COMPREHENSIVE AUDIT =====
|
||||
${endpointStrings.join(',\n')}`;
|
||||
|
||||
const updatedSection = sectionContent.trimEnd() + ',' + newSection + '\n';
|
||||
const replacement = beforeSection + updatedSection + afterSection;
|
||||
|
||||
return content.replace(match[0], replacement);
|
||||
} else {
|
||||
console.log(` ⚠️ Could not find ${sectionName} section`);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update parameter mismatches in existing endpoints
|
||||
*/
|
||||
updateParameterMismatches(content) {
|
||||
console.log('\n🔧 Updating parameter mismatches...');
|
||||
|
||||
let updatedContent = content;
|
||||
let updateCount = 0;
|
||||
|
||||
this.auditResults.parameterMismatches.forEach(mismatch => {
|
||||
const { endpoint, tool, missing, different } = mismatch;
|
||||
|
||||
// Find the specific endpoint in the content
|
||||
const pathPattern = `path:\\s*["']${tool.path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}["']`;
|
||||
const methodPattern = `method:\\s*["']${tool.method}["']`;
|
||||
|
||||
// Create a more specific regex to find this exact endpoint
|
||||
const endpointRegex = new RegExp(
|
||||
`(\\{[\\s\\S]*?${pathPattern}[\\s\\S]*?${methodPattern}[\\s\\S]*?parameters:\\s*\\{)([\\s\\S]*?)(\\}[\\s\\S]*?\\})`,
|
||||
'g'
|
||||
);
|
||||
|
||||
const match = endpointRegex.exec(updatedContent);
|
||||
if (match) {
|
||||
const beforeParams = match[1];
|
||||
const currentParams = match[2];
|
||||
const afterParams = match[3];
|
||||
|
||||
// Add missing parameters
|
||||
const newParams = [];
|
||||
missing.forEach(param => {
|
||||
const cleanName = param.name.replace(/[^a-zA-Z0-9_]/g, '_');
|
||||
newParams.push(` ${cleanName}: {
|
||||
type: "${param.type}",
|
||||
required: ${param.required},
|
||||
description: "${param.description || 'Parameter'}",
|
||||
}`);
|
||||
});
|
||||
|
||||
// Update different parameters
|
||||
let updatedParams = currentParams;
|
||||
different.forEach(diff => {
|
||||
const paramName = diff.name;
|
||||
const apiParam = diff.api;
|
||||
|
||||
// Update the parameter definition
|
||||
const paramRegex = new RegExp(
|
||||
`(${paramName}:\\s*\\{[^}]*type:\\s*["'])([^"']+)(["'][^}]*\\})`,
|
||||
'g'
|
||||
);
|
||||
updatedParams = updatedParams.replace(paramRegex, `$1${apiParam.type}$3`);
|
||||
|
||||
const requiredRegex = new RegExp(
|
||||
`(${paramName}:\\s*\\{[^}]*required:\\s*)(true|false)`,
|
||||
'g'
|
||||
);
|
||||
updatedParams = updatedParams.replace(requiredRegex, `$1${apiParam.required}`);
|
||||
});
|
||||
|
||||
// Combine existing and new parameters
|
||||
const finalParams = updatedParams.trim() +
|
||||
(newParams.length > 0 ? (updatedParams.trim() ? ',\n' : '') + newParams.join(',\n') : '');
|
||||
|
||||
const replacement = beforeParams + finalParams + afterParams;
|
||||
updatedContent = updatedContent.replace(match[0], replacement);
|
||||
updateCount++;
|
||||
|
||||
console.log(` ✅ Updated ${tool.path} (${missing.length} missing, ${different.length} different)`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ Updated ${updateCount} endpoints with parameter fixes`);
|
||||
return updatedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate JavaScript syntax
|
||||
*/
|
||||
validateSyntax(content) {
|
||||
try {
|
||||
// Write to temporary file and try to require it
|
||||
const tempPath = path.join(process.cwd(), 'temp-endpoints-validation.js');
|
||||
fs.writeFileSync(tempPath, content);
|
||||
|
||||
// Try to parse as module (basic syntax check)
|
||||
const { execSync } = require('child_process');
|
||||
execSync(`node -c "${tempPath}"`, { stdio: 'pipe' });
|
||||
|
||||
// Clean up
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
console.log('✅ Syntax validation passed');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ Syntax validation failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create backup of current endpoints.js
|
||||
*/
|
||||
createBackup() {
|
||||
try {
|
||||
const endpointsPath = path.join(process.cwd(), 'src/config/endpoints.js');
|
||||
const backupPath = `src/config/endpoints_backup_phase3_${Date.now()}.js`;
|
||||
|
||||
fs.copyFileSync(endpointsPath, backupPath);
|
||||
console.log(`💾 Created backup: ${backupPath}`);
|
||||
return backupPath;
|
||||
} catch (error) {
|
||||
console.error('❌ Error creating backup:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Phase 3 integration
|
||||
*/
|
||||
async runIntegration() {
|
||||
console.log('🚀 PHASE 3: INTEGRATION AND SYNTAX VALIDATION\n');
|
||||
|
||||
// Load audit results
|
||||
if (!this.loadAuditResults()) return false;
|
||||
|
||||
// Create backup
|
||||
const backupPath = this.createBackup();
|
||||
if (!backupPath) return false;
|
||||
|
||||
try {
|
||||
// Load current endpoints.js
|
||||
const endpointsPath = path.join(process.cwd(), 'src/config/endpoints.js');
|
||||
let content = fs.readFileSync(endpointsPath, 'utf8');
|
||||
|
||||
// Update parameter mismatches first
|
||||
content = this.updateParameterMismatches(content);
|
||||
|
||||
// Add new endpoints for each auth type
|
||||
Object.entries(this.newToolsByAuthType).forEach(([authType, tools]) => {
|
||||
const sectionName = `${authType.toUpperCase()}_ENDPOINTS`;
|
||||
content = this.addEndpointsToSection(content, sectionName, tools);
|
||||
console.log(` ✅ Added ${tools.length} endpoints to ${sectionName}`);
|
||||
});
|
||||
|
||||
// Validate syntax
|
||||
if (!this.validateSyntax(content)) {
|
||||
console.error('❌ Syntax validation failed, restoring backup');
|
||||
fs.copyFileSync(backupPath, endpointsPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write updated content
|
||||
fs.writeFileSync(endpointsPath, content);
|
||||
console.log('✅ Updated endpoints.js successfully');
|
||||
|
||||
// Generate summary
|
||||
const totalNewTools = Object.values(this.newToolsByAuthType).reduce((sum, tools) => sum + tools.length, 0);
|
||||
const totalParameterFixes = this.auditResults.parameterMismatches.length;
|
||||
|
||||
console.log('\n📊 INTEGRATION SUMMARY:');
|
||||
console.log(`✅ Added ${totalNewTools} new endpoints`);
|
||||
console.log(`✅ Fixed ${totalParameterFixes} parameter mismatches`);
|
||||
console.log(`✅ Syntax validation passed`);
|
||||
console.log(`💾 Backup created: ${backupPath}`);
|
||||
|
||||
// Show distribution by auth type
|
||||
console.log('\n📋 New Tools by Authentication Type:');
|
||||
Object.entries(this.newToolsByAuthType).forEach(([authType, tools]) => {
|
||||
console.log(` ${authType.toUpperCase()}: ${tools.length} tools`);
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ Error during integration:', error.message);
|
||||
|
||||
// Restore backup on error
|
||||
try {
|
||||
fs.copyFileSync(backupPath, endpointsPath);
|
||||
console.log('🔄 Restored backup due to error');
|
||||
} catch (restoreError) {
|
||||
console.error('❌ Failed to restore backup:', restoreError.message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run Phase 3
|
||||
const integration = new Phase3Integration();
|
||||
integration.runIntegration().then(success => {
|
||||
if (success) {
|
||||
console.log('\n🎉 Phase 3 integration completed successfully!');
|
||||
console.log('\n📋 Next steps:');
|
||||
console.log('1. Run test-basic.js to verify functionality');
|
||||
console.log('2. Update MCP-TOOLS-REFERENCE.md documentation');
|
||||
console.log('3. Test new endpoints with real API calls');
|
||||
} else {
|
||||
console.log('\n❌ Phase 3 integration failed');
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user