canina/docs/audit/generate_evidence.js
2026-08-06 20:54:44 +03:30

82 lines
3.0 KiB
JavaScript

import fs from 'fs';
import crypto from 'crypto';
const classification = JSON.parse(fs.readFileSync('docs/audit/28-full-repository-classification.json', 'utf8'));
const evidenceEntries = [];
for (const file of classification) {
if (!file.includedInAudit) continue;
try {
const fileBytes = fs.readFileSync(file.path);
const sha256 = crypto.createHash('sha256').update(fileBytes).digest('hex');
const textContent = fileBytes.toString('utf8');
const lines = textContent.split(/\r?\n/);
const lineCount = lines.length;
const byteCount = fileBytes.length;
// Extract imports
const importMatches = textContent.match(/^import\s+.*?from\s+['"].*?['"];?/gm) || [];
const imports = importMatches.map(i => i.trim()).slice(0, 15);
// Extract exports
const exportMatches = textContent.match(/^export\s+.*?$/gm) || [];
const exports = exportMatches.map(e => e.trim()).slice(0, 15);
// Extract top-level symbols (functions, classes, consts)
const symbolMatches = textContent.match(/export\s+(class|function|const|interface|type)\s+([A-Za-z0-9_]+)/g) || [];
const topLevelSymbols = symbolMatches.map(s => s.replace(/export\s+(class|function|const|interface|type)\s+/, '')).slice(0, 15);
// Extract decorators
const decoratorMatches = textContent.match(/@[A-Za-z0-9_]+\s*\(/g) || [];
const frameworkDecorators = [...new Set(decoratorMatches.map(d => d.replace(/[\s(]/g, '')))].slice(0, 15);
// Extract test suites
const suiteMatches = textContent.match(/(describe|it|test)\s*\(\s*['"](.*?)['"]/g) || [];
const testSuiteNames = suiteMatches.map(s => s.replace(/(describe|it|test)\s*\(\s*['"]/, '').replace(/['"]$/, '')).slice(0, 15);
// Extract JSON keys or config keys
let configurationKeys = [];
if (file.path.endsWith('.json') || file.path.endsWith('.yml') || file.path.endsWith('.toml')) {
const keyMatches = textContent.match(/"([^"]+)":/g) || [];
configurationKeys = [...new Set(keyMatches.map(k => k.replace(/"/g, '').replace(':', '')))].slice(0, 15);
}
evidenceEntries.push({
path: file.path,
sha256,
byteCount,
lineCount,
language: file.path.endsWith('.ts') || file.path.endsWith('.tsx') ? 'TypeScript' : (file.path.endsWith('.json') ? 'JSON' : 'Plain text'),
imports,
exports,
topLevelSymbols,
frameworkDecorators,
testSuiteNames,
configurationKeys,
readSucceeded: true,
readError: null
});
} catch (err) {
evidenceEntries.push({
path: file.path,
sha256: null,
byteCount: 0,
lineCount: 0,
language: 'Unknown',
imports: [],
exports: [],
topLevelSymbols: [],
frameworkDecorators: [],
testSuiteNames: [],
configurationKeys: [],
readSucceeded: false,
readError: err.message
});
}
}
fs.writeFileSync('docs/audit/29-file-content-evidence.json', JSON.stringify(evidenceEntries, null, 2), 'utf8');
console.log(`Generated content evidence for ${evidenceEntries.length} files in 29-file-content-evidence.json`);