UNPKG

pury

Version:

🛡️ AI-powered security scanner with advanced threat detection, dual reporting system (detailed & summary), and comprehensive code analysis

84 lines 3.35 kB
import { minimatch } from 'minimatch'; import { DEFAULT_EXCLUDE_PATTERNS, TEXT_FILE_EXTENSIONS } from '../config/defaults.js'; export class PatternMatcher { includePatterns; excludePatterns; constructor(include = ['**/*'], exclude = DEFAULT_EXCLUDE_PATTERNS) { this.includePatterns = include; this.excludePatterns = exclude; } shouldIncludeFile(filePath) { // First check if it matches include patterns const isIncluded = this.includePatterns.some(pattern => minimatch(filePath, pattern, { dot: true })); if (!isIncluded) { return false; } // Then check if it matches any exclude patterns const isExcluded = this.excludePatterns.some(pattern => minimatch(filePath, pattern, { dot: true })); return !isExcluded; } shouldIncludeDirectory(dirPath) { // Don't scan directories that match exclude patterns const isExcluded = this.excludePatterns.some(pattern => { // For directory patterns, we need to handle both exact matches and parent directories const normalizedPattern = pattern.endsWith('/**') ? pattern.slice(0, -3) : pattern; return (minimatch(dirPath, normalizedPattern, { dot: true }) || minimatch(dirPath, pattern, { dot: true })); }); return !isExcluded; } isTextFile(filePath) { const extension = this.getFileExtension(filePath); return TEXT_FILE_EXTENSIONS.includes(extension); } isSupportedFile(filePath) { // File must be included by patterns and be a text file return this.shouldIncludeFile(filePath) && this.isTextFile(filePath); } getFileExtension(filePath) { const parts = filePath.split('.'); return parts.length > 1 ? `.${parts.pop()?.toLowerCase()}` : ''; } addIncludePattern(pattern) { if (!this.includePatterns.includes(pattern)) { this.includePatterns.push(pattern); } } addExcludePattern(pattern) { if (!this.excludePatterns.includes(pattern)) { this.excludePatterns.push(pattern); } } removeIncludePattern(pattern) { this.includePatterns = this.includePatterns.filter(p => p !== pattern); } removeExcludePattern(pattern) { this.excludePatterns = this.excludePatterns.filter(p => p !== pattern); } getPatterns() { return { include: [...this.includePatterns], exclude: [...this.excludePatterns] }; } static createForLanguage(language) { const languagePatterns = { javascript: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'], typescript: ['**/*.ts', '**/*.tsx'], python: ['**/*.py', '**/*.pyw'], java: ['**/*.java'], csharp: ['**/*.cs'], cpp: ['**/*.cpp', '**/*.cxx', '**/*.cc', '**/*.c', '**/*.h', '**/*.hpp'], php: ['**/*.php'], ruby: ['**/*.rb'], go: ['**/*.go'], rust: ['**/*.rs'], swift: ['**/*.swift'], kotlin: ['**/*.kt'], scala: ['**/*.scala'] }; const patterns = languagePatterns[language.toLowerCase()] || ['**/*']; return new PatternMatcher(patterns); } } //# sourceMappingURL=pattern-matcher.js.map