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