@zrhsh/wukong-cli 0.1.6 → 0.1.8
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 +140 -120
- package/dist/cli.js +292 -146
- package/dist/cli.js.map +1 -1
- package/package.json +18 -2
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,65 @@ var init_esm_shims = __esm({
|
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
// src/utils/debug.ts
|
|
33
|
+
import chalk from "chalk";
|
|
34
|
+
function setDebugMode(enabled, explicit = true) {
|
|
35
|
+
if (explicit) {
|
|
36
|
+
debugMode = enabled;
|
|
37
|
+
explicitSet = true;
|
|
38
|
+
}
|
|
39
|
+
global.__debugMode = enabled;
|
|
40
|
+
}
|
|
41
|
+
function isDebugMode() {
|
|
42
|
+
if (explicitSet) {
|
|
43
|
+
return debugMode === true;
|
|
44
|
+
}
|
|
45
|
+
if (global.__debugMode === true) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return process.env.WUKONG_CLI_DEBUG === "true";
|
|
49
|
+
}
|
|
50
|
+
function debugRequest(method, url, headers, body) {
|
|
51
|
+
if (!isDebugMode()) return;
|
|
52
|
+
console.log("");
|
|
53
|
+
console.log(chalk.dim("=== HTTP Request ==="));
|
|
54
|
+
console.log(chalk.cyan(`${method} ${url}`));
|
|
55
|
+
if (headers) {
|
|
56
|
+
console.log(chalk.dim("Headers:"));
|
|
57
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
58
|
+
if (key.toLowerCase() === "authorization") {
|
|
59
|
+
const truncated = value.length > 50 ? value.substring(0, 50) + "..." : value;
|
|
60
|
+
console.log(chalk.dim(` ${key}: ${truncated}`));
|
|
61
|
+
} else {
|
|
62
|
+
console.log(chalk.dim(` ${key}: ${value}`));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (body) {
|
|
67
|
+
console.log(chalk.dim("Body:"));
|
|
68
|
+
console.log(chalk.dim(JSON.stringify(body, null, 2)));
|
|
69
|
+
}
|
|
70
|
+
console.log("");
|
|
71
|
+
}
|
|
72
|
+
function debugResponse(status, statusText, body, duration) {
|
|
73
|
+
if (!isDebugMode()) return;
|
|
74
|
+
const statusColor = status >= 200 && status < 300 ? chalk.green : chalk.red;
|
|
75
|
+
console.log(chalk.dim("=== HTTP Response") + chalk.dim(` (${duration}ms) ===`));
|
|
76
|
+
console.log(statusColor(`Status: ${status} ${statusText}`));
|
|
77
|
+
console.log(chalk.dim("Body:"));
|
|
78
|
+
console.log(chalk.dim(JSON.stringify(body, null, 2)));
|
|
79
|
+
console.log("");
|
|
80
|
+
}
|
|
81
|
+
var debugMode, explicitSet;
|
|
82
|
+
var init_debug = __esm({
|
|
83
|
+
"src/utils/debug.ts"() {
|
|
84
|
+
"use strict";
|
|
85
|
+
init_esm_shims();
|
|
86
|
+
debugMode = null;
|
|
87
|
+
explicitSet = false;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
32
91
|
// src/constants/config.ts
|
|
33
92
|
var API_ENDPOINTS, POLL_CONFIG;
|
|
34
93
|
var init_config = __esm({
|
|
@@ -167,17 +226,27 @@ function loadConfig() {
|
|
|
167
226
|
}
|
|
168
227
|
function getMergedEnvironmentConfig(env) {
|
|
169
228
|
const config = loadConfig();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
229
|
+
if (!config.environments || !(env in config.environments)) {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`Environment '${env}' not found in configuration. Please run 'wukong-cli init' to create a valid configuration file.`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
const envConfig = config.environments[env];
|
|
235
|
+
const requiredFields = ["authBaseUrl", "apiBaseUrl", "clientId"];
|
|
236
|
+
const missingFields = requiredFields.filter((field) => !(field in envConfig));
|
|
237
|
+
if (missingFields.length > 0) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Missing required configuration fields for environment '${env}': ${missingFields.join(", ")}. Please run 'wukong-cli init' to create a valid configuration file.`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
const defaultConfig = ENVIRONMENTS[env];
|
|
243
|
+
const displayName = defaultConfig?.displayName || env;
|
|
175
244
|
return {
|
|
176
245
|
name: env,
|
|
177
|
-
displayName
|
|
178
|
-
authBaseUrl:
|
|
179
|
-
apiBaseUrl:
|
|
180
|
-
clientId:
|
|
246
|
+
displayName,
|
|
247
|
+
authBaseUrl: envConfig.authBaseUrl,
|
|
248
|
+
apiBaseUrl: envConfig.apiBaseUrl,
|
|
249
|
+
clientId: envConfig.clientId
|
|
181
250
|
};
|
|
182
251
|
}
|
|
183
252
|
function getAllEnvironments() {
|
|
@@ -236,15 +305,15 @@ function getEnvironmentConfig() {
|
|
|
236
305
|
return getMergedEnvironmentConfig(getCurrentEnvironment());
|
|
237
306
|
}
|
|
238
307
|
function getOceanetConfig() {
|
|
239
|
-
const
|
|
308
|
+
const envConfig = getEnvironmentConfig();
|
|
240
309
|
const env = getCurrentEnvironment();
|
|
241
310
|
return {
|
|
242
311
|
// 认证服务基础地址 (设备码授权、登录、登出等)
|
|
243
|
-
AUTH_BASE_URL:
|
|
312
|
+
AUTH_BASE_URL: envConfig.authBaseUrl,
|
|
244
313
|
// 业务 API 基础地址
|
|
245
|
-
API_BASE_URL:
|
|
314
|
+
API_BASE_URL: envConfig.apiBaseUrl,
|
|
246
315
|
// 客户端 ID
|
|
247
|
-
CLIENT_ID:
|
|
316
|
+
CLIENT_ID: envConfig.clientId,
|
|
248
317
|
// Token 存储服务名(不同环境分开存储)
|
|
249
318
|
SERVICE_NAME: `wukong-cli-${env}`,
|
|
250
319
|
// 轮询配置
|
|
@@ -253,11 +322,11 @@ function getOceanetConfig() {
|
|
|
253
322
|
AUTH_ENDPOINTS: API_ENDPOINTS.AUTH,
|
|
254
323
|
// 业务 API 端点
|
|
255
324
|
API_ENDPOINTS: API_ENDPOINTS.API,
|
|
256
|
-
// 调试模式
|
|
325
|
+
// 调试模式 (保留这个环境变量,因为它是运行时选项)
|
|
257
326
|
DEBUG: getEnv("WUKONG_CLI_DEBUG", "false") === "true",
|
|
258
327
|
// 当前环境信息
|
|
259
328
|
ENVIRONMENT: env,
|
|
260
|
-
ENVIRONMENT_DISPLAY:
|
|
329
|
+
ENVIRONMENT_DISPLAY: envConfig.displayName
|
|
261
330
|
};
|
|
262
331
|
}
|
|
263
332
|
var currentEnv, getEnv, OCEANET_CONFIG;
|
|
@@ -272,7 +341,7 @@ var init_oceanet = __esm({
|
|
|
272
341
|
getEnv = (key, defaultValue) => {
|
|
273
342
|
return process.env[key] || defaultValue;
|
|
274
343
|
};
|
|
275
|
-
OCEANET_CONFIG = getOceanetConfig
|
|
344
|
+
OCEANET_CONFIG = getOceanetConfig;
|
|
276
345
|
}
|
|
277
346
|
});
|
|
278
347
|
|
|
@@ -291,6 +360,7 @@ var init_device_flow_service = __esm({
|
|
|
291
360
|
"use strict";
|
|
292
361
|
init_esm_shims();
|
|
293
362
|
init_oceanet();
|
|
363
|
+
init_debug();
|
|
294
364
|
DeviceFlowService = class {
|
|
295
365
|
/**
|
|
296
366
|
* 获取设备授权码
|
|
@@ -303,14 +373,19 @@ var init_device_flow_service = __esm({
|
|
|
303
373
|
clientId: config.CLIENT_ID
|
|
304
374
|
}
|
|
305
375
|
};
|
|
376
|
+
const requestHeaders = {
|
|
377
|
+
"Content-Type": "application/json"
|
|
378
|
+
};
|
|
379
|
+
debugRequest("POST", url, requestHeaders, requestBody);
|
|
380
|
+
const startTime = Date.now();
|
|
306
381
|
const response = await fetch(url, {
|
|
307
382
|
method: "POST",
|
|
308
|
-
headers:
|
|
309
|
-
"Content-Type": "application/json"
|
|
310
|
-
},
|
|
383
|
+
headers: requestHeaders,
|
|
311
384
|
body: JSON.stringify(requestBody)
|
|
312
385
|
});
|
|
386
|
+
const duration = Date.now() - startTime;
|
|
313
387
|
const data = await response.json();
|
|
388
|
+
debugResponse(response.status, response.statusText, data, duration);
|
|
314
389
|
if (data.code !== 200) {
|
|
315
390
|
throw new Error(
|
|
316
391
|
`(${data.code}) ${data.message || "Failed to get device code"}`
|
|
@@ -340,14 +415,19 @@ var init_device_flow_service = __esm({
|
|
|
340
415
|
deviceCode
|
|
341
416
|
}
|
|
342
417
|
};
|
|
418
|
+
const requestHeaders = {
|
|
419
|
+
"Content-Type": "application/json"
|
|
420
|
+
};
|
|
421
|
+
debugRequest("POST", url, requestHeaders, requestBody);
|
|
422
|
+
const requestStartTime = Date.now();
|
|
343
423
|
const response = await fetch(url, {
|
|
344
424
|
method: "POST",
|
|
345
|
-
headers:
|
|
346
|
-
"Content-Type": "application/json"
|
|
347
|
-
},
|
|
425
|
+
headers: requestHeaders,
|
|
348
426
|
body: JSON.stringify(requestBody)
|
|
349
427
|
});
|
|
428
|
+
const duration = Date.now() - requestStartTime;
|
|
350
429
|
const data = await response.json();
|
|
430
|
+
debugResponse(response.status, response.statusText, data, duration);
|
|
351
431
|
if (data.code !== 200) {
|
|
352
432
|
await new Promise(
|
|
353
433
|
(resolve) => setTimeout(resolve, config.POLL.INTERVAL * 1e3)
|
|
@@ -419,7 +499,7 @@ var init_ora_ui_callbacks = __esm({
|
|
|
419
499
|
});
|
|
420
500
|
|
|
421
501
|
// src/core/auth/keytar-adapter.ts
|
|
422
|
-
import { createRequire } from "module";
|
|
502
|
+
import { createRequire as createRequire2 } from "module";
|
|
423
503
|
function isKeytarAvailable() {
|
|
424
504
|
return keytarModule !== null;
|
|
425
505
|
}
|
|
@@ -441,15 +521,15 @@ async function deletePassword(service, account) {
|
|
|
441
521
|
}
|
|
442
522
|
return await keytarModule.deletePassword(service, account);
|
|
443
523
|
}
|
|
444
|
-
var
|
|
524
|
+
var require3, keytarModule;
|
|
445
525
|
var init_keytar_adapter = __esm({
|
|
446
526
|
"src/core/auth/keytar-adapter.ts"() {
|
|
447
527
|
"use strict";
|
|
448
528
|
init_esm_shims();
|
|
449
|
-
|
|
529
|
+
require3 = createRequire2(import.meta.url);
|
|
450
530
|
keytarModule = null;
|
|
451
531
|
try {
|
|
452
|
-
keytarModule =
|
|
532
|
+
keytarModule = require3("keytar");
|
|
453
533
|
} catch (error) {
|
|
454
534
|
keytarModule = null;
|
|
455
535
|
}
|
|
@@ -634,60 +714,79 @@ var init_token_cache = __esm({
|
|
|
634
714
|
|
|
635
715
|
// src/cli.ts
|
|
636
716
|
init_esm_shims();
|
|
717
|
+
init_debug();
|
|
637
718
|
import { Command as Command4 } from "commander";
|
|
638
719
|
|
|
639
|
-
// src/utils/
|
|
720
|
+
// src/utils/version-check.ts
|
|
640
721
|
init_esm_shims();
|
|
641
|
-
import
|
|
642
|
-
var
|
|
643
|
-
var
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
722
|
+
import { createRequire } from "module";
|
|
723
|
+
var require2 = createRequire(import.meta.url);
|
|
724
|
+
var packageJson = require2("../package.json");
|
|
725
|
+
var PACKAGE_NAME = "@zrhsh/wukong-cli";
|
|
726
|
+
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
727
|
+
var CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
|
|
728
|
+
var lastCheckTime = 0;
|
|
729
|
+
var cachedLatestVersion = null;
|
|
730
|
+
async function getLatestVersion() {
|
|
731
|
+
try {
|
|
732
|
+
const response = await fetch(`${NPM_REGISTRY_URL}/${PACKAGE_NAME}`);
|
|
733
|
+
const data = await response.json();
|
|
734
|
+
return data["dist-tags"]?.latest || null;
|
|
735
|
+
} catch (error) {
|
|
736
|
+
return null;
|
|
648
737
|
}
|
|
649
|
-
global.__debugMode = enabled;
|
|
650
738
|
}
|
|
651
|
-
function
|
|
652
|
-
|
|
653
|
-
|
|
739
|
+
async function checkForUpdate() {
|
|
740
|
+
const now = Date.now();
|
|
741
|
+
const currentVersion = packageJson.version;
|
|
742
|
+
if (now - lastCheckTime < CHECK_INTERVAL && cachedLatestVersion) {
|
|
743
|
+
return {
|
|
744
|
+
hasUpdate: cachedLatestVersion !== currentVersion,
|
|
745
|
+
currentVersion,
|
|
746
|
+
latestVersion: cachedLatestVersion
|
|
747
|
+
};
|
|
654
748
|
}
|
|
655
|
-
|
|
656
|
-
|
|
749
|
+
const latestVersion = await getLatestVersion();
|
|
750
|
+
if (!latestVersion) {
|
|
751
|
+
return {
|
|
752
|
+
hasUpdate: false,
|
|
753
|
+
currentVersion,
|
|
754
|
+
latestVersion: null
|
|
755
|
+
};
|
|
657
756
|
}
|
|
658
|
-
|
|
757
|
+
lastCheckTime = now;
|
|
758
|
+
cachedLatestVersion = latestVersion;
|
|
759
|
+
return {
|
|
760
|
+
hasUpdate: latestVersion !== currentVersion,
|
|
761
|
+
currentVersion,
|
|
762
|
+
latestVersion
|
|
763
|
+
};
|
|
659
764
|
}
|
|
660
|
-
function
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
console.log(chalk.cyan(`${method} ${url}`));
|
|
665
|
-
if (headers) {
|
|
666
|
-
console.log(chalk.dim("Headers:"));
|
|
667
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
668
|
-
if (key.toLowerCase() === "authorization") {
|
|
669
|
-
const truncated = value.length > 50 ? value.substring(0, 50) + "..." : value;
|
|
670
|
-
console.log(chalk.dim(` ${key}: ${truncated}`));
|
|
671
|
-
} else {
|
|
672
|
-
console.log(chalk.dim(` ${key}: ${value}`));
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
if (body) {
|
|
677
|
-
console.log(chalk.dim("Body:"));
|
|
678
|
-
console.log(chalk.dim(JSON.stringify(body, null, 2)));
|
|
765
|
+
async function showUpdateNotification() {
|
|
766
|
+
const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();
|
|
767
|
+
if (!hasUpdate || !latestVersion) {
|
|
768
|
+
return;
|
|
679
769
|
}
|
|
680
770
|
console.log("");
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
console.log(
|
|
686
|
-
console.log(
|
|
687
|
-
console.log(
|
|
688
|
-
console.log(
|
|
771
|
+
console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
772
|
+
console.log("\u2551" + " ".repeat(58) + "\u2551");
|
|
773
|
+
console.log("\u2551" + " \u{1F389} \u65B0\u7248\u672C\u53EF\u7528!".padEnd(60) + "\u2551");
|
|
774
|
+
console.log("\u2551" + " ".repeat(58) + "\u2551");
|
|
775
|
+
console.log(`\u2551 \u5F53\u524D\u7248\u672C: ${currentVersion.padEnd(10)} \u6700\u65B0\u7248\u672C: ${latestVersion.padEnd(10)} \u2551`);
|
|
776
|
+
console.log("\u2551" + " ".repeat(58) + "\u2551");
|
|
777
|
+
console.log("\u2551" + " \u66F4\u65B0\u547D\u4EE4:".padEnd(60) + "\u2551");
|
|
778
|
+
console.log(`\u2551 npm install -g ${PACKAGE_NAME}@latest`.padEnd(60) + "\u2551");
|
|
779
|
+
console.log("\u2551" + " ".repeat(58) + "\u2551");
|
|
780
|
+
console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
689
781
|
console.log("");
|
|
690
782
|
}
|
|
783
|
+
async function checkAndUpdate(silent = false) {
|
|
784
|
+
if (!silent) {
|
|
785
|
+
await showUpdateNotification();
|
|
786
|
+
} else {
|
|
787
|
+
await checkForUpdate();
|
|
788
|
+
}
|
|
789
|
+
}
|
|
691
790
|
|
|
692
791
|
// src/commands/auth.ts
|
|
693
792
|
init_esm_shims();
|
|
@@ -801,6 +900,7 @@ async function pollToken(deviceCode) {
|
|
|
801
900
|
// src/core/auth/token-manager.ts
|
|
802
901
|
init_esm_shims();
|
|
803
902
|
init_oceanet();
|
|
903
|
+
init_debug();
|
|
804
904
|
import ora2 from "ora";
|
|
805
905
|
var TokenManager = class {
|
|
806
906
|
/**
|
|
@@ -859,14 +959,20 @@ var TokenManager = class {
|
|
|
859
959
|
try {
|
|
860
960
|
const config = getOceanetConfig();
|
|
861
961
|
const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;
|
|
962
|
+
const requestHeaders = {
|
|
963
|
+
"Content-Type": "application/json"
|
|
964
|
+
};
|
|
965
|
+
const requestBody = { param: refreshToken };
|
|
966
|
+
debugRequest("POST", url, requestHeaders, requestBody);
|
|
967
|
+
const startTime = Date.now();
|
|
862
968
|
const response = await fetch(url, {
|
|
863
969
|
method: "POST",
|
|
864
|
-
headers:
|
|
865
|
-
|
|
866
|
-
},
|
|
867
|
-
body: JSON.stringify({ param: refreshToken })
|
|
970
|
+
headers: requestHeaders,
|
|
971
|
+
body: JSON.stringify(requestBody)
|
|
868
972
|
});
|
|
973
|
+
const duration = Date.now() - startTime;
|
|
869
974
|
const data = await response.json();
|
|
975
|
+
debugResponse(response.status, response.statusText, data, duration);
|
|
870
976
|
if (data.code !== 200) {
|
|
871
977
|
spinner.fail("Token refresh failed");
|
|
872
978
|
throw new Error(data.message || "Refresh token failed");
|
|
@@ -906,13 +1012,24 @@ var TokenManager = class {
|
|
|
906
1012
|
async logout(accessToken) {
|
|
907
1013
|
try {
|
|
908
1014
|
const config = getOceanetConfig();
|
|
909
|
-
|
|
1015
|
+
const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`;
|
|
1016
|
+
const requestHeaders = {
|
|
1017
|
+
"Content-Type": "application/json",
|
|
1018
|
+
"Authorization": `Bearer ${accessToken}`
|
|
1019
|
+
};
|
|
1020
|
+
debugRequest("POST", url, requestHeaders);
|
|
1021
|
+
const startTime = Date.now();
|
|
1022
|
+
const response = await fetch(url, {
|
|
910
1023
|
method: "POST",
|
|
911
|
-
headers:
|
|
912
|
-
"Content-Type": "application/json",
|
|
913
|
-
"Authorization": `Bearer ${accessToken}`
|
|
914
|
-
}
|
|
1024
|
+
headers: requestHeaders
|
|
915
1025
|
});
|
|
1026
|
+
const duration = Date.now() - startTime;
|
|
1027
|
+
let data;
|
|
1028
|
+
try {
|
|
1029
|
+
data = await response.json();
|
|
1030
|
+
} catch {
|
|
1031
|
+
}
|
|
1032
|
+
debugResponse(response.status, response.statusText, data || "No response body", duration);
|
|
916
1033
|
} catch (error) {
|
|
917
1034
|
}
|
|
918
1035
|
await this.clearTokens();
|
|
@@ -961,6 +1078,7 @@ init_esm_shims();
|
|
|
961
1078
|
|
|
962
1079
|
// src/core/http/base-http-client.ts
|
|
963
1080
|
init_esm_shims();
|
|
1081
|
+
init_debug();
|
|
964
1082
|
init_oceanet();
|
|
965
1083
|
function buildUrl(endpoint, params) {
|
|
966
1084
|
if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
|
|
@@ -1265,6 +1383,8 @@ function getRetoken() {
|
|
|
1265
1383
|
}
|
|
1266
1384
|
|
|
1267
1385
|
// src/core/http/authenticating-http-client.ts
|
|
1386
|
+
init_debug();
|
|
1387
|
+
init_oceanet();
|
|
1268
1388
|
var AuthenticatingHttpClient = class {
|
|
1269
1389
|
constructor(baseClient, tokenCache) {
|
|
1270
1390
|
this.baseClient = baseClient;
|
|
@@ -1296,7 +1416,9 @@ var AuthenticatingHttpClient = class {
|
|
|
1296
1416
|
...options.headers,
|
|
1297
1417
|
"Authorization": `Bearer ${accessToken}`
|
|
1298
1418
|
};
|
|
1299
|
-
const
|
|
1419
|
+
const config = getOceanetConfig();
|
|
1420
|
+
const baseUrl = options.baseUrl || config.API_BASE_URL;
|
|
1421
|
+
const url = endpoint.startsWith("http") ? endpoint : `${baseUrl}${endpoint}`;
|
|
1300
1422
|
debugRequest(options.method || "GET", url, headers, options.body);
|
|
1301
1423
|
const retoken = getRetoken();
|
|
1302
1424
|
const startTime = Date.now();
|
|
@@ -1319,8 +1441,11 @@ var AuthenticatingHttpClient = class {
|
|
|
1319
1441
|
await retoken.refreshToken();
|
|
1320
1442
|
const newAccessToken = this.tokenCache.getAccessToken();
|
|
1321
1443
|
if (newAccessToken) {
|
|
1444
|
+
const config2 = getOceanetConfig();
|
|
1445
|
+
const baseUrl2 = options.baseUrl || config2.API_BASE_URL;
|
|
1446
|
+
const retryUrl = endpoint.startsWith("http") ? endpoint : `${baseUrl2}${endpoint}`;
|
|
1322
1447
|
const retryResponse = await fetch(
|
|
1323
|
-
|
|
1448
|
+
retryUrl,
|
|
1324
1449
|
{
|
|
1325
1450
|
method: options.method || "GET",
|
|
1326
1451
|
headers: {
|
|
@@ -1500,11 +1625,11 @@ authCommands.command("login").description("Login using Device Authorization Flow
|
|
|
1500
1625
|
const allEnvs = getAllEnvironments();
|
|
1501
1626
|
setCurrentEnvironment(env);
|
|
1502
1627
|
const config = getOceanetConfig();
|
|
1503
|
-
const
|
|
1628
|
+
const envConfig = allEnvs[env];
|
|
1504
1629
|
console.log("");
|
|
1505
1630
|
console.log(chalk5.bgBlue.white.bold(" Wukong CLI Login "));
|
|
1506
1631
|
console.log("");
|
|
1507
|
-
printEnvironmentInfo(env,
|
|
1632
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1508
1633
|
console.log("");
|
|
1509
1634
|
const { verificationUri, deviceCode, expiresIn, interval } = await getDeviceCode();
|
|
1510
1635
|
console.log("");
|
|
@@ -1542,7 +1667,7 @@ authCommands.command("login").description("Login using Device Authorization Flow
|
|
|
1542
1667
|
console.log(chalk5.bgGreen.black.bold(" [OK] Login Successful "));
|
|
1543
1668
|
console.log("");
|
|
1544
1669
|
console.log(chalk5.green("[OK] Tokens saved securely"));
|
|
1545
|
-
printEnvironmentInfo(env,
|
|
1670
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1546
1671
|
console.log(chalk5.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));
|
|
1547
1672
|
console.log("");
|
|
1548
1673
|
console.log(chalk5.dim("Next:"), chalk5.cyan("wukong-cli auth status"));
|
|
@@ -1557,23 +1682,25 @@ authCommands.command("logout").description("Logout and clear saved tokens").acti
|
|
|
1557
1682
|
const env = getCurrentEnvironment();
|
|
1558
1683
|
const allEnvs = getAllEnvironments();
|
|
1559
1684
|
setCurrentEnvironment(env);
|
|
1560
|
-
const
|
|
1685
|
+
const envConfig = allEnvs[env];
|
|
1561
1686
|
try {
|
|
1562
1687
|
const accessToken = await getAccessToken();
|
|
1563
1688
|
if (accessToken) {
|
|
1564
1689
|
await logout(accessToken);
|
|
1565
1690
|
}
|
|
1566
1691
|
console.log("");
|
|
1567
|
-
console.log(chalk5.green(`[OK] Logged out from ${env}`), chalk5.dim(`(${
|
|
1692
|
+
console.log(chalk5.green(`[OK] Logged out from ${env}`), chalk5.dim(`(${envConfig.displayName})`));
|
|
1568
1693
|
console.log("");
|
|
1569
1694
|
} catch {
|
|
1570
1695
|
console.log("");
|
|
1571
|
-
console.log(chalk5.yellow(`\u25CB Already logged out from ${env}`), chalk5.dim(`(${
|
|
1696
|
+
console.log(chalk5.yellow(`\u25CB Already logged out from ${env}`), chalk5.dim(`(${envConfig.displayName})`));
|
|
1572
1697
|
console.log("");
|
|
1573
1698
|
}
|
|
1574
1699
|
});
|
|
1575
1700
|
authCommands.command("refresh").description("Manually refresh access token").action(async () => {
|
|
1576
1701
|
const env = getCurrentEnvironment();
|
|
1702
|
+
const allEnvs = getAllEnvironments();
|
|
1703
|
+
const envConfig = allEnvs[env];
|
|
1577
1704
|
const config = getOceanetConfig();
|
|
1578
1705
|
try {
|
|
1579
1706
|
const accessToken = await getAccessToken();
|
|
@@ -1614,14 +1741,14 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
1614
1741
|
const env = getCurrentEnvironment();
|
|
1615
1742
|
const allEnvs = getAllEnvironments();
|
|
1616
1743
|
setCurrentEnvironment(env);
|
|
1617
|
-
const
|
|
1744
|
+
const envConfig = allEnvs[env];
|
|
1618
1745
|
const config = getOceanetConfig();
|
|
1619
1746
|
try {
|
|
1620
1747
|
const accessToken = await getAccessToken();
|
|
1621
1748
|
if (!accessToken) {
|
|
1622
1749
|
console.log(chalk5.yellow(`[ERROR] Not authenticated`));
|
|
1623
1750
|
console.log("");
|
|
1624
|
-
printEnvironmentInfo(env,
|
|
1751
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1625
1752
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
1626
1753
|
console.log("");
|
|
1627
1754
|
return;
|
|
@@ -1633,7 +1760,7 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
1633
1760
|
console.log(chalk5.green("[OK] Authenticated"));
|
|
1634
1761
|
console.log("");
|
|
1635
1762
|
const displayUser = userInfo.firstName ? `${userInfo.firstName} (${userInfo.username})` : userInfo.username || "N/A";
|
|
1636
|
-
printEnvironmentInfo(env,
|
|
1763
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1637
1764
|
console.log(chalk5.dim("User:"), chalk5.cyan(displayUser));
|
|
1638
1765
|
console.log(chalk5.dim("Email:"), chalk5.cyan(userInfo.email || "N/A"));
|
|
1639
1766
|
console.log(chalk5.dim("OrgCode:"), chalk5.cyan(userInfo.ouCode || "N/A"));
|
|
@@ -1645,69 +1772,26 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
1645
1772
|
console.log("");
|
|
1646
1773
|
console.log(chalk5.red("Error:"), chalk5.dim(errorMsg));
|
|
1647
1774
|
console.log("");
|
|
1648
|
-
printEnvironmentInfo(env,
|
|
1775
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1649
1776
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
1650
1777
|
console.log("");
|
|
1651
1778
|
}
|
|
1652
1779
|
} catch (error) {
|
|
1653
1780
|
console.log(chalk5.yellow(`\u2717 Not authenticated`));
|
|
1654
1781
|
console.log("");
|
|
1655
|
-
printEnvironmentInfo(env,
|
|
1782
|
+
printEnvironmentInfo(env, envConfig.displayName);
|
|
1656
1783
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
1657
1784
|
console.log("");
|
|
1658
1785
|
}
|
|
1659
1786
|
});
|
|
1660
1787
|
|
|
1661
|
-
// src/commands/
|
|
1788
|
+
// src/commands/http.ts
|
|
1662
1789
|
init_esm_shims();
|
|
1663
1790
|
import { Command as Command2 } from "commander";
|
|
1664
1791
|
import ora4 from "ora";
|
|
1665
1792
|
import chalk6 from "chalk";
|
|
1666
|
-
var testCommand = new Command2("test").description("Test API request with saved token").action(async () => {
|
|
1667
|
-
try {
|
|
1668
|
-
const accessToken = await getAccessToken();
|
|
1669
|
-
if (!accessToken) {
|
|
1670
|
-
console.log("");
|
|
1671
|
-
console.log(chalk6.red("[ERROR] Not authenticated"));
|
|
1672
|
-
console.log("");
|
|
1673
|
-
console.log(chalk6.dim("Please run: wukong-cli auth login"));
|
|
1674
|
-
console.log("");
|
|
1675
|
-
process.exit(1);
|
|
1676
|
-
}
|
|
1677
|
-
const spinner = ora4("Testing API connection...").start();
|
|
1678
|
-
try {
|
|
1679
|
-
const client = getClient();
|
|
1680
|
-
const userInfo = await client.get("/oceanet-auth/web/userInfo");
|
|
1681
|
-
spinner.succeed("API request successful");
|
|
1682
|
-
console.log("");
|
|
1683
|
-
console.log(chalk6.green("User Info:"));
|
|
1684
|
-
console.log(chalk6.dim(JSON.stringify(userInfo, null, 2)));
|
|
1685
|
-
console.log("");
|
|
1686
|
-
} catch (error) {
|
|
1687
|
-
spinner.fail("API request failed");
|
|
1688
|
-
if (error.message.includes("401") || error.message.includes("expired")) {
|
|
1689
|
-
console.log("");
|
|
1690
|
-
console.log(chalk6.yellow("Token expired or invalid"));
|
|
1691
|
-
console.log(chalk6.dim("Try: wukong-cli auth refresh"));
|
|
1692
|
-
console.log("");
|
|
1693
|
-
} else {
|
|
1694
|
-
throw error;
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
} catch (error) {
|
|
1698
|
-
console.log("");
|
|
1699
|
-
console.log(chalk6.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1700
|
-
console.log("");
|
|
1701
|
-
process.exit(1);
|
|
1702
|
-
}
|
|
1703
|
-
});
|
|
1704
|
-
|
|
1705
|
-
// src/commands/http.ts
|
|
1706
|
-
init_esm_shims();
|
|
1707
|
-
import { Command as Command3 } from "commander";
|
|
1708
|
-
import ora5 from "ora";
|
|
1709
|
-
import chalk7 from "chalk";
|
|
1710
1793
|
init_oceanet();
|
|
1794
|
+
init_debug();
|
|
1711
1795
|
function fixGitBashPath(url) {
|
|
1712
1796
|
if (url.includes(":") && !url.startsWith("http")) {
|
|
1713
1797
|
const oceanetIndex = url.indexOf("/oceanet-");
|
|
@@ -1734,16 +1818,17 @@ function buildUrl2(url, baseUrl) {
|
|
|
1734
1818
|
if (cleanUrl.startsWith("http")) {
|
|
1735
1819
|
return cleanUrl;
|
|
1736
1820
|
}
|
|
1737
|
-
const
|
|
1821
|
+
const config = OCEANET_CONFIG();
|
|
1822
|
+
const base = baseUrl || config.API_BASE_URL;
|
|
1738
1823
|
return `${base}${cleanUrl}`;
|
|
1739
1824
|
}
|
|
1740
1825
|
async function executeRequest(method, url, options) {
|
|
1741
|
-
const spinner =
|
|
1826
|
+
const spinner = ora4("Sending request...").start();
|
|
1742
1827
|
try {
|
|
1743
1828
|
const accessToken = await getAccessToken();
|
|
1744
1829
|
if (!accessToken) {
|
|
1745
1830
|
spinner.fail("Not authenticated");
|
|
1746
|
-
console.error(
|
|
1831
|
+
console.error(chalk6.red("Please run: wukong-cli auth login"));
|
|
1747
1832
|
process.exit(1);
|
|
1748
1833
|
}
|
|
1749
1834
|
const fullUrl = buildUrl2(url, options.baseUrl);
|
|
@@ -1760,29 +1845,33 @@ async function executeRequest(method, url, options) {
|
|
|
1760
1845
|
headers["Content-Type"] = "application/json";
|
|
1761
1846
|
}
|
|
1762
1847
|
}
|
|
1763
|
-
spinner.text = `${method} ${
|
|
1848
|
+
spinner.text = `${method} ${chalk6.cyan(fullUrl)}`;
|
|
1849
|
+
debugRequest(method, fullUrl, headers, options.data ? JSON.parse(options.data) : void 0);
|
|
1850
|
+
const startTime = Date.now();
|
|
1764
1851
|
const response = await fetch(fullUrl, {
|
|
1765
1852
|
method,
|
|
1766
1853
|
headers,
|
|
1767
1854
|
body: method !== "GET" && method !== "DELETE" ? body : void 0
|
|
1768
1855
|
});
|
|
1856
|
+
const duration = Date.now() - startTime;
|
|
1769
1857
|
const data = await response.json();
|
|
1858
|
+
debugResponse(response.status, response.statusText, data, duration);
|
|
1770
1859
|
spinner.succeed("Response received");
|
|
1771
1860
|
console.log("");
|
|
1772
|
-
console.log(
|
|
1861
|
+
console.log(chalk6.dim("Status:"), response.status, response.statusText);
|
|
1773
1862
|
console.log("");
|
|
1774
|
-
console.log(
|
|
1863
|
+
console.log(chalk6.dim("Response:"));
|
|
1775
1864
|
console.log(JSON.stringify(data, null, 2));
|
|
1776
1865
|
} catch (error) {
|
|
1777
1866
|
spinner.fail("Request failed");
|
|
1778
1867
|
if (error instanceof Error) {
|
|
1779
|
-
console.error(
|
|
1868
|
+
console.error(chalk6.red(error.message));
|
|
1780
1869
|
}
|
|
1781
1870
|
process.exit(1);
|
|
1782
1871
|
}
|
|
1783
1872
|
}
|
|
1784
|
-
var httpCommand = new
|
|
1785
|
-
httpCommand.command("get <url>").description("Send GET request (uses
|
|
1873
|
+
var httpCommand = new Command2("http");
|
|
1874
|
+
httpCommand.command("get <url>").description("Send GET request (uses configured base URL or override with -b)").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).action(async (url, options) => {
|
|
1786
1875
|
await executeRequest("GET", url, options);
|
|
1787
1876
|
});
|
|
1788
1877
|
httpCommand.command("post <url>").description("Send POST request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").action(async (url, options) => {
|
|
@@ -1795,9 +1884,64 @@ httpCommand.command("delete <url>").description("Send DELETE request").option("-
|
|
|
1795
1884
|
await executeRequest("DELETE", url, options);
|
|
1796
1885
|
});
|
|
1797
1886
|
|
|
1887
|
+
// src/commands/init.ts
|
|
1888
|
+
init_esm_shims();
|
|
1889
|
+
import { Command as Command3 } from "commander";
|
|
1890
|
+
import { writeFileSync as writeFileSync3, existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
1891
|
+
import { join as join3, dirname as dirname3 } from "path";
|
|
1892
|
+
import { homedir as homedir3 } from "os";
|
|
1893
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1894
|
+
import chalk7 from "chalk";
|
|
1895
|
+
function getProjectRoot2() {
|
|
1896
|
+
let currentDir = dirname3(fileURLToPath3(import.meta.url));
|
|
1897
|
+
while (currentDir !== dirname3(currentDir)) {
|
|
1898
|
+
if (existsSync3(join3(currentDir, "package.json"))) {
|
|
1899
|
+
return currentDir;
|
|
1900
|
+
}
|
|
1901
|
+
currentDir = dirname3(currentDir);
|
|
1902
|
+
}
|
|
1903
|
+
return process.cwd();
|
|
1904
|
+
}
|
|
1905
|
+
async function executeInit() {
|
|
1906
|
+
const configPath = join3(homedir3(), "wukong-cli.json");
|
|
1907
|
+
const templatePath = join3(getProjectRoot2(), "wukong-cli.json.template");
|
|
1908
|
+
if (!existsSync3(templatePath)) {
|
|
1909
|
+
console.error(chalk7.red("\u274C Template configuration file not found"));
|
|
1910
|
+
console.error(chalk7.yellow(`Expected location: ${templatePath}`));
|
|
1911
|
+
process.exit(1);
|
|
1912
|
+
}
|
|
1913
|
+
try {
|
|
1914
|
+
const templateContent = readFileSync3(templatePath, "utf-8");
|
|
1915
|
+
const configExists = existsSync3(configPath);
|
|
1916
|
+
if (configExists) {
|
|
1917
|
+
console.log(chalk7.yellow("\u26A0\uFE0F Existing configuration file will be overwritten"));
|
|
1918
|
+
}
|
|
1919
|
+
writeFileSync3(configPath, templateContent, "utf-8");
|
|
1920
|
+
console.log(chalk7.green("\u2705 Configuration file created successfully"));
|
|
1921
|
+
console.log(chalk7.gray(`Location: ${configPath}`));
|
|
1922
|
+
if (configExists) {
|
|
1923
|
+
console.log(chalk7.yellow("Previous configuration has been overwritten"));
|
|
1924
|
+
}
|
|
1925
|
+
try {
|
|
1926
|
+
const config = JSON.parse(templateContent);
|
|
1927
|
+
console.log(chalk7.gray("\nConfiguration preview:"));
|
|
1928
|
+
console.log(chalk7.gray(` Default Environment: ${config.defaultEnv}`));
|
|
1929
|
+
console.log(chalk7.gray(` Configured Environments: ${Object.keys(config.environments).join(", ")}`));
|
|
1930
|
+
} catch (parseError) {
|
|
1931
|
+
}
|
|
1932
|
+
} catch (error) {
|
|
1933
|
+
console.error(chalk7.red("\u274C Failed to create configuration file"));
|
|
1934
|
+
console.error(chalk7.yellow(`Error: ${error}`));
|
|
1935
|
+
process.exit(1);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
var initCommand = new Command3("init").description("Initialize configuration file (creates or overwrites ~/wukong-cli.json)").action(async () => {
|
|
1939
|
+
await executeInit();
|
|
1940
|
+
});
|
|
1941
|
+
|
|
1798
1942
|
// src/cli.ts
|
|
1799
1943
|
var program = new Command4();
|
|
1800
|
-
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.1.
|
|
1944
|
+
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.1.8").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
|
|
1801
1945
|
const options = thisCommand.opts();
|
|
1802
1946
|
if (options.debug === true) {
|
|
1803
1947
|
setDebugMode(true, true);
|
|
@@ -1806,10 +1950,12 @@ program.name("wukong-cli").description("Wukong CLI - TypeScript implementation")
|
|
|
1806
1950
|
}
|
|
1807
1951
|
});
|
|
1808
1952
|
program.addCommand(authCommands);
|
|
1809
|
-
program.addCommand(testCommand);
|
|
1810
1953
|
program.addCommand(httpCommand);
|
|
1954
|
+
program.addCommand(initCommand);
|
|
1811
1955
|
if (process.argv.length === 2) {
|
|
1812
1956
|
program.help();
|
|
1813
1957
|
}
|
|
1958
|
+
checkAndUpdate().catch(() => {
|
|
1959
|
+
});
|
|
1814
1960
|
program.parse();
|
|
1815
1961
|
//# sourceMappingURL=cli.js.map
|