tree-cli-tool
Version:
A powerful command-line tool to display directory tree structure with various configuration options and output formats
205 lines • 7.28 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MarkdownFormatter = exports.JsonFormatter = exports.TextFormatter = exports.BaseFormatter = void 0;
exports.createFormatter = createFormatter;
const chalk_1 = __importDefault(require("chalk"));
class BaseFormatter {
constructor(options) {
this.options = options;
}
formatSize(size) {
const units = ['B', 'KB', 'MB', 'GB'];
let unitIndex = 0;
let formattedSize = size;
while (formattedSize >= 1024 && unitIndex < units.length - 1) {
formattedSize /= 1024;
unitIndex++;
}
return `${formattedSize.toFixed(unitIndex > 0 ? 1 : 0)}${units[unitIndex]}`;
}
formatDate(date) {
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
}
exports.BaseFormatter = BaseFormatter;
class TextFormatter extends BaseFormatter {
format(tree, stats) {
const lines = [];
// 添加根目录
lines.push(this.formatNode(tree, '', true, true));
// 递归添加子节点
if (tree.children) {
this.formatChildren(tree.children, '', lines);
}
// 添加统计信息
lines.push('');
lines.push(this.formatStats(stats));
return lines.join('\n');
}
formatChildren(children, prefix, lines) {
children.forEach((child, index) => {
const isLast = index === children.length - 1;
const symbol = isLast
? TextFormatter.TREE_SYMBOLS.lastBranch
: TextFormatter.TREE_SYMBOLS.branch;
const nextPrefix = prefix +
(isLast
? TextFormatter.TREE_SYMBOLS.space
: TextFormatter.TREE_SYMBOLS.vertical);
lines.push(this.formatNode(child, prefix + symbol, false, isLast));
if (child.children && child.children.length > 0) {
this.formatChildren(child.children, nextPrefix, lines);
}
});
}
formatNode(node, prefix, isRoot, isLast) {
let line = prefix + node.name;
// 添加文件大小信息(只对文件显示,不对目录显示)
if (this.options.showSize && node.size !== undefined && !node.isDirectory) {
line += ` (${this.formatSize(node.size)})`;
}
// 添加修改时间信息
if (this.options.showDate && node.modifiedTime) {
line += ` [${this.formatDate(node.modifiedTime)}]`;
}
// 应用颜色
if (this.options.colorize) {
if (node.isDirectory) {
line = chalk_1.default.blue.bold(line);
}
else {
const ext = node.name.split('.').pop()?.toLowerCase();
switch (ext) {
case 'js':
case 'ts':
case 'jsx':
case 'tsx':
line = chalk_1.default.yellow(line);
break;
case 'json':
line = chalk_1.default.green(line);
break;
case 'md':
case 'txt':
line = chalk_1.default.white(line);
break;
case 'css':
case 'scss':
case 'sass':
line = chalk_1.default.magenta(line);
break;
case 'html':
case 'htm':
line = chalk_1.default.red(line);
break;
default:
line = chalk_1.default.gray(line);
}
}
}
return line;
}
formatStats(stats) {
let result = `${stats.totalDirectories} directories, ${stats.totalFiles} files`;
if (this.options.showSize) {
result += `, ${this.formatSize(stats.totalSize)} total`;
}
return this.options.colorize ? chalk_1.default.cyan(result) : result;
}
}
exports.TextFormatter = TextFormatter;
TextFormatter.TREE_SYMBOLS = {
branch: '├── ',
lastBranch: '└── ',
vertical: '│ ',
space: ' ',
};
class JsonFormatter extends BaseFormatter {
format(tree, stats) {
const result = {
tree: this.nodeToJson(tree),
stats,
};
return JSON.stringify(result, null, 2);
}
nodeToJson(node) {
const result = {
name: node.name,
path: node.path,
isDirectory: node.isDirectory,
depth: node.depth,
};
if (node.size !== undefined) {
result.size = node.size;
}
if (node.modifiedTime) {
result.modifiedTime = node.modifiedTime.toISOString();
}
if (node.children && node.children.length > 0) {
result.children = node.children.map(child => this.nodeToJson(child));
}
return result;
}
}
exports.JsonFormatter = JsonFormatter;
class MarkdownFormatter extends BaseFormatter {
format(tree, stats) {
const lines = [];
lines.push(`# Directory Tree: ${tree.name}`);
lines.push('');
// 添加根目录
lines.push(`- **${tree.name}**${tree.isDirectory ? '/' : ''}`);
// 递归添加子节点
if (tree.children) {
this.formatChildren(tree.children, 1, lines);
}
// 添加统计信息
lines.push('');
lines.push('## Statistics');
lines.push('');
lines.push(`- **Directories**: ${stats.totalDirectories}`);
lines.push(`- **Files**: ${stats.totalFiles}`);
if (this.options.showSize) {
lines.push(`- **Total Size**: ${this.formatSize(stats.totalSize)}`);
}
return lines.join('\n');
}
formatChildren(children, depth, lines) {
const indent = ' '.repeat(depth);
children.forEach(child => {
let line = `${indent}- `;
if (child.isDirectory) {
line += `**${child.name}**/`;
}
else {
line += child.name;
}
// 添加文件大小信息(只对文件显示,不对目录显示)
if (this.options.showSize &&
child.size !== undefined &&
!child.isDirectory) {
line += ` _(${this.formatSize(child.size)})_`;
}
lines.push(line);
if (child.children && child.children.length > 0) {
this.formatChildren(child.children, depth + 1, lines);
}
});
}
}
exports.MarkdownFormatter = MarkdownFormatter;
function createFormatter(options) {
switch (options.format) {
case 'json':
return new JsonFormatter(options);
case 'markdown':
return new MarkdownFormatter(options);
case 'text':
default:
return new TextFormatter(options);
}
}
//# sourceMappingURL=formatters.js.map