ts-comment-remover
Version:
TypeScript file compression tool that removes comments and unnecessary whitespace using AST
119 lines ⢠4.55 kB
JavaScript
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
import { writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { compressTypeScriptFiles } from './compressor.js';
import { copyToClipboard, directoryExists, formatFileSize, getRelativePath, } from './utils.js';
import { interactiveMode } from './interactive.js';
const createProgram = () => {
const program = new Command();
return program
.name('ts-compress')
.description('TypeScript file compression tool')
.version('2.0.0')
.argument('[directory]', 'Target directory containing TypeScript files', '.')
.option('-o, --output <file>', 'Output to file instead of clipboard')
.option('-i, --interactive', 'Interactive mode to select files')
.option('-p, --preserve-structure', 'Preserve file structure in output')
.option('-v, --verbose', 'Verbose output')
.option('--include <patterns...>', 'Include file patterns', ['*.ts'])
.option('--exclude <patterns...>', 'Exclude file patterns', [
'*.d.ts',
'*.test.ts',
'*.spec.ts',
]);
};
const createStatsSummary = (result) => [
chalk.cyan('\nš Statistics:'),
` Files processed: ${chalk.bold(result.files.length)}`,
` Original size: ${chalk.bold(formatFileSize(result.totalStats.originalSize))}`,
` Compressed size: ${chalk.bold(formatFileSize(result.totalStats.compressedSize))}`,
` Compression ratio: ${chalk.bold(result.totalStats.ratio + '%')}`,
].join('\n');
const createFileDetails = (files, targetDir) => [
chalk.cyan('\nš File details:'),
...files.map(file => {
const relativePath = getRelativePath(file.path, targetDir);
return [
` ${relativePath}:`,
` Original: ${formatFileSize(file.stats.originalSize)}`,
` Compressed: ${formatFileSize(file.stats.compressedSize)}`,
` Ratio: ${file.stats.ratio}%`,
].join('\n');
}),
].join('\n');
const createResultDisplay = (result, options) => {
const mainStats = createStatsSummary(result);
return options.verbose
? `${mainStats}\n${createFileDetails(result.files, options.targetDir)}`
: mainStats;
};
const handleOutput = (output, outputFile) => async () => {
if (outputFile) {
await writeFile(outputFile, output, 'utf-8');
return chalk.green(`ā
Output written to ${outputFile}`);
}
await copyToClipboard(output)();
return chalk.green('ā
Compressed output copied to clipboard');
};
const createCompressOptions = (targetDir, options) => ({
targetDir,
outputFile: options.output,
includePatterns: options.include,
excludePatterns: options.exclude,
preserveStructure: options.preserveStructure,
verbose: options.verbose,
interactive: options.interactive,
});
const formatErrorMessage = (error) => chalk.red('Error: ') +
(error instanceof Error ? error.message : String(error));
const mainProcess = (directory, options) => async () => {
const targetDir = resolve(directory);
const spinner = ora();
const dirExists = await directoryExists(targetDir)();
if (!dirExists) {
throw new Error(`Directory '${targetDir}' does not exist`);
}
const compressOptions = createCompressOptions(targetDir, options);
if (options.interactive) {
await interactiveMode(compressOptions)();
return;
}
spinner.start('Compressing TypeScript files...');
try {
const result = await compressTypeScriptFiles(compressOptions)();
spinner.succeed('Compression complete');
const outputMessage = await handleOutput(result.output, options.output)();
console.log(outputMessage);
console.log(createResultDisplay(result, { ...options, targetDir }));
}
catch (error) {
spinner.fail('Compression failed');
throw error;
}
};
const cliAction = async (directory, options) => {
try {
await mainProcess(directory, options)();
}
catch (error) {
console.error(formatErrorMessage(error));
process.exit(1);
}
};
const setupErrorHandling = () => {
process.on('unhandledRejection', error => {
console.error(formatErrorMessage(error));
process.exit(1);
});
};
const runCLI = () => {
setupErrorHandling();
const program = createProgram();
program.action(cliAction);
program.parse();
};
runCLI();
//# sourceMappingURL=cli.js.map