xw-devtool-cli 1.0.38 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  一个基于 Node.js 的开发者命令行工具箱,旨在提供开箱即用的常用开发工具,帮助开发者快速处理日常任务。
6
6
 
7
- 主要功能包括:Base64 编解码、图片格式转换、图片与 Base64 互转、Mock 数据生成、时间戳/日期格式化、时间计算、URL 编解码、UUID 生成、汉字转拼音、颜色转换、变量格式转换、哈希计算、二维码生成、特殊符号大全、Markdown 语法工具、VS Code 代码段生成等。所有结果均自动复制到剪贴板,极大提升开发效率。
7
+ 主要功能包括:Base64 编解码、图片格式转换、图片与 Base64 互转、Mock 数据生成、时间戳/日期格式化、时间计算、URL 编解码、UUID 生成、汉字转拼音、颜色转换、变量格式转换、哈希计算、二维码生成、特殊符号大全、Markdown 语法工具、VS Code 代码段生成、当前目录树生成等。所有结果均自动复制到剪贴板,极大提升开发效率。
8
8
 
9
9
  ## ✨ 功能特性
10
10
 
@@ -51,6 +51,7 @@
51
51
  - **Markdown 语法工具**:提供常用 Markdown 语法模板 (Headers, Lists, Tables, Code 等),一键复制。
52
52
  - **VS Code 代码段生成器**:将代码转换为 VS Code Snippet JSON,自动生成语法速查表注释。
53
53
  - **Git 助手**: 标准化生成 Git 分支名 (feature/bugfix/custom) 和 Conventional Commits 提交日志。
54
+ - **当前目录树生成**:生成当前目录的文件树结构,支持指定层级,默认输出全部层级并自动复制到剪贴板。
54
55
  - **占位图生成**:自定义尺寸、背景色、文字颜色和格式生成占位图。
55
56
  - **便捷操作**:
56
57
  - 支持文件选择对话框 (Windows)。
@@ -132,7 +133,8 @@ s. Emoji 选择器
132
133
  t. Markdown 片段
133
134
  u. VS Code 代码片段生成
134
135
  v. Git 助手 (分支/提交模板)
135
- w. 设置 / 语言 (Settings)
136
+ w. 当前目录树生成
137
+ x. 设置 / 语言 (Settings)
136
138
  0. 退出
137
139
  =================================
