@xx-in/tools 0.0.1 → 0.0.3
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 +35 -5
- package/dist/cli.js +452 -848
- package/package.json +4 -2
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import process4 from "process";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@xx-in/tools",
|
|
10
|
-
version: "0.0.
|
|
10
|
+
version: "0.0.3",
|
|
11
11
|
description: "A command-line tool to run in any system",
|
|
12
12
|
license: "MIT",
|
|
13
13
|
type: "module",
|
|
@@ -20,7 +20,9 @@ var package_default = {
|
|
|
20
20
|
scripts: {
|
|
21
21
|
build: "tsup",
|
|
22
22
|
dev: "tsup --watch",
|
|
23
|
-
prepublishOnly: "npm run build"
|
|
23
|
+
prepublishOnly: "npm run build",
|
|
24
|
+
"publish:npm": "npm publish --access public",
|
|
25
|
+
"publish:npm:registry": "npm --registry=https://registry.npmjs.org/ publish --access public"
|
|
24
26
|
},
|
|
25
27
|
engines: {
|
|
26
28
|
node: ">=18"
|
|
@@ -70,7 +72,7 @@ _xx() {
|
|
|
70
72
|
'create:\u9012\u5F52\u521B\u5EFA\u6587\u4EF6\u6216\u76EE\u5F55'
|
|
71
73
|
'format:\u4F7F\u7528 Prettier \u683C\u5F0F\u5316\u4EE3\u7801'
|
|
72
74
|
'help:\u663E\u793A\u6307\u5B9A\u547D\u4EE4\u7684\u5E2E\u52A9\u4FE1\u606F'
|
|
73
|
-
'install
|
|
75
|
+
'install:macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668 (\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u4E0E tar \u5305)'
|
|
74
76
|
'ip:\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FA6\u6D4B'
|
|
75
77
|
'list:\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09'
|
|
76
78
|
'move:\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55'
|
|
@@ -80,7 +82,7 @@ _xx() {
|
|
|
80
82
|
'remove:\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09'
|
|
81
83
|
'search:\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55'
|
|
82
84
|
'translate:\u7EC8\u7AEF\u7FFB\u8BD1\u5DE5\u5177'
|
|
83
|
-
'uninstall
|
|
85
|
+
'uninstall:macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09'
|
|
84
86
|
'unzip:\u89E3\u538B ZIP \u538B\u7F29\u5305'
|
|
85
87
|
'upgrade:\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C'
|
|
86
88
|
'zip:\u81EA\u52A8\u8FC7\u6EE4\u5E76\u6253\u5305\u4E3A ZIP'
|
|
@@ -109,7 +111,7 @@ _xx() {
|
|
|
109
111
|
'copy:\u590D\u5236\u6587\u4EF6\u6216\u76EE\u5F55\uFF08\u652F\u6301\u9012\u5F52\u590D\u5236\uFF09'
|
|
110
112
|
'create:\u9012\u5F52\u521B\u5EFA\u6587\u4EF6\u6216\u76EE\u5F55'
|
|
111
113
|
'format:\u4F7F\u7528 Prettier \u683C\u5F0F\u5316\u4EE3\u7801'
|
|
112
|
-
'install
|
|
114
|
+
'install:macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668 (\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u4E0E tar \u5305)'
|
|
113
115
|
'ip:\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FA6\u6D4B'
|
|
114
116
|
'list:\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09'
|
|
115
117
|
'move:\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55'
|
|
@@ -119,7 +121,7 @@ _xx() {
|
|
|
119
121
|
'remove:\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09'
|
|
120
122
|
'search:\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55'
|
|
121
123
|
'translate:\u7EC8\u7AEF\u7FFB\u8BD1\u5DE5\u5177'
|
|
122
|
-
'uninstall
|
|
124
|
+
'uninstall:macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09'
|
|
123
125
|
'unzip:\u89E3\u538B ZIP \u538B\u7F29\u5305'
|
|
124
126
|
'upgrade:\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C'
|
|
125
127
|
'zip:\u81EA\u52A8\u8FC7\u6EE4\u5E76\u6253\u5305\u4E3A ZIP'
|
|
@@ -165,6 +167,10 @@ _xx() {
|
|
|
165
167
|
'-d[\u6307\u5B9A\u89E3\u538B\u5230\u7684\u76EE\u6807\u76EE\u5F55\u8DEF\u5F84]:directory:_files -/' \\
|
|
166
168
|
'*:Zip File:_files -g "*.zip"'
|
|
167
169
|
;;
|
|
170
|
+
upgrade)
|
|
171
|
+
_arguments \\
|
|
172
|
+
'-r[\u5F3A\u5236\u4F7F\u7528 npm \u5B98\u65B9\u6E90 https://registry.npmjs.org/]'
|
|
173
|
+
;;
|
|
168
174
|
zip)
|
|
169
175
|
_arguments \\
|
|
170
176
|
'*:Target Path:_files'
|
|
@@ -247,6 +253,11 @@ _xx_completion() {
|
|
|
247
253
|
COMPREPLY=( $(compgen -W "\${sub_opts}" -- \${cur}) )
|
|
248
254
|
return 0
|
|
249
255
|
;;
|
|
256
|
+
upgrade)
|
|
257
|
+
local sub_opts="-r --registry"
|
|
258
|
+
COMPREPLY=( $(compgen -W "\${sub_opts}" -- \${cur}) )
|
|
259
|
+
return 0
|
|
260
|
+
;;
|
|
250
261
|
help)
|
|
251
262
|
local sub_opts="completion copy create format ip list move open park proxy remove search translate uninstall unzip upgrade zip"
|
|
252
263
|
COMPREPLY=( $(compgen -W "\${sub_opts}" -- \${cur}) )
|
|
@@ -301,6 +312,7 @@ $xx_completer = {
|
|
|
301
312
|
"park" = @("-d", "-o", "-g")
|
|
302
313
|
"proxy" = @("on", "off")
|
|
303
314
|
"unzip" = @("-d")
|
|
315
|
+
"upgrade" = @("-r", "--registry")
|
|
304
316
|
"translate" = @("-t")
|
|
305
317
|
"help" = @("completion", "copy", "create", "format", "ip", "list", "move", "open", "park", "proxy", "remove", "search", "translate", "uninstall", "unzip", "upgrade", "zip")
|
|
306
318
|
}
|
|
@@ -535,12 +547,12 @@ function isCommandAvailable(cmd) {
|
|
|
535
547
|
}
|
|
536
548
|
function runCommand(cmd, args, options = {}) {
|
|
537
549
|
const stdio = options.stdio ?? "pipe";
|
|
538
|
-
return new Promise((
|
|
550
|
+
return new Promise((resolve13, reject) => {
|
|
539
551
|
const child = spawn(cmd, args, { stdio });
|
|
540
552
|
if (stdio === "inherit" || stdio === "ignore") {
|
|
541
553
|
child.on("error", reject);
|
|
542
554
|
child.on("close", (code) => {
|
|
543
|
-
|
|
555
|
+
resolve13({
|
|
544
556
|
success: code === 0,
|
|
545
557
|
code,
|
|
546
558
|
stdout: Buffer.alloc(0),
|
|
@@ -555,7 +567,7 @@ function runCommand(cmd, args, options = {}) {
|
|
|
555
567
|
child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
|
|
556
568
|
child.on("error", reject);
|
|
557
569
|
child.on("close", (code) => {
|
|
558
|
-
|
|
570
|
+
resolve13({
|
|
559
571
|
success: code === 0,
|
|
560
572
|
code,
|
|
561
573
|
stdout: Buffer.concat(stdoutChunks),
|
|
@@ -752,268 +764,289 @@ function registerFormatCommand(program2) {
|
|
|
752
764
|
}
|
|
753
765
|
|
|
754
766
|
// commands/install.ts
|
|
767
|
+
import fs6 from "fs/promises";
|
|
768
|
+
import pc6 from "picocolors";
|
|
769
|
+
import { resolve as resolve4, join as join5, basename as basename3 } from "path";
|
|
770
|
+
|
|
771
|
+
// utils/macos-apps.ts
|
|
755
772
|
import fs5 from "fs/promises";
|
|
773
|
+
import { basename as basename2, extname, join as join4 } from "path";
|
|
756
774
|
import pc5 from "picocolors";
|
|
757
|
-
|
|
775
|
+
var APP_DIR_NAME = ".xx-tools";
|
|
776
|
+
var PATH_MARKER_BEGIN = "# >>> xx-tools path >>>";
|
|
777
|
+
var PATH_MARKER_END = "# <<< xx-tools path <<<";
|
|
758
778
|
function getHomeDir() {
|
|
759
|
-
return process.env["HOME"] || process.
|
|
779
|
+
return process.env["HOME"] || process.cwd();
|
|
780
|
+
}
|
|
781
|
+
function getToolsRootDir() {
|
|
782
|
+
return join4(getHomeDir(), APP_DIR_NAME);
|
|
783
|
+
}
|
|
784
|
+
function getAppsDir() {
|
|
785
|
+
return join4(getToolsRootDir(), "apps");
|
|
786
|
+
}
|
|
787
|
+
function getBinDir() {
|
|
788
|
+
return join4(getToolsRootDir(), "bin");
|
|
760
789
|
}
|
|
761
|
-
|
|
790
|
+
function getManifestPath(appName) {
|
|
791
|
+
return join4(getAppsDir(), appName, ".xx-manifest.json");
|
|
792
|
+
}
|
|
793
|
+
function ensureMacOS() {
|
|
794
|
+
if (process.platform !== "darwin") {
|
|
795
|
+
console.error(pc5.red("\u274C \u5F53\u524D install/uninstall \u4EC5\u652F\u6301 macOS\u3002"));
|
|
796
|
+
return false;
|
|
797
|
+
}
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
async function ensureToolDirectories() {
|
|
801
|
+
await fs5.mkdir(getAppsDir(), { recursive: true });
|
|
802
|
+
await fs5.mkdir(getBinDir(), { recursive: true });
|
|
803
|
+
}
|
|
804
|
+
function getPreferredProfiles() {
|
|
762
805
|
const home = getHomeDir();
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
const segments = targetPath.split(".");
|
|
770
|
-
name = segments[segments.length - 1];
|
|
771
|
-
execLine = `flatpak run ${targetPath}`;
|
|
772
|
-
desktopFileName = `flatpak-${targetPath}.desktop`;
|
|
806
|
+
const shell = process.env["SHELL"] || "";
|
|
807
|
+
const profiles = [];
|
|
808
|
+
if (shell.includes("zsh")) {
|
|
809
|
+
profiles.push(join4(home, ".zshrc"), join4(home, ".zprofile"));
|
|
810
|
+
} else if (shell.includes("bash")) {
|
|
811
|
+
profiles.push(join4(home, ".bashrc"), join4(home, ".bash_profile"));
|
|
773
812
|
} else {
|
|
774
|
-
|
|
813
|
+
profiles.push(join4(home, ".zshrc"), join4(home, ".zprofile"));
|
|
814
|
+
}
|
|
815
|
+
return Array.from(new Set(profiles));
|
|
816
|
+
}
|
|
817
|
+
async function ensureBinDirOnPath() {
|
|
818
|
+
const pathBlock = `${PATH_MARKER_BEGIN}
|
|
819
|
+
export PATH="$HOME/${APP_DIR_NAME}/bin:$PATH"
|
|
820
|
+
${PATH_MARKER_END}`;
|
|
821
|
+
for (const profilePath of getPreferredProfiles()) {
|
|
822
|
+
let content = "";
|
|
775
823
|
try {
|
|
776
|
-
|
|
777
|
-
if (!stat.isFile()) {
|
|
778
|
-
console.error(pc5.red(`\u274C \u9519\u8BEF: '${targetPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
824
|
+
content = await fs5.readFile(profilePath, "utf-8");
|
|
781
825
|
} catch {
|
|
782
|
-
console.error(pc5.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6587\u4EF6 '${targetPath}'\u3002`));
|
|
783
|
-
return;
|
|
784
826
|
}
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
827
|
+
if (!content.includes(PATH_MARKER_BEGIN)) {
|
|
828
|
+
const separator = content.endsWith("\n") || content === "" ? "" : "\n";
|
|
829
|
+
await fs5.writeFile(
|
|
830
|
+
profilePath,
|
|
831
|
+
`${content}${separator}${pathBlock}
|
|
832
|
+
`,
|
|
833
|
+
"utf-8"
|
|
834
|
+
);
|
|
835
|
+
console.log(pc5.green(`\u2714 \u5DF2\u5199\u5165 PATH \u914D\u7F6E: ${profilePath}`));
|
|
790
836
|
}
|
|
791
|
-
execLine = isAppImage ? `"${absolutePath}" --no-sandbox` : `"${absolutePath}"`;
|
|
792
|
-
desktopFileName = `${name.replace(/\s+/g, "-").toLowerCase()}.desktop`;
|
|
793
|
-
}
|
|
794
|
-
const desktopFilePath = join4(applicationsDir, desktopFileName);
|
|
795
|
-
const desktopContent = `[Desktop Entry]
|
|
796
|
-
Name=${name}
|
|
797
|
-
Exec=${execLine}
|
|
798
|
-
Type=Application
|
|
799
|
-
Terminal=false
|
|
800
|
-
Categories=Utility;
|
|
801
|
-
`;
|
|
802
|
-
try {
|
|
803
|
-
await fs5.mkdir(applicationsDir, { recursive: true });
|
|
804
|
-
await fs5.writeFile(desktopFilePath, desktopContent, "utf-8");
|
|
805
|
-
console.log(pc5.green(`\u2714 \u5FEB\u6377\u65B9\u5F0F\u5DF2\u521B\u5EFA: ${desktopFilePath}`));
|
|
806
|
-
console.log(pc5.dim(`\u542F\u52A8\u547D\u4EE4: ${execLine}`));
|
|
807
|
-
} catch (err) {
|
|
808
|
-
console.error(
|
|
809
|
-
pc5.red("\u274C \u521B\u5EFA\u5FEB\u6377\u65B9\u5F0F\u5931\u8D25:"),
|
|
810
|
-
err instanceof Error ? err.message : err
|
|
811
|
-
);
|
|
812
837
|
}
|
|
813
838
|
}
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
const destPath = join4(greenAppDir, fileName);
|
|
819
|
-
const isAppImage = fileName.toLowerCase().endsWith(".appimage");
|
|
820
|
-
const appNameClean = basename2(absPath, isAppImage ? ".AppImage" : "");
|
|
821
|
-
try {
|
|
822
|
-
await fs5.mkdir(greenAppDir, { recursive: true });
|
|
823
|
-
console.log(
|
|
824
|
-
pc5.cyan(`\u{1F4E6} \u6B63\u5728\u5C06 AppImage \u90E8\u7F72\u81F3\u7EFF\u8272\u8F6F\u4EF6\u76EE\u5F55: ${destPath}...`)
|
|
825
|
-
);
|
|
826
|
-
await fs5.copyFile(absPath, destPath);
|
|
827
|
-
await fs5.chmod(destPath, 493);
|
|
828
|
-
await createShortcut(destPath);
|
|
829
|
-
console.log(pc5.green(`\u2728 AppImage \u90E8\u7F72\u5B8C\u6210\uFF01`));
|
|
830
|
-
console.log(
|
|
831
|
-
pc5.green(
|
|
832
|
-
`
|
|
833
|
-
\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u7EFF\u8272\u8F6F\u4EF6\u7684\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(appNameClean)}`
|
|
834
|
-
)
|
|
835
|
-
);
|
|
836
|
-
console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
|
|
837
|
-
console.log(pc5.bold(pc5.yellow(` xx delete ${appNameClean}`)));
|
|
838
|
-
} catch (err) {
|
|
839
|
-
console.error(
|
|
840
|
-
pc5.red("\u274C AppImage \u90E8\u7F72\u5931\u8D25:"),
|
|
841
|
-
err instanceof Error ? err.message : err
|
|
842
|
-
);
|
|
839
|
+
function getShellReloadCommand() {
|
|
840
|
+
const shell = process.env["SHELL"] || "";
|
|
841
|
+
if (shell.includes("zsh")) {
|
|
842
|
+
return "source ~/.zshrc";
|
|
843
843
|
}
|
|
844
|
+
if (shell.includes("bash")) {
|
|
845
|
+
return "source ~/.bashrc";
|
|
846
|
+
}
|
|
847
|
+
return "source ~/.zshrc";
|
|
844
848
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
const
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
"-f",
|
|
853
|
-
absPath,
|
|
854
|
-
"Package"
|
|
855
|
-
]);
|
|
856
|
-
if (success) {
|
|
857
|
-
const packageName = decodeOutput(stdout).trim();
|
|
858
|
-
console.log(
|
|
859
|
-
pc5.green(
|
|
860
|
-
`
|
|
861
|
-
\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5\u8F6F\u4EF6\u5305\u7684\u5B98\u65B9\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(packageName)}`
|
|
862
|
-
)
|
|
863
|
-
);
|
|
864
|
-
console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
|
|
865
|
-
console.log(pc5.bold(pc5.yellow(` xx delete ${packageName}`)));
|
|
866
|
-
}
|
|
867
|
-
} catch {
|
|
849
|
+
function stripArchiveSuffix(filePath) {
|
|
850
|
+
const lower = filePath.toLowerCase();
|
|
851
|
+
const name = basename2(filePath);
|
|
852
|
+
const suffixes = [".tar.gz", ".tgz", ".tar.xz", ".txz", ".zip", ".tar"];
|
|
853
|
+
for (const suffix of suffixes) {
|
|
854
|
+
if (lower.endsWith(suffix)) {
|
|
855
|
+
return name.slice(0, name.length - suffix.length);
|
|
868
856
|
}
|
|
869
|
-
} else {
|
|
870
|
-
console.error(pc5.red(`\u274C \u5B89\u88C5\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
|
|
871
857
|
}
|
|
858
|
+
return basename2(filePath, extname(filePath));
|
|
872
859
|
}
|
|
873
|
-
async function
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
)
|
|
892
|
-
);
|
|
893
|
-
console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5F7B\u5E95\u5378\u8F7D\u5B83\uFF1A`));
|
|
894
|
-
console.log(pc5.bold(pc5.yellow(` xx delete ${packageName}`)));
|
|
860
|
+
async function removeDirectoryContents(dirPath) {
|
|
861
|
+
await fs5.rm(dirPath, { recursive: true, force: true });
|
|
862
|
+
await fs5.mkdir(dirPath, { recursive: true });
|
|
863
|
+
}
|
|
864
|
+
async function findExecutablesRecursively(rootDir) {
|
|
865
|
+
const matches = [];
|
|
866
|
+
async function walk(currentDir) {
|
|
867
|
+
for (const entry of await fs5.readdir(currentDir, { withFileTypes: true })) {
|
|
868
|
+
if (entry.name.startsWith(".")) continue;
|
|
869
|
+
const fullPath = join4(currentDir, entry.name);
|
|
870
|
+
if (entry.isDirectory()) {
|
|
871
|
+
if (["node_modules", "lib", "libs", "include", "share", "man"].includes(
|
|
872
|
+
entry.name
|
|
873
|
+
)) {
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
await walk(fullPath);
|
|
877
|
+
continue;
|
|
895
878
|
}
|
|
896
|
-
|
|
879
|
+
if (!entry.isFile()) continue;
|
|
880
|
+
const stat = await fs5.stat(fullPath);
|
|
881
|
+
const isExecutable = stat.mode ? (stat.mode & 73) !== 0 : false;
|
|
882
|
+
if (!isExecutable) continue;
|
|
883
|
+
if (/\.(dylib|so|a|o|txt|md|json|yaml|yml|ts|js|c|h|sh)$/i.test(entry.name)) {
|
|
884
|
+
continue;
|
|
885
|
+
}
|
|
886
|
+
matches.push(fullPath);
|
|
897
887
|
}
|
|
898
|
-
} else {
|
|
899
|
-
console.error(pc5.red(`\u274C \u5B89\u88C5\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
|
|
900
888
|
}
|
|
889
|
+
await walk(rootDir);
|
|
890
|
+
return matches;
|
|
901
891
|
}
|
|
902
|
-
async function
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
892
|
+
async function createLinks(appName, executablePaths) {
|
|
893
|
+
const binDir = getBinDir();
|
|
894
|
+
const linkNames = [];
|
|
895
|
+
for (const executablePath of executablePaths) {
|
|
896
|
+
const linkName = basename2(executablePath);
|
|
897
|
+
const linkPath = join4(binDir, linkName);
|
|
898
|
+
await fs5.rm(linkPath, { force: true });
|
|
899
|
+
await fs5.symlink(executablePath, linkPath);
|
|
900
|
+
linkNames.push(linkName);
|
|
907
901
|
}
|
|
908
|
-
|
|
909
|
-
const folderName = basename2(absPath, ".tar.gz").replace(".tar", "");
|
|
910
|
-
const destDir = join4(greenAppDir, folderName);
|
|
911
|
-
try {
|
|
912
|
-
await fs5.mkdir(destDir, { recursive: true });
|
|
913
|
-
console.log(pc5.cyan(`\u{1F4E6} \u6B63\u5728\u89E3\u538B\u7EFF\u8272\u8F6F\u4EF6\u81F3: ${destDir}...`));
|
|
914
|
-
const tarStatus = await spawnCommand("tar", [
|
|
915
|
-
"-xzf",
|
|
916
|
-
absPath,
|
|
917
|
-
"-C",
|
|
918
|
-
destDir
|
|
919
|
-
]);
|
|
920
|
-
if (!tarStatus.success) {
|
|
921
|
-
console.error(pc5.red("\u274C \u89E3\u538B\u5931\u8D25\u3002"));
|
|
922
|
-
return;
|
|
923
|
-
}
|
|
902
|
+
if (linkNames.length > 0) {
|
|
924
903
|
console.log(
|
|
925
|
-
pc5.green(
|
|
904
|
+
pc5.green(
|
|
905
|
+
`\u2714 \u5DF2\u4E3A ${pc5.bold(appName)} \u521B\u5EFA\u7EC8\u7AEF\u547D\u4EE4: ${linkNames.join(", ")}`
|
|
906
|
+
)
|
|
926
907
|
);
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
908
|
+
}
|
|
909
|
+
return linkNames;
|
|
910
|
+
}
|
|
911
|
+
async function writeManifest(manifest) {
|
|
912
|
+
await fs5.writeFile(
|
|
913
|
+
getManifestPath(manifest.appName),
|
|
914
|
+
JSON.stringify(manifest, null, 2),
|
|
915
|
+
"utf-8"
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
async function readManifest(appName) {
|
|
919
|
+
try {
|
|
920
|
+
const content = await fs5.readFile(getManifestPath(appName), "utf-8");
|
|
921
|
+
return JSON.parse(content);
|
|
922
|
+
} catch {
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
async function removeInstalledApp(appName) {
|
|
927
|
+
const manifest = await readManifest(appName);
|
|
928
|
+
if (!manifest) return false;
|
|
929
|
+
for (const linkName of manifest.links) {
|
|
930
|
+
await fs5.rm(join4(getBinDir(), linkName), { force: true });
|
|
931
|
+
console.log(pc5.green(`\u2714 \u5DF2\u79FB\u9664\u7EC8\u7AEF\u547D\u4EE4: ${linkName}`));
|
|
932
|
+
}
|
|
933
|
+
await fs5.rm(manifest.installDir, { recursive: true, force: true });
|
|
934
|
+
console.log(pc5.green(`\u2714 \u5DF2\u79FB\u9664\u5B89\u88C5\u76EE\u5F55: ${manifest.installDir}`));
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
async function listInstalledApps() {
|
|
938
|
+
try {
|
|
939
|
+
const entries = await fs5.readdir(getAppsDir(), { withFileTypes: true });
|
|
940
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
941
|
+
} catch {
|
|
942
|
+
return [];
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
async function extractArchiveToDir(archivePath, destDir) {
|
|
946
|
+
const lower = archivePath.toLowerCase();
|
|
947
|
+
let args;
|
|
948
|
+
if (lower.endsWith(".tar.gz") || lower.endsWith(".tgz")) {
|
|
949
|
+
args = ["-xzf", archivePath, "-C", destDir];
|
|
950
|
+
} else if (lower.endsWith(".tar.xz") || lower.endsWith(".txz")) {
|
|
951
|
+
args = ["-xJf", archivePath, "-C", destDir];
|
|
952
|
+
} else if (lower.endsWith(".tar")) {
|
|
953
|
+
args = ["-xf", archivePath, "-C", destDir];
|
|
954
|
+
} else {
|
|
955
|
+
return false;
|
|
956
|
+
}
|
|
957
|
+
const result = await spawnCommand("tar", args);
|
|
958
|
+
return result.success;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// commands/install.ts
|
|
962
|
+
function printReloadHint() {
|
|
963
|
+
const reloadCommand = getShellReloadCommand();
|
|
964
|
+
console.log(
|
|
965
|
+
pc6.yellow(`\u{1F4A1} \u5982\u679C\u5F53\u524D\u7EC8\u7AEF\u8FD8\u4E0D\u80FD\u76F4\u63A5\u8FD0\u884C\u65B0\u547D\u4EE4\uFF0C\u8BF7\u6267\u884C: ${reloadCommand}`)
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
async function installBinary(absPath) {
|
|
969
|
+
const appName = basename3(absPath);
|
|
970
|
+
const installDir = join5(getAppsDir(), appName);
|
|
971
|
+
const targetDir = join5(installDir, "bin");
|
|
972
|
+
const targetPath = join5(targetDir, appName);
|
|
973
|
+
await fs6.mkdir(targetDir, { recursive: true });
|
|
974
|
+
await fs6.copyFile(absPath, targetPath);
|
|
975
|
+
await fs6.chmod(targetPath, 493);
|
|
976
|
+
const links = await createLinks(appName, [targetPath]);
|
|
977
|
+
await writeManifest({
|
|
978
|
+
appName,
|
|
979
|
+
installDir,
|
|
980
|
+
links,
|
|
981
|
+
type: "binary"
|
|
982
|
+
});
|
|
983
|
+
console.log(pc6.green(`\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u53EF\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C: ${pc6.bold(appName)}`));
|
|
984
|
+
console.log(pc6.cyan(`\u{1F449} \u5378\u8F7D\u547D\u4EE4: ${pc6.bold(`xx uninstall ${appName}`)}`));
|
|
985
|
+
printReloadHint();
|
|
986
|
+
}
|
|
987
|
+
async function installArchive(absPath) {
|
|
988
|
+
const appName = stripArchiveSuffix(absPath);
|
|
989
|
+
const installDir = join5(getAppsDir(), appName);
|
|
990
|
+
await removeDirectoryContents(installDir);
|
|
991
|
+
console.log(pc6.cyan(`\u{1F4E6} \u6B63\u5728\u89E3\u538B\u8F6F\u4EF6\u5305\u81F3: ${installDir}...`));
|
|
992
|
+
const extracted = await extractArchiveToDir(absPath, installDir);
|
|
993
|
+
if (!extracted) {
|
|
958
994
|
console.error(
|
|
959
|
-
|
|
960
|
-
err instanceof Error ? err.message : err
|
|
995
|
+
pc6.red("\u274C \u5F53\u524D\u4EC5\u652F\u6301 .tar.gz\u3001.tgz\u3001.tar.xz\u3001.txz\u3001.tar \u683C\u5F0F\u3002")
|
|
961
996
|
);
|
|
997
|
+
return;
|
|
962
998
|
}
|
|
999
|
+
const executables = await findExecutablesRecursively(installDir);
|
|
1000
|
+
if (executables.length === 0) {
|
|
1001
|
+
console.error(pc6.red("\u274C \u89E3\u538B\u5B8C\u6210\uFF0C\u4F46\u672A\u627E\u5230\u53EF\u6267\u884C\u6587\u4EF6\u3002"));
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
const links = await createLinks(appName, executables);
|
|
1005
|
+
await writeManifest({
|
|
1006
|
+
appName,
|
|
1007
|
+
installDir,
|
|
1008
|
+
links,
|
|
1009
|
+
type: "archive"
|
|
1010
|
+
});
|
|
1011
|
+
console.log(
|
|
1012
|
+
pc6.green(`\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u53EF\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C: ${pc6.bold(links.join(", "))}`)
|
|
1013
|
+
);
|
|
1014
|
+
console.log(pc6.cyan(`\u{1F449} \u5378\u8F7D\u547D\u4EE4: ${pc6.bold(`xx uninstall ${appName}`)}`));
|
|
1015
|
+
printReloadHint();
|
|
963
1016
|
}
|
|
964
1017
|
function registerInstallCommand(program2) {
|
|
965
1018
|
program2.command("install [path]").description(
|
|
966
|
-
"\
|
|
1019
|
+
"macOS \u672C\u5730\u5DE5\u5177\u5B89\u88C5\u5668\uFF08\u652F\u6301\u53EF\u6267\u884C\u6587\u4EF6\u3001.tar.gz\u3001.tgz\u3001.tar.xz\u3001.txz\u3001.tar\uFF09"
|
|
967
1020
|
).action(async (target) => {
|
|
1021
|
+
if (!ensureMacOS()) return;
|
|
968
1022
|
if (!target) {
|
|
969
|
-
console.error(
|
|
970
|
-
return;
|
|
971
|
-
}
|
|
972
|
-
const isFlatpak = !target.includes("/") && !target.includes("\\") && target.split(".").length >= 3;
|
|
973
|
-
if (isFlatpak) {
|
|
974
|
-
await createShortcut(target);
|
|
975
|
-
console.log(
|
|
976
|
-
pc5.green(
|
|
977
|
-
`
|
|
978
|
-
\u2728 \u5B89\u88C5\u6210\u529F\uFF01\u8BE5 Flatpak \u5FEB\u6377\u56FE\u6807\u7684\u5378\u8F7D\u540D\u79F0\u4E3A: ${pc5.bold(target)}`
|
|
979
|
-
)
|
|
980
|
-
);
|
|
981
|
-
console.log(pc5.cyan(`\u{1F449} \u4EE5\u540E\u60A8\u53EF\u4EE5\u901A\u8FC7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5220\u9664\u8BE5\u5FEB\u6377\u56FE\u6807\uFF1A`));
|
|
982
|
-
console.log(pc5.bold(pc5.yellow(` xx delete ${target}`)));
|
|
1023
|
+
console.error(pc6.red("\u274C \u8BF7\u63D0\u4F9B\u6709\u6548\u7684\u672C\u5730\u6587\u4EF6\u8DEF\u5F84\u3002"));
|
|
983
1024
|
return;
|
|
984
1025
|
}
|
|
985
1026
|
const absPath = resolve4(process.cwd(), target);
|
|
986
1027
|
try {
|
|
987
|
-
await
|
|
1028
|
+
const stat = await fs6.stat(absPath);
|
|
1029
|
+
if (!stat.isFile()) {
|
|
1030
|
+
console.error(pc6.red(`\u274C \u9519\u8BEF: '${target}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
988
1033
|
} catch {
|
|
989
|
-
console.error(
|
|
1034
|
+
console.error(pc6.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6307\u5B9A\u6587\u4EF6\u6216\u5305\u8DEF\u5F84 '${target}'\u3002`));
|
|
990
1035
|
return;
|
|
991
1036
|
}
|
|
1037
|
+
await ensureToolDirectories();
|
|
1038
|
+
await ensureBinDirOnPath();
|
|
992
1039
|
const lowerPath = target.toLowerCase();
|
|
993
|
-
if (lowerPath.endsWith(".
|
|
994
|
-
await
|
|
995
|
-
} else if (lowerPath.endsWith(".deb")) {
|
|
996
|
-
await installDeb(absPath);
|
|
997
|
-
} else if (lowerPath.endsWith(".rpm")) {
|
|
998
|
-
await installRpm(absPath);
|
|
999
|
-
} else if (lowerPath.endsWith(".tar.gz") || lowerPath.endsWith(".tgz")) {
|
|
1000
|
-
await installTarGz(absPath);
|
|
1040
|
+
if (lowerPath.endsWith(".tar.gz") || lowerPath.endsWith(".tgz") || lowerPath.endsWith(".tar.xz") || lowerPath.endsWith(".txz") || lowerPath.endsWith(".tar")) {
|
|
1041
|
+
await installArchive(absPath);
|
|
1001
1042
|
} else {
|
|
1002
|
-
|
|
1003
|
-
pc5.cyan(`\u{1F4E6} \u68C0\u6D4B\u5230\u901A\u7528\u672C\u5730\u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u6B63\u5728\u76F4\u63A5\u4E3A\u5176\u914D\u7F6E\u684C\u9762\u56FE\u6807...`)
|
|
1004
|
-
);
|
|
1005
|
-
await createShortcut(absPath);
|
|
1006
|
-
const execName = basename2(absPath);
|
|
1007
|
-
console.log(
|
|
1008
|
-
pc5.green(`
|
|
1009
|
-
\u2728 \u5FEB\u6377\u65B9\u5F0F\u521B\u5EFA\u6210\u529F\uFF01\u540D\u79F0\u4E3A: ${pc5.bold(execName)}`)
|
|
1010
|
-
);
|
|
1043
|
+
await installBinary(absPath);
|
|
1011
1044
|
}
|
|
1012
1045
|
});
|
|
1013
1046
|
}
|
|
1014
1047
|
|
|
1015
1048
|
// commands/ip.ts
|
|
1016
|
-
import
|
|
1049
|
+
import pc7 from "picocolors";
|
|
1017
1050
|
import os from "os";
|
|
1018
1051
|
function getInterfaceType(name) {
|
|
1019
1052
|
const lowerName = name.toLowerCase();
|
|
@@ -1187,7 +1220,7 @@ async function getDefaultRouteInfo() {
|
|
|
1187
1220
|
}
|
|
1188
1221
|
function registerIpCommand(program2) {
|
|
1189
1222
|
program2.command("ip").description("\u672C\u5730\u6D3B\u8DC3\u7F51\u5361\u3001\u672C\u673AIP\u53CA\u7F51\u5173\u4FA6\u6D4B\u5DE5\u5177").action(async () => {
|
|
1190
|
-
console.log(
|
|
1223
|
+
console.log(pc7.dim("\u6B63\u5728\u5206\u6790\u7F51\u7EDC\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u5019...\n"));
|
|
1191
1224
|
try {
|
|
1192
1225
|
let defaultRoute = { gateway: "", interfaceName: "" };
|
|
1193
1226
|
let routeError = "";
|
|
@@ -1198,7 +1231,7 @@ function registerIpCommand(program2) {
|
|
|
1198
1231
|
}
|
|
1199
1232
|
const cards = getActiveNetworkCards();
|
|
1200
1233
|
if (cards.length === 0) {
|
|
1201
|
-
console.log(
|
|
1234
|
+
console.log(pc7.red("\u274C \u672A\u68C0\u6D4B\u5230\u4EFB\u4F55\u6D3B\u8DC3\u7684\u975E\u672C\u5730\u56DE\u73AF\u7F51\u5361\u3002"));
|
|
1202
1235
|
return;
|
|
1203
1236
|
}
|
|
1204
1237
|
cards.sort((a, b) => {
|
|
@@ -1235,76 +1268,76 @@ function registerIpCommand(program2) {
|
|
|
1235
1268
|
ipv4.netmask
|
|
1236
1269
|
);
|
|
1237
1270
|
}
|
|
1238
|
-
let cardGateway =
|
|
1271
|
+
let cardGateway = pc7.dim("(\u975E\u9ED8\u8BA4\u8DEF\u7531\u51FA\u53E3\u7F51\u5361)");
|
|
1239
1272
|
if (isDefaultRouteCard) {
|
|
1240
1273
|
if (defaultRoute.gateway && defaultRoute.gateway !== "0.0.0.0") {
|
|
1241
|
-
cardGateway =
|
|
1274
|
+
cardGateway = pc7.yellow(defaultRoute.gateway);
|
|
1242
1275
|
} else {
|
|
1243
|
-
cardGateway =
|
|
1276
|
+
cardGateway = pc7.yellow("\u76F4\u63A5\u70B9\u5BF9\u70B9\u96A7\u9053\u8FDE\u63A5 (Point-to-Point)");
|
|
1244
1277
|
}
|
|
1245
1278
|
} else if (routeError) {
|
|
1246
|
-
cardGateway =
|
|
1279
|
+
cardGateway = pc7.dim(`\u68C0\u6D4B\u5931\u8D25 (\u539F\u56E0: ${routeError})`);
|
|
1247
1280
|
}
|
|
1248
1281
|
console.log(
|
|
1249
|
-
|
|
1282
|
+
pc7.cyan(
|
|
1250
1283
|
`================ \u6D3B\u8DC3\u7F51\u5361\u53CA\u7F51\u5173\u4FE1\u606F [${card.type}] ================`
|
|
1251
1284
|
)
|
|
1252
1285
|
);
|
|
1253
1286
|
console.log(
|
|
1254
|
-
`${
|
|
1287
|
+
`${pc7.green("\u7F51\u5361\u540D\u79F0 (Name):")} ${pc7.bold(card.name)}`
|
|
1255
1288
|
);
|
|
1256
1289
|
console.log(
|
|
1257
|
-
`${
|
|
1290
|
+
`${pc7.green("\u672C\u673A IP \u5730\u5740 (IP):")} ${pc7.bold(primaryAddr.address)}`
|
|
1258
1291
|
);
|
|
1259
1292
|
console.log(
|
|
1260
|
-
`${
|
|
1293
|
+
`${pc7.green("\u5B50\u7F51\u63A9\u7801 (Mask):")} ${primaryAddr.netmask}`
|
|
1261
1294
|
);
|
|
1262
|
-
console.log(`${
|
|
1263
|
-
console.log(`${
|
|
1295
|
+
console.log(`${pc7.green("\u9ED8\u8BA4\u7F51\u5173 (Gateway):")} ${cardGateway}`);
|
|
1296
|
+
console.log(`${pc7.green("MAC \u5730\u5740 (MAC):")} ${card.mac}`);
|
|
1264
1297
|
console.log(
|
|
1265
|
-
`${
|
|
1298
|
+
`${pc7.green("IP \u534F\u8BAE\u7248\u672C:")} ${primaryAddr.family === "IPv4" || primaryAddr.family === "4" ? "IPv4" : "IPv6"}`
|
|
1266
1299
|
);
|
|
1267
1300
|
if (ipv4 && ipv6) {
|
|
1268
1301
|
console.log(
|
|
1269
|
-
`${
|
|
1302
|
+
`${pc7.green("\u672C\u5730 IPv6 \u5730\u5740:")} ${pc7.dim(ipv6.address)}`
|
|
1270
1303
|
);
|
|
1271
1304
|
}
|
|
1272
1305
|
console.log(
|
|
1273
|
-
|
|
1306
|
+
pc7.cyan("====================================================")
|
|
1274
1307
|
);
|
|
1275
1308
|
console.log("");
|
|
1276
1309
|
}
|
|
1277
1310
|
} catch (error) {
|
|
1278
|
-
console.error(
|
|
1311
|
+
console.error(pc7.red("\u274C \u68C0\u6D4B\u5931\u8D25\u3002"));
|
|
1279
1312
|
if (error instanceof Error) {
|
|
1280
|
-
console.error(
|
|
1313
|
+
console.error(pc7.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
|
|
1281
1314
|
}
|
|
1282
1315
|
}
|
|
1283
1316
|
});
|
|
1284
1317
|
}
|
|
1285
1318
|
|
|
1286
1319
|
// commands/list.ts
|
|
1287
|
-
import
|
|
1288
|
-
import
|
|
1320
|
+
import fs7 from "fs/promises";
|
|
1321
|
+
import pc8 from "picocolors";
|
|
1289
1322
|
import { resolve as resolve5 } from "path";
|
|
1290
1323
|
function registerLsCommand(program2) {
|
|
1291
1324
|
program2.command("list [path]").description("\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u548C\u76EE\u5F55\uFF08\u542B\u9690\u85CF\u9879\uFF09").action(async (targetPath) => {
|
|
1292
1325
|
const inputPath = targetPath || ".";
|
|
1293
1326
|
const absolutePath = resolve5(process.cwd(), inputPath);
|
|
1294
1327
|
try {
|
|
1295
|
-
const stat = await
|
|
1328
|
+
const stat = await fs7.stat(absolutePath);
|
|
1296
1329
|
if (!stat.isDirectory()) {
|
|
1297
|
-
console.error(
|
|
1330
|
+
console.error(pc8.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
|
|
1298
1331
|
return;
|
|
1299
1332
|
}
|
|
1300
1333
|
const entries = [];
|
|
1301
|
-
for (const entry of await
|
|
1334
|
+
for (const entry of await fs7.readdir(absolutePath, {
|
|
1302
1335
|
withFileTypes: true
|
|
1303
1336
|
})) {
|
|
1304
1337
|
entries.push(entry);
|
|
1305
1338
|
}
|
|
1306
1339
|
if (entries.length === 0) {
|
|
1307
|
-
console.log(
|
|
1340
|
+
console.log(pc8.dim("\uFF08\u7A7A\u76EE\u5F55\uFF09"));
|
|
1308
1341
|
return;
|
|
1309
1342
|
}
|
|
1310
1343
|
entries.sort((a, b) => {
|
|
@@ -1316,13 +1349,13 @@ function registerLsCommand(program2) {
|
|
|
1316
1349
|
const isHidden = entry.name.startsWith(".");
|
|
1317
1350
|
if (entry.isDirectory()) {
|
|
1318
1351
|
if (isHidden) {
|
|
1319
|
-
console.log(
|
|
1352
|
+
console.log(pc8.dim(`\u{1F4C1} ${pc8.blue(entry.name)}/`));
|
|
1320
1353
|
} else {
|
|
1321
|
-
console.log(`\u{1F4C1} ${
|
|
1354
|
+
console.log(`\u{1F4C1} ${pc8.blue(pc8.bold(entry.name))}/`);
|
|
1322
1355
|
}
|
|
1323
1356
|
} else {
|
|
1324
1357
|
if (isHidden) {
|
|
1325
|
-
console.log(
|
|
1358
|
+
console.log(pc8.dim(`\u{1F4C4} ${entry.name}`));
|
|
1326
1359
|
} else {
|
|
1327
1360
|
console.log(`\u{1F4C4} ${entry.name}`);
|
|
1328
1361
|
}
|
|
@@ -1330,7 +1363,7 @@ function registerLsCommand(program2) {
|
|
|
1330
1363
|
}
|
|
1331
1364
|
} catch (err) {
|
|
1332
1365
|
console.error(
|
|
1333
|
-
|
|
1366
|
+
pc8.red(`\u274C \u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\u5185\u5BB9:`),
|
|
1334
1367
|
err instanceof Error ? err.message : err
|
|
1335
1368
|
);
|
|
1336
1369
|
}
|
|
@@ -1338,55 +1371,55 @@ function registerLsCommand(program2) {
|
|
|
1338
1371
|
}
|
|
1339
1372
|
|
|
1340
1373
|
// commands/move.ts
|
|
1341
|
-
import
|
|
1342
|
-
import
|
|
1343
|
-
import { dirname as
|
|
1374
|
+
import fs8 from "fs/promises";
|
|
1375
|
+
import pc9 from "picocolors";
|
|
1376
|
+
import { dirname as dirname3, resolve as resolve6, join as join6, basename as basename4 } from "path";
|
|
1344
1377
|
async function copyRecursive2(src, dest) {
|
|
1345
|
-
const fileInfo = await
|
|
1378
|
+
const fileInfo = await fs8.stat(src);
|
|
1346
1379
|
if (fileInfo.isDirectory()) {
|
|
1347
|
-
await
|
|
1348
|
-
for (const entry of await
|
|
1349
|
-
await copyRecursive2(
|
|
1380
|
+
await fs8.mkdir(dest, { recursive: true });
|
|
1381
|
+
for (const entry of await fs8.readdir(src, { withFileTypes: true })) {
|
|
1382
|
+
await copyRecursive2(join6(src, entry.name), join6(dest, entry.name));
|
|
1350
1383
|
}
|
|
1351
1384
|
} else if (fileInfo.isFile()) {
|
|
1352
|
-
await
|
|
1353
|
-
await
|
|
1385
|
+
await fs8.mkdir(dirname3(dest), { recursive: true });
|
|
1386
|
+
await fs8.copyFile(src, dest);
|
|
1354
1387
|
}
|
|
1355
1388
|
}
|
|
1356
1389
|
function registerMoveCommand(program2) {
|
|
1357
1390
|
program2.command("move <source> <target>").description("\u79FB\u52A8\u6216\u91CD\u547D\u540D\u6587\u4EF6\u53CA\u76EE\u5F55").action(async (source, target) => {
|
|
1358
1391
|
if (!source || !target) {
|
|
1359
|
-
console.error(
|
|
1392
|
+
console.error(pc9.red("\u274C \u8BF7\u63D0\u4F9B\u6E90\u8DEF\u5F84\u548C\u76EE\u6807\u8DEF\u5F84"));
|
|
1360
1393
|
return;
|
|
1361
1394
|
}
|
|
1362
1395
|
const absSource = resolve6(process.cwd(), source);
|
|
1363
1396
|
const absTarget = resolve6(process.cwd(), target);
|
|
1364
1397
|
try {
|
|
1365
|
-
await
|
|
1398
|
+
await fs8.stat(absSource);
|
|
1366
1399
|
let finalTarget = absTarget;
|
|
1367
1400
|
try {
|
|
1368
|
-
const targetStat = await
|
|
1401
|
+
const targetStat = await fs8.stat(absTarget);
|
|
1369
1402
|
if (targetStat.isDirectory()) {
|
|
1370
|
-
finalTarget =
|
|
1403
|
+
finalTarget = join6(absTarget, basename4(absSource));
|
|
1371
1404
|
}
|
|
1372
1405
|
} catch {
|
|
1373
1406
|
}
|
|
1374
|
-
const targetParentDir =
|
|
1375
|
-
await
|
|
1376
|
-
console.log(
|
|
1407
|
+
const targetParentDir = dirname3(finalTarget);
|
|
1408
|
+
await fs8.mkdir(targetParentDir, { recursive: true });
|
|
1409
|
+
console.log(pc9.cyan(`\u{1F4E6} \u6B63\u5728\u79FB\u52A8: ${source} \u27A1\uFE0F ${target}...`));
|
|
1377
1410
|
try {
|
|
1378
|
-
await
|
|
1411
|
+
await fs8.rename(absSource, finalTarget);
|
|
1379
1412
|
} catch {
|
|
1380
1413
|
await copyRecursive2(absSource, finalTarget);
|
|
1381
|
-
await
|
|
1414
|
+
await fs8.rm(absSource, { recursive: true });
|
|
1382
1415
|
}
|
|
1383
|
-
console.log(
|
|
1416
|
+
console.log(pc9.green(`\u2728 \u79FB\u52A8\u6210\u529F: ${source} \u27A1\uFE0F ${target}`));
|
|
1384
1417
|
} catch (err) {
|
|
1385
1418
|
if (isNotFoundError(err)) {
|
|
1386
|
-
console.error(
|
|
1419
|
+
console.error(pc9.red(`\u274C \u9519\u8BEF: \u6E90\u8DEF\u5F84\u4E0D\u5B58\u5728: ${absSource}`));
|
|
1387
1420
|
} else {
|
|
1388
1421
|
console.error(
|
|
1389
|
-
|
|
1422
|
+
pc9.red("\u274C \u79FB\u52A8\u5931\u8D25:"),
|
|
1390
1423
|
err instanceof Error ? err.message : err
|
|
1391
1424
|
);
|
|
1392
1425
|
}
|
|
@@ -1395,21 +1428,21 @@ function registerMoveCommand(program2) {
|
|
|
1395
1428
|
}
|
|
1396
1429
|
|
|
1397
1430
|
// commands/open.ts
|
|
1398
|
-
import
|
|
1399
|
-
import
|
|
1431
|
+
import fs9 from "fs/promises";
|
|
1432
|
+
import pc10 from "picocolors";
|
|
1400
1433
|
import { resolve as resolve7 } from "path";
|
|
1401
1434
|
function registerOpenCommand(program2) {
|
|
1402
1435
|
program2.command("open [path]").description("\u5728\u7CFB\u7EDF\u6587\u4EF6\u7BA1\u7406\u5668\u4E2D\u6253\u5F00\u6307\u5B9A\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09").action(async (targetPath) => {
|
|
1403
1436
|
const inputPath = targetPath || ".";
|
|
1404
1437
|
const absolutePath = resolve7(process.cwd(), inputPath);
|
|
1405
1438
|
try {
|
|
1406
|
-
const stat = await
|
|
1439
|
+
const stat = await fs9.stat(absolutePath);
|
|
1407
1440
|
if (!stat.isDirectory()) {
|
|
1408
|
-
console.error(
|
|
1441
|
+
console.error(pc10.red(`\u274C \u9519\u8BEF: '${inputPath}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
|
|
1409
1442
|
return;
|
|
1410
1443
|
}
|
|
1411
1444
|
} catch {
|
|
1412
|
-
console.error(
|
|
1445
|
+
console.error(pc10.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${inputPath}'\u3002`));
|
|
1413
1446
|
return;
|
|
1414
1447
|
}
|
|
1415
1448
|
const os3 = process.platform;
|
|
@@ -1425,16 +1458,16 @@ function registerOpenCommand(program2) {
|
|
|
1425
1458
|
cmd = "xdg-open";
|
|
1426
1459
|
args = [absolutePath];
|
|
1427
1460
|
} else {
|
|
1428
|
-
console.error(
|
|
1461
|
+
console.error(pc10.red("\u274C \u6682\u4E0D\u652F\u6301\u5728\u5F53\u524D\u7CFB\u7EDF\u4E0B\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\u3002"));
|
|
1429
1462
|
return;
|
|
1430
1463
|
}
|
|
1431
1464
|
try {
|
|
1432
|
-
console.log(
|
|
1465
|
+
console.log(pc10.cyan(`\u{1F4C2} \u6B63\u5728\u6253\u5F00\u6587\u4EF6\u5939: ${absolutePath}...`));
|
|
1433
1466
|
await spawnCommand(cmd, args);
|
|
1434
|
-
console.log(
|
|
1467
|
+
console.log(pc10.green("\u2728 \u6210\u529F\u8C03\u8D77\u6587\u4EF6\u7BA1\u7406\u5668\uFF01"));
|
|
1435
1468
|
} catch (err) {
|
|
1436
1469
|
console.error(
|
|
1437
|
-
|
|
1470
|
+
pc10.red("\u274C \u65E0\u6CD5\u6253\u5F00\u7BA1\u7406\u5668:"),
|
|
1438
1471
|
err instanceof Error ? err.message : err
|
|
1439
1472
|
);
|
|
1440
1473
|
}
|
|
@@ -1442,19 +1475,19 @@ function registerOpenCommand(program2) {
|
|
|
1442
1475
|
}
|
|
1443
1476
|
|
|
1444
1477
|
// commands/park.ts
|
|
1445
|
-
import
|
|
1478
|
+
import fs10, { open } from "fs/promises";
|
|
1446
1479
|
import process2 from "process";
|
|
1447
|
-
import
|
|
1448
|
-
import { join as
|
|
1480
|
+
import pc11 from "picocolors";
|
|
1481
|
+
import { join as join7, isAbsolute, resolve as resolve8, dirname as dirname4 } from "path";
|
|
1449
1482
|
var CONFIG_FILE_NAME = ".park_config.json";
|
|
1450
1483
|
function getConfigFile() {
|
|
1451
1484
|
const home = process2.env["HOME"] || process2.env["USERPROFILE"] || process2.cwd();
|
|
1452
|
-
return
|
|
1485
|
+
return join7(home, CONFIG_FILE_NAME);
|
|
1453
1486
|
}
|
|
1454
1487
|
async function readConfig() {
|
|
1455
1488
|
try {
|
|
1456
1489
|
const path = getConfigFile();
|
|
1457
|
-
const content = await
|
|
1490
|
+
const content = await fs10.readFile(path, "utf-8");
|
|
1458
1491
|
return JSON.parse(content);
|
|
1459
1492
|
} catch {
|
|
1460
1493
|
return {};
|
|
@@ -1463,9 +1496,9 @@ async function readConfig() {
|
|
|
1463
1496
|
async function writeConfig(config) {
|
|
1464
1497
|
try {
|
|
1465
1498
|
const path = getConfigFile();
|
|
1466
|
-
await
|
|
1499
|
+
await fs10.writeFile(path, JSON.stringify(config, null, 2));
|
|
1467
1500
|
} catch (err) {
|
|
1468
|
-
console.error(
|
|
1501
|
+
console.error(pc11.red("\u274C \u5199\u5165\u5168\u5C40\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:"), err);
|
|
1469
1502
|
}
|
|
1470
1503
|
}
|
|
1471
1504
|
async function downloadImage(imageName, outputFilename, targetDir) {
|
|
@@ -1477,8 +1510,8 @@ async function downloadImage(imageName, outputFilename, targetDir) {
|
|
|
1477
1510
|
cleanName = decodeURIComponent(cleanName).substring(prefix.length);
|
|
1478
1511
|
}
|
|
1479
1512
|
const fullImageName = prefix + cleanName;
|
|
1480
|
-
console.log(
|
|
1481
|
-
console.log(
|
|
1513
|
+
console.log(pc11.cyan(`\u{1F4E6} \u76EE\u6807\u955C\u50CF: ${pc11.bold(fullImageName)}`));
|
|
1514
|
+
console.log(pc11.dim("\u6B63\u5728\u5411\u6253\u5305\u670D\u52A1\u5668\u63D0\u4EA4\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u5019...\n"));
|
|
1482
1515
|
try {
|
|
1483
1516
|
const response = await fetch("https://city189.cn:1091/", {
|
|
1484
1517
|
method: "POST",
|
|
@@ -1515,15 +1548,15 @@ async function downloadImage(imageName, outputFilename, targetDir) {
|
|
|
1515
1548
|
matchedFilename = match[0];
|
|
1516
1549
|
downloadUrl = `https://city189.cn:1091/download/${matchedFilename}`;
|
|
1517
1550
|
} else {
|
|
1518
|
-
console.error(
|
|
1519
|
-
console.log(
|
|
1551
|
+
console.error(pc11.red("\u274C \u672A\u80FD\u5728\u670D\u52A1\u5668\u54CD\u5E94\u4E2D\u5339\u914D\u5230\u6253\u5305\u6587\u4EF6\u540D\u3002"));
|
|
1552
|
+
console.log(pc11.yellow("\u670D\u52A1\u5668\u539F\u59CB\u54CD\u5E94\u5982\u4E0B\uFF1A"));
|
|
1520
1553
|
console.log(text);
|
|
1521
1554
|
throw new Error("\u65E0\u6CD5\u63D0\u53D6\u6253\u5305\u540E\u7684\u6587\u4EF6\u540D");
|
|
1522
1555
|
}
|
|
1523
1556
|
}
|
|
1524
|
-
console.log(
|
|
1525
|
-
console.log(
|
|
1526
|
-
console.log(
|
|
1557
|
+
console.log(pc11.green(`\u2705 \u6253\u5305\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F!`));
|
|
1558
|
+
console.log(pc11.green(`\u{1F517} \u4E0B\u8F7D\u94FE\u63A5: ${pc11.underline(downloadUrl)}`));
|
|
1559
|
+
console.log(pc11.cyan(`
|
|
1527
1560
|
\u{1F4E5} \u5F00\u59CB\u4E0B\u8F7D: ${matchedFilename}...`));
|
|
1528
1561
|
const downloadRes = await fetch(downloadUrl, {
|
|
1529
1562
|
headers: {
|
|
@@ -1548,10 +1581,10 @@ async function downloadImage(imageName, outputFilename, targetDir) {
|
|
|
1548
1581
|
downloadDir = config.defaultDownloadDir ? config.defaultDownloadDir : process2.cwd();
|
|
1549
1582
|
}
|
|
1550
1583
|
const baseFilename = outputFilename || matchedFilename || "bundle.tar";
|
|
1551
|
-
const finalPath = isAbsolute(baseFilename) ? baseFilename :
|
|
1552
|
-
const targetDirToCreate =
|
|
1584
|
+
const finalPath = isAbsolute(baseFilename) ? baseFilename : join7(downloadDir, baseFilename);
|
|
1585
|
+
const targetDirToCreate = dirname4(finalPath);
|
|
1553
1586
|
try {
|
|
1554
|
-
await
|
|
1587
|
+
await fs10.mkdir(targetDirToCreate, { recursive: true });
|
|
1555
1588
|
} catch {
|
|
1556
1589
|
}
|
|
1557
1590
|
const file = await open(finalPath, "w");
|
|
@@ -1578,11 +1611,11 @@ async function downloadImage(imageName, outputFilename, targetDir) {
|
|
|
1578
1611
|
}
|
|
1579
1612
|
}
|
|
1580
1613
|
await file.close();
|
|
1581
|
-
console.log("\n" +
|
|
1614
|
+
console.log("\n" + pc11.green(`\u2728 \u4E0B\u8F7D\u5E76\u4FDD\u5B58\u6210\u529F! \u6587\u4EF6\u8DEF\u5F84: ${finalPath}`));
|
|
1582
1615
|
} catch (error) {
|
|
1583
|
-
console.error(
|
|
1616
|
+
console.error(pc11.red("\n\u274C \u6267\u884C\u5931\u8D25\u3002"));
|
|
1584
1617
|
if (error instanceof Error) {
|
|
1585
|
-
console.error(
|
|
1618
|
+
console.error(pc11.red("\u9519\u8BEF\u8BE6\u60C5:"), error.message);
|
|
1586
1619
|
}
|
|
1587
1620
|
}
|
|
1588
1621
|
}
|
|
@@ -1595,11 +1628,11 @@ function registerParkCommand(program2) {
|
|
|
1595
1628
|
if (options.global) {
|
|
1596
1629
|
const absPath = resolve8(process2.cwd(), options.global);
|
|
1597
1630
|
await writeConfig({ defaultDownloadDir: absPath });
|
|
1598
|
-
console.log(
|
|
1631
|
+
console.log(pc11.green(`\u2728 \u5DF2\u6210\u529F\u8BBE\u7F6E\u5168\u5C40\u9ED8\u8BA4\u4E0B\u8F7D\u76EE\u5F55\u4E3A: ${absPath}`));
|
|
1599
1632
|
return;
|
|
1600
1633
|
}
|
|
1601
1634
|
if (!image) {
|
|
1602
|
-
console.error(
|
|
1635
|
+
console.error(pc11.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u9700\u8981\u4E0B\u8F7D\u7684\u955C\u50CF\u540D\u79F0\u3002"));
|
|
1603
1636
|
cmd.outputHelp();
|
|
1604
1637
|
return;
|
|
1605
1638
|
}
|
|
@@ -1609,7 +1642,7 @@ function registerParkCommand(program2) {
|
|
|
1609
1642
|
}
|
|
1610
1643
|
|
|
1611
1644
|
// commands/proxy.ts
|
|
1612
|
-
import
|
|
1645
|
+
import pc12 from "picocolors";
|
|
1613
1646
|
function registerProxyCommand(program2) {
|
|
1614
1647
|
program2.command("proxy [action] [port]").description(
|
|
1615
1648
|
"\u7BA1\u7406\u7EC8\u7AEF\u4E34\u65F6\u4EE3\u7406 (\u652F\u6301 proxy on [port] \u6216 proxy off\uFF0C\u65E0\u53C2\u6570\u65F6\u67E5\u770B\u5F53\u524D\u72B6\u6001)"
|
|
@@ -1617,29 +1650,29 @@ function registerProxyCommand(program2) {
|
|
|
1617
1650
|
if (action === "on") {
|
|
1618
1651
|
const p = port || "7890";
|
|
1619
1652
|
console.log(
|
|
1620
|
-
|
|
1653
|
+
pc12.yellow(
|
|
1621
1654
|
`\u26A0\uFE0F \u8B66\u544A: \u76F4\u63A5\u8FD0\u884C\u4E8C\u8FDB\u5236\u65E0\u6CD5\u76F4\u63A5\u4FEE\u6539\u5F53\u524D\u7EC8\u7AEF\u7684\u4E3B\u73AF\u5883\u53D8\u91CF\u3002`
|
|
1622
1655
|
)
|
|
1623
1656
|
);
|
|
1624
|
-
console.log(
|
|
1625
|
-
console.log(
|
|
1626
|
-
console.log(
|
|
1627
|
-
console.log(
|
|
1657
|
+
console.log(pc12.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u542F\u7528\u4EE3\u7406\uFF1A`));
|
|
1658
|
+
console.log(pc12.bold(` export http_proxy="http://127.0.0.1:${p}"`));
|
|
1659
|
+
console.log(pc12.bold(` export https_proxy="http://127.0.0.1:${p}"`));
|
|
1660
|
+
console.log(pc12.bold(` export all_proxy="socks5://127.0.0.1:${p}"`));
|
|
1628
1661
|
console.log(
|
|
1629
|
-
|
|
1662
|
+
pc12.dim(
|
|
1630
1663
|
`
|
|
1631
1664
|
\u{1F4A1} \u63D0\u793A\uFF1A\u6267\u884C\u4E00\u6B21 'xx completion' \u5E76\u91CD\u5F00\u7EC8\u7AEF\u540E\uFF0C\u5373\u53EF\u76F4\u63A5\u8FD0\u884C 'xx proxy on' \u4E00\u952E\u5F00\u542F\uFF01`
|
|
1632
1665
|
)
|
|
1633
1666
|
);
|
|
1634
1667
|
} else if (action === "off") {
|
|
1635
1668
|
console.log(
|
|
1636
|
-
|
|
1669
|
+
pc12.yellow(
|
|
1637
1670
|
`\u26A0\uFE0F \u8B66\u544A: \u76F4\u63A5\u8FD0\u884C\u4E8C\u8FDB\u5236\u65E0\u6CD5\u76F4\u63A5\u4FEE\u6539\u5F53\u524D\u7EC8\u7AEF\u7684\u4E3B\u73AF\u5883\u53D8\u91CF\u3002`
|
|
1638
1671
|
)
|
|
1639
1672
|
);
|
|
1640
|
-
console.log(
|
|
1673
|
+
console.log(pc12.cyan(`\u{1F449} \u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u624B\u52A8\u5173\u95ED\u4EE3\u7406\uFF1A`));
|
|
1641
1674
|
console.log(
|
|
1642
|
-
|
|
1675
|
+
pc12.bold(
|
|
1643
1676
|
` unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY`
|
|
1644
1677
|
)
|
|
1645
1678
|
);
|
|
@@ -1648,15 +1681,15 @@ function registerProxyCommand(program2) {
|
|
|
1648
1681
|
const httpsProxy = process.env["https_proxy"] || process.env["HTTPS_PROXY"];
|
|
1649
1682
|
const allProxy = process.env["all_proxy"] || process.env["ALL_PROXY"];
|
|
1650
1683
|
if (httpProxy || httpsProxy || allProxy) {
|
|
1651
|
-
console.log(
|
|
1652
|
-
if (httpProxy) console.log(` http_proxy = ${
|
|
1653
|
-
if (httpsProxy) console.log(` https_proxy = ${
|
|
1654
|
-
if (allProxy) console.log(` all_proxy = ${
|
|
1684
|
+
console.log(pc12.yellow("\u{1F50D} [xx] \u68C0\u6D4B\u5230\u5F53\u524D\u7EC8\u7AEF\u5DF2\u914D\u7F6E\u4E34\u65F6\u4EE3\u7406\uFF1A"));
|
|
1685
|
+
if (httpProxy) console.log(` http_proxy = ${pc12.bold(httpProxy)}`);
|
|
1686
|
+
if (httpsProxy) console.log(` https_proxy = ${pc12.bold(httpsProxy)}`);
|
|
1687
|
+
if (allProxy) console.log(` all_proxy = ${pc12.bold(allProxy)}`);
|
|
1655
1688
|
} else {
|
|
1656
|
-
console.log(
|
|
1689
|
+
console.log(pc12.green("\u{1F50D} [xx] \u5F53\u524D\u7EC8\u7AEF\u672A\u914D\u7F6E\u4EFB\u4F55\u4EE3\u7406 (\u76F4\u8FDE\u6A21\u5F0F)"));
|
|
1657
1690
|
}
|
|
1658
1691
|
console.log(
|
|
1659
|
-
|
|
1692
|
+
pc12.dim(
|
|
1660
1693
|
"\n\u{1F4A1} \u63D0\u793A\uFF1A\u60A8\u53EF\u4EE5\u4F7F\u7528 'xx proxy on [port]' \u5F00\u542F\u6216 'xx proxy off' \u5173\u95ED\u4E34\u65F6\u4EE3\u7406\u3002"
|
|
1661
1694
|
)
|
|
1662
1695
|
);
|
|
@@ -1665,15 +1698,15 @@ function registerProxyCommand(program2) {
|
|
|
1665
1698
|
}
|
|
1666
1699
|
|
|
1667
1700
|
// commands/remove.ts
|
|
1668
|
-
import
|
|
1669
|
-
import
|
|
1701
|
+
import fs11 from "fs/promises";
|
|
1702
|
+
import pc13 from "picocolors";
|
|
1670
1703
|
import { resolve as resolve9 } from "path";
|
|
1671
1704
|
import fg from "fast-glob";
|
|
1672
1705
|
import trash from "trash";
|
|
1673
1706
|
function registerRemoveCommand(program2) {
|
|
1674
1707
|
program2.command("remove <paths...>").description("\u5B89\u5168\u5730\u5C06\u6307\u5B9A\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\uFF08\u652F\u6301\u901A\u914D\u7B26\u53CA\u591A\u9009\uFF09").action(async (paths) => {
|
|
1675
1708
|
if (!paths || paths.length === 0) {
|
|
1676
|
-
console.error(
|
|
1709
|
+
console.error(pc13.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u653E\u5165\u56DE\u6536\u7AD9\u7684\u8DEF\u5F84\u6216\u901A\u914D\u7B26\u89C4\u5219"));
|
|
1677
1710
|
return;
|
|
1678
1711
|
}
|
|
1679
1712
|
const resolvedPathsToDelete = /* @__PURE__ */ new Set();
|
|
@@ -1693,21 +1726,21 @@ function registerRemoveCommand(program2) {
|
|
|
1693
1726
|
}
|
|
1694
1727
|
} catch (err) {
|
|
1695
1728
|
console.error(
|
|
1696
|
-
|
|
1729
|
+
pc13.red(`\u274C \u5339\u914D\u901A\u914D\u7B26 '${pattern}' \u65F6\u53D1\u751F\u5F02\u5E38:`),
|
|
1697
1730
|
err instanceof Error ? err.message : err
|
|
1698
1731
|
);
|
|
1699
1732
|
}
|
|
1700
1733
|
} else {
|
|
1701
1734
|
const absolutePath = resolve9(process.cwd(), pattern);
|
|
1702
1735
|
try {
|
|
1703
|
-
await
|
|
1736
|
+
await fs11.stat(absolutePath);
|
|
1704
1737
|
resolvedPathsToDelete.add(absolutePath);
|
|
1705
1738
|
} catch (err) {
|
|
1706
1739
|
if (isNotFoundError(err)) {
|
|
1707
1740
|
notFoundPaths.push(absolutePath);
|
|
1708
1741
|
} else {
|
|
1709
1742
|
console.error(
|
|
1710
|
-
|
|
1743
|
+
pc13.red(`\u274C \u83B7\u53D6\u8DEF\u5F84\u72B6\u6001\u5931\u8D25 [${pattern}]:`),
|
|
1711
1744
|
err instanceof Error ? err.message : err
|
|
1712
1745
|
);
|
|
1713
1746
|
}
|
|
@@ -1716,31 +1749,31 @@ function registerRemoveCommand(program2) {
|
|
|
1716
1749
|
}
|
|
1717
1750
|
if (notFoundPaths.length > 0) {
|
|
1718
1751
|
for (const path of notFoundPaths) {
|
|
1719
|
-
console.error(
|
|
1752
|
+
console.error(pc13.red(`\u274C \u8DEF\u5F84\u4E0D\u5B58\u5728: ${path}`));
|
|
1720
1753
|
}
|
|
1721
1754
|
}
|
|
1722
1755
|
if (resolvedPathsToDelete.size === 0) {
|
|
1723
|
-
console.log(
|
|
1756
|
+
console.log(pc13.yellow("\u2139\uFE0F \u672A\u80FD\u627E\u5230\u4EFB\u4F55\u4E0E\u6307\u5B9A\u6761\u4EF6\u5339\u914D\u7684\u6587\u4EF6\u6216\u76EE\u5F55\u3002"));
|
|
1724
1757
|
return;
|
|
1725
1758
|
}
|
|
1726
1759
|
try {
|
|
1727
1760
|
console.log(
|
|
1728
|
-
|
|
1761
|
+
pc13.cyan(
|
|
1729
1762
|
`\u{1F4E6} \u6B63\u5728\u5C06 ${resolvedPathsToDelete.size} \u4E2A\u9879\u79FB\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9...`
|
|
1730
1763
|
)
|
|
1731
1764
|
);
|
|
1732
1765
|
await trash(Array.from(resolvedPathsToDelete));
|
|
1733
1766
|
for (const path of resolvedPathsToDelete) {
|
|
1734
|
-
console.log(
|
|
1767
|
+
console.log(pc13.dim(` - \u5DF2\u79FB\u5165\u5783\u573E\u7BB1: ${path}`));
|
|
1735
1768
|
}
|
|
1736
1769
|
console.log(
|
|
1737
|
-
|
|
1770
|
+
pc13.green(
|
|
1738
1771
|
`\u2728 \u6210\u529F\uFF01\u5171 ${resolvedPathsToDelete.size} \u4E2A\u6587\u4EF6/\u76EE\u5F55\u5DF2\u5B89\u5168\u9001\u81F3\u7CFB\u7EDF\u56DE\u6536\u7AD9\u3002`
|
|
1739
1772
|
)
|
|
1740
1773
|
);
|
|
1741
1774
|
} catch (err) {
|
|
1742
1775
|
console.error(
|
|
1743
|
-
|
|
1776
|
+
pc13.red("\u274C \u79FB\u81F3\u56DE\u6536\u7AD9\u5931\u8D25:"),
|
|
1744
1777
|
err instanceof Error ? err.message : err
|
|
1745
1778
|
);
|
|
1746
1779
|
}
|
|
@@ -1748,32 +1781,32 @@ function registerRemoveCommand(program2) {
|
|
|
1748
1781
|
}
|
|
1749
1782
|
|
|
1750
1783
|
// commands/search.ts
|
|
1751
|
-
import
|
|
1752
|
-
import
|
|
1753
|
-
import { resolve as resolve10, basename as
|
|
1784
|
+
import fs12 from "fs/promises";
|
|
1785
|
+
import pc14 from "picocolors";
|
|
1786
|
+
import { resolve as resolve10, basename as basename5, relative } from "path";
|
|
1754
1787
|
import fg2 from "fast-glob";
|
|
1755
1788
|
function registerSearchCommand(program2) {
|
|
1756
1789
|
program2.command("search <keyword> [directory]").description(
|
|
1757
1790
|
"\u9012\u5F52\u641C\u7D22\u76EE\u5F55\u4E0B\u5305\u542B\u6307\u5B9A\u5173\u952E\u8BCD\u7684\u6587\u4EF6\u6216\u76EE\u5F55\uFF08\u652F\u6301 Ctrl+\u70B9\u51FB \u5FEB\u6377\u6253\u5F00\uFF09"
|
|
1758
1791
|
).action(async (keyword, directory) => {
|
|
1759
1792
|
if (!keyword) {
|
|
1760
|
-
console.error(
|
|
1793
|
+
console.error(pc14.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u641C\u7D22\u7684\u6587\u4EF6\u540D\u5173\u952E\u8BCD"));
|
|
1761
1794
|
return;
|
|
1762
1795
|
}
|
|
1763
1796
|
const startDir = directory || ".";
|
|
1764
1797
|
const absoluteStartDir = resolve10(process.cwd(), startDir);
|
|
1765
1798
|
try {
|
|
1766
|
-
const stat = await
|
|
1799
|
+
const stat = await fs12.stat(absoluteStartDir);
|
|
1767
1800
|
if (!stat.isDirectory()) {
|
|
1768
|
-
console.error(
|
|
1801
|
+
console.error(pc14.red(`\u274C \u9519\u8BEF: '${startDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
|
|
1769
1802
|
return;
|
|
1770
1803
|
}
|
|
1771
1804
|
} catch {
|
|
1772
|
-
console.error(
|
|
1805
|
+
console.error(pc14.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u8D77\u70B9\u76EE\u5F55 '${startDir}'\u3002`));
|
|
1773
1806
|
return;
|
|
1774
1807
|
}
|
|
1775
1808
|
console.log(
|
|
1776
|
-
|
|
1809
|
+
pc14.cyan(
|
|
1777
1810
|
`\u{1F50D} \u6B63\u5728\u76EE\u5F55 ${absoluteStartDir} \u4E2D\u9012\u5F52\u641C\u5BFB\u5305\u542B "${keyword}" \u7684\u9879\u76EE...
|
|
1778
1811
|
`
|
|
1779
1812
|
)
|
|
@@ -1794,30 +1827,30 @@ function registerSearchCommand(program2) {
|
|
|
1794
1827
|
]
|
|
1795
1828
|
});
|
|
1796
1829
|
for (const entryPath of entries) {
|
|
1797
|
-
const name =
|
|
1830
|
+
const name = basename5(entryPath);
|
|
1798
1831
|
if (name.toLowerCase().includes(keyword.toLowerCase())) {
|
|
1799
1832
|
matchCount++;
|
|
1800
1833
|
const relativePath = relative(absoluteStartDir, entryPath);
|
|
1801
1834
|
const isDirectory = !name.includes(".") || entryPath.endsWith("/");
|
|
1802
1835
|
let isDir = isDirectory;
|
|
1803
1836
|
try {
|
|
1804
|
-
const entryStat = await
|
|
1837
|
+
const entryStat = await fs12.stat(entryPath);
|
|
1805
1838
|
isDir = entryStat.isDirectory();
|
|
1806
1839
|
} catch {
|
|
1807
1840
|
}
|
|
1808
1841
|
const typeIcon = isDir ? "\u{1F4C1}" : "\u{1F4C4}";
|
|
1809
1842
|
const fileUri = `file://${entryPath}`;
|
|
1810
|
-
const hyperlink = `\x1B]8;;${fileUri}\x1B\\${
|
|
1811
|
-
console.log(`${typeIcon} ${hyperlink} -> ${
|
|
1843
|
+
const hyperlink = `\x1B]8;;${fileUri}\x1B\\${pc14.bold(name)}\x1B]8;;\x1B\\`;
|
|
1844
|
+
console.log(`${typeIcon} ${hyperlink} -> ${pc14.dim(fileUri)}`);
|
|
1812
1845
|
}
|
|
1813
1846
|
}
|
|
1814
1847
|
console.log(
|
|
1815
|
-
|
|
1848
|
+
pc14.green(`
|
|
1816
1849
|
\u2728 \u641C\u7D22\u5B8C\u6210\uFF01\u5171\u627E\u5230 ${matchCount} \u4E2A\u5339\u914D\u7684\u9879\u76EE\u3002`)
|
|
1817
1850
|
);
|
|
1818
1851
|
} catch (err) {
|
|
1819
1852
|
console.error(
|
|
1820
|
-
|
|
1853
|
+
pc14.red("\u274C \u641C\u5BFB\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:"),
|
|
1821
1854
|
err instanceof Error ? err.message : err
|
|
1822
1855
|
);
|
|
1823
1856
|
}
|
|
@@ -1825,7 +1858,7 @@ function registerSearchCommand(program2) {
|
|
|
1825
1858
|
}
|
|
1826
1859
|
|
|
1827
1860
|
// commands/translate.ts
|
|
1828
|
-
import
|
|
1861
|
+
import pc15 from "picocolors";
|
|
1829
1862
|
import { translate } from "google-translate-api-x";
|
|
1830
1863
|
import readline from "readline";
|
|
1831
1864
|
import process3 from "process";
|
|
@@ -1842,13 +1875,13 @@ async function performTranslation(text, userSpecifiedLang) {
|
|
|
1842
1875
|
to: targetLang
|
|
1843
1876
|
});
|
|
1844
1877
|
console.log(
|
|
1845
|
-
`${
|
|
1878
|
+
`${pc15.green("\u8BD1\u6587:")} ${pc15.bold(res.text)} ${pc15.dim(`(${res.from.language.iso} -> ${targetLang})`)}`
|
|
1846
1879
|
);
|
|
1847
1880
|
} catch (err) {
|
|
1848
1881
|
if (err instanceof Error) {
|
|
1849
|
-
console.error(
|
|
1882
|
+
console.error(pc15.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), err.message);
|
|
1850
1883
|
} else {
|
|
1851
|
-
console.error(
|
|
1884
|
+
console.error(pc15.red("\u274C \u7FFB\u8BD1\u51FA\u9519:"), String(err));
|
|
1852
1885
|
}
|
|
1853
1886
|
}
|
|
1854
1887
|
}
|
|
@@ -1856,11 +1889,11 @@ function startInteractiveMode(userSpecifiedLang) {
|
|
|
1856
1889
|
const rl = readline.createInterface({
|
|
1857
1890
|
input: process3.stdin,
|
|
1858
1891
|
output: process3.stdout,
|
|
1859
|
-
prompt:
|
|
1892
|
+
prompt: pc15.cyan("\u7FFB\u8BD1\u8F93\u5165 > ")
|
|
1860
1893
|
});
|
|
1861
1894
|
const modeTip = userSpecifiedLang === "auto" ? "\u667A\u80FD\u81EA\u52A8\u8BC6\u522B" : `\u5F3A\u5236\u76EE\u6807\u8BED\u8A00: ${userSpecifiedLang}`;
|
|
1862
|
-
console.log(
|
|
1863
|
-
console.log(
|
|
1895
|
+
console.log(pc15.yellow(`\u2728 \u5DF2\u8FDB\u5165\u4EA4\u4E92\u6A21\u5F0F (${modeTip})`));
|
|
1896
|
+
console.log(pc15.dim('\u8F93\u5165 "exit" \u6216\u6309 Ctrl+C \u9000\u51FA\n'));
|
|
1864
1897
|
rl.prompt();
|
|
1865
1898
|
rl.on("line", async (line) => {
|
|
1866
1899
|
const input = line.trim();
|
|
@@ -1874,7 +1907,7 @@ function startInteractiveMode(userSpecifiedLang) {
|
|
|
1874
1907
|
console.log();
|
|
1875
1908
|
rl.prompt();
|
|
1876
1909
|
}).on("close", () => {
|
|
1877
|
-
console.log(
|
|
1910
|
+
console.log(pc15.blue("\n\u518D\u89C1!"));
|
|
1878
1911
|
process3.exit(0);
|
|
1879
1912
|
});
|
|
1880
1913
|
}
|
|
@@ -1893,464 +1926,33 @@ function registerTanslateCommand(program2) {
|
|
|
1893
1926
|
}
|
|
1894
1927
|
|
|
1895
1928
|
// commands/uninstall.ts
|
|
1896
|
-
import
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
if (!await isCommandAvailable("snap")) return false;
|
|
1904
|
-
try {
|
|
1905
|
-
const { success } = await runCommand("snap", ["list", packageName]);
|
|
1906
|
-
return success;
|
|
1907
|
-
} catch {
|
|
1908
|
-
return false;
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
async function isSystemPackageInstalled(packageName) {
|
|
1912
|
-
try {
|
|
1913
|
-
const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
|
|
1914
|
-
if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
|
|
1915
|
-
const { success } = await runCommand("rpm", ["-q", packageName]);
|
|
1916
|
-
return success;
|
|
1917
|
-
} else {
|
|
1918
|
-
const { success, stdout } = await runCommand("dpkg-query", [
|
|
1919
|
-
"-W",
|
|
1920
|
-
"-f=${Status}",
|
|
1921
|
-
packageName
|
|
1922
|
-
]);
|
|
1923
|
-
if (success) {
|
|
1924
|
-
const status = decodeOutput(stdout).trim();
|
|
1925
|
-
return status.includes("installed");
|
|
1926
|
-
}
|
|
1927
|
-
return false;
|
|
1928
|
-
}
|
|
1929
|
-
} catch {
|
|
1930
|
-
return false;
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
async function findGreenAppPath(appName) {
|
|
1934
|
-
const home = getHomeDir2();
|
|
1935
|
-
const greenAppDir = join7(home, "GreenApp");
|
|
1936
|
-
const dirPath = join7(greenAppDir, appName);
|
|
1937
|
-
try {
|
|
1938
|
-
const stat = await fs12.stat(dirPath);
|
|
1939
|
-
if (stat.isDirectory()) return dirPath;
|
|
1940
|
-
} catch {
|
|
1941
|
-
}
|
|
1942
|
-
const appImagePath = join7(greenAppDir, `${appName}.AppImage`);
|
|
1943
|
-
const appImageLowerPath = join7(greenAppDir, `${appName}.appimage`);
|
|
1944
|
-
try {
|
|
1945
|
-
const stat = await fs12.stat(appImagePath);
|
|
1946
|
-
if (stat.isFile()) return appImagePath;
|
|
1947
|
-
} catch {
|
|
1948
|
-
try {
|
|
1949
|
-
const stat = await fs12.stat(appImageLowerPath);
|
|
1950
|
-
if (stat.isFile()) return appImageLowerPath;
|
|
1951
|
-
} catch {
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
if (appName.toLowerCase().endsWith(".appimage")) {
|
|
1955
|
-
const directPath = join7(greenAppDir, appName);
|
|
1956
|
-
try {
|
|
1957
|
-
const stat = await fs12.stat(directPath);
|
|
1958
|
-
if (stat.isFile()) return directPath;
|
|
1959
|
-
} catch {
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
return null;
|
|
1963
|
-
}
|
|
1964
|
-
async function extractDebPackageName(absPath) {
|
|
1965
|
-
try {
|
|
1966
|
-
const { success, stdout } = await runCommand("dpkg-deb", [
|
|
1967
|
-
"-f",
|
|
1968
|
-
absPath,
|
|
1969
|
-
"Package"
|
|
1970
|
-
]);
|
|
1971
|
-
if (success) {
|
|
1972
|
-
return decodeOutput(stdout).trim();
|
|
1973
|
-
}
|
|
1974
|
-
} catch {
|
|
1975
|
-
}
|
|
1976
|
-
return void 0;
|
|
1977
|
-
}
|
|
1978
|
-
async function extractRpmPackageName(absPath) {
|
|
1979
|
-
try {
|
|
1980
|
-
const { success, stdout } = await runCommand("rpm", [
|
|
1981
|
-
"-qp",
|
|
1982
|
-
"--queryformat",
|
|
1983
|
-
"%{NAME}",
|
|
1984
|
-
absPath
|
|
1985
|
-
]);
|
|
1986
|
-
if (success) {
|
|
1987
|
-
return decodeOutput(stdout).trim();
|
|
1988
|
-
}
|
|
1989
|
-
} catch {
|
|
1990
|
-
}
|
|
1991
|
-
return void 0;
|
|
1992
|
-
}
|
|
1993
|
-
async function searchGreenApps(query) {
|
|
1994
|
-
const home = getHomeDir2();
|
|
1995
|
-
const greenAppDir = join7(home, "GreenApp");
|
|
1996
|
-
const candidates = [];
|
|
1997
|
-
try {
|
|
1998
|
-
for (const entry of await fs12.readdir(greenAppDir, {
|
|
1999
|
-
withFileTypes: true
|
|
2000
|
-
})) {
|
|
2001
|
-
if (entry.name.toLowerCase().includes(query.toLowerCase())) {
|
|
2002
|
-
candidates.push(entry.name.replace(/\.appimage/i, ""));
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
} catch {
|
|
2006
|
-
}
|
|
2007
|
-
return candidates;
|
|
2008
|
-
}
|
|
2009
|
-
async function searchFlatpaks(query) {
|
|
2010
|
-
const candidates = [];
|
|
2011
|
-
if (!await isCommandAvailable("flatpak")) return candidates;
|
|
2012
|
-
try {
|
|
2013
|
-
const { success, stdout } = await runCommand("flatpak", [
|
|
2014
|
-
"list",
|
|
2015
|
-
"--columns=application,name"
|
|
2016
|
-
]);
|
|
2017
|
-
if (success) {
|
|
2018
|
-
const output = decodeOutput(stdout).trim();
|
|
2019
|
-
const lines = output.split("\n");
|
|
2020
|
-
for (const line of lines) {
|
|
2021
|
-
const parts = line.split(" ").map((p) => p.trim());
|
|
2022
|
-
if (parts.length >= 2) {
|
|
2023
|
-
const [id, name] = parts;
|
|
2024
|
-
if (id.toLowerCase().includes(query.toLowerCase()) || name.toLowerCase().includes(query.toLowerCase())) {
|
|
2025
|
-
candidates.push({ id, name });
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
} catch {
|
|
2031
|
-
}
|
|
2032
|
-
return candidates;
|
|
2033
|
-
}
|
|
2034
|
-
async function searchDebPackages(query) {
|
|
2035
|
-
const pkgs = [];
|
|
2036
|
-
try {
|
|
2037
|
-
const { success, stdout } = await runCommand("dpkg-query", [
|
|
2038
|
-
"-W",
|
|
2039
|
-
"-f=${Package}\n",
|
|
2040
|
-
`*${query}*`
|
|
2041
|
-
]);
|
|
2042
|
-
if (success) {
|
|
2043
|
-
const output = decodeOutput(stdout).trim();
|
|
2044
|
-
const lines = output.split("\n");
|
|
2045
|
-
for (const line of lines) {
|
|
2046
|
-
const name = line.trim();
|
|
2047
|
-
if (name && !name.startsWith("-f=")) {
|
|
2048
|
-
pkgs.push(name);
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
} catch {
|
|
2053
|
-
}
|
|
2054
|
-
return pkgs;
|
|
2055
|
-
}
|
|
2056
|
-
async function searchRpmPackages(query) {
|
|
2057
|
-
const pkgs = [];
|
|
2058
|
-
try {
|
|
2059
|
-
const { success, stdout } = await runCommand("rpm", [
|
|
2060
|
-
"-qa",
|
|
2061
|
-
"--queryformat",
|
|
2062
|
-
"%{NAME}\n",
|
|
2063
|
-
`*${query}*`
|
|
2064
|
-
]);
|
|
2065
|
-
if (success) {
|
|
2066
|
-
const output = decodeOutput(stdout).trim();
|
|
2067
|
-
const lines = output.split("\n");
|
|
2068
|
-
const uniquePkgs = /* @__PURE__ */ new Set();
|
|
2069
|
-
for (const line of lines) {
|
|
2070
|
-
const name = line.trim();
|
|
2071
|
-
if (name) {
|
|
2072
|
-
uniquePkgs.add(name);
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
pkgs.push(...uniquePkgs);
|
|
2076
|
-
}
|
|
2077
|
-
} catch {
|
|
2078
|
-
}
|
|
2079
|
-
return pkgs;
|
|
2080
|
-
}
|
|
2081
|
-
async function removeDeb(packageName) {
|
|
2082
|
-
console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 apt \u5378\u8F7D DEB \u8F6F\u4EF6\u5305: ${packageName}...`));
|
|
2083
|
-
const status = await spawnCommand("sudo", [
|
|
2084
|
-
"apt-get",
|
|
2085
|
-
"remove",
|
|
2086
|
-
"-y",
|
|
2087
|
-
packageName
|
|
2088
|
-
]);
|
|
2089
|
-
if (status.success) {
|
|
2090
|
-
console.log(pc15.green(`\u2714 \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
|
|
2091
|
-
} else {
|
|
2092
|
-
console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
async function removeRpm(packageName) {
|
|
2096
|
-
console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 dnf \u5378\u8F7D RPM \u8F6F\u4EF6\u5305: ${packageName}...`));
|
|
2097
|
-
const status = await spawnCommand("sudo", [
|
|
2098
|
-
"dnf",
|
|
2099
|
-
"remove",
|
|
2100
|
-
"-y",
|
|
2101
|
-
packageName
|
|
2102
|
-
]);
|
|
2103
|
-
if (status.success) {
|
|
2104
|
-
console.log(pc15.green(`\u2714 \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
|
|
2105
|
-
} else {
|
|
2106
|
-
console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`));
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
async function removeSnap(packageName) {
|
|
2110
|
-
console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 snap \u5378\u8F7D\u8F6F\u4EF6\u5305: ${packageName}...`));
|
|
2111
|
-
const status = await spawnCommand("sudo", ["snap", "remove", packageName]);
|
|
2112
|
-
if (status.success) {
|
|
2113
|
-
console.log(pc15.green(`\u2714 Snap \u8F6F\u4EF6\u5305 ${packageName} \u5DF2\u6210\u529F\u4ECE\u7CFB\u7EDF\u4E2D\u79FB\u9664\u3002`));
|
|
2114
|
-
} else {
|
|
2115
|
-
console.error(pc15.red(`\u274C \u5378\u8F7D\u5931\u8D25\uFF0C\u9000\u51FA\u7801: ${status.code}`));
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
async function uninstallFlatpak(packageName) {
|
|
2119
|
-
if (!await isCommandAvailable("flatpak")) {
|
|
2120
|
-
console.error(pc15.red("\u274C \u5F53\u524D\u7CFB\u7EDF\u4E2D\u672A\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5\u7684 flatpak \u5DE5\u5177\u3002"));
|
|
2121
|
-
return;
|
|
2122
|
-
}
|
|
2123
|
-
console.log(pc15.cyan(`\u{1F4E6} \u6B63\u5728\u901A\u8FC7 flatpak \u5378\u8F7D\u5E94\u7528: ${packageName}...`));
|
|
2124
|
-
const status = await spawnCommand("flatpak", [
|
|
2125
|
-
"uninstall",
|
|
2126
|
-
"-y",
|
|
2127
|
-
packageName
|
|
2128
|
-
]);
|
|
2129
|
-
if (status.success) {
|
|
2130
|
-
const home = getHomeDir2();
|
|
2131
|
-
const desktopPath = join7(
|
|
2132
|
-
home,
|
|
2133
|
-
".local/share/applications",
|
|
2134
|
-
`flatpak-${packageName}.desktop`
|
|
2135
|
-
);
|
|
2136
|
-
try {
|
|
2137
|
-
await fs12.rm(desktopPath);
|
|
2138
|
-
console.log(pc15.green(`\u2714 \u5DF2\u6E05\u9664 Flatpak \u5173\u8054\u684C\u9762\u5FEB\u6377\u56FE\u6807\u3002`));
|
|
2139
|
-
} catch {
|
|
2140
|
-
}
|
|
2141
|
-
console.log(pc15.green("\u2728 Flatpak \u5E94\u7528\u53CA\u56FE\u6807\u6E05\u7406\u5B8C\u6210\uFF01"));
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
async function performRemoveGreenApp(greenPath, appName) {
|
|
2145
|
-
const home = getHomeDir2();
|
|
2146
|
-
const applicationsDir = join7(home, ".local/share/applications");
|
|
2147
|
-
try {
|
|
2148
|
-
for (const entry of await fs12.readdir(applicationsDir, {
|
|
2149
|
-
withFileTypes: true
|
|
2150
|
-
})) {
|
|
2151
|
-
if (entry.isFile() && entry.name.endsWith(".desktop")) {
|
|
2152
|
-
const filePath = join7(applicationsDir, entry.name);
|
|
2153
|
-
const content = await fs12.readFile(filePath, "utf-8");
|
|
2154
|
-
if (content.includes(greenPath) || content.includes(appName)) {
|
|
2155
|
-
await fs12.rm(filePath);
|
|
2156
|
-
console.log(pc15.green(`\u2714 \u5DF2\u6E05\u9664\u684C\u9762\u5FEB\u6377\u56FE\u6807: ${filePath}`));
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
1929
|
+
import pc16 from "picocolors";
|
|
1930
|
+
function registerUninstallCommand(program2) {
|
|
1931
|
+
program2.command("uninstall <package>").description("macOS \u672C\u5730\u5DE5\u5177\u5378\u8F7D\u5668\uFF08\u79FB\u9664\u5B89\u88C5\u76EE\u5F55\u548C\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\uFF09").action(async (pkg) => {
|
|
1932
|
+
if (!ensureMacOS()) return;
|
|
1933
|
+
if (!pkg) {
|
|
1934
|
+
console.error(pc16.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u5378\u8F7D\u7684\u5E94\u7528\u540D\u3002"));
|
|
1935
|
+
return;
|
|
2159
1936
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
console.log(pc15.green(`\u2714 \u5DF2\u6210\u529F\u6E05\u9664\u7EFF\u8272\u8F6F\u4EF6\u4E3B\u4F53: ${greenPath}`));
|
|
2165
|
-
} catch (err) {
|
|
2166
|
-
console.error(
|
|
2167
|
-
pc15.red(`\u274C \u6E05\u9664\u8F6F\u4EF6\u4E3B\u4F53\u5931\u8D25:`),
|
|
2168
|
-
err instanceof Error ? err.message : err
|
|
2169
|
-
);
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
async function performFuzzySearchAndRecommendation(query) {
|
|
2173
|
-
const hasSnap = await isCommandAvailable("snap");
|
|
2174
|
-
const [greenCands, flatpakCands, snapCands] = await Promise.all([
|
|
2175
|
-
searchGreenApps(query),
|
|
2176
|
-
searchFlatpaks(query),
|
|
2177
|
-
hasSnap ? (async () => {
|
|
2178
|
-
const candidates = [];
|
|
2179
|
-
try {
|
|
2180
|
-
const { success, stdout } = await runCommand("snap", ["list"]);
|
|
2181
|
-
if (success) {
|
|
2182
|
-
const lines = decodeOutput(stdout).split("\n");
|
|
2183
|
-
for (let i = 1; i < lines.length; i++) {
|
|
2184
|
-
const name = lines[i].trim().split(/\s+/)[0];
|
|
2185
|
-
if (name && name.toLowerCase().includes(query.toLowerCase())) {
|
|
2186
|
-
candidates.push(name);
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
} catch {
|
|
2191
|
-
}
|
|
2192
|
-
return candidates;
|
|
2193
|
-
})() : Promise.resolve([])
|
|
2194
|
-
]);
|
|
2195
|
-
let systemCands = [];
|
|
2196
|
-
try {
|
|
2197
|
-
const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
|
|
2198
|
-
if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
|
|
2199
|
-
systemCands = await searchRpmPackages(query);
|
|
2200
|
-
} else {
|
|
2201
|
-
systemCands = await searchDebPackages(query);
|
|
1937
|
+
const removed = await removeInstalledApp(pkg);
|
|
1938
|
+
if (removed) {
|
|
1939
|
+
console.log(pc16.green("\u2728 \u5378\u8F7D\u5B8C\u6210\uFF01\u76F8\u5173\u7EC8\u7AEF\u547D\u4EE4\u5165\u53E3\u4E5F\u5DF2\u6E05\u7406\u3002"));
|
|
1940
|
+
return;
|
|
2202
1941
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2206
|
-
const totalCands = greenCands.length + flatpakCands.length + snapCands.length + systemCands.length;
|
|
2207
|
-
if (totalCands > 0) {
|
|
2208
|
-
console.log(
|
|
2209
|
-
pc15.cyan(
|
|
2210
|
-
`\u{1F4A1} \u5E2E\u60A8\u5728\u7CFB\u7EDF\u4E2D\u641C\u5BFB\u5230\u4EE5\u4E0B ${totalCands} \u4E2A\u5305\u542B "${query}" \u7684\u76F8\u5173\u5339\u914D\u9879\uFF1A
|
|
2211
|
-
`
|
|
2212
|
-
)
|
|
1942
|
+
const candidates = (await listInstalledApps()).filter(
|
|
1943
|
+
(name) => name.toLowerCase().includes(pkg.toLowerCase())
|
|
2213
1944
|
);
|
|
2214
|
-
if (
|
|
2215
|
-
console.log(
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
|
|
2219
|
-
);
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
if (flatpakCands.length > 0) {
|
|
2223
|
-
console.log(pc15.bold(pc15.magenta("\n\u{1F4E6} [Flatpak] \u5019\u9009\uFF1A")));
|
|
2224
|
-
for (const cand of flatpakCands) {
|
|
1945
|
+
if (candidates.length > 0) {
|
|
1946
|
+
console.log(pc16.yellow("\u274C \u672A\u627E\u5230\u7CBE\u786E\u5339\u914D\u7684\u5DF2\u5B89\u88C5\u5E94\u7528\u3002"));
|
|
1947
|
+
console.log(pc16.cyan("\u4F60\u53EF\u80FD\u60F3\u5378\u8F7D\u4EE5\u4E0B\u9879\u76EE\uFF1A"));
|
|
1948
|
+
for (const candidate of candidates) {
|
|
2225
1949
|
console.log(
|
|
2226
|
-
` - ${
|
|
1950
|
+
` - ${candidate} ${pc16.dim(`(xx uninstall ${candidate})`)}`
|
|
2227
1951
|
);
|
|
2228
1952
|
}
|
|
2229
|
-
}
|
|
2230
|
-
if (snapCands.length > 0) {
|
|
2231
|
-
console.log(pc15.bold(pc15.yellow("\n\u26A1 [Snap] \u5019\u9009\uFF1A")));
|
|
2232
|
-
for (const cand of snapCands) {
|
|
2233
|
-
console.log(
|
|
2234
|
-
` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
|
|
2235
|
-
);
|
|
2236
|
-
}
|
|
2237
|
-
}
|
|
2238
|
-
if (systemCands.length > 0) {
|
|
2239
|
-
console.log(pc15.bold(pc15.blue("\n\u2699 [\u7CFB\u7EDF\u6E90\u7EA7] \u5019\u9009\uFF1A")));
|
|
2240
|
-
for (const cand of systemCands) {
|
|
2241
|
-
console.log(
|
|
2242
|
-
` - ${cand} ${pc15.dim(`(\u5378\u8F7D\u547D\u4EE4: xx uninstall ${cand})`)}`
|
|
2243
|
-
);
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
|
-
console.log(pc15.cyan(`
|
|
2247
|
-
\u{1F3C1} \u641C\u5BFB\u5B8C\u6210\uFF01`));
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2250
|
-
async function parseUninstallTarget(target) {
|
|
2251
|
-
const lower = target.toLowerCase();
|
|
2252
|
-
const greenPath = await findGreenAppPath(target);
|
|
2253
|
-
if (greenPath) {
|
|
2254
|
-
return { type: "green", raw: target, greenPath };
|
|
2255
|
-
}
|
|
2256
|
-
const isFlatpak = !target.includes("/") && !target.includes("\\") && target.split(".").length >= 3;
|
|
2257
|
-
if (isFlatpak) {
|
|
2258
|
-
return { type: "flatpak", raw: target };
|
|
2259
|
-
}
|
|
2260
|
-
if (lower.endsWith(".deb")) {
|
|
2261
|
-
const absPath = resolve11(process.cwd(), target);
|
|
2262
|
-
try {
|
|
2263
|
-
const stat = await fs12.stat(absPath);
|
|
2264
|
-
if (stat.isFile()) {
|
|
2265
|
-
const extractedPackageName = await extractDebPackageName(absPath);
|
|
2266
|
-
return {
|
|
2267
|
-
type: "deb",
|
|
2268
|
-
raw: target,
|
|
2269
|
-
resolvedPath: absPath,
|
|
2270
|
-
extractedPackageName
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
} catch {
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2276
|
-
if (lower.endsWith(".rpm")) {
|
|
2277
|
-
const absPath = resolve11(process.cwd(), target);
|
|
2278
|
-
try {
|
|
2279
|
-
const stat = await fs12.stat(absPath);
|
|
2280
|
-
if (stat.isFile()) {
|
|
2281
|
-
const extractedPackageName = await extractRpmPackageName(absPath);
|
|
2282
|
-
return {
|
|
2283
|
-
type: "rpm",
|
|
2284
|
-
raw: target,
|
|
2285
|
-
resolvedPath: absPath,
|
|
2286
|
-
extractedPackageName
|
|
2287
|
-
};
|
|
2288
|
-
}
|
|
2289
|
-
} catch {
|
|
2290
|
-
}
|
|
2291
|
-
}
|
|
2292
|
-
if (await isSnapInstalled(target)) {
|
|
2293
|
-
return { type: "snap", raw: target };
|
|
2294
|
-
}
|
|
2295
|
-
if (await isSystemPackageInstalled(target)) {
|
|
2296
|
-
return { type: "system", raw: target };
|
|
2297
|
-
}
|
|
2298
|
-
return { type: "unknown", raw: target };
|
|
2299
|
-
}
|
|
2300
|
-
function registerUninstallCommand(program2) {
|
|
2301
|
-
program2.command("uninstall <package>").description("\u901A\u7528\u5E94\u7528\u5378\u8F7D\u5668\uFF08\u652F\u6301\u5305\u540D\u3001Flatpak\u3001Snap\u3001\u672C\u5730\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\uFF09").action(async (pkg) => {
|
|
2302
|
-
if (!pkg) {
|
|
2303
|
-
console.error(
|
|
2304
|
-
pc15.red("\u274C \u8BF7\u63D0\u4F9B\u8981\u5378\u8F7D\u7684\u8F6F\u4EF6\u5305\u540D\u79F0\u3001\u5B89\u88C5\u5305\u6216\u7EFF\u8272\u8F6F\u4EF6\u540D\u3002")
|
|
2305
|
-
);
|
|
2306
|
-
return;
|
|
2307
|
-
}
|
|
2308
|
-
try {
|
|
2309
|
-
const parsed = await parseUninstallTarget(pkg);
|
|
2310
|
-
switch (parsed.type) {
|
|
2311
|
-
case "green":
|
|
2312
|
-
await performRemoveGreenApp(parsed.greenPath, parsed.raw);
|
|
2313
|
-
console.log(pc15.green("\u2728 \u7EFF\u8272\u5E94\u7528\u53CA\u684C\u9762\u5FEB\u6377\u65B9\u5F0F\u6E05\u7406\u5B8C\u6210\uFF01"));
|
|
2314
|
-
break;
|
|
2315
|
-
case "flatpak":
|
|
2316
|
-
await uninstallFlatpak(parsed.raw);
|
|
2317
|
-
break;
|
|
2318
|
-
case "snap":
|
|
2319
|
-
await removeSnap(parsed.raw);
|
|
2320
|
-
break;
|
|
2321
|
-
case "deb": {
|
|
2322
|
-
const debPkgName = parsed.extractedPackageName || parsed.raw;
|
|
2323
|
-
await removeDeb(debPkgName);
|
|
2324
|
-
break;
|
|
2325
|
-
}
|
|
2326
|
-
case "rpm": {
|
|
2327
|
-
const rpmPkgName = parsed.extractedPackageName || parsed.raw;
|
|
2328
|
-
await removeRpm(rpmPkgName);
|
|
2329
|
-
break;
|
|
2330
|
-
}
|
|
2331
|
-
case "system": {
|
|
2332
|
-
const osRelease = await fs12.readFile("/etc/os-release", "utf-8");
|
|
2333
|
-
if (osRelease.includes("fedora") || osRelease.includes("rhel") || osRelease.includes("centos")) {
|
|
2334
|
-
await removeRpm(parsed.raw);
|
|
2335
|
-
} else {
|
|
2336
|
-
await removeDeb(parsed.raw);
|
|
2337
|
-
}
|
|
2338
|
-
break;
|
|
2339
|
-
}
|
|
2340
|
-
case "unknown":
|
|
2341
|
-
await performFuzzySearchAndRecommendation(parsed.raw);
|
|
2342
|
-
break;
|
|
2343
|
-
default: {
|
|
2344
|
-
const _exhaustiveCheck = parsed;
|
|
2345
|
-
throw new Error(
|
|
2346
|
-
`\u672A\u5904\u7406\u7684\u5378\u8F7D\u5206\u652F\u7C7B\u578B: ${JSON.stringify(_exhaustiveCheck)}`
|
|
2347
|
-
);
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
} catch (err) {
|
|
1953
|
+
} else {
|
|
2351
1954
|
console.error(
|
|
2352
|
-
|
|
2353
|
-
err instanceof Error ? err.message : String(err)
|
|
1955
|
+
pc16.red(`\u274C \u672A\u627E\u5230\u5DF2\u5B89\u88C5\u5E94\u7528 '${pkg}'\u3002\u8BF7\u5148\u8FD0\u884C xx install \u5B89\u88C5\u3002`)
|
|
2354
1956
|
);
|
|
2355
1957
|
}
|
|
2356
1958
|
});
|
|
@@ -2358,8 +1960,8 @@ function registerUninstallCommand(program2) {
|
|
|
2358
1960
|
|
|
2359
1961
|
// commands/unzip.ts
|
|
2360
1962
|
import fs13 from "fs/promises";
|
|
2361
|
-
import
|
|
2362
|
-
import { join as join8, basename as basename6, extname, resolve as
|
|
1963
|
+
import pc17 from "picocolors";
|
|
1964
|
+
import { join as join8, basename as basename6, extname as extname2, resolve as resolve11 } from "path";
|
|
2363
1965
|
|
|
2364
1966
|
// utils/archive.ts
|
|
2365
1967
|
import AdmZip from "adm-zip";
|
|
@@ -2388,7 +1990,7 @@ async function uncompressTgz(src, destDir) {
|
|
|
2388
1990
|
async function uncompressRar(src, dest) {
|
|
2389
1991
|
const hasUnrar = isCommandAvailable("unrar");
|
|
2390
1992
|
if (hasUnrar) {
|
|
2391
|
-
console.log(
|
|
1993
|
+
console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF unrar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
|
|
2392
1994
|
const status = await spawnCommand("unrar", ["x", "-y", src, dest]);
|
|
2393
1995
|
if (!status.success) {
|
|
2394
1996
|
throw new Error(`unrar \u6267\u884C\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`);
|
|
@@ -2397,7 +1999,7 @@ async function uncompressRar(src, dest) {
|
|
|
2397
1999
|
}
|
|
2398
2000
|
const hasRar = isCommandAvailable("rar");
|
|
2399
2001
|
if (hasRar) {
|
|
2400
|
-
console.log(
|
|
2002
|
+
console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u8C03\u7528\u7CFB\u7EDF rar \u63D0\u53D6 RAR \u538B\u7F29\u5305...`));
|
|
2401
2003
|
const status = await spawnCommand("rar", ["x", "-y", src, dest]);
|
|
2402
2004
|
if (!status.success) {
|
|
2403
2005
|
throw new Error(`rar \u6267\u884C\u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801: ${status.code}`);
|
|
@@ -2418,20 +2020,20 @@ function registerUnzipCommand(program2) {
|
|
|
2418
2020
|
"\u8BF7\u8F93\u5165\u8981\u89E3\u538B\u7684\u538B\u7F29\u5305\u6587\u4EF6\u8DEF\u5F84 (Enter compressed file path):"
|
|
2419
2021
|
);
|
|
2420
2022
|
if (!input) {
|
|
2421
|
-
console.error(
|
|
2023
|
+
console.error(pc17.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u538B\u7F29\u5305\u6587\u4EF6\u3002"));
|
|
2422
2024
|
return;
|
|
2423
2025
|
}
|
|
2424
2026
|
srcFile = input.trim();
|
|
2425
2027
|
}
|
|
2426
|
-
const absSrcFile =
|
|
2028
|
+
const absSrcFile = resolve11(srcFile);
|
|
2427
2029
|
try {
|
|
2428
2030
|
const stat = await fs13.stat(absSrcFile);
|
|
2429
2031
|
if (!stat.isFile()) {
|
|
2430
|
-
console.error(
|
|
2032
|
+
console.error(pc17.red(`\u274C \u9519\u8BEF: '${srcFile}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6\u3002`));
|
|
2431
2033
|
return;
|
|
2432
2034
|
}
|
|
2433
2035
|
} catch {
|
|
2434
|
-
console.error(
|
|
2036
|
+
console.error(pc17.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u6587\u4EF6 '${srcFile}'\u3002`));
|
|
2435
2037
|
return;
|
|
2436
2038
|
}
|
|
2437
2039
|
const lowerSrc = absSrcFile.toLowerCase();
|
|
@@ -2441,17 +2043,17 @@ function registerUnzipCommand(program2) {
|
|
|
2441
2043
|
} else if (lowerSrc.endsWith(".tgz")) {
|
|
2442
2044
|
folderName = basename6(absSrcFile, ".tgz");
|
|
2443
2045
|
} else {
|
|
2444
|
-
folderName = basename6(absSrcFile,
|
|
2046
|
+
folderName = basename6(absSrcFile, extname2(absSrcFile));
|
|
2445
2047
|
}
|
|
2446
2048
|
let destDir = options.dir;
|
|
2447
2049
|
if (!destDir) {
|
|
2448
2050
|
destDir = join8(process.cwd(), folderName);
|
|
2449
2051
|
} else {
|
|
2450
|
-
destDir =
|
|
2052
|
+
destDir = resolve11(process.cwd(), destDir);
|
|
2451
2053
|
}
|
|
2452
2054
|
try {
|
|
2453
|
-
console.log(
|
|
2454
|
-
console.log(
|
|
2055
|
+
console.log(pc17.cyan(`\u{1F4E6} \u6B63\u5728\u51C6\u5907\u89E3\u538B: ${absSrcFile}...`));
|
|
2056
|
+
console.log(pc17.cyan(`\u{1F4E5} \u76EE\u6807\u8F93\u51FA\u76EE\u5F55: ${destDir}`));
|
|
2455
2057
|
await fs13.mkdir(destDir, { recursive: true });
|
|
2456
2058
|
if (lowerSrc.endsWith(".tar.gz") || lowerSrc.endsWith(".tgz")) {
|
|
2457
2059
|
await uncompressTgz(absSrcFile, destDir);
|
|
@@ -2463,16 +2065,16 @@ function registerUnzipCommand(program2) {
|
|
|
2463
2065
|
await uncompressRar(absSrcFile, destDir);
|
|
2464
2066
|
} else {
|
|
2465
2067
|
console.log(
|
|
2466
|
-
|
|
2068
|
+
pc17.yellow(
|
|
2467
2069
|
"\u26A0\uFE0F \u672A\u80FD\u8BC6\u522B\u7684\u538B\u7F29\u5305\u683C\u5F0F\u540E\u7F00\u3002\u5C06\u9ED8\u8BA4\u5C1D\u8BD5\u4F5C\u4E3A\u6807\u51C6 ZIP \u8FDB\u884C\u63D0\u53D6..."
|
|
2468
2070
|
)
|
|
2469
2071
|
);
|
|
2470
2072
|
await uncompressZip(absSrcFile, destDir);
|
|
2471
2073
|
}
|
|
2472
|
-
console.log(
|
|
2074
|
+
console.log(pc17.green(`\u2728 \u63D0\u53D6\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230: ${destDir}`));
|
|
2473
2075
|
} catch (error) {
|
|
2474
2076
|
console.error(
|
|
2475
|
-
|
|
2077
|
+
pc17.red("\u274C \u63D0\u53D6\u5931\u8D25:"),
|
|
2476
2078
|
error instanceof Error ? error.message : error
|
|
2477
2079
|
);
|
|
2478
2080
|
}
|
|
@@ -2480,39 +2082,41 @@ function registerUnzipCommand(program2) {
|
|
|
2480
2082
|
}
|
|
2481
2083
|
|
|
2482
2084
|
// commands/upgrade.ts
|
|
2483
|
-
import
|
|
2085
|
+
import pc18 from "picocolors";
|
|
2484
2086
|
function registerUpgradeCommand(program2) {
|
|
2485
|
-
program2.command("upgrade").description("\u68C0\u67E5\u5E76\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C").action(async () => {
|
|
2486
|
-
|
|
2487
|
-
|
|
2087
|
+
program2.command("upgrade").description("\u68C0\u67E5\u5E76\u81EA\u52A8\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177\u81F3\u6700\u65B0\u7248\u672C").option("-r, --registry", "\u5F3A\u5236\u4F7F\u7528 npm \u5B98\u65B9\u6E90 https://registry.npmjs.org/").action(async (options) => {
|
|
2088
|
+
const args = ["install", "-g"];
|
|
2089
|
+
if (options.registry) {
|
|
2090
|
+
args.push("--registry=https://registry.npmjs.org/");
|
|
2091
|
+
}
|
|
2092
|
+
args.push("@xx-in/tools@latest");
|
|
2093
|
+
console.log(pc18.cyan("\u{1F916} \u6B63\u5728\u4E3A\u60A8\u68C0\u67E5\u5E76\u66F4\u65B0 xx \u547D\u4EE4\u884C\u5DE5\u5177..."));
|
|
2094
|
+
console.log(pc18.dim(`\u6267\u884C\u547D\u4EE4: npm ${args.join(" ")}
|
|
2095
|
+
`));
|
|
2488
2096
|
try {
|
|
2489
|
-
const status = await spawnCommand("npm",
|
|
2490
|
-
"install",
|
|
2491
|
-
"-g",
|
|
2492
|
-
"@xx-in/tools@latest"
|
|
2493
|
-
]);
|
|
2097
|
+
const status = await spawnCommand("npm", args);
|
|
2494
2098
|
if (status.success) {
|
|
2495
2099
|
console.log(
|
|
2496
|
-
|
|
2100
|
+
pc18.cyan("\n\u{1F916} \u6B63\u5728\u4E3A\u60A8\u5F3A\u5236\u8986\u76D6\u5E76\u5237\u65B0\u7EC8\u7AEF\u81EA\u52A8\u8865\u5168\u811A\u672C...")
|
|
2497
2101
|
);
|
|
2498
2102
|
await autoInstallCompletion();
|
|
2499
2103
|
console.log(
|
|
2500
|
-
|
|
2104
|
+
pc18.green("\n\u2728 xx \u81EA\u52A8\u66F4\u65B0\u5E76\u91CD\u5237\u8865\u5168\u6210\u529F\uFF01\u5DF2\u6210\u529F\u52A0\u8F7D\u6700\u65B0\u7248\u672C\u3002")
|
|
2501
2105
|
);
|
|
2502
2106
|
} else {
|
|
2503
2107
|
console.error(
|
|
2504
|
-
|
|
2108
|
+
pc18.red(`
|
|
2505
2109
|
\u274C \u66F4\u65B0\u5931\u8D25\uFF0C\u9000\u51FA\u4EE3\u7801 (Exit Code): ${status.code}`)
|
|
2506
2110
|
);
|
|
2507
2111
|
}
|
|
2508
2112
|
} catch (err) {
|
|
2509
2113
|
console.error(
|
|
2510
|
-
|
|
2114
|
+
pc18.red(
|
|
2511
2115
|
"\n\u274C \u65E0\u6CD5\u6267\u884C\u66F4\u65B0\u547D\u4EE4\uFF0C\u8BF7\u786E\u8BA4\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF\u4E2D\u662F\u5426\u5DF2\u6B63\u786E\u914D\u7F6E Node.js \u4E0E npm\u3002"
|
|
2512
2116
|
)
|
|
2513
2117
|
);
|
|
2514
2118
|
if (err instanceof Error) {
|
|
2515
|
-
console.error(
|
|
2119
|
+
console.error(pc18.red("\u9519\u8BEF\u8BE6\u60C5:"), err.message);
|
|
2516
2120
|
}
|
|
2517
2121
|
}
|
|
2518
2122
|
});
|
|
@@ -2521,8 +2125,8 @@ function registerUpgradeCommand(program2) {
|
|
|
2521
2125
|
// commands/zip.ts
|
|
2522
2126
|
import fs14 from "fs/promises";
|
|
2523
2127
|
import os2 from "os";
|
|
2524
|
-
import
|
|
2525
|
-
import { join as join9, basename as basename7, relative as relative2, resolve as
|
|
2128
|
+
import pc19 from "picocolors";
|
|
2129
|
+
import { join as join9, basename as basename7, relative as relative2, resolve as resolve12 } from "path";
|
|
2526
2130
|
var IGNORE_FILE_NAME = ".cpzipignore";
|
|
2527
2131
|
var DEFAULT_BLACKLIST = [
|
|
2528
2132
|
"# cpzip \u5FFD\u7565\u914D\u7F6E\u6587\u4EF6",
|
|
@@ -2541,20 +2145,20 @@ async function getBlacklist(absSrcDir) {
|
|
|
2541
2145
|
const cwdIgnorePath = join9(process.cwd(), IGNORE_FILE_NAME);
|
|
2542
2146
|
try {
|
|
2543
2147
|
const content = await fs14.readFile(targetIgnorePath, "utf-8");
|
|
2544
|
-
console.log(
|
|
2148
|
+
console.log(pc19.cyan(`[zip] \u627E\u5230\u76EE\u6807\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${targetIgnorePath}`));
|
|
2545
2149
|
return parseIgnoreContent(content);
|
|
2546
2150
|
} catch {
|
|
2547
2151
|
}
|
|
2548
2152
|
try {
|
|
2549
2153
|
const content = await fs14.readFile(cwdIgnorePath, "utf-8");
|
|
2550
|
-
console.log(
|
|
2154
|
+
console.log(pc19.cyan(`[zip] \u627E\u5230\u5F53\u524D\u76EE\u5F55\u4E0B\u7684\u5FFD\u7565\u6587\u4EF6: ${cwdIgnorePath}`));
|
|
2551
2155
|
return parseIgnoreContent(content);
|
|
2552
2156
|
} catch (err) {
|
|
2553
2157
|
if (isNotFoundError(err)) {
|
|
2554
|
-
console.log(
|
|
2158
|
+
console.log(pc19.dim(`[zip] \u672A\u627E\u5230\u5FFD\u7565\u6587\u4EF6\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u8FC7\u6EE4\u89C4\u5219\u3002`));
|
|
2555
2159
|
return parseIgnoreContent(DEFAULT_BLACKLIST.join("\n"));
|
|
2556
2160
|
}
|
|
2557
|
-
console.error(
|
|
2161
|
+
console.error(pc19.red(`[zip] \u8BFB\u53D6\u5FFD\u7565\u6587\u4EF6\u5931\u8D25\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u89C4\u5219\u3002`), err);
|
|
2558
2162
|
return parseIgnoreContent(DEFAULT_BLACKLIST.join("\n"));
|
|
2559
2163
|
}
|
|
2560
2164
|
}
|
|
@@ -2603,20 +2207,20 @@ function registerZipCommand(program2) {
|
|
|
2603
2207
|
if (!srcDir) {
|
|
2604
2208
|
const input = prompt("\u8BF7\u8F93\u5165\u8981\u6253\u5305\u7684\u76EE\u5F55\u8DEF\u5F84 (Enter directory path):");
|
|
2605
2209
|
if (!input) {
|
|
2606
|
-
console.error(
|
|
2210
|
+
console.error(pc19.red("\u274C \u9519\u8BEF: \u672A\u6307\u5B9A\u6709\u6548\u7684\u8F93\u5165\u76EE\u5F55\u3002"));
|
|
2607
2211
|
return;
|
|
2608
2212
|
}
|
|
2609
2213
|
srcDir = input.trim();
|
|
2610
2214
|
}
|
|
2611
|
-
const absSrcDir =
|
|
2215
|
+
const absSrcDir = resolve12(srcDir);
|
|
2612
2216
|
try {
|
|
2613
2217
|
const stat = await fs14.stat(absSrcDir);
|
|
2614
2218
|
if (!stat.isDirectory()) {
|
|
2615
|
-
console.error(
|
|
2219
|
+
console.error(pc19.red(`\u274C \u9519\u8BEF: '${srcDir}' \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u76EE\u5F55\u3002`));
|
|
2616
2220
|
return;
|
|
2617
2221
|
}
|
|
2618
2222
|
} catch {
|
|
2619
|
-
console.error(
|
|
2223
|
+
console.error(pc19.red(`\u274C \u9519\u8BEF: \u627E\u4E0D\u5230\u76EE\u5F55 '${srcDir}'\u3002`));
|
|
2620
2224
|
return;
|
|
2621
2225
|
}
|
|
2622
2226
|
const dirName = basename7(absSrcDir);
|
|
@@ -2625,13 +2229,13 @@ function registerZipCommand(program2) {
|
|
|
2625
2229
|
const tempDir = await fs14.mkdtemp(join9(os2.tmpdir(), "cpzip_temp_"));
|
|
2626
2230
|
const tempCopyTarget = join9(tempDir, dirName);
|
|
2627
2231
|
try {
|
|
2628
|
-
console.log(
|
|
2232
|
+
console.log(pc19.cyan(`\u{1F4E6} \u6B63\u5728\u590D\u5236\u76EE\u5F55\u5E76\u8FC7\u6EE4\u5FFD\u7565\u9879...`));
|
|
2629
2233
|
await copyRecursive3(absSrcDir, tempCopyTarget, absSrcDir, blacklist);
|
|
2630
|
-
console.log(
|
|
2234
|
+
console.log(pc19.cyan(`\u26A1 \u6B63\u5728\u6253\u5305\u4E3A ZIP \u538B\u7F29\u5305...`));
|
|
2631
2235
|
await compressZip(tempCopyTarget, outputZip);
|
|
2632
|
-
console.log(
|
|
2236
|
+
console.log(pc19.green(`\u2728 \u6253\u5305\u6210\u529F\uFF01\u538B\u7F29\u5305\u4FDD\u5B58\u4E3A: ${outputZip}`));
|
|
2633
2237
|
} catch (error) {
|
|
2634
|
-
console.error(
|
|
2238
|
+
console.error(pc19.red("\u274C \u6253\u5305\u5931\u8D25:"), error);
|
|
2635
2239
|
} finally {
|
|
2636
2240
|
try {
|
|
2637
2241
|
await fs14.rm(tempDir, { recursive: true });
|