UNPKG

sca-tool

Version:

Universal static code analysis tool for calculating API operation costs across multiple frameworks (NestJS, Express, Fastify)

331 lines 11.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.EditorDetector = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const os = __importStar(require("os")); /** * Editor detection utility for SCA-Tool */ class EditorDetector { static EDITOR_COMMANDS = { 'code': { command: 'code', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'Visual Studio Code' }, 'code-insiders': { command: 'code-insiders', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'Visual Studio Code Insiders' }, 'cursor': { command: 'cursor', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'Cursor' }, 'webstorm': { command: 'webstorm', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'WebStorm' }, 'idea': { command: 'idea', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'IntelliJ IDEA' }, 'subl': { command: 'subl', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'Sublime Text' }, 'atom': { command: 'atom', args: [], supportsLineNumbers: true, lineNumberFormat: ':line', name: 'Atom' }, 'vim': { command: 'vim', args: [], supportsLineNumbers: true, lineNumberFormat: '+line', name: 'Vim' }, 'nvim': { command: 'nvim', args: [], supportsLineNumbers: true, lineNumberFormat: '+line', name: 'Neovim' }, 'emacs': { command: 'emacs', args: [], supportsLineNumbers: true, lineNumberFormat: '+line', name: 'Emacs' } }; /** * Detect the available code editor */ static detectEditor() { const detectedEditor = this.findAvailableEditor(); const defaultEditor = detectedEditor || 'code'; // Default to VS Code return { defaultEditor, detectedEditor, openInEditor: false, editorCommands: this.EDITOR_COMMANDS, integration: { generateVSCodeTasks: detectedEditor === 'code' || detectedEditor === 'code-insiders', generateEditorConfig: true } }; } /** * Find the first available editor from the list */ static findAvailableEditor() { // Check environment variables first const envEditor = process.env.EDITOR || process.env.VISUAL; if (envEditor) { const editorName = path.basename(envEditor); if (this.EDITOR_COMMANDS[editorName]) { return editorName; } } // Check for VS Code first (most common for TypeScript development) const priorityOrder = ['code', 'code-insiders', 'cursor', 'webstorm', 'idea', 'subl', 'atom', 'vim', 'nvim', 'emacs']; for (const editor of priorityOrder) { if (this.isCommandAvailable(editor)) { return editor; } } // Check for platform-specific installations if (process.platform === 'win32') { return this.detectWindowsEditor(); } else if (process.platform === 'darwin') { return this.detectMacEditor(); } else { return this.detectLinuxEditor(); } return undefined; } /** * Check if a command is available in PATH */ static isCommandAvailable(command) { try { const { execSync } = require('child_process'); const checkCommand = process.platform === 'win32' ? `where ${command}` : `which ${command}`; execSync(checkCommand, { stdio: 'ignore' }); return true; } catch { return false; } } /** * Detect editor on Windows */ static detectWindowsEditor() { const commonPaths = [ 'C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe', 'C:\\Program Files\\Microsoft VS Code\\Code.exe', 'C:\\Program Files (x86)\\Microsoft VS Code\\Code.exe', 'C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\cursor\\Cursor.exe' ]; for (const editorPath of commonPaths) { const expandedPath = editorPath.replace('%USERNAME%', os.userInfo().username); if (fs.existsSync(expandedPath)) { if (expandedPath.includes('cursor')) return 'cursor'; if (expandedPath.includes('Code')) return 'code'; } } return undefined; } /** * Detect editor on macOS */ static detectMacEditor() { const commonPaths = [ '/Applications/Visual Studio Code.app', '/Applications/Visual Studio Code - Insiders.app', '/Applications/Cursor.app', '/Applications/WebStorm.app', '/Applications/IntelliJ IDEA.app', '/Applications/Sublime Text.app' ]; for (const editorPath of commonPaths) { if (fs.existsSync(editorPath)) { if (editorPath.includes('Cursor')) return 'cursor'; if (editorPath.includes('Visual Studio Code - Insiders')) return 'code-insiders'; if (editorPath.includes('Visual Studio Code')) return 'code'; if (editorPath.includes('WebStorm')) return 'webstorm'; if (editorPath.includes('IntelliJ')) return 'idea'; if (editorPath.includes('Sublime')) return 'subl'; } } return undefined; } /** * Detect editor on Linux */ static detectLinuxEditor() { // Linux usually relies on PATH, so this is mostly for completeness const commonCommands = ['code', 'code-insiders', 'cursor', 'webstorm', 'idea', 'subl']; for (const command of commonCommands) { if (this.isCommandAvailable(command)) { return command; } } return undefined; } /** * Generate VS Code tasks.json for SCA integration */ static generateVSCodeTasks(outputPath = '.vscode/tasks.json') { const tasksConfig = { version: '2.0.0', tasks: [ { label: 'SCA: Analyze Current File', type: 'shell', command: 'sca', args: ['file', '${file}', '--framework', 'nestjs'], group: 'build', presentation: { echo: true, reveal: 'always', focus: false, panel: 'shared' }, problemMatcher: [] }, { label: 'SCA: Analyze Project', type: 'shell', command: 'sca', args: ['project', '${workspaceFolder}/src', '--format', 'html', '--output', 'reports/analysis.html'], group: 'build', presentation: { echo: true, reveal: 'always', focus: false, panel: 'shared' }, problemMatcher: [] }, { label: 'SCA: Generate HTML Report', type: 'shell', command: 'sca', args: ['project', '${workspaceFolder}/src', '--format', 'html', '--output', 'reports/sca-report.html'], group: 'build', presentation: { echo: true, reveal: 'always', focus: false, panel: 'shared' }, problemMatcher: [] } ] }; // Ensure .vscode directory exists const vscodeDirPath = path.dirname(outputPath); if (!fs.existsSync(vscodeDirPath)) { fs.mkdirSync(vscodeDirPath, { recursive: true }); } fs.writeFileSync(outputPath, JSON.stringify(tasksConfig, null, 2)); console.log(`✅ Generated VS Code tasks at ${outputPath}`); } /** * Open file in detected editor */ static openInEditor(filePath, lineNumber, editorConfig) { const config = editorConfig || this.detectEditor(); const editor = config.detectedEditor || config.defaultEditor || 'code'; const editorInfo = this.EDITOR_COMMANDS[editor]; if (!editorInfo) { console.warn(`⚠️ Unknown editor: ${editor}`); return; } try { const { spawn } = require('child_process'); let args = [...editorInfo.args]; if (lineNumber && editorInfo.supportsLineNumbers) { const lineArg = filePath + editorInfo.lineNumberFormat.replace('line', lineNumber.toString()); args.push(lineArg); } else { args.push(filePath); } spawn(editorInfo.command, args, { detached: true, stdio: 'ignore' }); console.log(`📝 Opening ${filePath} in ${editorInfo.name}${lineNumber ? ` at line ${lineNumber}` : ''}`); } catch (error) { console.error(`❌ Failed to open editor: ${error}`); } } } exports.EditorDetector = EditorDetector; //# sourceMappingURL=editor-detector.js.map