unused-exports-check
Version:
Generic scanner to detect unused TypeScript exports (API + CLI)
77 lines (76 loc) • 3.33 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = __importDefault(require("node:fs"));
const index_1 = require("./index");
const program = new commander_1.Command();
program
.name('unused-exports-check')
.description('Detect unused TypeScript exports (generic, repo-agnostic)')
.option('-r, --root <path>', 'Repository root directory', process.cwd())
.option('-g, --glob <pattern...>', 'Glob patterns to include', ['src/**/*.ts', 'src/**/*.tsx'])
.option('-i, --ignore <pattern...>', 'Extra ignore glob patterns', [])
.option('--tsconfig <file>', 'Path to tsconfig.json', '')
.option('--report <file>', 'Write report to file (default: reports/unused-exports-<timestamp>.txt)', '')
.option('--fail', 'Exit with code 1 if unused exports are found', false)
.parse(process.argv);
function ts() {
const d = new Date();
const pad = (n) => String(n).padStart(2, '0');
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
}
async function main() {
const opts = program.opts();
const root = node_path_1.default.resolve(opts.root);
const unused = await (0, index_1.scan)({ root, globs: opts.glob, ignore: opts.ignore, tsconfig: opts.tsconfig || undefined });
if (unused.length === 0) {
console.log('No unused exports found.');
process.exit(0);
}
const lines = [];
lines.push('# Unused exports report');
lines.push('');
lines.push(`Generated: ${new Date().toISOString()}`);
lines.push(`Repository root: ${root}`);
lines.push(`Patterns: ${opts.glob.join(', ')}`);
if (opts.ignore && opts.ignore.length)
lines.push(`Ignored: ${opts.ignore.join(', ')}`);
lines.push('');
lines.push(`Total unused exports: ${unused.length}`);
lines.push('');
const byFile = new Map();
for (const u of unused) {
const rel = node_path_1.default.relative(root, u.filePath);
const arr = byFile.get(rel);
if (arr)
arr.push(u);
else
byFile.set(rel, [u]);
}
const entries = Array.from(byFile.entries()).sort((a, b) => a[0] > b[0] ? 1 : -1);
for (const [rel, arr] of entries) {
lines.push(rel);
for (const u of arr)
lines.push(` - ${u.exportName} [${u.kind}]`);
lines.push('');
}
const report = lines.join('\n');
const out = opts.report && String(opts.report).trim().length ? node_path_1.default.resolve(process.cwd(), opts.report) : node_path_1.default.resolve(process.cwd(), `reports/unused-exports-${ts()}.txt`);
node_fs_1.default.mkdirSync(node_path_1.default.dirname(out), { recursive: true });
node_fs_1.default.writeFileSync(out, report, 'utf-8');
console.log(`Report written to: ${out}`);
if (opts.fail) {
try {
(0, index_1.assertNone)(unused);
}
catch {
process.exit(1);
}
}
}
main().catch((err) => { console.error(err); process.exit(2); });