@zrhsh/wukong-cli 0.4.24 → 0.4.25
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 +13 -5
- package/dist/cli.js +532 -234
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -201,7 +201,7 @@ var init_environments = __esm({
|
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
// src/config/config-loader.ts
|
|
204
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync, mkdirSync as mkdirSync2 } from "fs";
|
|
204
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync, existsSync, mkdirSync as mkdirSync2 } from "fs";
|
|
205
205
|
import { join as join2, dirname as dirname2 } from "path";
|
|
206
206
|
import { homedir as homedir2 } from "os";
|
|
207
207
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -228,7 +228,7 @@ function createDefaultConfig() {
|
|
|
228
228
|
const defaultConfig = JSON.parse(templateContent);
|
|
229
229
|
ensureConfigDir();
|
|
230
230
|
writeFileSync2(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
|
|
231
|
-
} catch (
|
|
231
|
+
} catch (error2) {
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
function getProjectRoot() {
|
|
@@ -258,8 +258,8 @@ function loadConfig() {
|
|
|
258
258
|
const content = readFileSync2(configPath, "utf-8");
|
|
259
259
|
const config = JSON.parse(content);
|
|
260
260
|
return config;
|
|
261
|
-
} catch (
|
|
262
|
-
console.warn(`Warning: Failed to load config from ${configPath}: ${
|
|
261
|
+
} catch (error2) {
|
|
262
|
+
console.warn(`Warning: Failed to load config from ${configPath}: ${error2}`);
|
|
263
263
|
return {};
|
|
264
264
|
}
|
|
265
265
|
}
|
|
@@ -325,6 +325,24 @@ function getDefaultEnvironment() {
|
|
|
325
325
|
}
|
|
326
326
|
return DEFAULT_ENVIRONMENT;
|
|
327
327
|
}
|
|
328
|
+
function resolveEnvironment() {
|
|
329
|
+
const envFromVar = process.env.WUKONG_CLI_ENV;
|
|
330
|
+
if (envFromVar && isValidEnvironment(envFromVar)) {
|
|
331
|
+
return { env: envFromVar, source: "env-var" };
|
|
332
|
+
}
|
|
333
|
+
const config = loadConfig();
|
|
334
|
+
if (config.defaultEnv && isValidEnvironment(config.defaultEnv)) {
|
|
335
|
+
return { env: config.defaultEnv, source: "config" };
|
|
336
|
+
}
|
|
337
|
+
return { env: DEFAULT_ENVIRONMENT, source: "default" };
|
|
338
|
+
}
|
|
339
|
+
function saveUserConfig(config) {
|
|
340
|
+
ensureConfigDir();
|
|
341
|
+
const configPath = getUserConfigPath();
|
|
342
|
+
const tempPath = `${configPath}.${process.pid}.tmp`;
|
|
343
|
+
writeFileSync2(tempPath, JSON.stringify(config, null, 2), "utf-8");
|
|
344
|
+
renameSync(tempPath, configPath);
|
|
345
|
+
}
|
|
328
346
|
var CONFIG_DIR, CONFIG_FILE_PATH;
|
|
329
347
|
var init_config_loader = __esm({
|
|
330
348
|
"src/config/config-loader.ts"() {
|
|
@@ -581,7 +599,7 @@ var init_keytar_adapter = __esm({
|
|
|
581
599
|
keytarModule = null;
|
|
582
600
|
try {
|
|
583
601
|
keytarModule = require2("keytar");
|
|
584
|
-
} catch (
|
|
602
|
+
} catch (error2) {
|
|
585
603
|
keytarModule = null;
|
|
586
604
|
}
|
|
587
605
|
}
|
|
@@ -915,7 +933,7 @@ var VersionChecker = class {
|
|
|
915
933
|
if (result.hasUpdate && notifier && result.latestVersion) {
|
|
916
934
|
notifier.notify(result.currentVersion, result.latestVersion);
|
|
917
935
|
}
|
|
918
|
-
} catch (
|
|
936
|
+
} catch (error2) {
|
|
919
937
|
}
|
|
920
938
|
}
|
|
921
939
|
/**
|
|
@@ -960,7 +978,7 @@ var NpmVersionProvider = class {
|
|
|
960
978
|
}
|
|
961
979
|
const data = await response.json();
|
|
962
980
|
return data["dist-tags"]?.latest || null;
|
|
963
|
-
} catch (
|
|
981
|
+
} catch (error2) {
|
|
964
982
|
return null;
|
|
965
983
|
}
|
|
966
984
|
}
|
|
@@ -1089,9 +1107,9 @@ var CliDeviceFlowAdapter = class {
|
|
|
1089
1107
|
const result = await this.deviceFlow.getDeviceCode();
|
|
1090
1108
|
this.ui.onSuccess("Device code obtained");
|
|
1091
1109
|
return result;
|
|
1092
|
-
} catch (
|
|
1110
|
+
} catch (error2) {
|
|
1093
1111
|
this.ui.onError("Failed to get device code");
|
|
1094
|
-
throw
|
|
1112
|
+
throw error2;
|
|
1095
1113
|
}
|
|
1096
1114
|
}
|
|
1097
1115
|
/**
|
|
@@ -1103,9 +1121,9 @@ var CliDeviceFlowAdapter = class {
|
|
|
1103
1121
|
const result = await this.deviceFlow.pollToken(deviceCode);
|
|
1104
1122
|
this.ui.onSuccess("Authorization successful!");
|
|
1105
1123
|
return result;
|
|
1106
|
-
} catch (
|
|
1124
|
+
} catch (error2) {
|
|
1107
1125
|
this.ui.onError("Authorization error");
|
|
1108
|
-
throw
|
|
1126
|
+
throw error2;
|
|
1109
1127
|
}
|
|
1110
1128
|
}
|
|
1111
1129
|
};
|
|
@@ -1228,9 +1246,9 @@ var TokenManager = class {
|
|
|
1228
1246
|
...yst_access_token ? { ystAccessToken: yst_access_token } : {},
|
|
1229
1247
|
...yst_new_refresh_token ? { ystRefreshToken: yst_new_refresh_token } : {}
|
|
1230
1248
|
};
|
|
1231
|
-
} catch (
|
|
1249
|
+
} catch (error2) {
|
|
1232
1250
|
spinner.fail("Token refresh error");
|
|
1233
|
-
throw
|
|
1251
|
+
throw error2;
|
|
1234
1252
|
}
|
|
1235
1253
|
}
|
|
1236
1254
|
async refreshYstAccessToken(ystRefreshToken) {
|
|
@@ -1262,9 +1280,9 @@ var TokenManager = class {
|
|
|
1262
1280
|
ystAccessToken: access_token,
|
|
1263
1281
|
ystRefreshToken: refresh_token
|
|
1264
1282
|
};
|
|
1265
|
-
} catch (
|
|
1283
|
+
} catch (error2) {
|
|
1266
1284
|
spinner.fail("YST token refresh error");
|
|
1267
|
-
throw
|
|
1285
|
+
throw error2;
|
|
1268
1286
|
}
|
|
1269
1287
|
}
|
|
1270
1288
|
async clearTokens() {
|
|
@@ -1304,7 +1322,7 @@ var TokenManager = class {
|
|
|
1304
1322
|
} catch {
|
|
1305
1323
|
}
|
|
1306
1324
|
debugResponse(response.status, response.statusText, data || "No response body", duration);
|
|
1307
|
-
} catch (
|
|
1325
|
+
} catch (error2) {
|
|
1308
1326
|
}
|
|
1309
1327
|
await this.clearTokens();
|
|
1310
1328
|
}
|
|
@@ -1371,104 +1389,46 @@ init_esm_shims();
|
|
|
1371
1389
|
init_debug();
|
|
1372
1390
|
init_oceanet();
|
|
1373
1391
|
import axios from "axios";
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1392
|
+
|
|
1393
|
+
// src/core/http/api-error-handler.ts
|
|
1394
|
+
init_esm_shims();
|
|
1395
|
+
|
|
1396
|
+
// src/core/http/response-envelope.ts
|
|
1397
|
+
init_esm_shims();
|
|
1398
|
+
function isPlainObject(value) {
|
|
1399
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1382
1400
|
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
httpClientInstance = createHttpClient();
|
|
1401
|
+
function isEnveloped(body) {
|
|
1402
|
+
if (!isPlainObject(body)) {
|
|
1403
|
+
return false;
|
|
1387
1404
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
function buildUrl(endpoint, options = {}) {
|
|
1391
|
-
const { baseUrl, params } = options;
|
|
1392
|
-
if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
|
|
1393
|
-
let url2 = endpoint;
|
|
1394
|
-
if (params) {
|
|
1395
|
-
const searchParams = new URLSearchParams(params);
|
|
1396
|
-
const separator = url2.includes("?") ? "&" : "?";
|
|
1397
|
-
url2 += `${separator}${searchParams.toString()}`;
|
|
1398
|
-
}
|
|
1399
|
-
return url2;
|
|
1400
|
-
}
|
|
1401
|
-
const config = getOceanetConfig();
|
|
1402
|
-
const base = baseUrl || config.API_BASE_URL;
|
|
1403
|
-
let url = `${base}${endpoint}`;
|
|
1404
|
-
if (params) {
|
|
1405
|
-
const searchParams = new URLSearchParams(params);
|
|
1406
|
-
url += `?${searchParams.toString()}`;
|
|
1405
|
+
if (typeof body.code === "number") {
|
|
1406
|
+
return true;
|
|
1407
1407
|
}
|
|
1408
|
-
return
|
|
1408
|
+
return body.success === false;
|
|
1409
1409
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
method = "GET",
|
|
1414
|
-
headers = {},
|
|
1415
|
-
body,
|
|
1416
|
-
params,
|
|
1417
|
-
baseUrl
|
|
1418
|
-
} = options;
|
|
1419
|
-
const url = buildUrl(endpoint, { baseUrl, params });
|
|
1420
|
-
const requestHeaders = {
|
|
1421
|
-
...headers,
|
|
1422
|
-
"Content-Type": "application/json"
|
|
1423
|
-
};
|
|
1424
|
-
debugRequest(method, url, requestHeaders, body);
|
|
1425
|
-
const startTime = Date.now();
|
|
1426
|
-
const response = await getHttpClient().request({
|
|
1427
|
-
url,
|
|
1428
|
-
method: method.toLowerCase(),
|
|
1429
|
-
headers: requestHeaders,
|
|
1430
|
-
data: body ?? void 0,
|
|
1431
|
-
timeout: 3e4
|
|
1432
|
-
});
|
|
1433
|
-
const duration = Date.now() - startTime;
|
|
1434
|
-
const data = response.data;
|
|
1435
|
-
debugResponse(response.status, response.statusText, data, duration);
|
|
1436
|
-
return data;
|
|
1437
|
-
}
|
|
1438
|
-
async get(endpoint, params) {
|
|
1439
|
-
return this.request(endpoint, { method: "GET", params });
|
|
1440
|
-
}
|
|
1441
|
-
async post(endpoint, data, headers) {
|
|
1442
|
-
return this.request(endpoint, {
|
|
1443
|
-
method: "POST",
|
|
1444
|
-
body: data,
|
|
1445
|
-
headers
|
|
1446
|
-
});
|
|
1410
|
+
function unwrapResponse(body) {
|
|
1411
|
+
if (!isEnveloped(body)) {
|
|
1412
|
+
return body;
|
|
1447
1413
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
body: data,
|
|
1452
|
-
headers
|
|
1453
|
-
});
|
|
1414
|
+
const envelope = body;
|
|
1415
|
+
if ("result" in envelope) {
|
|
1416
|
+
return envelope.result;
|
|
1454
1417
|
}
|
|
1455
|
-
|
|
1456
|
-
return
|
|
1418
|
+
if ("data" in envelope) {
|
|
1419
|
+
return envelope.data;
|
|
1457
1420
|
}
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
});
|
|
1421
|
+
return body;
|
|
1422
|
+
}
|
|
1423
|
+
function extractErrorMessage(body, fallback) {
|
|
1424
|
+
if (!isPlainObject(body)) {
|
|
1425
|
+
return fallback;
|
|
1464
1426
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
init_esm_shims();
|
|
1427
|
+
const message = body.msg ?? body.errorMsg ?? body.message;
|
|
1428
|
+
return typeof message === "string" && message ? message : fallback;
|
|
1429
|
+
}
|
|
1469
1430
|
|
|
1470
1431
|
// src/core/http/api-error-handler.ts
|
|
1471
|
-
init_esm_shims();
|
|
1472
1432
|
import chalk4 from "chalk";
|
|
1473
1433
|
var ApiError = class extends Error {
|
|
1474
1434
|
constructor(code, message, retryable = false) {
|
|
@@ -1488,25 +1448,25 @@ var ApiErrorHandler = class {
|
|
|
1488
1448
|
*/
|
|
1489
1449
|
registerDefaultHandlers() {
|
|
1490
1450
|
this.register(9913, (response) => {
|
|
1491
|
-
const
|
|
1451
|
+
const error2 = new ApiError(
|
|
1492
1452
|
response.code,
|
|
1493
|
-
response
|
|
1453
|
+
extractErrorMessage(response, "Token expired or invalid"),
|
|
1494
1454
|
true
|
|
1495
1455
|
// 可重试
|
|
1496
1456
|
);
|
|
1497
|
-
throw
|
|
1457
|
+
throw error2;
|
|
1498
1458
|
});
|
|
1499
1459
|
this.register(9909, (response) => {
|
|
1500
1460
|
throw new ApiError(
|
|
1501
1461
|
response.code,
|
|
1502
|
-
response
|
|
1462
|
+
extractErrorMessage(response, "Access denied"),
|
|
1503
1463
|
false
|
|
1504
1464
|
);
|
|
1505
1465
|
});
|
|
1506
1466
|
this.register(9914, (response) => {
|
|
1507
1467
|
throw new ApiError(
|
|
1508
1468
|
response.code,
|
|
1509
|
-
response
|
|
1469
|
+
extractErrorMessage(response, "Session expired, please login again"),
|
|
1510
1470
|
false
|
|
1511
1471
|
);
|
|
1512
1472
|
});
|
|
@@ -1514,7 +1474,7 @@ var ApiErrorHandler = class {
|
|
|
1514
1474
|
this.register(code, (response) => {
|
|
1515
1475
|
throw new ApiError(
|
|
1516
1476
|
response.code,
|
|
1517
|
-
response
|
|
1477
|
+
extractErrorMessage(response, "Authentication failed"),
|
|
1518
1478
|
code === 401
|
|
1519
1479
|
// 401 可以尝试刷新 token
|
|
1520
1480
|
);
|
|
@@ -1531,20 +1491,26 @@ var ApiErrorHandler = class {
|
|
|
1531
1491
|
}
|
|
1532
1492
|
/**
|
|
1533
1493
|
* 处理 API 响应
|
|
1494
|
+
* 裸响应(无信封、无错误码)不参与错误判定,由调用方原样透传
|
|
1534
1495
|
* @param response API 响应
|
|
1535
|
-
* @throws {ApiError}
|
|
1496
|
+
* @throws {ApiError} 当信封包含错误码时
|
|
1536
1497
|
*/
|
|
1537
1498
|
handle(response) {
|
|
1538
|
-
if (response
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
response.code,
|
|
1545
|
-
response.msg || response.errorMsg || response.message || "Unknown API error"
|
|
1546
|
-
);
|
|
1499
|
+
if (!isEnveloped(response)) {
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
const envelope = response;
|
|
1503
|
+
if (envelope.code === 200) {
|
|
1504
|
+
return;
|
|
1547
1505
|
}
|
|
1506
|
+
const handler = this.errorHandlers.get(envelope.code);
|
|
1507
|
+
if (handler) {
|
|
1508
|
+
handler(envelope);
|
|
1509
|
+
}
|
|
1510
|
+
throw new ApiError(
|
|
1511
|
+
envelope.code,
|
|
1512
|
+
extractErrorMessage(envelope, "Unknown API error")
|
|
1513
|
+
);
|
|
1548
1514
|
}
|
|
1549
1515
|
/**
|
|
1550
1516
|
* 检查响应是否为错误
|
|
@@ -1552,7 +1518,7 @@ var ApiErrorHandler = class {
|
|
|
1552
1518
|
* @returns 是否为错误
|
|
1553
1519
|
*/
|
|
1554
1520
|
isError(response) {
|
|
1555
|
-
return response.code !== 200;
|
|
1521
|
+
return isEnveloped(response) && response.code !== 200;
|
|
1556
1522
|
}
|
|
1557
1523
|
/**
|
|
1558
1524
|
* 尝试从错误中恢复
|
|
@@ -1560,8 +1526,8 @@ var ApiErrorHandler = class {
|
|
|
1560
1526
|
* @param recoverFunction 恢复函数
|
|
1561
1527
|
* @returns 恢复结果或抛出错误
|
|
1562
1528
|
*/
|
|
1563
|
-
async tryRecover(
|
|
1564
|
-
if (
|
|
1529
|
+
async tryRecover(error2, recoverFunction) {
|
|
1530
|
+
if (error2 instanceof ApiError && error2.retryable) {
|
|
1565
1531
|
console.log("");
|
|
1566
1532
|
console.log(chalk4.yellow("\u26A0 Token expired, attempting refresh..."));
|
|
1567
1533
|
try {
|
|
@@ -1570,12 +1536,12 @@ var ApiErrorHandler = class {
|
|
|
1570
1536
|
console.log("");
|
|
1571
1537
|
console.log(chalk4.yellow("\u26A0 Auto-refresh failed:"), chalk4.dim(refreshError.message));
|
|
1572
1538
|
throw new ApiError(
|
|
1573
|
-
|
|
1574
|
-
`${
|
|
1539
|
+
error2.code,
|
|
1540
|
+
`${error2.message} (Auto-refresh failed)`
|
|
1575
1541
|
);
|
|
1576
1542
|
}
|
|
1577
1543
|
}
|
|
1578
|
-
throw
|
|
1544
|
+
throw error2;
|
|
1579
1545
|
}
|
|
1580
1546
|
};
|
|
1581
1547
|
var errorHandlerInstance = null;
|
|
@@ -1586,6 +1552,118 @@ function getApiErrorHandler() {
|
|
|
1586
1552
|
return errorHandlerInstance;
|
|
1587
1553
|
}
|
|
1588
1554
|
|
|
1555
|
+
// src/core/http/base-http-client.ts
|
|
1556
|
+
function createHttpClient() {
|
|
1557
|
+
return axios.create({
|
|
1558
|
+
timeout: 3e4,
|
|
1559
|
+
validateStatus: () => true,
|
|
1560
|
+
headers: {
|
|
1561
|
+
"Accept": "application/json"
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
var httpClientInstance = null;
|
|
1566
|
+
function getHttpClient() {
|
|
1567
|
+
if (!httpClientInstance) {
|
|
1568
|
+
httpClientInstance = createHttpClient();
|
|
1569
|
+
}
|
|
1570
|
+
return httpClientInstance;
|
|
1571
|
+
}
|
|
1572
|
+
function buildUrl(endpoint, options = {}) {
|
|
1573
|
+
const { baseUrl, params } = options;
|
|
1574
|
+
if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
|
|
1575
|
+
let url2 = endpoint;
|
|
1576
|
+
if (params) {
|
|
1577
|
+
const searchParams = new URLSearchParams(params);
|
|
1578
|
+
const separator = url2.includes("?") ? "&" : "?";
|
|
1579
|
+
url2 += `${separator}${searchParams.toString()}`;
|
|
1580
|
+
}
|
|
1581
|
+
return url2;
|
|
1582
|
+
}
|
|
1583
|
+
const config = getOceanetConfig();
|
|
1584
|
+
const base = baseUrl || config.API_BASE_URL;
|
|
1585
|
+
let url = `${base}${endpoint}`;
|
|
1586
|
+
if (params) {
|
|
1587
|
+
const searchParams = new URLSearchParams(params);
|
|
1588
|
+
url += `?${searchParams.toString()}`;
|
|
1589
|
+
}
|
|
1590
|
+
return url;
|
|
1591
|
+
}
|
|
1592
|
+
function describeBody(data) {
|
|
1593
|
+
if (data === void 0 || data === null || data === "") {
|
|
1594
|
+
return "";
|
|
1595
|
+
}
|
|
1596
|
+
const text = typeof data === "string" ? data : JSON.stringify(data);
|
|
1597
|
+
const compact = text.replace(/\s+/g, " ").trim();
|
|
1598
|
+
return compact.length > 160 ? `${compact.substring(0, 160)}...` : compact;
|
|
1599
|
+
}
|
|
1600
|
+
var BaseHttpClient = class {
|
|
1601
|
+
async request(endpoint, options = {}) {
|
|
1602
|
+
const {
|
|
1603
|
+
method = "GET",
|
|
1604
|
+
headers = {},
|
|
1605
|
+
body,
|
|
1606
|
+
params,
|
|
1607
|
+
baseUrl
|
|
1608
|
+
} = options;
|
|
1609
|
+
const url = buildUrl(endpoint, { baseUrl, params });
|
|
1610
|
+
const requestHeaders = {
|
|
1611
|
+
...headers,
|
|
1612
|
+
"Content-Type": "application/json"
|
|
1613
|
+
};
|
|
1614
|
+
debugRequest(method, url, requestHeaders, body);
|
|
1615
|
+
const startTime = Date.now();
|
|
1616
|
+
const response = await getHttpClient().request({
|
|
1617
|
+
url,
|
|
1618
|
+
method: method.toLowerCase(),
|
|
1619
|
+
headers: requestHeaders,
|
|
1620
|
+
data: body ?? void 0,
|
|
1621
|
+
timeout: 3e4
|
|
1622
|
+
});
|
|
1623
|
+
const duration = Date.now() - startTime;
|
|
1624
|
+
const data = response.data;
|
|
1625
|
+
debugResponse(response.status, response.statusText, data, duration);
|
|
1626
|
+
if ((response.status < 200 || response.status >= 300) && !isEnveloped(data)) {
|
|
1627
|
+
const detail = describeBody(data);
|
|
1628
|
+
throw new ApiError(
|
|
1629
|
+
response.status,
|
|
1630
|
+
`HTTP ${response.status} ${response.statusText}${detail ? `: ${detail}` : ""}`
|
|
1631
|
+
);
|
|
1632
|
+
}
|
|
1633
|
+
return data;
|
|
1634
|
+
}
|
|
1635
|
+
async get(endpoint, params) {
|
|
1636
|
+
return this.request(endpoint, { method: "GET", params });
|
|
1637
|
+
}
|
|
1638
|
+
async post(endpoint, data, headers) {
|
|
1639
|
+
return this.request(endpoint, {
|
|
1640
|
+
method: "POST",
|
|
1641
|
+
body: data,
|
|
1642
|
+
headers
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
async put(endpoint, data, headers) {
|
|
1646
|
+
return this.request(endpoint, {
|
|
1647
|
+
method: "PUT",
|
|
1648
|
+
body: data,
|
|
1649
|
+
headers
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
async delete(endpoint) {
|
|
1653
|
+
return this.request(endpoint, { method: "DELETE" });
|
|
1654
|
+
}
|
|
1655
|
+
async patch(endpoint, data, headers) {
|
|
1656
|
+
return this.request(endpoint, {
|
|
1657
|
+
method: "PATCH",
|
|
1658
|
+
body: data,
|
|
1659
|
+
headers
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
// src/core/http/authenticating-http-client.ts
|
|
1665
|
+
init_esm_shims();
|
|
1666
|
+
|
|
1589
1667
|
// src/core/http/interceptors.ts
|
|
1590
1668
|
init_esm_shims();
|
|
1591
1669
|
init_oceanet();
|
|
@@ -1619,10 +1697,10 @@ function createRetokenInstance(credentialStore, tokenCache) {
|
|
|
1619
1697
|
console.log("");
|
|
1620
1698
|
}
|
|
1621
1699
|
if (data.code === 401 || data.code === 403) {
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
throw
|
|
1700
|
+
const error2 = new Error(data.message || "Refresh token expired or invalid");
|
|
1701
|
+
error2.code = data.code;
|
|
1702
|
+
error2.isAuthFailure = true;
|
|
1703
|
+
throw error2;
|
|
1626
1704
|
}
|
|
1627
1705
|
const result = data.result || data;
|
|
1628
1706
|
if (!result.access_token && !result.accessToken) {
|
|
@@ -1663,11 +1741,11 @@ function createRetokenInstance(credentialStore, tokenCache) {
|
|
|
1663
1741
|
store.setPassword(cfg.SERVICE_NAME, "refresh_token", refreshToken),
|
|
1664
1742
|
...tokens?.ystAccessToken ? [store.setPassword(cfg.SERVICE_NAME, "yst_access_token", tokens.ystAccessToken)] : [],
|
|
1665
1743
|
...tokens?.ystRefreshToken ? [store.setPassword(cfg.SERVICE_NAME, "yst_refresh_token", tokens.ystRefreshToken)] : []
|
|
1666
|
-
]).catch((
|
|
1744
|
+
]).catch((error2) => {
|
|
1667
1745
|
if (cfg.DEBUG || global.__debugMode) {
|
|
1668
1746
|
console.log("");
|
|
1669
1747
|
console.log("=== Token Persist Failed ===");
|
|
1670
|
-
console.log(
|
|
1748
|
+
console.log(error2?.message || String(error2));
|
|
1671
1749
|
console.log("");
|
|
1672
1750
|
}
|
|
1673
1751
|
});
|
|
@@ -1831,20 +1909,20 @@ var AuthenticatingHttpClient = class {
|
|
|
1831
1909
|
}
|
|
1832
1910
|
try {
|
|
1833
1911
|
return await this.tryRequest(endpoint, options);
|
|
1834
|
-
} catch (
|
|
1912
|
+
} catch (error2) {
|
|
1835
1913
|
if (debug) {
|
|
1836
1914
|
console.log("=== [DIAGNOSTIC] First Request Failed ===");
|
|
1837
|
-
console.log(" Error:",
|
|
1915
|
+
console.log(" Error:", error2 instanceof ApiError ? `ApiError(code=${error2.code})` : String(error2));
|
|
1838
1916
|
console.log("");
|
|
1839
1917
|
}
|
|
1840
|
-
if (
|
|
1918
|
+
if (error2 instanceof ApiError && error2.code === 9913) {
|
|
1841
1919
|
if (debug) {
|
|
1842
1920
|
console.log("=== [DIAGNOSTIC] Reactive Refresh Triggered (9913) ===");
|
|
1843
1921
|
}
|
|
1844
1922
|
await this.refreshTokenAndPersist(retoken);
|
|
1845
1923
|
return await this.tryRequest(endpoint, options);
|
|
1846
1924
|
}
|
|
1847
|
-
throw
|
|
1925
|
+
throw error2;
|
|
1848
1926
|
}
|
|
1849
1927
|
}
|
|
1850
1928
|
/**
|
|
@@ -1858,7 +1936,7 @@ var AuthenticatingHttpClient = class {
|
|
|
1858
1936
|
"Not authenticated. Please run: wukong-cli auth login"
|
|
1859
1937
|
);
|
|
1860
1938
|
}
|
|
1861
|
-
const
|
|
1939
|
+
const body = await this.baseClient.request(
|
|
1862
1940
|
endpoint,
|
|
1863
1941
|
{
|
|
1864
1942
|
...options,
|
|
@@ -1868,12 +1946,12 @@ var AuthenticatingHttpClient = class {
|
|
|
1868
1946
|
}
|
|
1869
1947
|
}
|
|
1870
1948
|
);
|
|
1871
|
-
if (
|
|
1872
|
-
throw new ApiError(
|
|
1949
|
+
if (isEnveloped(body) && body.code === 9913) {
|
|
1950
|
+
throw new ApiError(9913, extractErrorMessage(body, "Token expired"), true);
|
|
1873
1951
|
}
|
|
1874
1952
|
const errorHandler = getApiErrorHandler();
|
|
1875
|
-
errorHandler.handle(
|
|
1876
|
-
return
|
|
1953
|
+
errorHandler.handle(body);
|
|
1954
|
+
return unwrapResponse(body);
|
|
1877
1955
|
}
|
|
1878
1956
|
/**
|
|
1879
1957
|
* GET 请求
|
|
@@ -2082,17 +2160,17 @@ authCommands.command("login").description("Login using Device Authorization Flow
|
|
|
2082
2160
|
console.log("");
|
|
2083
2161
|
console.log(chalk5.dim("Next:"), chalk5.cyan("wukong-cli auth status"));
|
|
2084
2162
|
console.log("");
|
|
2085
|
-
} catch (
|
|
2086
|
-
if (
|
|
2163
|
+
} catch (error2) {
|
|
2164
|
+
if (error2 instanceof ConfigFileError) {
|
|
2087
2165
|
console.log("");
|
|
2088
2166
|
console.log(chalk5.red(`[ERROR] Configuration Error`));
|
|
2089
2167
|
console.log("");
|
|
2090
|
-
console.log(chalk5.red(
|
|
2168
|
+
console.log(chalk5.red(error2.toUserMessage()));
|
|
2091
2169
|
console.log("");
|
|
2092
2170
|
return;
|
|
2093
2171
|
}
|
|
2094
2172
|
console.log("");
|
|
2095
|
-
console.log(chalk5.red(`[ERROR] ${
|
|
2173
|
+
console.log(chalk5.red(`[ERROR] ${error2 instanceof Error ? error2.message : "Unknown error"}`));
|
|
2096
2174
|
console.log("");
|
|
2097
2175
|
}
|
|
2098
2176
|
});
|
|
@@ -2141,21 +2219,21 @@ authCommands.command("refresh").description("Manually refresh access token").act
|
|
|
2141
2219
|
printEnvironmentInfo(env, envConfig.displayName);
|
|
2142
2220
|
console.log(chalk5.dim("New tokens saved securely"));
|
|
2143
2221
|
console.log("");
|
|
2144
|
-
} catch (
|
|
2222
|
+
} catch (error2) {
|
|
2145
2223
|
spinner.fail("Token refresh failed");
|
|
2146
|
-
throw
|
|
2224
|
+
throw error2;
|
|
2147
2225
|
}
|
|
2148
|
-
} catch (
|
|
2149
|
-
if (
|
|
2226
|
+
} catch (error2) {
|
|
2227
|
+
if (error2 instanceof ConfigFileError) {
|
|
2150
2228
|
console.log("");
|
|
2151
2229
|
console.log(chalk5.red(`[ERROR] Configuration Error`));
|
|
2152
2230
|
console.log("");
|
|
2153
|
-
console.log(chalk5.red(
|
|
2231
|
+
console.log(chalk5.red(error2.toUserMessage()));
|
|
2154
2232
|
console.log("");
|
|
2155
2233
|
return;
|
|
2156
2234
|
}
|
|
2157
2235
|
console.log("");
|
|
2158
|
-
console.log(chalk5.red(`[ERROR] ${
|
|
2236
|
+
console.log(chalk5.red(`[ERROR] ${error2 instanceof Error ? error2.message : "Unknown error"}`));
|
|
2159
2237
|
console.log("");
|
|
2160
2238
|
printEnvironmentInfo(env, envConfig.displayName);
|
|
2161
2239
|
console.log(chalk5.dim(`Your session may have expired. Please run:`));
|
|
@@ -2193,8 +2271,8 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2193
2271
|
console.log(chalk5.dim("OrgCode:"), chalk5.cyan(userInfo.ouCode || "N/A"));
|
|
2194
2272
|
console.log(chalk5.dim("OrgName:"), chalk5.cyan(userInfo.ouName || "N/A"));
|
|
2195
2273
|
console.log("");
|
|
2196
|
-
} catch (
|
|
2197
|
-
const errorMsg =
|
|
2274
|
+
} catch (error2) {
|
|
2275
|
+
const errorMsg = error2 instanceof Error ? error2.message : String(error2);
|
|
2198
2276
|
console.log(chalk5.yellow(`[ERROR] Not authenticated`));
|
|
2199
2277
|
console.log("");
|
|
2200
2278
|
console.log(chalk5.red("Error:"), chalk5.dim(errorMsg));
|
|
@@ -2203,11 +2281,11 @@ authCommands.command("status").description("Show authentication status").action(
|
|
|
2203
2281
|
console.log(chalk5.dim(`Run: wukong-cli auth login`));
|
|
2204
2282
|
console.log("");
|
|
2205
2283
|
}
|
|
2206
|
-
} catch (
|
|
2207
|
-
if (
|
|
2284
|
+
} catch (error2) {
|
|
2285
|
+
if (error2 instanceof ConfigFileError) {
|
|
2208
2286
|
console.log(chalk5.red(`[ERROR] Configuration Error`));
|
|
2209
2287
|
console.log("");
|
|
2210
|
-
console.log(chalk5.red(
|
|
2288
|
+
console.log(chalk5.red(error2.toUserMessage()));
|
|
2211
2289
|
console.log("");
|
|
2212
2290
|
return;
|
|
2213
2291
|
}
|
|
@@ -2363,17 +2441,17 @@ authCommands.command("token").description("Display current token structure and J
|
|
|
2363
2441
|
}
|
|
2364
2442
|
console.log("");
|
|
2365
2443
|
}
|
|
2366
|
-
} catch (
|
|
2367
|
-
if (
|
|
2444
|
+
} catch (error2) {
|
|
2445
|
+
if (error2 instanceof ConfigFileError) {
|
|
2368
2446
|
console.log("");
|
|
2369
2447
|
console.log(chalk5.red("[ERROR] Configuration Error"));
|
|
2370
2448
|
console.log("");
|
|
2371
|
-
console.log(chalk5.red(
|
|
2449
|
+
console.log(chalk5.red(error2.toUserMessage()));
|
|
2372
2450
|
console.log("");
|
|
2373
2451
|
return;
|
|
2374
2452
|
}
|
|
2375
2453
|
console.log("");
|
|
2376
|
-
console.log(chalk5.red(`[ERROR] ${
|
|
2454
|
+
console.log(chalk5.red(`[ERROR] ${error2 instanceof Error ? error2.message : "Unknown error"}`));
|
|
2377
2455
|
console.log("");
|
|
2378
2456
|
}
|
|
2379
2457
|
});
|
|
@@ -2475,7 +2553,9 @@ async function executeRequest(method, url, options) {
|
|
|
2475
2553
|
console.error(chalk6.red(`HTTP ${response.status}: ${errText.substring(0, 200)}`));
|
|
2476
2554
|
process.exit(1);
|
|
2477
2555
|
}
|
|
2478
|
-
const
|
|
2556
|
+
const body = await response.json();
|
|
2557
|
+
getApiErrorHandler().handle(body);
|
|
2558
|
+
const data2 = unwrapResponse(body);
|
|
2479
2559
|
spinner.succeed("Response received");
|
|
2480
2560
|
console.log("");
|
|
2481
2561
|
console.log(chalk6.dim("Status:"), `${response.status} ${response.statusText}`);
|
|
@@ -2517,25 +2597,25 @@ async function executeRequest(method, url, options) {
|
|
|
2517
2597
|
console.log("");
|
|
2518
2598
|
console.log(chalk6.dim("Response:"));
|
|
2519
2599
|
console.log(JSON.stringify(data, null, 2));
|
|
2520
|
-
} catch (
|
|
2600
|
+
} catch (error2) {
|
|
2521
2601
|
spinner.fail("Request failed");
|
|
2522
|
-
if (
|
|
2602
|
+
if (error2 instanceof ConfigFileError) {
|
|
2523
2603
|
console.log("");
|
|
2524
2604
|
console.log(chalk6.red(`[ERROR] Configuration Error`));
|
|
2525
2605
|
console.log("");
|
|
2526
|
-
console.log(chalk6.red(
|
|
2606
|
+
console.log(chalk6.red(error2.toUserMessage()));
|
|
2527
2607
|
console.log("");
|
|
2528
2608
|
process.exit(1);
|
|
2529
2609
|
}
|
|
2530
|
-
if (
|
|
2610
|
+
if (error2 instanceof ApiError) {
|
|
2531
2611
|
console.log("");
|
|
2532
|
-
console.log(chalk6.red(`API Error (code: ${
|
|
2533
|
-
console.log(chalk6.red(
|
|
2612
|
+
console.log(chalk6.red(`API Error (code: ${error2.code})`));
|
|
2613
|
+
console.log(chalk6.red(error2.message));
|
|
2534
2614
|
console.log("");
|
|
2535
2615
|
process.exit(1);
|
|
2536
2616
|
}
|
|
2537
|
-
if (
|
|
2538
|
-
console.error(chalk6.red(
|
|
2617
|
+
if (error2 instanceof Error) {
|
|
2618
|
+
console.error(chalk6.red(error2.message));
|
|
2539
2619
|
}
|
|
2540
2620
|
process.exit(1);
|
|
2541
2621
|
}
|
|
@@ -2610,9 +2690,9 @@ async function executeInit() {
|
|
|
2610
2690
|
console.log(chalk7.gray(` Configured Environments: ${Object.keys(config.environments).join(", ")}`));
|
|
2611
2691
|
} catch (parseError) {
|
|
2612
2692
|
}
|
|
2613
|
-
} catch (
|
|
2693
|
+
} catch (error2) {
|
|
2614
2694
|
console.error(chalk7.red("\u274C Failed to create configuration file"));
|
|
2615
|
-
console.error(chalk7.yellow(`Error: ${
|
|
2695
|
+
console.error(chalk7.yellow(`Error: ${error2}`));
|
|
2616
2696
|
process.exit(1);
|
|
2617
2697
|
}
|
|
2618
2698
|
}
|
|
@@ -2623,88 +2703,306 @@ var initCommand = new Command3("init").description("Initialize configuration fil
|
|
|
2623
2703
|
// src/commands/env.ts
|
|
2624
2704
|
init_esm_shims();
|
|
2625
2705
|
init_environments();
|
|
2706
|
+
init_config_loader();
|
|
2626
2707
|
import { Command as Command4 } from "commander";
|
|
2708
|
+
import chalk9 from "chalk";
|
|
2709
|
+
|
|
2710
|
+
// src/utils/prompt/select.ts
|
|
2711
|
+
init_esm_shims();
|
|
2712
|
+
import { createInterface, emitKeypressEvents } from "readline";
|
|
2627
2713
|
import chalk8 from "chalk";
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
function
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2714
|
+
function resolvePromptMode(stdin = process.stdin, stdout = process.stdout) {
|
|
2715
|
+
if (!stdin?.isTTY || !stdout?.isTTY) {
|
|
2716
|
+
return "none";
|
|
2717
|
+
}
|
|
2718
|
+
return typeof stdin.setRawMode === "function" ? "arrow" : "numbered";
|
|
2719
|
+
}
|
|
2720
|
+
function parseSelection(input, options) {
|
|
2721
|
+
const trimmed = input.trim();
|
|
2722
|
+
if (!trimmed) {
|
|
2723
|
+
return -1;
|
|
2724
|
+
}
|
|
2725
|
+
const byNumber = Number(trimmed);
|
|
2726
|
+
if (Number.isInteger(byNumber) && byNumber >= 1 && byNumber <= options.length) {
|
|
2727
|
+
return byNumber - 1;
|
|
2728
|
+
}
|
|
2729
|
+
return options.findIndex((option) => String(option.value) === trimmed);
|
|
2730
|
+
}
|
|
2731
|
+
async function select(config) {
|
|
2732
|
+
if (config.options.length === 0) {
|
|
2640
2733
|
return null;
|
|
2641
2734
|
}
|
|
2735
|
+
const mode = resolvePromptMode();
|
|
2736
|
+
if (mode === "arrow") {
|
|
2737
|
+
return selectByArrow(config);
|
|
2738
|
+
}
|
|
2739
|
+
if (mode === "numbered") {
|
|
2740
|
+
return selectByNumber(config);
|
|
2741
|
+
}
|
|
2742
|
+
return null;
|
|
2642
2743
|
}
|
|
2643
|
-
function
|
|
2644
|
-
|
|
2744
|
+
function clampIndex(index, length) {
|
|
2745
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
2746
|
+
return 0;
|
|
2747
|
+
}
|
|
2748
|
+
return index >= length ? length - 1 : index;
|
|
2645
2749
|
}
|
|
2646
|
-
function
|
|
2750
|
+
function renderRow(label, active) {
|
|
2751
|
+
const pointer = active ? chalk8.cyan("\u276F") : " ";
|
|
2752
|
+
const text = active ? chalk8.cyan.bold(label) : chalk8.dim(label);
|
|
2753
|
+
return `${pointer} ${text}`;
|
|
2754
|
+
}
|
|
2755
|
+
function selectByArrow(config) {
|
|
2647
2756
|
return new Promise((resolve) => {
|
|
2648
|
-
const
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2757
|
+
const { stdin, stdout } = process;
|
|
2758
|
+
const total = config.options.length;
|
|
2759
|
+
let index = clampIndex(config.initialIndex ?? 0, total);
|
|
2760
|
+
let drawn = false;
|
|
2761
|
+
emitKeypressEvents(stdin);
|
|
2762
|
+
stdin.setRawMode(true);
|
|
2763
|
+
stdin.resume();
|
|
2764
|
+
stdout.write("\x1B[?25l");
|
|
2765
|
+
const draw = () => {
|
|
2766
|
+
if (drawn) {
|
|
2767
|
+
stdout.write(`\x1B[${total + 1}A`);
|
|
2768
|
+
}
|
|
2769
|
+
const rows = [config.message, ...config.options.map((option, i) => renderRow(option.label, i === index))];
|
|
2770
|
+
stdout.write(rows.map((row) => `\x1B[2K${row}`).join("\n") + "\n");
|
|
2771
|
+
drawn = true;
|
|
2772
|
+
};
|
|
2773
|
+
const finish = (value) => {
|
|
2774
|
+
stdin.removeListener("keypress", onKeypress);
|
|
2775
|
+
stdin.setRawMode(false);
|
|
2776
|
+
stdin.pause();
|
|
2777
|
+
stdout.write("\x1B[?25h");
|
|
2778
|
+
resolve(value);
|
|
2779
|
+
};
|
|
2780
|
+
const onKeypress = (_str, key) => {
|
|
2781
|
+
if (key.ctrl && key.name === "c") {
|
|
2782
|
+
finish(null);
|
|
2657
2783
|
return;
|
|
2658
2784
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2785
|
+
switch (key.name) {
|
|
2786
|
+
case "up":
|
|
2787
|
+
case "k":
|
|
2788
|
+
index = (index - 1 + total) % total;
|
|
2789
|
+
draw();
|
|
2790
|
+
break;
|
|
2791
|
+
case "down":
|
|
2792
|
+
case "j":
|
|
2793
|
+
index = (index + 1) % total;
|
|
2794
|
+
draw();
|
|
2795
|
+
break;
|
|
2796
|
+
case "return":
|
|
2797
|
+
case "enter":
|
|
2798
|
+
finish(config.options[index].value);
|
|
2799
|
+
break;
|
|
2800
|
+
case "escape":
|
|
2801
|
+
case "q":
|
|
2802
|
+
finish(null);
|
|
2803
|
+
break;
|
|
2804
|
+
default:
|
|
2805
|
+
break;
|
|
2666
2806
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
2807
|
+
};
|
|
2808
|
+
stdin.on("keypress", onKeypress);
|
|
2809
|
+
draw();
|
|
2669
2810
|
});
|
|
2670
2811
|
}
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
console.log(
|
|
2812
|
+
async function selectByNumber(config) {
|
|
2813
|
+
const { options } = config;
|
|
2814
|
+
console.log(config.message);
|
|
2815
|
+
options.forEach((option, i) => {
|
|
2816
|
+
console.log(` ${i + 1}) ${option.label}`);
|
|
2817
|
+
});
|
|
2818
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2819
|
+
try {
|
|
2820
|
+
const answer = await new Promise((resolve) => {
|
|
2821
|
+
rl.question(`Select [1-${options.length}]: `, resolve);
|
|
2822
|
+
});
|
|
2823
|
+
const selected = parseSelection(answer, options);
|
|
2824
|
+
return selected === -1 ? null : options[selected].value;
|
|
2825
|
+
} finally {
|
|
2826
|
+
rl.close();
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
// src/utils/symbols.ts
|
|
2831
|
+
init_esm_shims();
|
|
2832
|
+
var SYMBOLS = {
|
|
2833
|
+
OK: "[OK]",
|
|
2834
|
+
ERROR: "[ERROR]",
|
|
2835
|
+
WARNING: "[WARNING]",
|
|
2836
|
+
INFO: "[INFO]"
|
|
2837
|
+
};
|
|
2838
|
+
function success(message) {
|
|
2839
|
+
return `${SYMBOLS.OK} ${message}`;
|
|
2840
|
+
}
|
|
2841
|
+
function error(message) {
|
|
2842
|
+
return `${SYMBOLS.ERROR} ${message}`;
|
|
2843
|
+
}
|
|
2844
|
+
function warning(message) {
|
|
2845
|
+
return `${SYMBOLS.WARNING} ${message}`;
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
// src/commands/env.ts
|
|
2849
|
+
var ENV_NAMES = Object.keys(ENVIRONMENTS);
|
|
2850
|
+
var SOURCE_LABEL = {
|
|
2851
|
+
"env-var": "WUKONG_CLI_ENV",
|
|
2852
|
+
config: "config file",
|
|
2853
|
+
default: "built-in default"
|
|
2854
|
+
};
|
|
2855
|
+
function describeEnvironment(env) {
|
|
2856
|
+
const config = ENVIRONMENTS[env];
|
|
2857
|
+
return `${config.displayName} (${config.apiBaseUrl})`;
|
|
2858
|
+
}
|
|
2859
|
+
function renderEnvironmentList(current) {
|
|
2860
|
+
for (const name of ENV_NAMES) {
|
|
2861
|
+
const marker = name === current ? chalk9.green(" * ") : " ";
|
|
2862
|
+
const label = name === current ? chalk9.bold(name) : name;
|
|
2863
|
+
console.log(`${marker}${chalk9.cyan(label.padEnd(6))} ${describeEnvironment(name)}`);
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
function buildOptions(current) {
|
|
2867
|
+
return ENV_NAMES.map((name) => ({
|
|
2868
|
+
value: name,
|
|
2869
|
+
label: `${name} - ${describeEnvironment(name)}`
|
|
2870
|
+
}));
|
|
2871
|
+
}
|
|
2872
|
+
function persistEnvironment(name) {
|
|
2873
|
+
const config = loadConfig();
|
|
2874
|
+
saveUserConfig({ ...config, defaultEnv: name });
|
|
2875
|
+
}
|
|
2876
|
+
function reportSwitch(name, previous) {
|
|
2877
|
+
const config = ENVIRONMENTS[name];
|
|
2674
2878
|
console.log("");
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2879
|
+
console.log(success(`Switched to ${chalk9.bold(name)}`));
|
|
2880
|
+
console.log(chalk9.dim(` Environment: ${config.displayName}`));
|
|
2881
|
+
console.log(chalk9.dim(` API Base: ${config.apiBaseUrl}`));
|
|
2882
|
+
console.log(chalk9.dim(` Auth Base: ${config.authBaseUrl}`));
|
|
2883
|
+
console.log(chalk9.dim(` Config: ${getUserConfigPath()}`));
|
|
2884
|
+
if (previous !== name) {
|
|
2885
|
+
console.log(chalk9.dim(` Previous: ${previous}`));
|
|
2886
|
+
}
|
|
2887
|
+
if (process.env.WUKONG_CLI_ENV && process.env.WUKONG_CLI_ENV !== name) {
|
|
2888
|
+
console.log("");
|
|
2889
|
+
console.log(warning(`WUKONG_CLI_ENV=${process.env.WUKONG_CLI_ENV} is set and takes priority`));
|
|
2890
|
+
console.log(chalk9.dim(" Unset it to use the environment saved here."));
|
|
2683
2891
|
}
|
|
2684
2892
|
console.log("");
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
const
|
|
2893
|
+
}
|
|
2894
|
+
async function runInteractiveSwitch() {
|
|
2895
|
+
const { env: current } = resolveEnvironment();
|
|
2896
|
+
console.log("");
|
|
2897
|
+
console.log(chalk9.bgBlue.white.bold(" Environment Switch "));
|
|
2898
|
+
console.log("");
|
|
2899
|
+
if (resolvePromptMode() === "none") {
|
|
2900
|
+
renderEnvironmentList(current);
|
|
2901
|
+
console.log("");
|
|
2902
|
+
console.log(chalk9.dim(`Current: ${chalk9.cyan(current)}`));
|
|
2903
|
+
console.log(chalk9.dim("Interactive selection is unavailable here (stdin is not a terminal)."));
|
|
2904
|
+
console.log(chalk9.dim(`Use: ${chalk9.cyan("wukong-cli env use <name>")} to switch, ${chalk9.cyan("wukong-cli env list")} to list.`));
|
|
2905
|
+
console.log("");
|
|
2906
|
+
return;
|
|
2907
|
+
}
|
|
2908
|
+
const selected = await select({
|
|
2909
|
+
message: "Select an environment:",
|
|
2910
|
+
options: buildOptions(current),
|
|
2911
|
+
initialIndex: ENV_NAMES.indexOf(current)
|
|
2912
|
+
});
|
|
2688
2913
|
if (!selected) {
|
|
2689
2914
|
console.log("");
|
|
2690
|
-
console.log(
|
|
2915
|
+
console.log(chalk9.dim("Cancelled."));
|
|
2691
2916
|
console.log("");
|
|
2692
2917
|
return;
|
|
2693
2918
|
}
|
|
2694
|
-
if (selected ===
|
|
2919
|
+
if (selected === current) {
|
|
2695
2920
|
console.log("");
|
|
2696
|
-
console.log(
|
|
2921
|
+
console.log(chalk9.dim(`Already on ${chalk9.cyan(selected)}`));
|
|
2697
2922
|
console.log("");
|
|
2698
2923
|
return;
|
|
2699
2924
|
}
|
|
2700
|
-
|
|
2701
|
-
|
|
2925
|
+
persistEnvironment(selected);
|
|
2926
|
+
reportSwitch(selected, current);
|
|
2927
|
+
}
|
|
2928
|
+
function runList(json) {
|
|
2929
|
+
const { env: current, source } = resolveEnvironment();
|
|
2930
|
+
if (json) {
|
|
2931
|
+
console.log(
|
|
2932
|
+
JSON.stringify(
|
|
2933
|
+
{
|
|
2934
|
+
current,
|
|
2935
|
+
source,
|
|
2936
|
+
configPath: getUserConfigPath(),
|
|
2937
|
+
environments: ENV_NAMES.map((name) => ({ ...ENVIRONMENTS[name], current: name === current }))
|
|
2938
|
+
},
|
|
2939
|
+
null,
|
|
2940
|
+
2
|
|
2941
|
+
)
|
|
2942
|
+
);
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
console.log("");
|
|
2946
|
+
renderEnvironmentList(current);
|
|
2947
|
+
console.log("");
|
|
2948
|
+
console.log(chalk9.dim(`Current: ${chalk9.cyan(current)} (${SOURCE_LABEL[source]})`));
|
|
2949
|
+
console.log(chalk9.dim(`Config: ${getUserConfigPath()}`));
|
|
2950
|
+
console.log("");
|
|
2951
|
+
}
|
|
2952
|
+
function runCurrent(json) {
|
|
2953
|
+
const { env, source } = resolveEnvironment();
|
|
2954
|
+
const config = ENVIRONMENTS[env];
|
|
2955
|
+
if (json) {
|
|
2956
|
+
console.log(
|
|
2957
|
+
JSON.stringify(
|
|
2958
|
+
{
|
|
2959
|
+
environment: env,
|
|
2960
|
+
source,
|
|
2961
|
+
displayName: config.displayName,
|
|
2962
|
+
authBaseUrl: config.authBaseUrl,
|
|
2963
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
2964
|
+
clientId: config.clientId
|
|
2965
|
+
},
|
|
2966
|
+
null,
|
|
2967
|
+
2
|
|
2968
|
+
)
|
|
2969
|
+
);
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2702
2972
|
console.log("");
|
|
2703
|
-
console.log(
|
|
2704
|
-
console.log(
|
|
2705
|
-
console.log(
|
|
2706
|
-
console.log(
|
|
2973
|
+
console.log(`${chalk9.bold(env)} - ${chalk9.dim(config.displayName)}`);
|
|
2974
|
+
console.log(chalk9.dim(` API Base: ${config.apiBaseUrl}`));
|
|
2975
|
+
console.log(chalk9.dim(` Auth Base: ${config.authBaseUrl}`));
|
|
2976
|
+
console.log(chalk9.dim(` Client ID: ${config.clientId}`));
|
|
2977
|
+
console.log(chalk9.dim(` Source: ${SOURCE_LABEL[source]}`));
|
|
2707
2978
|
console.log("");
|
|
2979
|
+
}
|
|
2980
|
+
function runUse(name) {
|
|
2981
|
+
if (!isValidEnvironment(name)) {
|
|
2982
|
+
console.error(error(`Unknown environment: '${name}'`));
|
|
2983
|
+
console.error(chalk9.dim(`Available: ${ENV_NAMES.join(", ")}`));
|
|
2984
|
+
process.exitCode = 1;
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2987
|
+
const { env: previous } = resolveEnvironment();
|
|
2988
|
+
if (previous === name) {
|
|
2989
|
+
console.log(success(`Already on ${chalk9.bold(name)}`));
|
|
2990
|
+
return;
|
|
2991
|
+
}
|
|
2992
|
+
persistEnvironment(name);
|
|
2993
|
+
reportSwitch(name, previous);
|
|
2994
|
+
}
|
|
2995
|
+
var envCommand = new Command4("env").description("View or switch the default environment (dev/beta/uat/prod)").action(async () => {
|
|
2996
|
+
await runInteractiveSwitch();
|
|
2997
|
+
});
|
|
2998
|
+
envCommand.command("list").description("List all environments").option("--json", "Output as JSON").action((options) => {
|
|
2999
|
+
runList(Boolean(options.json));
|
|
3000
|
+
});
|
|
3001
|
+
envCommand.command("current").description("Show the active environment").option("--json", "Output as JSON").action((options) => {
|
|
3002
|
+
runCurrent(Boolean(options.json));
|
|
3003
|
+
});
|
|
3004
|
+
envCommand.command("use").description("Switch environment without prompting").argument("<environment>", `environment name (${ENV_NAMES.join("|")})`).action((name) => {
|
|
3005
|
+
runUse(name);
|
|
2708
3006
|
});
|
|
2709
3007
|
|
|
2710
3008
|
// src/commands/update.ts
|
|
@@ -2756,10 +3054,10 @@ var NpmUpdater = class {
|
|
|
2756
3054
|
child.stderr?.on("data", (data) => {
|
|
2757
3055
|
stderr += data.toString();
|
|
2758
3056
|
});
|
|
2759
|
-
child.on("error", (
|
|
3057
|
+
child.on("error", (error2) => {
|
|
2760
3058
|
reject(
|
|
2761
3059
|
new UpdateExecutionError(
|
|
2762
|
-
`Failed to start npm: ${
|
|
3060
|
+
`Failed to start npm: ${error2.message}`,
|
|
2763
3061
|
null
|
|
2764
3062
|
)
|
|
2765
3063
|
);
|
|
@@ -2811,8 +3109,8 @@ async function runUpdateCommand({
|
|
|
2811
3109
|
output.log(`Updated from ${currentVersion} to ${latestVersion}`);
|
|
2812
3110
|
output.log("Run: wukong-cli --version to verify.");
|
|
2813
3111
|
return 0;
|
|
2814
|
-
} catch (
|
|
2815
|
-
const message =
|
|
3112
|
+
} catch (error2) {
|
|
3113
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
2816
3114
|
output.error("Update failed!");
|
|
2817
3115
|
output.error(message);
|
|
2818
3116
|
output.error("");
|
|
@@ -2822,7 +3120,7 @@ async function runUpdateCommand({
|
|
|
2822
3120
|
}
|
|
2823
3121
|
var updateCommand = new Command5("update").description("Update wukong-cli to the latest npm version").action(async () => {
|
|
2824
3122
|
const exitCode = await runUpdateCommand({
|
|
2825
|
-
currentVersion: "0.4.
|
|
3123
|
+
currentVersion: "0.4.25",
|
|
2826
3124
|
versionProvider: new NpmVersionProvider(
|
|
2827
3125
|
"@zrhsh/wukong-cli",
|
|
2828
3126
|
"https://registry.npmjs.org"
|
|
@@ -2837,7 +3135,7 @@ var updateCommand = new Command5("update").description("Update wukong-cli to the
|
|
|
2837
3135
|
|
|
2838
3136
|
// src/cli.ts
|
|
2839
3137
|
var program = new Command6();
|
|
2840
|
-
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.
|
|
3138
|
+
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.25").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
|
|
2841
3139
|
const options = thisCommand.opts();
|
|
2842
3140
|
if (options.debug === true) {
|
|
2843
3141
|
setDebugMode(true, true);
|
|
@@ -2856,7 +3154,7 @@ if (process.argv.length === 2) {
|
|
|
2856
3154
|
program.parse();
|
|
2857
3155
|
setImmediate(() => {
|
|
2858
3156
|
try {
|
|
2859
|
-
const versionChecker = getVersionChecker("0.4.
|
|
3157
|
+
const versionChecker = getVersionChecker("0.4.25");
|
|
2860
3158
|
const notifier = new ConsoleNotifier();
|
|
2861
3159
|
versionChecker.checkInBackground(notifier).catch(() => {
|
|
2862
3160
|
});
|