138
140
  ```
@@ -169,6 +171,13 @@ w. 设置 / 语言 (Settings)
169
171
  - 默认输出到源目录下的 `compressed_YYYYMMDD_HHmmss` 文件夹。
170
172
  - 自动复制输出目录路径。
171
173
  - 完成后可选直接打开输出目录。
174
+
175
+ ### 当前目录树生成
176
+ - 选择 `w` 进入。
177
+ - 先选择层级模式:
178
+ - **所有层级**:从当前目录递归到最深层。
179
+ - **指定层级**:输入层级数字(`0` 表示仅根目录,`1` 表示包含第一层子项)。
180
+ - 生成后的目录树会自动复制到剪贴板,便于粘贴到文档或 Issue 中。
172
181
 
173
182
  ### 3. 占位图生成 (Placeholder Image)
174
183
  - 选择 `3` 进入。
package/README_EN.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A Node.js-based developer command-line toolbox designed to provide out-of-the-box common development tools to help developers handle daily tasks quickly.
6
6
 
7
- Key features include: Base64 encoding/decoding, image format conversion, image <-> Base64, Mock data generation, timestamp/date formatting, time calculation, URL encoding/decoding, UUID generation, Chinese pinyin conversion, color conversion, variable format conversion, hash calculation, QR code generation, special symbols, Markdown snippets, VS Code snippet generation, etc. All results are automatically copied to the clipboard, greatly improving development efficiency.
7
+ Key features include: Base64 encoding/decoding, image format conversion, image <-> Base64, Mock data generation, timestamp/date formatting, time calculation, URL encoding/decoding, UUID generation, Chinese pinyin conversion, color conversion, variable format conversion, hash calculation, QR code generation, special symbols, Markdown snippets, VS Code snippet generation, current directory tree generation, etc. All results are automatically copied to the clipboard, greatly improving development efficiency.
8
8
 
9
9
  ## ✨ Features
10
10
 
@@ -45,6 +45,7 @@ Key features include: Base64 encoding/decoding, image format conversion, image <
45
45
  - **Markdown Snippets**: Common Markdown templates.
46
46
  - **VS Code Snippets**: Generate VS Code snippet JSON from code.
47
47
  - **Git Helper**: Generate standardized Git branch names (feature/bugfix) and Conventional Commits messages.
48
+ - **Current Directory Tree**: Generate the file tree for the current directory, with optional depth limit (default: all levels), and copy result to clipboard.
48
49
  - **Convenience**:
49
50
  - File selection dialog (Windows).
50
51
  - Auto-copy results to clipboard.
@@ -119,6 +120,7 @@ i. Special Characters (Symbols)
119
120
  j. Emoji Picker
120
121
  k. Markdown Snippets
121
122
  l. VS Code Snippet Generator
123
+ m. Current Directory Tree
122
124
  s. Settings (Language)
123
125
  0. Exit
124
126
  =================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xw-devtool-cli",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "type": "module",
5
5
  "description": "基于node的开发者助手cli",
6
6
  "main": "index.js",
@@ -59,7 +59,9 @@
59
59
  "git",
60
60
  "git-branch",
61
61
  "commit-message",
62
- "conventional-commits"
62
+ "conventional-commits",
63
+ "directory-tree",
64
+ "file-tree"
63
65
  ],
64
66
  "author": "npmxw",
65
67
  "license": "ISC",
@@ -0,0 +1,90 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import inquirer from 'inquirer';
4
+ import i18next from '../i18n.js';
5
+ import { selectFromMenu } from '../utils/menu.js';
6
+ import { copy } from '../utils/clipboard.js';
7
+
8
+ export async function fileTreeHandler() {
9
+ const mode = await selectFromMenu(
10
+ i18next.t('fileTree.depthMode'),
11
+ [
12
+ { name: i18next.t('fileTree.allDepth'), value: 'all' },
13
+ { name: i18next.t('fileTree.customDepth'), value: 'custom' }
14
+ ],
15
+ true,
16
+ i18next.t('common.back')
17
+ );
18
+
19
+ if (mode === '__BACK__') {
20
+ return;
21
+ }
22
+
23
+ let maxDepth = Infinity;
24
+ if (mode === 'custom') {
25
+ const { depth } = await inquirer.prompt([
26
+ {
27
+ type: 'input',
28
+ name: 'depth',
29
+ message: i18next.t('fileTree.depthPrompt'),
30
+ validate: (input) => {
31
+ const value = Number.parseInt(input, 10);
32
+ if (!Number.isInteger(value) || value < 0) {
33
+ return i18next.t('fileTree.depthInvalid');
34
+ }
35
+ return true;
36
+ }
37
+ }
38
+ ]);
39
+ maxDepth = Number.parseInt(depth, 10);
40
+ }
41
+
42
+ const cwd = process.cwd();
43
+ const tree = buildTree(cwd, maxDepth);
44
+ const depthText = Number.isFinite(maxDepth) ? String(maxDepth) : i18next.t('fileTree.allDepth');
45
+
46
+ console.log(i18next.t('fileTree.generated', { path: cwd, depth: depthText }));
47
+ const preview = tree.length > 2000 ? `${tree.slice(0, 1000)}\n...\n${tree.slice(-800)}` : tree;
48
+ console.log(`\n${preview}\n`);
49
+ await copy(tree);
50
+ }
51
+
52
+ export function buildTree(rootPath, maxDepth) {
53
+ const rootName = path.basename(rootPath) || rootPath;
54
+ const lines = [rootName];
55
+
56
+ walkDir(rootPath, '', 0, maxDepth, lines);
57
+
58
+ return lines.join('\n');
59
+ }
60
+
61
+ function walkDir(currentPath, prefix, depth, maxDepth, lines) {
62
+ if (depth >= maxDepth) {
63
+ return;
64
+ }
65
+
66
+ let entries = [];
67
+ try {
68
+ entries = fs.readdirSync(currentPath, { withFileTypes: true });
69
+ } catch (error) {
70
+ lines.push(`${prefix}└── [${i18next.t('fileTree.readFailed')}: ${error.message}]`);
71
+ return;
72
+ }
73
+
74
+ entries.sort((a, b) => {
75
+ if (a.isDirectory() && !b.isDirectory()) return -1;
76
+ if (!a.isDirectory() && b.isDirectory()) return 1;
77
+ return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
78
+ });
79
+
80
+ entries.forEach((entry, index) => {
81
+ const isLast = index === entries.length - 1;
82
+ const connector = isLast ? '└── ' : '├── ';
83
+ lines.push(`${prefix}${connector}${entry.name}`);
84
+
85
+ if (entry.isDirectory()) {
86
+ const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`;
87
+ walkDir(path.join(currentPath, entry.name), nextPrefix, depth + 1, maxDepth, lines);
88
+ }
89
+ });
90
+ }
package/src/index.js CHANGED
@@ -35,6 +35,7 @@ import { pixelDistanceHandler } from './commands/pixelDistance.js';
35
35
  import { screenMarkHandler } from './commands/screenMark.js';
