xw-devtool-cli 1.0.8 → 1.0.10
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 +90 -66
- package/package.json +1 -1
- package/src/commands/placeholderImg.js +188 -0
- package/src/index.js +21 -9
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- **图片工具**:
|
|
11
11
|
- **图片格式转换**:支持 PNG、JPG、WebP 格式互转,可调整压缩质量。
|
|
12
12
|
- **图片 ↔ Base64**:支持图片转 Base64 字符串,以及 Base64 还原为图片文件。
|
|
13
|
+
- **占位图生成**:快速生成指定尺寸、颜色、文字的占位图片 (Placeholder Image)。
|
|
13
14
|
- **Mock 数据生成**:
|
|
14
15
|
- 支持生成:英文段落 (Lorem Ipsum)、中文字符、中国居民身份证号、电子邮箱、URL、订单号、手机号、座机号。
|
|
15
16
|
- 支持批量生成。
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
- **特殊符号大全**:包含常用符号、箭头、数学符号、货币、希腊字母等 170+ 个符号,支持一键复制。
|
|
28
29
|
- **Emoji 输入**:支持分类查看和选择常用 Emoji,一键复制到剪贴板。
|
|
29
30
|
- **HTML 实体工具**:支持 HTML 实体编码与解码 (如 `&` <-> `&`)。
|
|
31
|
+
- **占位图生成**:自定义尺寸、背景色、文字颜色和格式生成占位图。
|
|
30
32
|
- **便捷操作**:
|
|
31
33
|
- 支持文件选择对话框 (Windows)。
|
|
32
34
|
- 结果自动复制到剪贴板。
|
|
@@ -59,42 +61,30 @@ xw-devtool
|
|
|
59
61
|
=================================
|
|
60
62
|
xw-devtool-cli Menu
|
|
61
63
|
=================================
|
|
62
|
-
1.
|
|
63
|
-
2.
|
|
64
|
-
3. Image
|
|
65
|
-
4.
|
|
66
|
-
5.
|
|
67
|
-
6.
|
|
68
|
-
7.
|
|
69
|
-
8.
|
|
70
|
-
9.
|
|
71
|
-
a.
|
|
72
|
-
b.
|
|
73
|
-
c.
|
|
74
|
-
d.
|
|
75
|
-
e.
|
|
76
|
-
f.
|
|
64
|
+
1. Image <-> Base64
|
|
65
|
+
2. Image Format Convert
|
|
66
|
+
3. Placeholder Image Generator
|
|
67
|
+
4. QR Code Generator
|
|
68
|
+
5. URL Encode/Decode
|
|
69
|
+
6. String Encode/Decode (Base64)
|
|
70
|
+
7. HTML Entity Encode/Decode
|
|
71
|
+
8. Variable Format Converter
|
|
72
|
+
9. Chinese to Pinyin
|
|
73
|
+
a. Time Format / Timestamp
|
|
74
|
+
b. Color Converter (Hex <-> RGB)
|
|
75
|
+
c. Get UUID
|
|
76
|
+
d. Hash Calculator (MD5/SHA/SM3)
|
|
77
|
+
e. Mock Text
|
|
78
|
+
f. Special Characters (Symbols)
|
|
79
|
+
g. Emoji Picker
|
|
77
80
|
0. Exit
|
|
78
81
|
=================================
|
|
79
82
|
```
|
|
80
83
|
|
|
81
84
|
## 📖 详细使用指南
|
|
82
85
|
|
|
83
|
-
### 1.
|
|
86
|
+
### 1. 图片与 Base64 互转
|
|
84
87
|
- 选择 `1` 进入。
|
|
85
|
-
- 选择 `Encode` (编码) 或 `Decode` (解码)。
|
|
86
|
-
- 输入 URL 字符串,结果自动复制。
|
|
87
|
-
|
|
88
|
-
### 2. 字符串 Base64 转换
|
|
89
|
-
- 选择 `2` 进入。
|
|
90
|
-
- 支持三种输入源:
|
|
91
|
-
- **Clipboard**: 直接读取剪贴板内容(适合处理长文本)。
|
|
92
|
-
- **File**: 读取文本文件内容。
|
|
93
|
-
- **Manual input**: 手动粘贴或输入文本。
|
|
94
|
-
- 输出支持:直接复制、保存为文件、预览后复制。
|
|
95
|
-
|
|
96
|
-
### 3. 图片与 Base64 互转
|
|
97
|
-
- 选择 `3` 进入。
|
|
98
88
|
- **Image -> Base64**:
|
|
99
89
|
- 选择图片文件(支持对话框选择)。
|
|
100
90
|
- 输出 Base64 字符串(可保存为 `.txt` 文件防止控制台卡顿)。
|
|
@@ -102,72 +92,106 @@ f. HTML Entity Encode/Decode
|
|
|
102
92
|
- 输入 Base64 字符串(支持从文件读取或剪贴板读取)。
|
|
103
93
|
- 自动识别图片格式并保存为文件。
|
|
104
94
|
|
|
105
|
-
###
|
|
106
|
-
- 选择 `
|
|
95
|
+
### 2. 图片格式转换
|
|
96
|
+
- 选择 `2` 进入。
|
|
107
97
|
- 选择源图片文件。
|
|
108
98
|
- 选择目标格式 (PNG / JPG / WebP)。
|
|
109
99
|
- 设置压缩参数(如 JPG 质量 1-100,PNG 压缩等级 0-9)。
|
|
110
100
|
- 生成的新图片将保存在源文件同级目录。
|
|
111
101
|
|
|
112
|
-
###
|
|
102
|
+
### 3. 占位图生成 (Placeholder Image)
|
|
103
|
+
- 选择 `3` 进入。
|
|
104
|
+
- **模式 1:本地图片文件 (Local Image File)**
|
|
105
|
+
- 自动生成图片文件到当前目录。
|
|
106
|
+
- 支持自定义:
|
|
107
|
+
- **尺寸**: 宽度和高度 (px)。
|
|
108
|
+
- **颜色**: 背景色和文字颜色(支持 Hex 或颜色名)。
|
|
109
|
+
- **内容**: 自定义图片中间的文字(默认显示尺寸)。
|
|
110
|
+
- **格式**: 输出 PNG, JPG, WebP, GIF。
|
|
111
|
+
- 文件名默认包含时间戳,避免覆盖。
|
|
112
|
+
- **模式 2:远程图片 URL (Remote Image URL)**
|
|
113
|
+
- 自动生成云端占位图链接并复制到剪贴板。
|
|
114
|
+
- 支持多个主流服务商:
|
|
115
|
+
- **Picsum Photos**: 随机风景图,支持灰度、模糊效果。
|
|
116
|
+
- **DummyImage**: 简单、经典。
|
|
117
|
+
- **Via Placeholder**: 标准占位图。
|
|
118
|
+
- **Placehold.jp**: 适合日文环境。
|
|
119
|
+
- **DevTool Tech**: 高度可定制。
|
|
120
|
+
- **FPO Img**: "For Placement Only" 风格。
|
|
121
|
+
- 支持自定义尺寸、颜色、文字等参数(视具体服务商而定)。
|
|
122
|
+
|
|
123
|
+
### 4. 二维码生成
|
|
124
|
+
- 选择 `4` 进入。
|
|
125
|
+
- 输入文本或 URL(支持直接回车读取剪贴板)。
|
|
126
|
+
- 终端直接显示二维码预览。
|
|
127
|
+
- 可选保存为 PNG 图片,默认文件名包含时间戳。
|
|
128
|
+
|
|
129
|
+
### 5. URL 编解码
|
|
113
130
|
- 选择 `5` 进入。
|
|
114
|
-
-
|
|
115
|
-
-
|
|
131
|
+
- 选择 `Encode` (编码) 或 `Decode` (解码)。
|
|
132
|
+
- 输入 URL 字符串,结果自动复制。
|
|
116
133
|
|
|
117
|
-
### 6.
|
|
134
|
+
### 6. 字符串 Base64 转换
|
|
118
135
|
- 选择 `6` 进入。
|
|
119
|
-
-
|
|
120
|
-
-
|
|
136
|
+
- 支持三种输入源:
|
|
137
|
+
- **Clipboard**: 直接读取剪贴板内容(适合处理长文本)。
|
|
138
|
+
- **File**: 读取文本文件内容。
|
|
139
|
+
- **Manual input**: 手动粘贴或输入文本。
|
|
140
|
+
- 输出支持:直接复制、保存为文件、预览后复制。
|
|
121
141
|
|
|
122
|
-
### 7.
|
|
142
|
+
### 7. HTML 实体编码/解码
|
|
123
143
|
- 选择 `7` 进入。
|
|
124
|
-
-
|
|
144
|
+
- 支持两种编码模式:
|
|
145
|
+
- **Standard**: 仅编码特殊字符(如 `<` `>` `&` 及非 ASCII 字符)。
|
|
146
|
+
- **Everything**: 编码所有字符(包括 ASCII 字母数字)。
|
|
147
|
+
- 支持直接回车读取剪贴板内容。
|
|
148
|
+
- 结果自动复制到剪贴板。
|
|
125
149
|
|
|
126
|
-
### 8.
|
|
150
|
+
### 8. 变量格式转换
|
|
127
151
|
- 选择 `8` 进入。
|
|
152
|
+
- 输入变量名(支持直接回车读取剪贴板)。
|
|
153
|
+
- 自动展示 CamelCase, PascalCase, SnakeCase, KebabCase, ConstantCase 五种格式。
|
|
154
|
+
- 选择一种格式自动复制。
|
|
155
|
+
|
|
156
|
+
### 9. 中文转拼音
|
|
157
|
+
- 选择 `9` 进入。
|
|
128
158
|
- 输入中文字符串(支持直接回车读取剪贴板)。
|
|
129
159
|
- 输出对应的拼音(无声调)。
|
|
130
160
|
|
|
131
|
-
###
|
|
132
|
-
- 选择 `
|
|
161
|
+
### 10. 时间格式化 (Time Format)
|
|
162
|
+
- 选择 `a` 进入。
|
|
163
|
+
- 支持时间戳转日期字符串,或日期字符串转时间戳。
|
|
164
|
+
- 直接回车可获取当前时间戳。
|
|
165
|
+
|
|
166
|
+
### 11. 颜色转换 (Hex <-> RGB)
|
|
167
|
+
- 选择 `b` 进入。
|
|
133
168
|
- 输入 Hex 颜色值 (如 #333) 或 RGB 值 (如 rgb(51,51,51))。
|
|
134
169
|
- 自动转换并显示对应格式。
|
|
135
170
|
|
|
136
|
-
###
|
|
137
|
-
- 选择 `
|
|
138
|
-
-
|
|
139
|
-
- 自动展示 CamelCase, PascalCase, SnakeCase, KebabCase, ConstantCase 五种格式。
|
|
140
|
-
- 选择一种格式自动复制。
|
|
171
|
+
### 12. Get UUID
|
|
172
|
+
- 选择 `c` 进入。
|
|
173
|
+
- 自动生成一个 UUID v4 并复制到剪贴板。
|
|
141
174
|
|
|
142
|
-
###
|
|
143
|
-
- 选择 `
|
|
175
|
+
### 13. 哈希计算 (Encryption)
|
|
176
|
+
- 选择 `d` 进入。
|
|
144
177
|
- 输入文本(支持直接回车读取剪贴板)。
|
|
145
178
|
- 同时计算并显示 MD5, SHA1, SHA256, SHA512, SM3 哈希值。
|
|
146
179
|
|
|
147
|
-
###
|
|
148
|
-
- 选择 `
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
- 可选保存为 PNG 图片,默认文件名包含时间戳。
|
|
180
|
+
### 14. Mock 数据生成
|
|
181
|
+
- 选择 `e` 进入。
|
|
182
|
+
- 提供多种数据类型:英文段落、中文字符、身份证号、邮箱、手机号等。
|
|
183
|
+
- 支持指定生成数量。
|
|
152
184
|
|
|
153
|
-
###
|
|
154
|
-
- 选择 `
|
|
185
|
+
### 15. 特殊符号大全
|
|
186
|
+
- 选择 `f` 进入。
|
|
155
187
|
- 网格化展示常用特殊符号。
|
|
156
188
|
- 输入符号对应的编号即可一键复制。
|
|
157
189
|
|
|
158
|
-
###
|
|
159
|
-
- 选择 `
|
|
190
|
+
### 16. Emoji 输入
|
|
191
|
+
- 选择 `g` 进入。
|
|
160
192
|
- 分类展示常用 Emoji (表情、手势、动物、食物等)。
|
|
161
193
|
- 输入编号选择并复制 Emoji 到剪贴板。
|
|
162
194
|
|
|
163
|
-
### 15. HTML 实体编码/解码
|
|
164
|
-
- 选择 `f` 进入。
|
|
165
|
-
- 支持两种编码模式:
|
|
166
|
-
- **Standard**: 仅编码特殊字符(如 `<` `>` `&` 及非 ASCII 字符)。
|
|
167
|
-
- **Everything**: 编码所有字符(包括 ASCII 字母数字)。
|
|
168
|
-
- 支持直接回车读取剪贴板内容。
|
|
169
|
-
- 结果自动复制到剪贴板。
|
|
170
|
-
|
|
171
195
|
## 📄 License
|
|
172
196
|
|
|
173
197
|
ISC
|
package/package.json
CHANGED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import sharp from 'sharp';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { copy } from '../utils/clipboard.js';
|
|
5
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
6
|
+
|
|
7
|
+
export async function placeholderImgHandler() {
|
|
8
|
+
const mode = await selectFromMenu('Generate Placeholder Image', [
|
|
9
|
+
{ name: 'Local Image File', value: 'local' },
|
|
10
|
+
{ name: 'Remote Image URL', value: 'remote' }
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
if (mode === 'local') {
|
|
14
|
+
await generateLocalImage();
|
|
15
|
+
} else {
|
|
16
|
+
await generateRemoteUrl();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function generateLocalImage() {
|
|
21
|
+
const answers = await inquirer.prompt([
|
|
22
|
+
{
|
|
23
|
+
type: 'input',
|
|
24
|
+
name: 'width',
|
|
25
|
+
message: 'Width (px):',
|
|
26
|
+
default: '300',
|
|
27
|
+
validate: validateNumber
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'input',
|
|
31
|
+
name: 'height',
|
|
32
|
+
message: 'Height (px):',
|
|
33
|
+
default: '200',
|
|
34
|
+
validate: validateNumber
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'input',
|
|
38
|
+
name: 'bgColor',
|
|
39
|
+
message: 'Background Color (Hex/Name):',
|
|
40
|
+
default: '#cccccc'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'input',
|
|
44
|
+
name: 'textColor',
|
|
45
|
+
message: 'Text Color (Hex/Name):',
|
|
46
|
+
default: '#333333'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: 'input',
|
|
50
|
+
name: 'text',
|
|
51
|
+
message: 'Text (leave empty for size):',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'list',
|
|
55
|
+
name: 'format',
|
|
56
|
+
message: 'Output Format:',
|
|
57
|
+
choices: ['png', 'jpg', 'webp', 'gif'],
|
|
58
|
+
default: 'png'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'input',
|
|
62
|
+
name: 'filename',
|
|
63
|
+
message: 'Filename (without extension):',
|
|
64
|
+
default: () => `placeholder-${Date.now()}`
|
|
65
|
+
}
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
const width = parseInt(answers.width);
|
|
69
|
+
const height = parseInt(answers.height);
|
|
70
|
+
const text = answers.text || `${width}x${height}`;
|
|
71
|
+
const fontSize = Math.floor(Math.min(width, height) / 5);
|
|
72
|
+
|
|
73
|
+
const svgImage = `
|
|
74
|
+
<svg width="${width}" height="${height}" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
75
|
+
<rect width="100%" height="100%" fill="${answers.bgColor}" />
|
|
76
|
+
<text x="50%" y="50%" font-size="${fontSize}" fill="${answers.textColor}" text-anchor="middle" dy=".3em" font-family="Arial, sans-serif">${text}</text>
|
|
77
|
+
</svg>
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
const buffer = Buffer.from(svgImage);
|
|
81
|
+
const outputFilename = `${answers.filename}.${answers.format}`;
|
|
82
|
+
const outputPath = path.resolve(process.cwd(), outputFilename);
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
await sharp(buffer)
|
|
86
|
+
.toFormat(answers.format)
|
|
87
|
+
.toFile(outputPath);
|
|
88
|
+
|
|
89
|
+
console.log(`\nImage generated successfully: ${outputPath}`);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error(`\nFailed to generate image: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function generateRemoteUrl() {
|
|
96
|
+
const provider = await selectFromMenu('Select Provider', [
|
|
97
|
+
{ name: 'Picsum Photos (Random photo)', value: 'picsum' },
|
|
98
|
+
{ name: 'DummyImage (Simple)', value: 'dummyimage' },
|
|
99
|
+
{ name: 'Via Placeholder (Standard)', value: 'placeholder' },
|
|
100
|
+
{ name: 'Placehold.jp (JP Style)', value: 'placeholdjp' },
|
|
101
|
+
{ name: 'DevTool Tech (Customizable)', value: 'devtool' },
|
|
102
|
+
{ name: 'FPO Img (For Placement Only)', value: 'fpoimg' }
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
// Picsum is special (random photos)
|
|
106
|
+
if (provider === 'picsum') {
|
|
107
|
+
const answers = await inquirer.prompt([
|
|
108
|
+
{ type: 'input', name: 'width', message: 'Width:', default: '300', validate: validateNumber },
|
|
109
|
+
{ type: 'input', name: 'height', message: 'Height:', default: '300', validate: validateNumber },
|
|
110
|
+
{ type: 'confirm', name: 'random', message: 'Add random parameter?', default: true },
|
|
111
|
+
{ type: 'confirm', name: 'grayscale', message: 'Grayscale?', default: false },
|
|
112
|
+
{ type: 'input', name: 'blur', message: 'Blur level (1-10, leave empty for none):', validate: (val) => !val || (parseInt(val) >= 1 && parseInt(val) <= 10) ? true : '1-10' }
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
let url = `https://picsum.photos/${answers.width}/${answers.height}`;
|
|
116
|
+
const params = [];
|
|
117
|
+
if (answers.grayscale) params.push('grayscale');
|
|
118
|
+
if (answers.blur) params.push(`blur=${answers.blur}`);
|
|
119
|
+
if (answers.random) params.push(`random=${Math.floor(Math.random() * 1000)}`);
|
|
120
|
+
|
|
121
|
+
if (params.length > 0) {
|
|
122
|
+
url += '?' + params.join('&');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await finishUrl(url);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Common prompts for others
|
|
130
|
+
const answers = await inquirer.prompt([
|
|
131
|
+
{ type: 'input', name: 'width', message: 'Width:', default: '300', validate: validateNumber },
|
|
132
|
+
{ type: 'input', name: 'height', message: 'Height:', default: '300', validate: validateNumber },
|
|
133
|
+
{ type: 'input', name: 'bgColor', message: 'Background Color (Hex without #):', default: 'cccccc' },
|
|
134
|
+
{ type: 'input', name: 'textColor', message: 'Text Color (Hex without #):', default: '969696' },
|
|
135
|
+
{ type: 'input', name: 'text', message: 'Text Content (leave empty for size):' },
|
|
136
|
+
{ type: 'list', name: 'format', message: 'Format:', choices: ['png', 'jpg', 'gif'], default: 'png' }
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
let url = '';
|
|
140
|
+
const { width, height, bgColor, textColor, format } = answers;
|
|
141
|
+
const text = answers.text || `${width}x${height}`;
|
|
142
|
+
const cleanBg = bgColor.replace('#', '');
|
|
143
|
+
const cleanText = textColor.replace('#', '');
|
|
144
|
+
const encodedText = encodeURIComponent(text);
|
|
145
|
+
|
|
146
|
+
switch (provider) {
|
|
147
|
+
case 'dummyimage':
|
|
148
|
+
// https://dummyimage.com/300x300/999999/ff4400.png?text=EXAMPLE
|
|
149
|
+
url = `https://dummyimage.com/${width}x${height}/${cleanBg}/${cleanText}.${format}`;
|
|
150
|
+
if (text) url += `?text=${encodedText}`;
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
case 'placeholder':
|
|
154
|
+
// https://via.placeholder.com/640x300/999999/ff4400.png?text=example
|
|
155
|
+
url = `https://via.placeholder.com/${width}x${height}/${cleanBg}/${cleanText}.${format}`;
|
|
156
|
+
if (text) url += `?text=${encodedText}`;
|
|
157
|
+
break;
|
|
158
|
+
|
|
159
|
+
case 'placeholdjp':
|
|
160
|
+
// https://placehold.jp/999999/ff4400/300x300.png?text=EXAMPLE
|
|
161
|
+
url = `https://placehold.jp/${cleanBg}/${cleanText}/${width}x${height}.${format}`;
|
|
162
|
+
if (text) url += `?text=${encodedText}`;
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case 'devtool':
|
|
166
|
+
// https://devtool.tech/api/placeholder/300/300?text=示例&color=#ffffff&bgColor=#333333
|
|
167
|
+
// Note: devtool.tech needs # for colors
|
|
168
|
+
url = `https://devtool.tech/api/placeholder/${width}/${height}?text=${encodedText}&color=%23${cleanText}&bgColor=%23${cleanBg}`;
|
|
169
|
+
break;
|
|
170
|
+
|
|
171
|
+
case 'fpoimg':
|
|
172
|
+
// https://fpoimg.com/300x300?text=example&bg_color=999999&text_color=ff4400
|
|
173
|
+
url = `https://fpoimg.com/${width}x${height}?text=${encodedText}&bg_color=${cleanBg}&text_color=${cleanText}`;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
await finishUrl(url);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function finishUrl(url) {
|
|
181
|
+
console.log(`\nGenerated URL:\n${url}\n`);
|
|
182
|
+
await copy(url);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function validateNumber(input) {
|
|
186
|
+
const val = parseInt(input);
|
|
187
|
+
return !isNaN(val) && val > 0 ? true : 'Please enter a valid positive number';
|
|
188
|
+
}
|
package/src/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { qrcodeHandler } from './commands/qrcode.js';
|
|
|
15
15
|
import { specialCharsHandler } from './commands/specialChars.js';
|
|
16
16
|
import { emojiHandler } from './commands/emoji.js';
|
|
17
17
|
import { htmlEntitiesHandler } from './commands/htmlEntities.js';
|
|
18
|
+
import { placeholderImgHandler } from './commands/placeholderImg.js';
|
|
18
19
|
|
|
19
20
|
process.on('SIGINT', () => {
|
|
20
21
|
console.log('\nBye!');
|
|
@@ -32,21 +33,29 @@ process.on('unhandledRejection', (err) => {
|
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
const features = [
|
|
35
|
-
|
|
36
|
-
{ name: 'String Encode/Decode (Base64)', value: 'base64' },
|
|
36
|
+
// Image Tools
|
|
37
37
|
{ name: 'Image <-> Base64', value: 'imgBase64' },
|
|
38
38
|
{ name: 'Image Format Convert', value: 'imgConvert' },
|
|
39
|
-
{ name: '
|
|
40
|
-
{ name: '
|
|
41
|
-
|
|
39
|
+
{ name: 'Placeholder Image Generator', value: 'placeholderImg' },
|
|
40
|
+
{ name: 'QR Code Generator', value: 'qrcode' },
|
|
41
|
+
|
|
42
|
+
// Encode/Decode & Formatting
|
|
43
|
+
{ name: 'URL Encode/Decode', value: 'url' },
|
|
44
|
+
{ name: 'String Encode/Decode (Base64)', value: 'base64' },
|
|
45
|
+
{ name: 'HTML Entity Encode/Decode', value: 'htmlEntities' },
|
|
46
|
+
{ name: 'Variable Format Converter', value: 'variableFormat' },
|
|
42
47
|
{ name: 'Chinese to Pinyin', value: 'pinyin' },
|
|
48
|
+
|
|
49
|
+
// Utils (Time, Color, UUID, Hash)
|
|
50
|
+
{ name: 'Time Format / Timestamp', value: 'timeFormat' },
|
|
43
51
|
{ name: 'Color Converter (Hex <-> RGB)', value: 'color' },
|
|
44
|
-
{ name: '
|
|
52
|
+
{ name: 'Get UUID', value: 'uuid' },
|
|
45
53
|
{ name: 'Hash Calculator (MD5/SHA/SM3)', value: 'hashing' },
|
|
46
|
-
|
|
54
|
+
|
|
55
|
+
// Content/Mocking
|
|
56
|
+
{ name: 'Mock Text', value: 'mock' },
|
|
47
57
|
{ name: 'Special Characters (Symbols)', value: 'specialChars' },
|
|
48
|
-
{ name: 'Emoji Picker', value: 'emoji' }
|
|
49
|
-
{ name: 'HTML Entity Encode/Decode', value: 'htmlEntities' }
|
|
58
|
+
{ name: 'Emoji Picker', value: 'emoji' }
|
|
50
59
|
];
|
|
51
60
|
|
|
52
61
|
async function main() {
|
|
@@ -170,6 +179,9 @@ async function handleAction(action) {
|
|
|
170
179
|
case 'htmlEntities':
|
|
171
180
|
await htmlEntitiesHandler();
|
|
172
181
|
break;
|
|
182
|
+
case 'placeholderImg':
|
|
183
|
+
await placeholderImgHandler();
|
|
184
|
+
break;
|
|
173
185
|
default:
|
|
174
186
|
console.log('Feature not implemented yet.');
|
|
175
187
|
}
|