xw-devtool-cli 1.0.42 → 1.0.43

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
 
@@ -46,6 +46,7 @@
46
46
  - **变量格式转换**:支持 CamelCase, PascalCase, SnakeCase, KebabCase, ConstantCase 互转。
47
47
  - **哈希计算**:支持 MD5, SHA1, SHA256, SHA512, SM3 算法。
48
48
  - **二维码生成**:终端直接显示二维码,支持保存为 PNG 图片(带时间戳文件名)。
49
+ - **二维码识别**:支持选择二维码图片进行识别,识别结果自动复制到剪贴板。
49
50
  - **特殊符号大全**:包含常用符号、箭头、数学符号、货币、希腊字母等 170+ 个符号,支持一键复制。
50
51
  - **Emoji 输入**:支持分类查看和选择常用 Emoji,一键复制到剪贴板。
51
52
  - **HTML 实体工具**:支持 HTML 实体编码与解码 (如 `&` <-> `&amp;`)。
@@ -208,6 +209,13 @@ x. 设置 / 语言 (Settings)
208
209
  - 输入文本或 URL(支持直接回车读取剪贴板)。
209
210
  - 终端直接显示二维码预览。
210
211
  - 可选保存为 PNG 图片,默认文件名包含时间戳。
212
+
213
+ ### 二维码识别
214
+ - 选择 `qrcodeDecode`(菜单对应数字/字母)进入。
215
+ - 支持两种图片输入方式:
216
+ - **选择文件(对话框)**
217
+ - **手动输入文件路径**
218
+ - 自动识别二维码内容并复制到剪贴板。
211
219
 
212
220
  ### 5. URL 编解码
213
221
  - 选择 `5` 进入。
@@ -346,7 +354,7 @@ x. 设置 / 语言 (Settings)
346
354
 
347
355
  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.
348
356
 
349
- 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.
357
+ 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, QR code recognition, special symbols, Markdown snippets, VS Code snippet generation, current directory tree generation, etc. Most results can be copied to the clipboard in one step, greatly improving development efficiency.
350
358
 
351
359
  ### ✨ Features
352
360
 
@@ -381,6 +389,7 @@ Key features include: Base64 encoding/decoding, image format conversion, image <
381
389
  - **Variable Format**: CamelCase, PascalCase, SnakeCase, KebabCase, ConstantCase.
382
390
  - **Hash Calculator**: MD5, SHA1, SHA256, SHA512, SM3.
383
391
  - **QR Code**: Display QR codes in terminal, save as PNG.
392
+ - **QR Code Reader**: Select an image with QR code and decode content, then copy the result to clipboard automatically.
384
393
  - **Special Symbols**: 170+ symbols, arrows, math symbols, etc.
385
394
  - **Emoji Picker**: Browse and copy emojis.
386
395
  - **HTML Entity**: Encode/Decode HTML entities.