36
36
  import { gitHelperHandler } from './commands/gitHelper.js';
37
37
  import { imgCompressHandler } from './commands/imgCompress.js';
38
+ import { fileTreeHandler } from './commands/fileTree.js';
38
39
 
39
40
  process.on('SIGINT', () => {
40
41
  console.log(`\n${i18next.t('menu.bye')}`);
@@ -91,6 +92,7 @@ function getFeatures() {
91
92
  { name: i18next.t('menu.features.markdown'), value: 'markdown' },
92
93
  { name: i18next.t('menu.features.vscodeSnippet'), value: 'vscodeSnippet' },
93
94
  { name: i18next.t('menu.features.gitHelper'), value: 'gitHelper' },
95
+ { name: i18next.t('menu.features.fileTree'), value: 'fileTree' },
94
96
 
95
97
  // Settings
96
98
  { name: i18next.t('menu.features.settings'), value: 'settings' }
@@ -293,6 +295,9 @@ async function handleAction(action) {
293
295
  case 'gitHelper':
294
296
  await gitHelperHandler();
295
297
  break;
298
+ case 'fileTree':
299
+ await fileTreeHandler();
300
+ break;
296
301
  case 'settings':
297
302
  await handleSettings();
298
303
  break;
package/src/locales/en.js CHANGED
@@ -64,6 +64,7 @@ export default {
64
64
  markdown: 'Markdown Snippets',
65
65
  vscodeSnippet: 'VS Code Snippet Generator',
66
66
  gitHelper: 'Git Helper (Branch/Commit Template)',
67
+ fileTree: 'Current Directory Tree',
67
68
  settings: 'Settings / Language'
68
69
  }
69
70
  },
@@ -157,5 +158,14 @@ export default {
157
158
  scanResult: 'Images found',
158
159
  preservePrompt: 'Preserve original directory structure in output?',
159
160
  suffixPrompt: 'Append filename suffix (compressed + timestamp)?'
161
+ },
162
+ fileTree: {
163
+ depthMode: 'Select tree depth mode',
164
+ allDepth: 'All levels',
165
+ customDepth: 'Specify depth',
166
+ depthPrompt: 'Enter depth (0 means root only):',
167
+ depthInvalid: 'Please enter an integer greater than or equal to 0',
168
+ generated: 'Directory tree generated (path: {{path}}, depth: {{depth}}) and copied to clipboard',
169
+ readFailed: 'Failed to read directory'
160
170
  }
161
171
  };
package/src/locales/zh.js CHANGED
@@ -64,6 +64,7 @@ export default {
64
64
  markdown: 'Markdown 片段',
65
65
  vscodeSnippet: 'VS Code 代码片段生成',
66
66
  gitHelper: 'Git 助手 (分支/提交模板)',
67
+ fileTree: '当前目录树生成',
67
68
  settings: '设置 / 语言 (Settings)'
68
69
  }
69
70
  },
@@ -158,5 +159,14 @@ export default {
158
159
  preservePrompt: '递归时是否按原始目录结构输出'
159
160
  ,
160
161
  suffixPrompt: '是否在文件名添加后缀(compressed+时间戳)'
162
+ },
163
+ fileTree: {
164
+ depthMode: '请选择目录树生成层级',
165
+ allDepth: '所有层级',
166
+ customDepth: '指定层级',
167
+ depthPrompt: '请输入层级(0 表示仅根目录):',
168
+ depthInvalid: '请输入大于等于 0 的整数',
169
+ generated: '目录树已生成(路径: {{path}},层级: {{depth}}),已复制到剪贴板',
170
+ readFailed: '读取目录失败'
161
171
  }
162
172
  };