securityCheck.tsā¢3.37 kB
import pc from 'picocolors';
import { logger } from '../../shared/logger.js';
import { initTaskRunner } from '../../shared/processConcurrency.js';
import type { RepomixProgressCallback } from '../../shared/types.js';
import type { RawFile } from '../file/fileTypes.js';
import type { GitDiffResult } from '../git/gitDiffHandle.js';
import type { GitLogResult } from '../git/gitLogHandle.js';
import type { SecurityCheckTask, SecurityCheckType } from './workers/securityCheckWorker.js';
export interface SuspiciousFileResult {
filePath: string;
messages: string[];
type: SecurityCheckType;
}
export const runSecurityCheck = async (
rawFiles: RawFile[],
progressCallback: RepomixProgressCallback = () => {},
gitDiffResult?: GitDiffResult,
gitLogResult?: GitLogResult,
deps = {
initTaskRunner,
},
): Promise<SuspiciousFileResult[]> => {
const gitDiffTasks: SecurityCheckTask[] = [];
const gitLogTasks: SecurityCheckTask[] = [];
// Add Git diff content for security checking if available
if (gitDiffResult) {
if (gitDiffResult.workTreeDiffContent) {
gitDiffTasks.push({
filePath: 'Working tree changes',
content: gitDiffResult.workTreeDiffContent,
type: 'gitDiff',
});
}
if (gitDiffResult.stagedDiffContent) {
gitDiffTasks.push({
filePath: 'Staged changes',
content: gitDiffResult.stagedDiffContent,
type: 'gitDiff',
});
}
}
// Add Git log content for security checking if available
if (gitLogResult) {
if (gitLogResult.logContent) {
gitLogTasks.push({
filePath: 'Git log history',
content: gitLogResult.logContent,
type: 'gitLog',
});
}
}
const taskRunner = deps.initTaskRunner<SecurityCheckTask, SuspiciousFileResult | null>({
numOfTasks: rawFiles.length + gitDiffTasks.length + gitLogTasks.length,
workerPath: new URL('./workers/securityCheckWorker.js', import.meta.url).href,
runtime: 'worker_threads',
});
const fileTasks = rawFiles.map(
(file) =>
({
filePath: file.path,
content: file.content,
type: 'file',
}) satisfies SecurityCheckTask,
);
// Combine file tasks, Git diff tasks, and Git log tasks
const tasks = [...fileTasks, ...gitDiffTasks, ...gitLogTasks];
try {
logger.trace(`Starting security check for ${tasks.length} files/content`);
const startTime = process.hrtime.bigint();
let completedTasks = 0;
const totalTasks = tasks.length;
const results = await Promise.all(
tasks.map((task) =>
taskRunner.run(task).then((result) => {
completedTasks++;
progressCallback(`Running security check... (${completedTasks}/${totalTasks}) ${pc.dim(task.filePath)}`);
logger.trace(`Running security check... (${completedTasks}/${totalTasks}) ${task.filePath}`);
return result;
}),
),
);
const endTime = process.hrtime.bigint();
const duration = Number(endTime - startTime) / 1e6;
logger.trace(`Security check completed in ${duration.toFixed(2)}ms`);
return results.filter((result): result is SuspiciousFileResult => result !== null);
} catch (error) {
logger.error('Error during security check:', error);
throw error;
} finally {
// Always cleanup worker pool
await taskRunner.cleanup();
}
};