@@ -494,6 +503,13 @@ You can enter a feature key directly, or type a keyword (e.g. `json`, `image`, `
494
503
  - Input text or URL.
495
504
  - Preview in terminal.
496
505
  - Option to save as PNG.
506
+
507
+ #### QR Code Reader
508
+ - Select `qrcodeDecode` (menu key).
509
+ - Image input methods:
510
+ - **Select file (dialog)**
511
+ - **Enter file path manually**
512
+ - Decode content and copy it to clipboard automatically.
497
513
 
498
514
  #### 5. URL Encode/Decode
499
515
  - Select `5`.
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, current directory tree generation, etc. Most results can be copied to the clipboard in one step, 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, QR code recognition, special symbols, Markdown snippets, VS Code snippet generation, current directory tree generation, etc. Most results can be copied to the clipboard in one step, greatly improving development efficiency.
8
8
 
9
9
  ## ✨ Features
10
10
 
@@ -40,6 +40,7 @@ Key features include: Base64 encoding/decoding, image format conversion, image <
40
40
  - **Variable Format**: CamelCase, PascalCase, SnakeCase, KebabCase, ConstantCase.
41
41
  - **Hash Calculator**: MD5, SHA1, SHA256, SHA512, SM3.
42
42
  - **QR Code**: Display QR codes in terminal, save as PNG.
43
+ - **QR Code Reader**: Select a QR code image and recognize the content, then copy the result to clipboard.
43
44
  - **Special Symbols**: 170+ symbols, arrows, math symbols, etc.
44
45
  - **Emoji Picker**: Browse and copy emojis.
45
46
  - **HTML Entity**: Encode/Decode HTML entities.
@@ -160,6 +161,13 @@ s. Settings (Language)
160
161
  - Preview in terminal.
161
162
  - Option to save as PNG.
162
163
 
164
+ ### QR Code Reader
165
+ - Select `qrcodeDecode` (menu key).
166
+ - Supports two input methods:
167
+ - **Select file (dialog)**
168
+ - **Enter file path manually**
169
+ - Recognized content is copied to clipboard automatically.
170
+
163
171
  ### 5. URL Encode/Decode
164
172
  - Select `5`.
165
173
  - Select `Encode` or `Decode`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xw-devtool-cli",
3
- "version": "1.0.42",
3
+ "version": "1.0.43",
4
4
  "type": "module",
5
5
  "description": "基于node的开发者助手cli",
6
6
  "main": "index.js",
@@ -42,6 +42,8 @@
42
42
  "png",
43
43
  "placeholder-image",
44
44
  "qrcode",
45
+ "qr-code-reader",
46
+ "qr-decoder",
45
47
  "json-format",
46
48
  "json-formatter",
47
49
  "variable-case",
@@ -87,6 +89,7 @@
87
89
  "he": "^1.2.0",
88
90
  "i18next": "^25.7.3",
89
91
  "inquirer": "^13.1.0",
92
+ "jsqr": "^1.4.0",
90
93
  "lorem-ipsum": "^2.0.8",
91
94
  "pinyin": "^4.0.0",
92
95
  "qrcode": "^1.5.4",
@@ -0,0 +1,76 @@
1
+ import fs from 'fs';
2
+ import inquirer from 'inquirer';
3
+ import jsQR from 'jsqr';
4
+ import sharp from 'sharp';
5
+ import i18next from '../i18n.js';
6
+ import { selectFile } from '../utils/fileDialog.js';
7
+ import { selectFromMenu } from '../utils/menu.js';
8
+ import { outputText } from '../utils/output.js';
9
+
10
+ async function getImagePath() {
11
+ const method = await selectFromMenu(
12
+ i18next.t('qrcodeDecode.selectInputMethod'),
13
+ [
14
+ { name: i18next.t('qrcodeDecode.inputDialog'), value: 'dialog' },
15
+ { name: i18next.t('qrcodeDecode.inputManual'), value: 'manual' }
16
+ ],
17
+ true,
18
+ i18next.t('common.back')
19
+ );
20
+ if (method === '__BACK__') {
21
+ return null;
22
+ }
23
+
24
+ let imagePath = '';
25
+ if (method === 'dialog') {
26
+ imagePath = selectFile('Image Files|*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.webp|All Files|*.*') || '';
27
+ if (!imagePath) {
28
+ console.log(i18next.t('qrcodeDecode.dialogUnavailable'));
29
+ }
30
+ }
31
+
32
+ if (!imagePath) {
33
+ const answer = await inquirer.prompt([
34
+ {
35
+ type: 'input',
36
+ name: 'path',
37
+ message: i18next.t('qrcodeDecode.enterPath'),
38
+ validate: (value) => (fs.existsSync(value) ? true : i18next.t('qrcodeDecode.notExist'))
39
+ }
40
+ ]);
41
+ imagePath = answer.path;
42
+ }
43
+
44
+ return imagePath;
45
+ }
46
+
47
+ async function decodeQRCodeFromImage(imagePath) {
48
+ const { data, info } = await sharp(imagePath)
49
+ .rotate()
50
+ .ensureAlpha()
51
+ .raw()
52
+ .toBuffer({ resolveWithObject: true });
53
+ const pixelData = new Uint8ClampedArray(data);
54
+ const result = jsQR(pixelData, info.width, info.height, { inversionAttempts: 'attemptBoth' });
55
+ return result ? result.data : '';
56
+ }
57
+
58
+ export async function qrcodeDecodeHandler() {
59
+ const imagePath = await getImagePath();
60
+ if (!imagePath) {
61
+ return;
62
+ }
63
+
64
+ try {
65
+ const decoded = await decodeQRCodeFromImage(imagePath);
66
+ if (!decoded) {
67
+ console.log(i18next.t('qrcodeDecode.notFound'));
68
+ return;
69
+ }
70
+ await outputText(decoded, { showPreview: false, copyToClipboard: true });
71
+ console.log(i18next.t('qrcodeDecode.success'));
72
+ console.log(`${i18next.t('qrcodeDecode.result')}\n${decoded}\n`);
73
+ } catch (error) {
74
+ console.error(i18next.t('qrcodeDecode.decodeFail', { message: error.message }));
75
+ }
76
+ }
package/src/index.js CHANGED
@@ -23,6 +23,7 @@ import { variableFormatHandler } from './commands/variableFormat.js';
23
23
  import { jsonFormatHandler } from './commands/jsonFormat.js';
24
24
  import { hashingHandler } from './commands/hashing.js';
25
25
  import { qrcodeHandler } from './commands/qrcode.js';
26
+ import { qrcodeDecodeHandler } from './commands/qrcodeDecode.js';
26
27
  import { specialCharsHandler } from './commands/specialChars.js';
27
28
  import { emojiHandler } from './commands/emoji.js';
28
29
  import { htmlEntitiesHandler } from './commands/htmlEntities.js';
@@ -68,6 +69,7 @@ function getFeatures() {
68
69
  { name: i18next.t('menu.features.imgCompress'), value: 'imgCompress' },
69
70
  { name: i18next.t('menu.features.placeholderImg'), value: 'placeholderImg' },
70
71
  { name: i18next.t('menu.features.qrcode'), value: 'qrcode' },
72
+ { name: i18next.t('menu.features.qrcodeDecode'), value: 'qrcodeDecode' },
71
73
 
72
74
  // Encode/Decode & Formatting
73
75
  { name: i18next.t('menu.features.url'), value: 'url' },
@@ -336,6 +338,9 @@ async function handleAction(action) {
336
338
  case 'qrcode':
337
339
  await qrcodeHandler();
338
340
  break;
341
+ case 'qrcodeDecode':
342
+ await qrcodeDecodeHandler();
343
+ break;
339
344
  case 'specialChars':
340
345
  await specialCharsHandler();
341
346
  break;
package/src/locales/en.js CHANGED
@@ -50,6 +50,7 @@ export default {
50
50
  imgCompress: 'Image Compression',
51
51
  placeholderImg: 'Placeholder Image Generator',
52
52
  qrcode: 'QR Code Generator',
53
+ qrcodeDecode: 'QR Code Reader',
53
54
  url: 'URL Encode/Decode',
54
55
  baseConvert: 'Number Base Converter',
55
56
  base64: 'String Encode/Decode (Base64)',
@@ -110,6 +111,18 @@ export default {
110
111
  y2Prompt: 'Enter Y2 (px or %):',
111
112
  result: 'Picked Color'
112
113
  },
114
+ qrcodeDecode: {
115
+ selectInputMethod: 'Select QR image input method',
116
+ inputDialog: 'Select file (dialog)',
117
+ inputManual: 'Enter file path manually',
118
+ dialogUnavailable: 'File dialog is unavailable or canceled. Please enter the file path manually.',
119
+ enterPath: 'Enter QR code image path:',
120
+ notExist: 'File does not exist.',
121
+ notFound: 'No QR code detected. Please make sure the image is clear and contains a QR code.',
122
+ success: 'Recognition completed. Content copied to clipboard.',
123
+ result: 'Recognized content:',
124
+ decodeFail: 'Failed to decode QR code: {{message}}'
125
+ },
113
126
  url: {
114
127
  title: 'URL Encode/Decode',
115
128
  encode: 'Encode',
package/src/locales/zh.js CHANGED
@@ -50,6 +50,7 @@ export default {
50
50
  imgCompress: '图片压缩',
51
51
  placeholderImg: '占位图生成器',
52
52
  qrcode: '二维码生成器',
53
+ qrcodeDecode: '二维码识别',
53
54
  url: 'URL 编码/解码',
54
55
  baseConvert: '进制转换工具',
55
56
  base64: '字符串 编码/解码 (Base64)',
@@ -110,6 +111,18 @@ export default {
110
111
  y2Prompt: '输入 Y2(px 或 %):',
111
112
  result: '吸取结果'
112
113
  },
114
+ qrcodeDecode: {
115
+ selectInputMethod: '选择二维码图片输入方式',
116
+ inputDialog: '选择文件(对话框)',
117
+ inputManual: '手动输入文件路径',
118
+ dialogUnavailable: '文件对话框不可用或已取消,请手动输入文件路径。',
119
+ enterPath: '请输入二维码图片路径:',
120
+ notExist: '文件不存在。',
121
+ notFound: '未识别到二维码,请确认图片清晰且包含二维码。',
122
+ success: '识别完成,内容已复制到剪贴板。',
123
+ result: '识别结果:',
124
+ decodeFail: '二维码识别失败: {{message}}'
125
+ },
113
126
  url: {
114
127
  title: 'URL 编码/解码',
115
128
  encode: '编码',