uncloseai.com/validate_exports.js

69 lines
No EOL
2.5 KiB
JavaScript

// Quick validation script to check if imports match exports
import { promises as fs } from 'fs';
import path from 'path';
const srcDir = './src';
async function validateExports() {
const files = await fs.readdir(srcDir);
const jsFiles = files.filter(f => f.endsWith('.js'));
console.log('🔍 Validating exports/imports...\n');
const exportMap = new Map();
const importMap = new Map();
// Extract exports and imports
for (const file of jsFiles) {
const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
// Extract exports
const exportMatches = content.match(/export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/g);
if (exportMatches) {
const exports = exportMatches.map(match => {
const parts = match.split(/\s+/);
return parts[parts.length - 1];
});
exportMap.set(file, exports);
}
// Extract imports
const importMatches = content.match(/import\s+{([^}]+)}\s+from\s+["']\.\/([^"']+)["']/g);
if (importMatches) {
importMatches.forEach(match => {
const parts = match.match(/import\s+{([^}]+)}\s+from\s+["']\.\/([^"']+)["']/);
if (parts) {
const imports = parts[1].split(',').map(s => s.trim());
const fromFile = parts[2];
if (!importMap.has(file)) importMap.set(file, []);
importMap.get(file).push({ imports, fromFile });
}
});
}
}
// Validate
let errors = 0;
for (const [file, importData] of importMap) {
for (const { imports, fromFile } of importData) {
const targetFile = fromFile.endsWith('.js') ? fromFile : fromFile + '.js';
const exports = exportMap.get(targetFile) || [];
for (const importName of imports) {
if (!exports.includes(importName)) {
console.log(`${file}: imports '${importName}' from ${targetFile}, but it's not exported`);
console.log(` Available exports: ${exports.join(', ') || 'none'}`);
errors++;
}
}
}
}
if (errors === 0) {
console.log('✅ All imports match their exports!');
} else {
console.log(`\n💥 Found ${errors} import/export mismatches`);
}
}
validateExports().catch(console.error);