UNPKG

pury

Version:

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

110 lines 3.61 kB
import { Severity, FindingType } from '../types/index.js'; import { fileExists } from './file-utils.js'; export class ValidationError extends Error { field; constructor(message, field) { super(message); this.field = field; this.name = 'ValidationError'; } } export async function validateScanOptions(options) { if (!options.path) { throw new ValidationError('Scan path is required', 'path'); } if (!(await fileExists(options.path))) { throw new ValidationError(`Scan path does not exist: ${options.path}`, 'path'); } if (options.maxFileSize && options.maxFileSize < 0) { throw new ValidationError('maxFileSize must be positive', 'maxFileSize'); } if (options.exclude && !Array.isArray(options.exclude)) { throw new ValidationError('exclude must be an array of strings', 'exclude'); } if (options.include && !Array.isArray(options.include)) { throw new ValidationError('include must be an array of strings', 'include'); } } export function validateConfig(config) { const defaultConfig = { scanner: { exclude: [ 'node_modules/**', 'dist/**', 'build/**', '.git/**', '*.min.js', '*.map', 'coverage/**' ], include: ['**/*'], maxFileSize: 1024 * 1024, // 1MB followSymlinks: false }, analyzers: { malware: { enabled: true, sensitivity: 'medium' }, secrets: { enabled: true, sensitivity: 'medium' }, vulnerabilities: { enabled: true, sensitivity: 'medium' }, codeQuality: { enabled: false, sensitivity: 'medium' } }, ai: { provider: 'gemini', gemini: { model: 'gemini-2.5-flash', temperature: 0.1, maxTokens: 2048 } }, output: { format: 'console', verbose: false } }; return mergeDeep(defaultConfig, config); } export function validateSeverity(severity) { if (!Object.values(Severity).includes(severity)) { throw new ValidationError(`Invalid severity: ${severity}. Must be one of: ${Object.values(Severity).join(', ')}`); } return severity; } export function validateFindingType(type) { if (!Object.values(FindingType).includes(type)) { throw new ValidationError(`Invalid finding type: ${type}. Must be one of: ${Object.values(FindingType).join(', ')}`); } return type; } export function validateApiKey(apiKey) { if (!apiKey || apiKey.trim().length === 0) { throw new ValidationError('API key is required for AI analysis'); } if (apiKey.length < 10) { throw new ValidationError('API key appears to be invalid (too short)'); } } export function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } export function validateUrl(url) { try { new URL(url); return true; } catch { return false; } } function mergeDeep(target, source) { const result = { ...target }; for (const key in source) { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { result[key] = mergeDeep(result[key] || {}, source[key]); } else if (source[key] !== undefined) { result[key] = source[key]; } } return result; } //# sourceMappingURL=validation.js.map