xw-devtool-cli 1.0.2 → 1.0.4
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/package.json +3 -1
- package/src/commands/color.js +56 -0
- package/src/commands/hashing.js +58 -0
- package/src/commands/qrcode.js +61 -0
- package/src/commands/timeFormat.js +24 -1
- package/src/commands/variableFormat.js +94 -0
- package/src/index.js +50 -17
- package/src/utils/clipboard.js +9 -0
- package/src/commands/timestamp.js +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xw-devtool-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "基于node的开发者助手cli",
|
|
6
6
|
"main": "index.js",
|
|
@@ -51,7 +51,9 @@
|
|
|
51
51
|
"inquirer": "^13.1.0",
|
|
52
52
|
"lorem-ipsum": "^2.0.8",
|
|
53
53
|
"pinyin": "^4.0.0",
|
|
54
|
+
"qrcode": "^1.5.4",
|
|
54
55
|
"sharp": "^0.33.5",
|
|
56
|
+
"tinycolor2": "^1.6.0",
|
|
55
57
|
"uuid": "^13.0.0"
|
|
56
58
|
}
|
|
57
59
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import tinycolor from 'tinycolor2';
|
|
3
|
+
import { copy } from '../utils/clipboard.js';
|
|
4
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
5
|
+
|
|
6
|
+
export async function colorHandler() {
|
|
7
|
+
const { input } = await inquirer.prompt([
|
|
8
|
+
{
|
|
9
|
+
type: 'input',
|
|
10
|
+
name: 'input',
|
|
11
|
+
message: 'Enter color (Hex, RGB, HSL, or Name):',
|
|
12
|
+
validate: (input) => {
|
|
13
|
+
const color = tinycolor(input);
|
|
14
|
+
return color.isValid() || 'Invalid color format';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
const color = tinycolor(input);
|
|
20
|
+
|
|
21
|
+
const results = [];
|
|
22
|
+
results.push(`Hex: ${color.toHexString().toUpperCase()}`);
|
|
23
|
+
results.push(`RGB: ${color.toRgbString()}`);
|
|
24
|
+
results.push(`HSL: ${color.toHslString()}`);
|
|
25
|
+
results.push(`HSV: ${color.toHsvString()}`);
|
|
26
|
+
|
|
27
|
+
// CMYK conversion (manual, as tinycolor doesn't support it directly)
|
|
28
|
+
const rgb = color.toRgb();
|
|
29
|
+
const r = rgb.r / 255;
|
|
30
|
+
const g = rgb.g / 255;
|
|
31
|
+
const b = rgb.b / 255;
|
|
32
|
+
let k = 1 - Math.max(r, g, b);
|
|
33
|
+
let c = (1 - r - k) / (1 - k) || 0;
|
|
34
|
+
let m = (1 - g - k) / (1 - k) || 0;
|
|
35
|
+
let y = (1 - b - k) / (1 - k) || 0;
|
|
36
|
+
|
|
37
|
+
// Round to 2 decimal places
|
|
38
|
+
const toPercent = (n) => Math.round(n * 100);
|
|
39
|
+
const cmyk = `cmyk(${toPercent(c)}%, ${toPercent(m)}%, ${toPercent(y)}%, ${toPercent(k)}%)`;
|
|
40
|
+
results.push(`CMYK: ${cmyk}`);
|
|
41
|
+
|
|
42
|
+
console.log('\n=== Conversion Results ===');
|
|
43
|
+
results.forEach(res => console.log(res));
|
|
44
|
+
console.log('==========================\n');
|
|
45
|
+
|
|
46
|
+
// Allow user to copy one of the formats
|
|
47
|
+
const copyChoice = await selectFromMenu('Select format to copy', [
|
|
48
|
+
{ name: 'Hex', value: color.toHexString().toUpperCase() },
|
|
49
|
+
{ name: 'RGB', value: color.toRgbString() },
|
|
50
|
+
{ name: 'HSL', value: color.toHslString() },
|
|
51
|
+
{ name: 'HSV', value: color.toHsvString() },
|
|
52
|
+
{ name: 'CMYK', value: cmyk }
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
await copy(copyChoice);
|
|
56
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import { copy, read } from '../utils/clipboard.js';
|
|
4
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
5
|
+
|
|
6
|
+
export async function hashingHandler() {
|
|
7
|
+
const { input } = await inquirer.prompt([
|
|
8
|
+
{
|
|
9
|
+
type: 'input',
|
|
10
|
+
name: 'input',
|
|
11
|
+
message: 'Enter text to hash (Press Enter to paste from clipboard):',
|
|
12
|
+
}
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
let textToHash = input;
|
|
16
|
+
|
|
17
|
+
if (!textToHash || textToHash.length === 0) {
|
|
18
|
+
textToHash = await read();
|
|
19
|
+
if (!textToHash || textToHash.length === 0) {
|
|
20
|
+
console.log('Clipboard is empty or could not be read.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.log(`\nUsing clipboard content: "${textToHash}"`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const algorithms = [
|
|
27
|
+
{ name: 'MD5', algo: 'md5' },
|
|
28
|
+
{ name: 'SHA1', algo: 'sha1' },
|
|
29
|
+
{ name: 'SHA256', algo: 'sha256' },
|
|
30
|
+
{ name: 'SHA512', algo: 'sha512' },
|
|
31
|
+
{ name: 'SM3', algo: 'sm3' }
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const results = [];
|
|
35
|
+
|
|
36
|
+
console.log('\n=== Hash Results ===');
|
|
37
|
+
for (const { name, algo } of algorithms) {
|
|
38
|
+
try {
|
|
39
|
+
const hash = crypto.createHash(algo).update(textToHash).digest('hex');
|
|
40
|
+
results.push({ name, value: hash });
|
|
41
|
+
console.log(`${name.padEnd(8)}: ${hash}`);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.log(`${name.padEnd(8)}: Not supported in this environment`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
console.log('====================\n');
|
|
47
|
+
|
|
48
|
+
if (results.length === 0) return;
|
|
49
|
+
|
|
50
|
+
const copyChoice = await selectFromMenu('Select hash to copy',
|
|
51
|
+
results.map(r => ({
|
|
52
|
+
name: `${r.name} (${r.value.substring(0, 10)}...)`,
|
|
53
|
+
value: r.value
|
|
54
|
+
}))
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
await copy(copyChoice);
|
|
58
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import QRCode from 'qrcode';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import dayjs from 'dayjs';
|
|
6
|
+
import { read } from '../utils/clipboard.js';
|
|
7
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
8
|
+
|
|
9
|
+
export async function qrcodeHandler() {
|
|
10
|
+
const { input } = await inquirer.prompt([
|
|
11
|
+
{
|
|
12
|
+
type: 'input',
|
|
13
|
+
name: 'input',
|
|
14
|
+
message: 'Enter text to generate QR code (Press Enter to paste from clipboard):',
|
|
15
|
+
}
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
let textToEncode = input;
|
|
19
|
+
|
|
20
|
+
if (!textToEncode || textToEncode.length === 0) {
|
|
21
|
+
textToEncode = await read();
|
|
22
|
+
if (!textToEncode || textToEncode.length === 0) {
|
|
23
|
+
console.log('Clipboard is empty or could not be read.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(`\nUsing clipboard content: "${textToEncode}"`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Display in terminal
|
|
31
|
+
const string = await QRCode.toString(textToEncode, { type: 'terminal', small: true });
|
|
32
|
+
console.log('\n=== QR Code ===\n');
|
|
33
|
+
console.log(string);
|
|
34
|
+
console.log('===============\n');
|
|
35
|
+
|
|
36
|
+
// Ask if user wants to save to file
|
|
37
|
+
const action = await selectFromMenu('What would you like to do next?', [
|
|
38
|
+
{ name: 'Back to menu', value: 'back' },
|
|
39
|
+
{ name: 'Save as PNG image', value: 'save' }
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
if (action === 'save') {
|
|
43
|
+
const defaultFilename = `qrcode_${dayjs().format('YYYYMMDD_HHmmss')}.png`;
|
|
44
|
+
const { filename } = await inquirer.prompt([
|
|
45
|
+
{
|
|
46
|
+
type: 'input',
|
|
47
|
+
name: 'filename',
|
|
48
|
+
message: `Enter filename (default: ${defaultFilename}):`,
|
|
49
|
+
default: defaultFilename
|
|
50
|
+
}
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
const outputPath = path.resolve(process.cwd(), filename);
|
|
54
|
+
await QRCode.toFile(outputPath, textToEncode);
|
|
55
|
+
console.log(`\nQR Code saved to: ${outputPath}\n`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error('Error generating QR code:', err.message);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import dayjs from 'dayjs';
|
|
3
|
+
import 'dayjs/locale/zh-cn.js';
|
|
3
4
|
import { copy } from '../utils/clipboard.js';
|
|
5
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
6
|
+
|
|
7
|
+
dayjs.locale('zh-cn');
|
|
4
8
|
|
|
5
9
|
export async function timeFormatHandler() {
|
|
6
10
|
const { input } = await inquirer.prompt([
|
|
@@ -35,7 +39,26 @@ export async function timeFormatHandler() {
|
|
|
35
39
|
return;
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
const
|
|
42
|
+
const formatPattern = await selectFromMenu('Select Output Format', [
|
|
43
|
+
{ name: 'YYYY-MM-DD HH:mm:ss', value: 'YYYY-MM-DD HH:mm:ss' },
|
|
44
|
+
{ name: 'YYYY-MM-DD HH:mm', value: 'YYYY-MM-DD HH:mm' },
|
|
45
|
+
{ name: 'YYYY-MM-DD', value: 'YYYY-MM-DD' },
|
|
46
|
+
{ name: 'HH:mm:ss', value: 'HH:mm:ss' },
|
|
47
|
+
{ name: 'YYYY-MM-DD HH:mm:ss dddd', value: 'YYYY-MM-DD HH:mm:ss dddd' },
|
|
48
|
+
{ name: 'dddd', value: 'dddd' },
|
|
49
|
+
{ name: 'Timestamp (ms)', value: 'timestamp-ms' },
|
|
50
|
+
{ name: 'Timestamp (s)', value: 'timestamp-s' }
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
let formatted;
|
|
54
|
+
if (formatPattern === 'timestamp-ms') {
|
|
55
|
+
formatted = String(date.valueOf());
|
|
56
|
+
} else if (formatPattern === 'timestamp-s') {
|
|
57
|
+
formatted = String(date.unix());
|
|
58
|
+
} else {
|
|
59
|
+
formatted = date.format(formatPattern);
|
|
60
|
+
}
|
|
61
|
+
|
|
39
62
|
console.log(`\nFormatted: ${formatted}\n`);
|
|
40
63
|
await copy(formatted);
|
|
41
64
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import { copy, read } from '../utils/clipboard.js';
|
|
3
|
+
import { selectFromMenu } from '../utils/menu.js';
|
|
4
|
+
|
|
5
|
+
export async function variableFormatHandler() {
|
|
6
|
+
const { input } = await inquirer.prompt([
|
|
7
|
+
{
|
|
8
|
+
type: 'input',
|
|
9
|
+
name: 'input',
|
|
10
|
+
message: 'Enter variable name to convert (Press Enter to paste from clipboard):',
|
|
11
|
+
}
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
let textToConvert = input;
|
|
15
|
+
|
|
16
|
+
if (!textToConvert || textToConvert.trim().length === 0) {
|
|
17
|
+
textToConvert = await read();
|
|
18
|
+
if (!textToConvert || textToConvert.trim().length === 0) {
|
|
19
|
+
console.log('Clipboard is empty or could not be read.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log(`\nUsing clipboard content: "${textToConvert}"`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const words = splitIntoWords(textToConvert);
|
|
26
|
+
|
|
27
|
+
if (words.length === 0) {
|
|
28
|
+
console.log('Could not parse any words from input.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const results = {
|
|
33
|
+
'camelCase': toCamelCase(words),
|
|
34
|
+
'PascalCase': toPascalCase(words),
|
|
35
|
+
'snake_case': toSnakeCase(words),
|
|
36
|
+
'kebab-case': toKebabCase(words),
|
|
37
|
+
'CONSTANT_CASE': toConstantCase(words)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
console.log('\n=== Conversion Results ===');
|
|
41
|
+
Object.entries(results).forEach(([key, value]) => {
|
|
42
|
+
console.log(`${key.padEnd(15)}: ${value}`);
|
|
43
|
+
});
|
|
44
|
+
console.log('==========================\n');
|
|
45
|
+
|
|
46
|
+
const copyChoice = await selectFromMenu('Select format to copy',
|
|
47
|
+
Object.entries(results).map(([key, value]) => ({
|
|
48
|
+
name: `${key} (${value})`,
|
|
49
|
+
value: value
|
|
50
|
+
}))
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
await copy(copyChoice);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function splitIntoWords(str) {
|
|
57
|
+
// 1. Handle CamelCase/camelCase by inserting space before uppercase letters that follow lowercase letters
|
|
58
|
+
let temp = str.replace(/([a-z])([A-Z])/g, '$1 $2');
|
|
59
|
+
|
|
60
|
+
// 2. Handle consecutive uppercase followed by lowercase (e.g. JSONParser -> JSON Parser)
|
|
61
|
+
temp = temp.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
|
|
62
|
+
|
|
63
|
+
// 3. Replace non-alphanumeric characters with spaces
|
|
64
|
+
temp = temp.replace(/[^a-zA-Z0-9]+/g, ' ');
|
|
65
|
+
|
|
66
|
+
// 4. Split by whitespace and filter empty strings
|
|
67
|
+
return temp
|
|
68
|
+
.trim()
|
|
69
|
+
.split(/\s+/)
|
|
70
|
+
.filter(w => w.length > 0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function toCamelCase(words) {
|
|
74
|
+
return words.map((w, i) => {
|
|
75
|
+
if (i === 0) return w.toLowerCase();
|
|
76
|
+
return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
|
|
77
|
+
}).join('');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function toPascalCase(words) {
|
|
81
|
+
return words.map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function toSnakeCase(words) {
|
|
85
|
+
return words.map(w => w.toLowerCase()).join('_');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function toKebabCase(words) {
|
|
89
|
+
return words.map(w => w.toLowerCase()).join('-');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function toConstantCase(words) {
|
|
93
|
+
return words.map(w => w.toUpperCase()).join('_');
|
|
94
|
+
}
|
package/src/index.js
CHANGED
|
@@ -5,10 +5,13 @@ import { base64Handler } from './commands/base64.js';
|
|
|
5
5
|
import { imgBase64Handler } from './commands/imgBase64.js';
|
|
6
6
|
import { imgConvertHandler } from './commands/imgConvert.js';
|
|
7
7
|
import { timeFormatHandler } from './commands/timeFormat.js';
|
|
8
|
-
import { timestampHandler } from './commands/timestamp.js';
|
|
9
8
|
import { mockHandler } from './commands/mock.js';
|
|
10
9
|
import { uuidHandler } from './commands/uuid.js';
|
|
11
10
|
import { pinyinHandler } from './commands/pinyin.js';
|
|
11
|
+
import { colorHandler } from './commands/color.js';
|
|
12
|
+
import { variableFormatHandler } from './commands/variableFormat.js';
|
|
13
|
+
import { hashingHandler } from './commands/hashing.js';
|
|
14
|
+
import { qrcodeHandler } from './commands/qrcode.js';
|
|
12
15
|
|
|
13
16
|
process.on('SIGINT', () => {
|
|
14
17
|
console.log('\nBye!');
|
|
@@ -30,11 +33,14 @@ const features = [
|
|
|
30
33
|
{ name: 'String Encode/Decode (Base64)', value: 'base64' },
|
|
31
34
|
{ name: 'Image <-> Base64', value: 'imgBase64' },
|
|
32
35
|
{ name: 'Image Format Convert', value: 'imgConvert' },
|
|
33
|
-
{ name: 'Time Format', value: 'timeFormat' },
|
|
34
|
-
{ name: 'Get Current Timestamp', value: 'timestamp' },
|
|
36
|
+
{ name: 'Time Format / Timestamp', value: 'timeFormat' },
|
|
35
37
|
{ name: 'Mock Text', value: 'mock' },
|
|
36
38
|
{ name: 'Get UUID', value: 'uuid' },
|
|
37
|
-
{ name: 'Chinese to Pinyin', value: 'pinyin' }
|
|
39
|
+
{ name: 'Chinese to Pinyin', value: 'pinyin' },
|
|
40
|
+
{ name: 'Color Converter (Hex <-> RGB)', value: 'color' },
|
|
41
|
+
{ name: 'Variable Format Converter', value: 'variableFormat' },
|
|
42
|
+
{ name: 'Hash Calculator (MD5/SHA/SM3)', value: 'hashing' },
|
|
43
|
+
{ name: 'QR Code Generator', value: 'qrcode' }
|
|
38
44
|
];
|
|
39
45
|
|
|
40
46
|
async function main() {
|
|
@@ -48,12 +54,29 @@ async function main() {
|
|
|
48
54
|
program.parse(process.argv);
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
function getFeatureKey(index) {
|
|
58
|
+
if (index < 9) {
|
|
59
|
+
return String(index + 1);
|
|
60
|
+
}
|
|
61
|
+
return String.fromCharCode('a'.charCodeAt(0) + (index - 9));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getFeatureIndex(key) {
|
|
65
|
+
if (/^[1-9]$/.test(key)) {
|
|
66
|
+
return parseInt(key) - 1;
|
|
67
|
+
}
|
|
68
|
+
if (/^[a-z]$/.test(key.toLowerCase())) {
|
|
69
|
+
return key.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0) + 9;
|
|
70
|
+
}
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
73
|
+
|
|
51
74
|
async function showMenu() {
|
|
52
75
|
console.log('\n=================================');
|
|
53
76
|
console.log(' xw-devtool-cli Menu');
|
|
54
77
|
console.log('=================================');
|
|
55
78
|
features.forEach((feature, index) => {
|
|
56
|
-
console.log(`${index
|
|
79
|
+
console.log(`${getFeatureKey(index)}. ${feature.name}`);
|
|
57
80
|
});
|
|
58
81
|
console.log('0. Exit');
|
|
59
82
|
console.log('=================================\n');
|
|
@@ -62,25 +85,26 @@ async function showMenu() {
|
|
|
62
85
|
{
|
|
63
86
|
type: 'input',
|
|
64
87
|
name: 'choice',
|
|
65
|
-
message:
|
|
88
|
+
message: `Please enter the feature key (0-9, a-z):`,
|
|
66
89
|
validate: (input) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
if (input === '0') return true;
|
|
91
|
+
|
|
92
|
+
const index = getFeatureIndex(input);
|
|
93
|
+
if (index >= 0 && index < features.length) {
|
|
94
|
+
return true;
|
|
70
95
|
}
|
|
71
|
-
return
|
|
96
|
+
return 'Invalid selection. Please enter a valid menu key.';
|
|
72
97
|
}
|
|
73
98
|
}
|
|
74
99
|
]);
|
|
75
100
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (index === 0) {
|
|
101
|
+
if (choice === '0') {
|
|
79
102
|
console.log('Bye!');
|
|
80
103
|
process.exit(0);
|
|
81
104
|
}
|
|
82
105
|
|
|
83
|
-
const
|
|
106
|
+
const index = getFeatureIndex(choice);
|
|
107
|
+
const selectedFeature = features[index];
|
|
84
108
|
|
|
85
109
|
try {
|
|
86
110
|
await handleAction(selectedFeature.value);
|
|
@@ -110,9 +134,6 @@ async function handleAction(action) {
|
|
|
110
134
|
case 'timeFormat':
|
|
111
135
|
await timeFormatHandler();
|
|
112
136
|
break;
|
|
113
|
-
case 'timestamp':
|
|
114
|
-
await timestampHandler();
|
|
115
|
-
break;
|
|
116
137
|
case 'mock':
|
|
117
138
|
await mockHandler();
|
|
118
139
|
break;
|
|
@@ -122,6 +143,18 @@ async function handleAction(action) {
|
|
|
122
143
|
case 'pinyin':
|
|
123
144
|
await pinyinHandler();
|
|
124
145
|
break;
|
|
146
|
+
case 'color':
|
|
147
|
+
await colorHandler();
|
|
148
|
+
break;
|
|
149
|
+
case 'variableFormat':
|
|
150
|
+
await variableFormatHandler();
|
|
151
|
+
break;
|
|
152
|
+
case 'hashing':
|
|
153
|
+
await hashingHandler();
|
|
154
|
+
break;
|
|
155
|
+
case 'qrcode':
|
|
156
|
+
await qrcodeHandler();
|
|
157
|
+
break;
|
|
125
158
|
default:
|
|
126
159
|
console.log('Feature not implemented yet.');
|
|
127
160
|
}
|
package/src/utils/clipboard.js
CHANGED
|
@@ -8,3 +8,12 @@ export async function copy(text) {
|
|
|
8
8
|
console.error('Failed to copy to clipboard (might not be supported in this environment):', e.message);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
export async function read() {
|
|
13
|
+
try {
|
|
14
|
+
return await clipboardy.read();
|
|
15
|
+
} catch (e) {
|
|
16
|
+
console.error('Failed to read from clipboard:', e.message);
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
}
|