UNPKG

unused-exports-check

Version:

Generic scanner to detect unused TypeScript exports (API + CLI)

77 lines (76 loc) 3.33 kB
#!/usr/bin/env node "use strict"; 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); });