UNPKG

userpravah

Version:

UserPravah is an extensible, framework-agnostic tool for analyzing user flows and navigation patterns in web applications. It supports multiple frameworks (Angular, React) and output formats (DOT/Graphviz, JSON) with a plugin-based architecture for easy e

135 lines (133 loc) • 5.55 kB
#!/usr/bin/env node import * as path from 'path'; import { MainAnalyzer } from './main-analyzer.js'; import { AngularAdapter } from './analyzers/angular/angular-adapter.js'; import { DotOutputFormatter } from './formatters/dot-formatter.js'; import { BasicPatternCollector } from './core/pattern-collector.interface.js'; function parseArgs(args) { const cliArgs = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case '-p': case '--project': cliArgs.projectPath = args[++i]; break; case '-f': case '--framework': cliArgs.framework = args[++i]; break; case '-o': case '--format': cliArgs.format = args[++i]; break; case '-d': case '--dir': cliArgs.outputDir = args[++i]; break; case '--show-patterns': cliArgs.showPatterns = true; break; case '-h': case '--help': cliArgs.help = true; break; } } return cliArgs; } function printHelp() { console.log(` Usage: angular-flow-analyzer [options] Options: -p, --project <path> Path to the Angular project (required) -f, --framework <name> Framework to analyze (default: "angular") -o, --format <type> Output format (default: "dot") -d, --dir <path> Output directory (default: ".") --show-patterns Display discovered coding patterns after analysis -h, --help Show this help message `); } async function run() { const rawArgs = process.argv.slice(2); const args = parseArgs(rawArgs); if (args.help || rawArgs.length === 0) { printHelp(); process.exit(0); } const projectPath = args.projectPath; if (!projectPath) { console.error('āŒ Error: Project path (-p, --project) is required.'); printHelp(); process.exit(1); } const frameworkName = args.framework || 'angular'; const outputFormat = args.format || 'dot'; const outputDirectory = args.outputDir || '.'; // Default to current directory console.log(`šŸ› ļø Analyzer starting with options:`); console.log(` Project Path: ${path.resolve(projectPath)}`); console.log(` Framework: ${frameworkName}`); console.log(` Output Format: ${outputFormat}`); console.log(` Output Directory: ${path.resolve(outputDirectory)}`); if (args.showPatterns) console.log(` Show Patterns: true`); try { // Instantiate the pattern collector (can be shared) const patternCollector = new BasicPatternCollector(); // Instantiate adapters and formatters // The AngularAdapter constructor now takes projectPath and an optional patternCollector const angularAdapter = new AngularAdapter(path.resolve(projectPath), patternCollector); // Add other adapters here as they are developed, e.g.: // const reactAdapter = new ReactAdapter(path.resolve(projectPath), patternCollector); const dotFormatter = new DotOutputFormatter(); // Add other formatters here: // const jsonFormatter = new JsonOutputFormatter(); const mainAnalyzer = new MainAnalyzer([angularAdapter], // Pass all available adapters [dotFormatter], // Pass all available formatters patternCollector // Pass the central pattern collector ); await mainAnalyzer.analyzeAndGenerateOutput(path.resolve(projectPath), frameworkName, outputFormat, path.resolve(outputDirectory)); if (args.showPatterns) { console.log("\nšŸ“œ Discovered Coding Patterns:"); const allPatterns = mainAnalyzer.getCollectedPatterns(); if (allPatterns.length === 0) { console.log(" No specific patterns were collected during this analysis."); } else { // Group patterns by type for better readability const patternsByType = {}; allPatterns.forEach(p => { if (!patternsByType[p.type]) patternsByType[p.type] = []; patternsByType[p.type].push(p); }); for (const type in patternsByType) { console.log(` Type: ${type} (${patternsByType[type].length} occurrences)`); patternsByType[type].forEach(pattern => { let detailsString = JSON.stringify(pattern.details); if (detailsString && detailsString.length > 100) { detailsString = detailsString.substring(0, 97) + '...'; } console.log(` - File: ${pattern.file}${pattern.lineNumber ? ':' + pattern.lineNumber : ''}`); if (pattern.details) console.log(` Details: ${detailsString}`); }); } } } } catch (error) { console.error('\nāŒ Fatal Error during analysis execution:'); if (error.stack) { console.error(error.stack); } else { console.error(error); } process.exit(1); } } // Remove the old AngularFlowAnalyzer class definition and its direct execution // The run() function will be the new entry point. run();