vibe-guard
Version:
🛡️ Vibe-Guard Security Scanner - 25 essential security rules to catch vulnerabilities before they catch you! Zero dependencies, instant setup, works everywhere, optimized performance. Detects SQL injection, XSS, exposed secrets, CSRF, CORS issues, and mo
213 lines • 7.78 kB
JavaScript
;
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.ConfigLoader = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
class ConfigLoader {
/**
* Load configuration from the nearest vibe-guard.json file
*/
static loadConfig(projectPath) {
const configPath = this.findConfigFile(projectPath);
if (!configPath) {
return {};
}
try {
const configContent = fs.readFileSync(configPath, 'utf-8');
const config = JSON.parse(configContent);
// Validate and normalize config
return this.validateConfig(config);
}
catch (error) {
console.warn(`Warning: Could not load config from ${configPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
return {};
}
}
/**
* Find the nearest configuration file in the project hierarchy
*/
static findConfigFile(projectPath) {
let currentPath = path.resolve(projectPath);
while (currentPath !== path.dirname(currentPath)) {
for (const configFile of this.CONFIG_FILES) {
const configPath = path.join(currentPath, configFile);
if (fs.existsSync(configPath)) {
return configPath;
}
}
currentPath = path.dirname(currentPath);
}
return null;
}
/**
* Validate and normalize configuration
*/
static validateConfig(config) {
const validated = {};
// Validate output format
if (config.outputFormat && ['table', 'json', 'sarif', 'html'].includes(config.outputFormat)) {
validated.outputFormat = config.outputFormat;
}
// Validate severity
if (config.severity && ['critical', 'high', 'medium', 'low'].includes(config.severity)) {
validated.severity = config.severity;
}
// Validate arrays
if (Array.isArray(config.exclude)) {
validated.exclude = config.exclude.filter((item) => typeof item === 'string');
}
if (Array.isArray(config.include)) {
validated.include = config.include.filter((item) => typeof item === 'string');
}
// Validate strings
if (typeof config.outputFile === 'string') {
validated.outputFile = config.outputFile;
}
if (typeof config.maxFileSize === 'string') {
validated.maxFileSize = config.maxFileSize;
}
// Validate booleans
if (typeof config.verbose === 'boolean') {
validated.verbose = config.verbose;
}
if (typeof config.parallel === 'boolean') {
validated.parallel = config.parallel;
}
// Validate numbers
if (typeof config.maxWorkers === 'number' && config.maxWorkers > 0) {
validated.maxWorkers = config.maxWorkers;
}
// Validate rules configuration
if (config.rules && typeof config.rules === 'object') {
validated.rules = {};
for (const [ruleName, ruleConfig] of Object.entries(config.rules)) {
if (typeof ruleConfig === 'object' && ruleConfig !== null) {
const rule = ruleConfig;
validated.rules[ruleName] = {
enabled: typeof rule.enabled === 'boolean' ? rule.enabled : true,
severity: ['critical', 'high', 'medium', 'low'].includes(rule.severity) ? rule.severity : undefined,
patterns: Array.isArray(rule.patterns) ? rule.patterns.filter((p) => typeof p === 'string') : undefined,
excludePatterns: Array.isArray(rule.excludePatterns) ? rule.excludePatterns.filter((p) => typeof p === 'string') : undefined
};
}
}
}
return validated;
}
/**
* Merge configuration with CLI options (CLI takes precedence)
*/
static mergeConfig(config, cliOptions) {
return {
target: cliOptions.target || '.',
format: cliOptions.format ?? config.outputFormat ?? 'table',
verbose: cliOptions.verbose ?? config.verbose ?? false,
exclude: cliOptions.exclude || config.exclude || [],
include: cliOptions.include || config.include || []
};
}
/**
* Create a default configuration file
*/
static createDefaultConfig() {
return {
exclude: [
'node_modules/**',
'dist/**',
'build/**',
'.git/**',
'coverage/**',
'**/*.min.js',
'**/*.bundle.js'
],
outputFormat: 'table',
verbose: false,
severity: 'low',
maxFileSize: '5MB',
parallel: false,
maxWorkers: 4
};
}
/**
* Generate a sample configuration file content
*/
static generateSampleConfig() {
const sampleConfig = {
exclude: [
'node_modules/**',
'dist/**',
'build/**',
'.git/**',
'coverage/**',
'**/*.min.js',
'**/*.bundle.js'
],
include: [
'src/**/*.{js,ts,jsx,tsx}',
'lib/**/*.{js,ts}'
],
outputFormat: 'table',
outputFile: 'security-report.json',
verbose: false,
severity: 'low',
maxFileSize: '5MB',
parallel: false,
maxWorkers: 4,
rules: {
'sql-injection': {
enabled: true,
severity: 'critical'
},
'xss-detection': {
enabled: true,
severity: 'high'
},
'exposed-secrets': {
enabled: true,
severity: 'critical'
}
}
};
return JSON.stringify(sampleConfig, null, 2);
}
}
exports.ConfigLoader = ConfigLoader;
ConfigLoader.CONFIG_FILES = [
'vibe-guard.json',
'.vibe-guard.json',
'vibe-guard.config.json'
];
//# sourceMappingURL=config.js.map