/** * @fileoverview Extract all API endpoints from api-docs.json * Analyzes the OpenAPI specification and extracts endpoint details */ import fs from 'fs'; import path from 'path'; /** * Extract all endpoints from api-docs.json */ function extractEndpoints() { try { // Read the api-docs.json file const apiDocsPath = path.join(process.cwd(), '..', 'api-docs.json'); const apiDocsContent = fs.readFileSync(apiDocsPath, 'utf8'); const apiDocs = JSON.parse(apiDocsContent); console.log('=== API DOCS ANALYSIS ==='); console.log(`Title: ${apiDocs.info.title}`); console.log(`Version: ${apiDocs.info.version}`); console.log(`Description: ${apiDocs.info.description}`); console.log(''); const endpoints = []; const paths = apiDocs.paths || {}; // Extract all endpoints Object.keys(paths).forEach(pathKey => { const pathData = paths[pathKey]; // Each path can have multiple HTTP methods Object.keys(pathData).forEach(method => { const methodData = pathData[method]; const endpoint = { path: pathKey, method: method.toUpperCase(), operationId: methodData.operationId, summary: methodData.summary, description: methodData.description, tags: methodData.tags || [], parameters: extractParameters(methodData), requestBody: extractRequestBody(methodData), responses: methodData.responses, security: methodData.security || [], requiresAuth: (methodData.security && methodData.security.length > 0) }; endpoints.push(endpoint); }); }); console.log(`=== EXTRACTED ${endpoints.length} ENDPOINTS ===`); console.log(''); // Group by tags for analysis const endpointsByTag = {}; endpoints.forEach(endpoint => { endpoint.tags.forEach(tag => { if (!endpointsByTag[tag]) { endpointsByTag[tag] = []; } endpointsByTag[tag].push(endpoint); }); }); // Display summary by tags console.log('=== ENDPOINTS BY TAG ==='); Object.keys(endpointsByTag).sort().forEach(tag => { console.log(`${tag}: ${endpointsByTag[tag].length} endpoints`); }); console.log(''); // Display authentication analysis const authEndpoints = endpoints.filter(e => e.requiresAuth); const publicEndpoints = endpoints.filter(e => !e.requiresAuth); console.log('=== AUTHENTICATION ANALYSIS ==='); console.log(`Authenticated endpoints: ${authEndpoints.length}`); console.log(`Public endpoints: ${publicEndpoints.length}`); console.log(''); // Save detailed analysis const analysis = { summary: { totalEndpoints: endpoints.length, authenticatedEndpoints: authEndpoints.length, publicEndpoints: publicEndpoints.length, tags: Object.keys(endpointsByTag).sort() }, endpointsByTag, allEndpoints: endpoints }; const outputPath = path.join(process.cwd(), 'api-docs-analysis.json'); fs.writeFileSync(outputPath, JSON.stringify(analysis, null, 2)); console.log(`Detailed analysis saved to: ${outputPath}`); // Display all endpoints console.log(''); console.log('=== ALL ENDPOINTS ==='); endpoints.forEach((endpoint, index) => { console.log(`${index + 1}. ${endpoint.method} ${endpoint.path}`); console.log(` Summary: ${endpoint.summary}`); console.log(` Tags: ${endpoint.tags.join(', ')}`); console.log(` Auth Required: ${endpoint.requiresAuth ? 'Yes' : 'No'}`); if (endpoint.parameters && endpoint.parameters.length > 0) { console.log(` Parameters: ${endpoint.parameters.length}`); } if (endpoint.requestBody) { console.log(` Request Body: Yes`); } console.log(''); }); return analysis; } catch (error) { console.error('Error extracting endpoints:', error); throw error; } } /** * Extract parameters from endpoint definition */ function extractParameters(methodData) { const parameters = []; // Path parameters, query parameters, etc. if (methodData.parameters) { methodData.parameters.forEach(param => { parameters.push({ name: param.name, in: param.in, // path, query, header, etc. required: param.required || false, type: param.schema?.type || 'string', description: param.description || '' }); }); } return parameters; } /** * Extract request body schema */ function extractRequestBody(methodData) { if (!methodData.requestBody) { return null; } const requestBody = { required: methodData.requestBody.required || false, content: {} }; // Extract content types and schemas if (methodData.requestBody.content) { Object.keys(methodData.requestBody.content).forEach(contentType => { const contentData = methodData.requestBody.content[contentType]; requestBody.content[contentType] = { schema: contentData.schema || {} }; }); } return requestBody; } // Run the extraction if (import.meta.url === `file://${process.argv[1]}`) { extractEndpoints(); } export { extractEndpoints };