@zrhsh/wukong-cli 0.4.28 → 0.4.29
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/dist/cli.js +136 -20
- package/dist/cli.js.map +1 -1
- package/package.json +12 -1
package/dist/cli.js
CHANGED
|
@@ -801,6 +801,7 @@ init_esm_shims();
|
|
|
801
801
|
var VersionCache = class {
|
|
802
802
|
lastCheckTime = 0;
|
|
803
803
|
cachedVersion = null;
|
|
804
|
+
cachedHighlights = [];
|
|
804
805
|
checkInterval;
|
|
805
806
|
/**
|
|
806
807
|
* Constructor
|
|
@@ -824,17 +825,27 @@ var VersionCache = class {
|
|
|
824
825
|
}
|
|
825
826
|
/**
|
|
826
827
|
* Set cached version with timestamp
|
|
828
|
+
*
|
|
829
|
+
* @param highlights 该版本的更新要点,缺省为空数组
|
|
827
830
|
*/
|
|
828
|
-
set(version) {
|
|
831
|
+
set(version, highlights = []) {
|
|
829
832
|
this.cachedVersion = version;
|
|
833
|
+
this.cachedHighlights = highlights;
|
|
830
834
|
this.lastCheckTime = Date.now();
|
|
831
835
|
}
|
|
836
|
+
/**
|
|
837
|
+
* Get cached highlights
|
|
838
|
+
*/
|
|
839
|
+
getHighlights() {
|
|
840
|
+
return this.cachedHighlights;
|
|
841
|
+
}
|
|
832
842
|
/**
|
|
833
843
|
* Clear cache
|
|
834
844
|
*/
|
|
835
845
|
clear() {
|
|
836
846
|
this.lastCheckTime = 0;
|
|
837
847
|
this.cachedVersion = null;
|
|
848
|
+
this.cachedHighlights = [];
|
|
838
849
|
}
|
|
839
850
|
/**
|
|
840
851
|
* Get time since last check
|
|
@@ -853,6 +864,10 @@ var VersionCache = class {
|
|
|
853
864
|
get version() {
|
|
854
865
|
return this.cachedVersion;
|
|
855
866
|
}
|
|
867
|
+
/** Cached highlights */
|
|
868
|
+
get highlights() {
|
|
869
|
+
return this.cachedHighlights;
|
|
870
|
+
}
|
|
856
871
|
};
|
|
857
872
|
|
|
858
873
|
// src/utils/version/compare.ts
|
|
@@ -897,23 +912,28 @@ var VersionChecker = class {
|
|
|
897
912
|
return {
|
|
898
913
|
hasUpdate: compareVersions(cached, this.currentVersion) > 0,
|
|
899
914
|
currentVersion: this.currentVersion,
|
|
900
|
-
latestVersion: cached
|
|
915
|
+
latestVersion: cached,
|
|
916
|
+
latestHighlights: this.cache.getHighlights()
|
|
901
917
|
};
|
|
902
918
|
}
|
|
903
919
|
}
|
|
904
|
-
const
|
|
905
|
-
|
|
920
|
+
const release = this.provider.getLatestRelease ? await this.provider.getLatestRelease() : await this.provider.getLatestVersion().then(
|
|
921
|
+
(version) => version ? { version, highlights: [] } : null
|
|
922
|
+
);
|
|
923
|
+
if (!release) {
|
|
906
924
|
return {
|
|
907
925
|
hasUpdate: false,
|
|
908
926
|
currentVersion: this.currentVersion,
|
|
909
|
-
latestVersion: null
|
|
927
|
+
latestVersion: null,
|
|
928
|
+
latestHighlights: []
|
|
910
929
|
};
|
|
911
930
|
}
|
|
912
|
-
this.cache.set(
|
|
931
|
+
this.cache.set(release.version, release.highlights);
|
|
913
932
|
return {
|
|
914
|
-
hasUpdate: compareVersions(
|
|
933
|
+
hasUpdate: compareVersions(release.version, this.currentVersion) > 0,
|
|
915
934
|
currentVersion: this.currentVersion,
|
|
916
|
-
latestVersion
|
|
935
|
+
latestVersion: release.version,
|
|
936
|
+
latestHighlights: release.highlights
|
|
917
937
|
};
|
|
918
938
|
}
|
|
919
939
|
/**
|
|
@@ -923,7 +943,7 @@ var VersionChecker = class {
|
|
|
923
943
|
try {
|
|
924
944
|
const result = await this.checkForUpdate();
|
|
925
945
|
if (result.hasUpdate && notifier && result.latestVersion) {
|
|
926
|
-
notifier.notify(result.currentVersion, result.latestVersion);
|
|
946
|
+
notifier.notify(result.currentVersion, result.latestVersion, result.latestHighlights);
|
|
927
947
|
}
|
|
928
948
|
} catch (error2) {
|
|
929
949
|
}
|
|
@@ -933,6 +953,7 @@ var VersionChecker = class {
|
|
|
933
953
|
*/
|
|
934
954
|
clearCache() {
|
|
935
955
|
this.cache.clear();
|
|
956
|
+
this.provider.clearCache?.();
|
|
936
957
|
}
|
|
937
958
|
/**
|
|
938
959
|
* Get current cache info
|
|
@@ -947,17 +968,37 @@ var VersionChecker = class {
|
|
|
947
968
|
|
|
948
969
|
// src/utils/version/provider.ts
|
|
949
970
|
init_esm_shims();
|
|
950
|
-
|
|
971
|
+
function parseHighlights(value) {
|
|
972
|
+
if (!Array.isArray(value)) {
|
|
973
|
+
return [];
|
|
974
|
+
}
|
|
975
|
+
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0).slice(0, 5);
|
|
976
|
+
}
|
|
977
|
+
var NpmVersionProvider = class _NpmVersionProvider {
|
|
951
978
|
constructor(packageName, registryUrl) {
|
|
952
979
|
this.packageName = packageName;
|
|
953
980
|
this.registryUrl = registryUrl;
|
|
954
981
|
this.timeout = 5e3;
|
|
955
982
|
}
|
|
956
983
|
timeout;
|
|
984
|
+
cachedRelease = null;
|
|
985
|
+
cachedAt = 0;
|
|
986
|
+
/** 同一次进程内复用结果,避免 getLatestVersion / getLatestRelease 重复请求 */
|
|
987
|
+
static REUSE_MS = 6e4;
|
|
957
988
|
/**
|
|
958
989
|
* Get latest version from npm
|
|
959
990
|
*/
|
|
960
991
|
async getLatestVersion() {
|
|
992
|
+
const release = await this.getLatestRelease();
|
|
993
|
+
return release?.version ?? null;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* 获取最新版本及其更新摘要
|
|
997
|
+
*/
|
|
998
|
+
async getLatestRelease() {
|
|
999
|
+
if (this.cachedRelease && Date.now() - this.cachedAt < _NpmVersionProvider.REUSE_MS) {
|
|
1000
|
+
return this.cachedRelease;
|
|
1001
|
+
}
|
|
961
1002
|
try {
|
|
962
1003
|
const controller = new AbortController();
|
|
963
1004
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
@@ -969,11 +1010,28 @@ var NpmVersionProvider = class {
|
|
|
969
1010
|
return null;
|
|
970
1011
|
}
|
|
971
1012
|
const data = await response.json();
|
|
972
|
-
|
|
1013
|
+
const version = data["dist-tags"]?.latest;
|
|
1014
|
+
if (!version) {
|
|
1015
|
+
return null;
|
|
1016
|
+
}
|
|
1017
|
+
const highlights = parseHighlights(
|
|
1018
|
+
data.versions?.[version]?.wukongCli?.highlights ?? data.wukongCli?.highlights
|
|
1019
|
+
);
|
|
1020
|
+
const release = { version, highlights };
|
|
1021
|
+
this.cachedRelease = release;
|
|
1022
|
+
this.cachedAt = Date.now();
|
|
1023
|
+
return release;
|
|
973
1024
|
} catch (error2) {
|
|
974
1025
|
return null;
|
|
975
1026
|
}
|
|
976
1027
|
}
|
|
1028
|
+
/**
|
|
1029
|
+
* 清除进程内复用缓存
|
|
1030
|
+
*/
|
|
1031
|
+
clearCache() {
|
|
1032
|
+
this.cachedRelease = null;
|
|
1033
|
+
this.cachedAt = 0;
|
|
1034
|
+
}
|
|
977
1035
|
};
|
|
978
1036
|
|
|
979
1037
|
// src/utils/version/persistent-cache.ts
|
|
@@ -994,6 +1052,7 @@ var PersistentVersionCache = class extends VersionCache {
|
|
|
994
1052
|
if (typeof data.lastCheckTime === "number" && typeof data.version === "string") {
|
|
995
1053
|
this.lastCheckTime = data.lastCheckTime;
|
|
996
1054
|
this.cachedVersion = data.version;
|
|
1055
|
+
this.cachedHighlights = Array.isArray(data.highlights) ? data.highlights.filter((item) => typeof item === "string") : [];
|
|
997
1056
|
}
|
|
998
1057
|
} catch {
|
|
999
1058
|
}
|
|
@@ -1003,14 +1062,15 @@ var PersistentVersionCache = class extends VersionCache {
|
|
|
1003
1062
|
mkdirSync(dirname(this.cacheFilePath), { recursive: true });
|
|
1004
1063
|
const data = {
|
|
1005
1064
|
lastCheckTime: this.lastCheckTime,
|
|
1006
|
-
version: this.cachedVersion ?? ""
|
|
1065
|
+
version: this.cachedVersion ?? "",
|
|
1066
|
+
highlights: this.cachedHighlights
|
|
1007
1067
|
};
|
|
1008
1068
|
writeFileSync(this.cacheFilePath, JSON.stringify(data), "utf-8");
|
|
1009
1069
|
} catch {
|
|
1010
1070
|
}
|
|
1011
1071
|
}
|
|
1012
|
-
set(version) {
|
|
1013
|
-
super.set(version);
|
|
1072
|
+
set(version, highlights = []) {
|
|
1073
|
+
super.set(version, highlights);
|
|
1014
1074
|
this.saveToFile();
|
|
1015
1075
|
}
|
|
1016
1076
|
clear() {
|
|
@@ -1026,10 +1086,24 @@ import { join } from "path";
|
|
|
1026
1086
|
// src/utils/version/notifier.ts
|
|
1027
1087
|
init_esm_shims();
|
|
1028
1088
|
import chalk2 from "chalk";
|
|
1089
|
+
var MAX_HIGHLIGHTS = 3;
|
|
1090
|
+
var SEPARATOR = "\u2500".repeat(58);
|
|
1029
1091
|
var ConsoleNotifier = class {
|
|
1030
|
-
notify(currentVersion, latestVersion) {
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1092
|
+
notify(currentVersion, latestVersion, highlights = []) {
|
|
1093
|
+
const lines = [
|
|
1094
|
+
SEPARATOR,
|
|
1095
|
+
`New version available: ${currentVersion} \u2192 ${latestVersion}`
|
|
1096
|
+
];
|
|
1097
|
+
if (highlights.length > 0) {
|
|
1098
|
+
lines.push("\u672C\u6B21\u66F4\u65B0\uFF1A");
|
|
1099
|
+
for (const item of highlights.slice(0, MAX_HIGHLIGHTS)) {
|
|
1100
|
+
lines.push(` \u2022 ${item}`);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
lines.push("\u5347\u7EA7\uFF1Awukong-cli update");
|
|
1104
|
+
lines.push(" \u6216 npm i -g @zrhsh/wukong-cli@latest");
|
|
1105
|
+
lines.push(SEPARATOR);
|
|
1106
|
+
process.stderr.write(chalk2.yellow(lines.join("\n")) + "\n");
|
|
1033
1107
|
}
|
|
1034
1108
|
};
|
|
1035
1109
|
|
|
@@ -2242,6 +2316,7 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2242
2316
|
printEnvironmentInfo(env, envConfig.displayName);
|
|
2243
2317
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
2244
2318
|
console.log("");
|
|
2319
|
+
process.exitCode = 1;
|
|
2245
2320
|
return;
|
|
2246
2321
|
}
|
|
2247
2322
|
try {
|
|
@@ -2266,6 +2341,7 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2266
2341
|
printEnvironmentInfo(env, envConfig.displayName);
|
|
2267
2342
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
2268
2343
|
console.log("");
|
|
2344
|
+
process.exitCode = 1;
|
|
2269
2345
|
}
|
|
2270
2346
|
} catch (error2) {
|
|
2271
2347
|
if (error2 instanceof ConfigFileError) {
|
|
@@ -2273,6 +2349,7 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2273
2349
|
console.log("");
|
|
2274
2350
|
console.log(chalk5.red(error2.toUserMessage()));
|
|
2275
2351
|
console.log("");
|
|
2352
|
+
process.exitCode = 1;
|
|
2276
2353
|
return;
|
|
2277
2354
|
}
|
|
2278
2355
|
console.log(chalk5.yellow(`\u2717 Not authenticated`));
|
|
@@ -2280,6 +2357,7 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2280
2357
|
printEnvironmentInfo(env, envConfig.displayName);
|
|
2281
2358
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
2282
2359
|
console.log("");
|
|
2360
|
+
process.exitCode = 1;
|
|
2283
2361
|
}
|
|
2284
2362
|
});
|
|
2285
2363
|
authCommands.command("token").description("Display current token structure and JWT payload claims").action(async () => {
|
|
@@ -2477,8 +2555,37 @@ function detectPageQueryEnvelope(body) {
|
|
|
2477
2555
|
};
|
|
2478
2556
|
}
|
|
2479
2557
|
|
|
2558
|
+
// src/core/http/response-guard.ts
|
|
2559
|
+
init_esm_shims();
|
|
2560
|
+
var AUTH_ERROR_CODES = [401, 403, 9913, 9914];
|
|
2561
|
+
var LOGIN_HINT = "Run: wukong-cli auth login";
|
|
2562
|
+
function isAuthErrorCode(code) {
|
|
2563
|
+
return AUTH_ERROR_CODES.includes(code);
|
|
2564
|
+
}
|
|
2565
|
+
function withLoginHint(message) {
|
|
2566
|
+
if (message.includes(LOGIN_HINT)) {
|
|
2567
|
+
return message;
|
|
2568
|
+
}
|
|
2569
|
+
return `${message}
|
|
2570
|
+
Hint: \u767B\u5F55\u6001\u53EF\u80FD\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u3002${LOGIN_HINT}`;
|
|
2571
|
+
}
|
|
2572
|
+
function looksLikeHtml(value) {
|
|
2573
|
+
if (typeof value !== "string") {
|
|
2574
|
+
return false;
|
|
2575
|
+
}
|
|
2576
|
+
const head = value.trimStart().slice(0, 64).toLowerCase();
|
|
2577
|
+
return head.startsWith("<!doctype html") || head.startsWith("<html");
|
|
2578
|
+
}
|
|
2579
|
+
function describeHtmlResponse() {
|
|
2580
|
+
return [
|
|
2581
|
+
"\u63A5\u53E3\u8FD4\u56DE\u7684\u662F HTML \u9875\u9762\uFF0C\u4E0D\u662F JSON\u3002",
|
|
2582
|
+
"\u5E38\u89C1\u539F\u56E0\uFF1A\u767B\u5F55\u6001\u5931\u6548\u88AB\u91CD\u5B9A\u5411\u5230\u767B\u5F55\u9875\u3001\u63A5\u53E3\u8DEF\u5F84\u9519\u8BEF\u3001base URL \u6307\u5411\u4E86\u524D\u7AEF\u7AD9\u70B9\u3002",
|
|
2583
|
+
`\u8BF7\u5148\u6267\u884C wukong-cli auth status \u786E\u8BA4\u767B\u5F55\u6001\uFF0C\u5FC5\u8981\u65F6 ${LOGIN_HINT}`
|
|
2584
|
+
].join("\n");
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2480
2587
|
// src/commands/http.ts
|
|
2481
|
-
function fail(message, jsonMode, errorCode = null) {
|
|
2588
|
+
function fail(message, jsonMode, errorCode = null, exitCode = 1) {
|
|
2482
2589
|
if (jsonMode) {
|
|
2483
2590
|
process.stderr.write(
|
|
2484
2591
|
JSON.stringify({ error: { code: errorCode, message } }, null, 2) + "\n"
|
|
@@ -2486,7 +2593,7 @@ function fail(message, jsonMode, errorCode = null) {
|
|
|
2486
2593
|
} else {
|
|
2487
2594
|
console.error(chalk6.red(message));
|
|
2488
2595
|
}
|
|
2489
|
-
process.exit(
|
|
2596
|
+
process.exit(exitCode);
|
|
2490
2597
|
}
|
|
2491
2598
|
function fixGitBashPath(url) {
|
|
2492
2599
|
if (url.includes(":") && !url.startsWith("http")) {
|
|
@@ -2627,7 +2734,12 @@ function handleError(error2, jsonMode) {
|
|
|
2627
2734
|
${error2.toUserMessage()}`, jsonMode);
|
|
2628
2735
|
}
|
|
2629
2736
|
if (error2 instanceof ApiError) {
|
|
2630
|
-
|
|
2737
|
+
const message = `API Error (code: ${error2.code}): ${error2.message}`;
|
|
2738
|
+
return fail(
|
|
2739
|
+
isAuthErrorCode(error2.code) ? withLoginHint(message) : message,
|
|
2740
|
+
jsonMode,
|
|
2741
|
+
error2.code
|
|
2742
|
+
);
|
|
2631
2743
|
}
|
|
2632
2744
|
return fail(error2 instanceof Error ? error2.message : String(error2), jsonMode);
|
|
2633
2745
|
}
|
|
@@ -2658,6 +2770,10 @@ async function executeRequest(method, url, options) {
|
|
|
2658
2770
|
};
|
|
2659
2771
|
warnOnPageQueryEnvelope(context);
|
|
2660
2772
|
const result = context.fullUrl.includes("/yst-") ? await sendWithYstToken(context) : await sendWithMainToken(context);
|
|
2773
|
+
if (looksLikeHtml(result.data)) {
|
|
2774
|
+
spinner.fail("Unexpected HTML response");
|
|
2775
|
+
fail(describeHtmlResponse(), jsonMode, null, 2);
|
|
2776
|
+
}
|
|
2661
2777
|
spinner.succeed(`Response received (${result.duration}ms)`);
|
|
2662
2778
|
renderResult(result, jsonMode);
|
|
2663
2779
|
} catch (error2) {
|