394 lines
12 KiB
JavaScript
394 lines
12 KiB
JavaScript
/**
|
|
* @fileoverview Complete structure rebuild for endpoints.js
|
|
* Rebuilds the entire file with proper structure and removes all duplicates
|
|
*/
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
/**
|
|
* Complete structure rebuild
|
|
*/
|
|
function completeStructureRebuild() {
|
|
try {
|
|
console.log('=== COMPLETE STRUCTURE REBUILD 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_rebuild_backup_${Date.now()}.js`);
|
|
fs.writeFileSync(backupPath, content);
|
|
console.log(`💾 Backup created: ${backupPath}`);
|
|
|
|
// Extract and rebuild the file structure
|
|
console.log('🔧 Rebuilding file structure...');
|
|
|
|
const rebuiltContent = rebuildFileStructure(content);
|
|
|
|
// Write the rebuilt content
|
|
fs.writeFileSync(endpointsPath, rebuiltContent);
|
|
|
|
console.log(`📊 Rebuilt file size: ${rebuiltContent.length} characters`);
|
|
console.log('');
|
|
console.log('✅ Complete structure rebuild completed!');
|
|
|
|
return {
|
|
backupPath: backupPath,
|
|
success: true
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error in complete structure rebuild:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rebuild the entire file structure
|
|
*/
|
|
function rebuildFileStructure(content) {
|
|
console.log(' Extracting file components...');
|
|
|
|
// Extract the header and imports
|
|
const headerMatch = content.match(/(\/\*\*[\s\S]*?\*\/[\s\S]*?export const AUTH_TYPES[\s\S]*?export const AUTH_ENDPOINTS[\s\S]*?\};)/);
|
|
const header = headerMatch ? headerMatch[1] : getDefaultHeader();
|
|
|
|
// Extract endpoint categories
|
|
const categoriesMatch = content.match(/(\/\*\*[\s\S]*?export const ENDPOINT_CATEGORIES[\s\S]*?\};)/);
|
|
const categories = categoriesMatch ? categoriesMatch[1] : getDefaultCategories();
|
|
|
|
// Extract and rebuild each section
|
|
const sections = [
|
|
'PUBLIC_ENDPOINTS',
|
|
'PROVIDER_ENDPOINTS',
|
|
'PATIENT_ENDPOINTS',
|
|
'PARTNER_ENDPOINTS',
|
|
'AFFILIATE_ENDPOINTS',
|
|
'NETWORK_ENDPOINTS'
|
|
];
|
|
|
|
const rebuiltSections = [];
|
|
|
|
sections.forEach(sectionName => {
|
|
console.log(` Rebuilding ${sectionName}...`);
|
|
const sectionContent = extractAndCleanSection(content, sectionName);
|
|
rebuiltSections.push(sectionContent);
|
|
});
|
|
|
|
// Combine all parts
|
|
const rebuiltContent = [
|
|
header,
|
|
'',
|
|
categories,
|
|
'',
|
|
...rebuiltSections
|
|
].join('\n');
|
|
|
|
return rebuiltContent;
|
|
}
|
|
|
|
/**
|
|
* Extract and clean a specific section
|
|
*/
|
|
function extractAndCleanSection(content, sectionName) {
|
|
const sectionRegex = new RegExp(`(export const ${sectionName}\\s*=\\s*\\[)([\\s\\S]*?)(\\];)`, 'g');
|
|
const match = sectionRegex.exec(content);
|
|
|
|
if (!match) {
|
|
console.log(` Warning: ${sectionName} not found`);
|
|
return `export const ${sectionName} = [];`;
|
|
}
|
|
|
|
const sectionContent = match[2];
|
|
const cleanedEndpoints = extractAndCleanEndpoints(sectionContent);
|
|
|
|
console.log(` Found ${cleanedEndpoints.length} endpoints`);
|
|
|
|
// Build the section with proper formatting
|
|
const sectionComment = getSectionComment(sectionName);
|
|
const formattedEndpoints = cleanedEndpoints.map(endpoint => formatEndpoint(endpoint)).join(',\n');
|
|
|
|
return `${sectionComment}
|
|
export const ${sectionName} = [
|
|
${formattedEndpoints}
|
|
];`;
|
|
}
|
|
|
|
/**
|
|
* Extract and clean endpoints from section content
|
|
*/
|
|
function extractAndCleanEndpoints(sectionContent) {
|
|
const endpoints = [];
|
|
const endpointRegex = /\{[\s\S]*?\}/g;
|
|
let match;
|
|
|
|
while ((match = endpointRegex.exec(sectionContent)) !== null) {
|
|
const endpointStr = match[0];
|
|
const cleanedEndpoint = cleanEndpoint(endpointStr);
|
|
if (cleanedEndpoint) {
|
|
endpoints.push(cleanedEndpoint);
|
|
}
|
|
}
|
|
|
|
return endpoints;
|
|
}
|
|
|
|
/**
|
|
* Clean and parse a single endpoint
|
|
*/
|
|
function cleanEndpoint(endpointStr) {
|
|
try {
|
|
// Extract basic properties
|
|
const pathMatch = endpointStr.match(/path:\s*"([^"]*)"/);
|
|
const methodMatch = endpointStr.match(/method:\s*"([^"]*)"/);
|
|
const controllerMatch = endpointStr.match(/controller:\s*"([^"]*)"/);
|
|
const categoryMatch = endpointStr.match(/category:\s*([^,}]*)/);
|
|
const descriptionMatch = endpointStr.match(/description:\s*"([^"]*)"/);
|
|
|
|
if (!pathMatch || !methodMatch) {
|
|
return null; // Invalid endpoint
|
|
}
|
|
|
|
const endpoint = {
|
|
path: pathMatch[1],
|
|
method: methodMatch[1],
|
|
controller: controllerMatch ? controllerMatch[1] : '',
|
|
category: categoryMatch ? categoryMatch[1].trim() : 'ENDPOINT_CATEGORIES.GENERAL',
|
|
description: descriptionMatch ? descriptionMatch[1] : ''
|
|
};
|
|
|
|
// Extract parameters
|
|
const parametersMatch = endpointStr.match(/parameters:\s*\{([\s\S]*?)\}/);
|
|
if (parametersMatch) {
|
|
endpoint.parameters = extractParameters(parametersMatch[1]);
|
|
}
|
|
|
|
return endpoint;
|
|
|
|
} catch (error) {
|
|
console.log(` Warning: Failed to parse endpoint: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract parameters from parameter content
|
|
*/
|
|
function extractParameters(paramContent) {
|
|
const parameters = {};
|
|
const seenParams = new Set();
|
|
|
|
// Find all parameter definitions
|
|
const paramRegex = /(\w+|"[^"]+"):\s*\{\s*type:\s*"([^"]*)",\s*required:\s*(true|false),\s*description:\s*"([^"]*)"\s*\}/g;
|
|
let match;
|
|
|
|
while ((match = paramRegex.exec(paramContent)) !== null) {
|
|
const paramName = match[1].replace(/"/g, '');
|
|
|
|
// Skip duplicates
|
|
if (seenParams.has(paramName)) {
|
|
continue;
|
|
}
|
|
seenParams.add(paramName);
|
|
|
|
parameters[paramName] = {
|
|
type: match[2],
|
|
required: match[3] === 'true',
|
|
description: match[4]
|
|
};
|
|
}
|
|
|
|
return parameters;
|
|
}
|
|
|
|
/**
|
|
* Format an endpoint object
|
|
*/
|
|
function formatEndpoint(endpoint) {
|
|
let formatted = ` {
|
|
path: "${endpoint.path}",
|
|
method: "${endpoint.method}",
|
|
controller: "${endpoint.controller}",
|
|
category: ${endpoint.category},
|
|
description: "${endpoint.description}"`;
|
|
|
|
if (endpoint.parameters && Object.keys(endpoint.parameters).length > 0) {
|
|
formatted += ',\n parameters: {\n';
|
|
|
|
const paramEntries = Object.entries(endpoint.parameters).map(([name, param]) => {
|
|
const quotedName = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name) ? name : `"${name}"`;
|
|
return ` ${quotedName}: { type: "${param.type}", required: ${param.required}, description: "${param.description}" }`;
|
|
});
|
|
|
|
formatted += paramEntries.join(',\n');
|
|
formatted += '\n }';
|
|
}
|
|
|
|
formatted += '\n }';
|
|
return formatted;
|
|
}
|
|
|
|
/**
|
|
* Get default header
|
|
*/
|
|
function getDefaultHeader() {
|
|
return `/**
|
|
* @fileoverview Comprehensive Laravel Healthcare MCP Server Endpoint Registry
|
|
* Contains 1000+ endpoints organized by authentication type and functionality
|
|
* Reorganized for proper healthcare security and HIPAA compliance
|
|
*/
|
|
|
|
export const AUTH_TYPES = {
|
|
PUBLIC: "public",
|
|
SANCTUM: "sanctum",
|
|
ADMIN: "admin",
|
|
AGENT: "agent",
|
|
PATIENT: "patient",
|
|
PRACTITIONER: "practitioner",
|
|
AFFILIATE: "affiliate",
|
|
PARTNER: "partner",
|
|
NETWORK: "network",
|
|
DOCTOR: "doctor",
|
|
PROVIDER: "provider",
|
|
};
|
|
|
|
export const AUTH_ENDPOINTS = {
|
|
[AUTH_TYPES.ADMIN]: {
|
|
login: "/api/admin/login",
|
|
method: "POST",
|
|
controller: "Admin\\\\Api\\\\LoginController@loginApi",
|
|
},
|
|
[AUTH_TYPES.AGENT]: {
|
|
login: "/agent/login/post",
|
|
method: "POST",
|
|
controller: "Agent\\\\Auth\\\\LoginController@login",
|
|
},
|
|
[AUTH_TYPES.PATIENT]: {
|
|
login: "/api/frontend/login",
|
|
method: "POST",
|
|
controller: "PatientController@loginApi",
|
|
},
|
|
[AUTH_TYPES.PRACTITIONER]: {
|
|
login: "/api/practitioner/login",
|
|
method: "POST",
|
|
controller: "PractitionerController@loginApi",
|
|
},
|
|
[AUTH_TYPES.AFFILIATE]: {
|
|
login: "/api/affiliate/login",
|
|
method: "POST",
|
|
controller: "AffiliateController@loginApi",
|
|
},
|
|
[AUTH_TYPES.PARTNER]: {
|
|
login: "/api/partner/login",
|
|
method: "POST",
|
|
controller: "PartnerController@loginApi",
|
|
},
|
|
[AUTH_TYPES.NETWORK]: {
|
|
login: "/api/network/login",
|
|
method: "POST",
|
|
controller: "NetworkController@loginApi",
|
|
},
|
|
[AUTH_TYPES.DOCTOR]: {
|
|
login: "/api/doctor/login",
|
|
method: "POST",
|
|
controller: "DoctorController@loginApi",
|
|
},
|
|
[AUTH_TYPES.PROVIDER]: {
|
|
login: "/api/provider/login",
|
|
method: "POST",
|
|
controller: "Provider\\\\Auth\\\\LoginController@login",
|
|
}
|
|
};`;
|
|
}
|
|
|
|
/**
|
|
* Get default categories
|
|
*/
|
|
function getDefaultCategories() {
|
|
return `/**
|
|
* Endpoint categories for MCP tool organization
|
|
*/
|
|
export const ENDPOINT_CATEGORIES = {
|
|
PATIENT_MANAGEMENT: "patient_management",
|
|
APPOINTMENT_SCHEDULING: "appointment_scheduling",
|
|
MEDICAL_RECORDS: "medical_records",
|
|
PRESCRIPTION_MANAGEMENT: "prescription_management",
|
|
USER_MANAGEMENT: "user_management",
|
|
AUTHENTICATION: "authentication",
|
|
BILLING_INSURANCE: "billing_insurance",
|
|
COMMUNICATION: "communication",
|
|
REPORTING_ANALYTICS: "reporting_analytics",
|
|
SYSTEM_ADMINISTRATION: "system_administration",
|
|
INVENTORY_MANAGEMENT: "inventory_management",
|
|
DOCUMENT_MANAGEMENT: "document_management",
|
|
PROVIDER_MANAGEMENT: "provider_management",
|
|
BUSINESS_OPERATIONS: "business_operations",
|
|
LOCATION_MANAGEMENT: "location_management"
|
|
};`;
|
|
}
|
|
|
|
/**
|
|
* Get section comment
|
|
*/
|
|
function getSectionComment(sectionName) {
|
|
const comments = {
|
|
PUBLIC_ENDPOINTS: '/**\n * Public endpoints (no authentication required)\n */',
|
|
PROVIDER_ENDPOINTS: '/**\n * Provider endpoints (requires provider authentication)\n */',
|
|
PATIENT_ENDPOINTS: '/**\n * Patient endpoints (requires patient authentication)\n */',
|
|
PARTNER_ENDPOINTS: '/**\n * Partner endpoints (requires partner authentication)\n */',
|
|
AFFILIATE_ENDPOINTS: '/**\n * Affiliate endpoints (requires affiliate authentication)\n */',
|
|
NETWORK_ENDPOINTS: '/**\n * Network endpoints (requires network authentication)\n */'
|
|
};
|
|
|
|
return comments[sectionName] || `/**\n * ${sectionName}\n */`;
|
|
}
|
|
|
|
// Run the complete structure rebuild
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
(async () => {
|
|
try {
|
|
const result = completeStructureRebuild();
|
|
|
|
console.log('');
|
|
console.log('=== VALIDATION ===');
|
|
|
|
// Test syntax
|
|
const { spawn } = await import('child_process');
|
|
const endpointsPath = path.join(process.cwd(), 'src/config/endpoints.js');
|
|
|
|
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('✅ Syntax validation passed');
|
|
console.log('🎉 Complete structure rebuild successful!');
|
|
console.log('✅ All duplicate parameters removed');
|
|
console.log('✅ File structure corrected');
|
|
} else {
|
|
console.error('❌ Syntax errors found:');
|
|
console.error(stderr);
|
|
}
|
|
|
|
console.log(`💾 Backup saved: ${result.backupPath}`);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('❌ Failed to rebuild structure:', error);
|
|
}
|
|
})();
|
|
}
|
|
|
|
export { completeStructureRebuild };
|