@zrhsh/wukong-cli 0.1.4 → 0.1.6

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 CHANGED
@@ -67,30 +67,30 @@ var init_environments = __esm({
67
67
  ENVIRONMENTS = {
68
68
  dev: {
69
69
  name: "dev",
70
- displayName: "\u5F00\u53D1\u73AF\u5883 (Development)",
70
+ displayName: "Development",
71
71
  authBaseUrl: "https://portal-dev.zrhsh.com",
72
72
  apiBaseUrl: "https://nrp-recode-dev.zrhsh.com",
73
73
  clientId: "wukong-cli-dev"
74
74
  },
75
75
  beta: {
76
76
  name: "beta",
77
- displayName: "\u6D4B\u8BD5\u73AF\u5883 (Testing)",
77
+ displayName: "Testing",
78
78
  authBaseUrl: "https://portal-beta.zrhsh.com",
79
79
  apiBaseUrl: "https://nrp-recode.zrhsh.com",
80
80
  clientId: "wukong-cli-beta"
81
81
  },
82
82
  uat: {
83
83
  name: "uat",
84
- displayName: "UAT\u73AF\u5883 (User Acceptance Testing)",
84
+ displayName: "UAT (User Acceptance Testing)",
85
85
  authBaseUrl: "https://portal-uat.zrhsh.com",
86
- apiBaseUrl: "https://nrp-recode-uat.zrhsh.com",
86
+ apiBaseUrl: "https://nrp-pd.zrhsh.com",
87
87
  clientId: "wukong-cli-uat"
88
88
  },
89
89
  prod: {
90
90
  name: "prod",
91
- displayName: "\u751F\u4EA7\u73AF\u5883 (Production)",
91
+ displayName: "Production",
92
92
  authBaseUrl: "https://portal.zrhsh.com",
93
- apiBaseUrl: "https://nrp-recode-prod.zrhsh.com",
93
+ apiBaseUrl: "https://nrp.zrhsh.com",
94
94
  clientId: "wukong-cli-prod"
95
95
  }
96
96
  };
@@ -236,15 +236,15 @@ function getEnvironmentConfig() {
236
236
  return getMergedEnvironmentConfig(getCurrentEnvironment());
237
237
  }
238
238
  function getOceanetConfig() {
239
- const envConfig = getEnvironmentConfig();
239
+ const envConfig2 = getEnvironmentConfig();
240
240
  const env = getCurrentEnvironment();
241
241
  return {
242
242
  // 认证服务基础地址 (设备码授权、登录、登出等)
243
- AUTH_BASE_URL: getEnv("OCEANET_AUTH_BASE_URL", envConfig.authBaseUrl),
243
+ AUTH_BASE_URL: getEnv("OCEANET_AUTH_BASE_URL", envConfig2.authBaseUrl),
244
244
  // 业务 API 基础地址
245
- API_BASE_URL: getEnv("OCEANET_API_BASE_URL", envConfig.apiBaseUrl),
245
+ API_BASE_URL: getEnv("OCEANET_API_BASE_URL", envConfig2.apiBaseUrl),
246
246
  // 客户端 ID
247
- CLIENT_ID: getEnv("OCEANET_CLIENT_ID", envConfig.clientId),
247
+ CLIENT_ID: getEnv("OCEANET_CLIENT_ID", envConfig2.clientId),
248
248
  // Token 存储服务名(不同环境分开存储)
249
249
  SERVICE_NAME: `wukong-cli-${env}`,
250
250
  // 轮询配置
@@ -257,7 +257,7 @@ function getOceanetConfig() {
257
257
  DEBUG: getEnv("WUKONG_CLI_DEBUG", "false") === "true",
258
258
  // 当前环境信息
259
259
  ENVIRONMENT: env,
260
- ENVIRONMENT_DISPLAY: envConfig.displayName
260
+ ENVIRONMENT_DISPLAY: envConfig2.displayName
261
261
  };
262
262
  }
263
263
  var currentEnv, getEnv, OCEANET_CONFIG;
@@ -692,13 +692,29 @@ function debugResponse(status, statusText, body, duration) {
692
692
  // src/commands/auth.ts
693
693
  init_esm_shims();
694
694
  import { Command } from "commander";
695
- import chalk4 from "chalk";
695
+ import chalk5 from "chalk";
696
696
  import ora3 from "ora";
697
697
 
698
+ // src/utils/environment.ts
699
+ init_esm_shims();
700
+ import chalk2 from "chalk";
701
+ function formatEnvironmentDisplay(env, displayName) {
702
+ if (env === "prod") {
703
+ return "";
704
+ }
705
+ return `${env} - ${displayName}`;
706
+ }
707
+ function printEnvironmentInfo(env, displayName) {
708
+ const display = formatEnvironmentDisplay(env, displayName);
709
+ if (display) {
710
+ console.log(chalk2.dim(`Environment: ${chalk2.cyan(display)}`));
711
+ }
712
+ }
713
+
698
714
  // src/core/auth/device-flow.ts
699
715
  init_esm_shims();
700
716
  init_oceanet();
701
- import chalk2 from "chalk";
717
+ import chalk3 from "chalk";
702
718
 
703
719
  // src/adapters/cli-device-flow.ts
704
720
  init_esm_shims();
@@ -762,17 +778,17 @@ async function getDeviceCode() {
762
778
  const adapter = createCliDeviceFlowAdapter();
763
779
  if (config.DEBUG) {
764
780
  console.log("");
765
- console.log(chalk2.dim("=== Debug Info ==="));
766
- console.log(chalk2.dim("Getting device authorization..."));
767
- console.log(chalk2.dim("Client ID:"), chalk2.yellow(config.CLIENT_ID));
781
+ console.log(chalk3.dim("=== Debug Info ==="));
782
+ console.log(chalk3.dim("Getting device authorization..."));
783
+ console.log(chalk3.dim("Client ID:"), chalk3.yellow(config.CLIENT_ID));
768
784
  console.log("");
769
785
  }
770
786
  const result = await adapter.getDeviceCode();
771
787
  if (config.DEBUG) {
772
- console.log(chalk2.dim("=== Response ==="));
773
- console.log(chalk2.dim("Device Code:"), chalk2.yellow(result.deviceCode));
774
- console.log(chalk2.dim("Verification URI:"), chalk2.cyan(result.verificationUri));
775
- console.log(chalk2.dim("Expires In:"), chalk2.yellow(result.expiresIn));
788
+ console.log(chalk3.dim("=== Response ==="));
789
+ console.log(chalk3.dim("Device Code:"), chalk3.yellow(result.deviceCode));
790
+ console.log(chalk3.dim("Verification URI:"), chalk3.cyan(result.verificationUri));
791
+ console.log(chalk3.dim("Expires In:"), chalk3.yellow(result.expiresIn));
776
792
  console.log("");
777
793
  }
778
794
  return result;
@@ -1041,7 +1057,7 @@ init_esm_shims();
1041
1057
 
1042
1058
  // src/core/http/api-error-handler.ts
1043
1059
  init_esm_shims();
1044
- import chalk3 from "chalk";
1060
+ import chalk4 from "chalk";
1045
1061
  var ApiError = class extends Error {
1046
1062
  constructor(code, message, retryable = false) {
1047
1063
  super(message);
@@ -1121,12 +1137,12 @@ var ApiErrorHandler = class {
1121
1137
  async tryRecover(error, recoverFunction) {
1122
1138
  if (error instanceof ApiError && error.retryable) {
1123
1139
  console.log("");
1124
- console.log(chalk3.yellow("\u26A0 Token expired, attempting refresh..."));
1140
+ console.log(chalk4.yellow("\u26A0 Token expired, attempting refresh..."));
1125
1141
  try {
1126
1142
  return await recoverFunction();
1127
1143
  } catch (refreshError) {
1128
1144
  console.log("");
1129
- console.log(chalk3.yellow("\u26A0 Auto-refresh failed:"), chalk3.dim(refreshError.message));
1145
+ console.log(chalk4.yellow("\u26A0 Auto-refresh failed:"), chalk4.dim(refreshError.message));
1130
1146
  throw new ApiError(
1131
1147
  error.code,
1132
1148
  `${error.message} (Auto-refresh failed)`
@@ -1484,56 +1500,56 @@ authCommands.command("login").description("Login using Device Authorization Flow
1484
1500
  const allEnvs = getAllEnvironments();
1485
1501
  setCurrentEnvironment(env);
1486
1502
  const config = getOceanetConfig();
1487
- const envConfig = allEnvs[env];
1503
+ const envConfig2 = allEnvs[env];
1488
1504
  console.log("");
1489
- console.log(chalk4.bgBlue.white.bold(" Wukong CLI Login "));
1505
+ console.log(chalk5.bgBlue.white.bold(" Wukong CLI Login "));
1490
1506
  console.log("");
1491
- console.log(chalk4.dim(`Environment: ${chalk4.cyan(env)} - ${envConfig.displayName}`));
1507
+ printEnvironmentInfo(env, envConfig2.displayName);
1492
1508
  console.log("");
1493
1509
  const { verificationUri, deviceCode, expiresIn, interval } = await getDeviceCode();
1494
1510
  console.log("");
1495
- console.log(chalk4.bold("\u2550".repeat(50)));
1496
- console.log(chalk4.bold(" \u8BF7\u5B8C\u6210\u6388\u6743 / Please complete authorization"));
1497
- console.log(chalk4.bold("\u2550".repeat(50)));
1511
+ console.log(chalk5.bold("=".repeat(50)));
1512
+ console.log(chalk5.bold(" Please complete authorization"));
1513
+ console.log(chalk5.bold("=".repeat(50)));
1498
1514
  console.log("");
1499
- console.log(chalk4.green(" \u6388\u6743\u94FE\u63A5 / Authorization URL:"));
1515
+ console.log(chalk5.green(" Authorization URL:"));
1500
1516
  console.log("");
1501
- console.log(chalk4.cyan(` ${verificationUri}`));
1517
+ console.log(chalk5.cyan(` ${verificationUri}`));
1502
1518
  console.log("");
1503
- console.error(chalk4.yellow.bold(">>> \u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u6B64\u94FE\u63A5\u5B8C\u6210\u6388\u6743 <<<"));
1504
- console.error(chalk4.cyan(verificationUri));
1519
+ console.error(chalk5.yellow.bold(">>> Please open this link in your browser <<<"));
1520
+ console.error(chalk5.cyan(verificationUri));
1505
1521
  console.error("");
1506
1522
  const open = await import("open").catch(() => null);
1507
1523
  if (open) {
1508
1524
  try {
1509
1525
  await open.default(verificationUri);
1510
- console.log(chalk4.dim(" \u6D4F\u89C8\u5668\u5DF2\u81EA\u52A8\u6253\u5F00 / Browser opened automatically"));
1526
+ console.log(chalk5.dim(" Browser opened automatically"));
1511
1527
  } catch {
1512
- console.log(chalk4.dim(" \u8BF7\u624B\u52A8\u590D\u5236\u94FE\u63A5\u5230\u6D4F\u89C8\u5668 / Please copy link to browser"));
1528
+ console.log(chalk5.dim(" Please copy link to browser"));
1513
1529
  }
1514
1530
  } else {
1515
- console.log(chalk4.dim(" \u8BF7\u624B\u52A8\u590D\u5236\u94FE\u63A5\u5230\u6D4F\u89C8\u5668 / Please copy link to browser"));
1531
+ console.log(chalk5.dim(" Please copy link to browser"));
1516
1532
  }
1517
1533
  console.log("");
1518
- console.log(chalk4.dim("\u2550".repeat(50)));
1519
- console.log(chalk4.dim(` Device Code: ${deviceCode}`));
1520
- console.log(chalk4.dim(` Expires in: ${expiresIn} seconds`));
1521
- console.log(chalk4.dim("\u2550".repeat(50)));
1534
+ console.log(chalk5.dim("\u2550".repeat(50)));
1535
+ console.log(chalk5.dim(` Device Code: ${deviceCode}`));
1536
+ console.log(chalk5.dim(` Expires in: ${expiresIn} seconds`));
1537
+ console.log(chalk5.dim("\u2550".repeat(50)));
1522
1538
  console.log("");
1523
1539
  const tokens = await pollToken(deviceCode);
1524
1540
  await saveToken(tokens.accessToken, tokens.refreshToken);
1525
1541
  console.log("");
1526
- console.log(chalk4.bgGreen.black.bold(" \u2713 \u767B\u5F55\u6210\u529F / Login Successful "));
1542
+ console.log(chalk5.bgGreen.black.bold(" [OK] Login Successful "));
1527
1543
  console.log("");
1528
- console.log(chalk4.green("\u2713 Tokens saved securely"));
1529
- console.log(chalk4.dim(`Environment: ${env} - ${envConfig.displayName}`));
1530
- console.log(chalk4.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));
1544
+ console.log(chalk5.green("[OK] Tokens saved securely"));
1545
+ printEnvironmentInfo(env, envConfig2.displayName);
1546
+ console.log(chalk5.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));
1531
1547
  console.log("");
1532
- console.log(chalk4.dim("Next:"), chalk4.cyan("wukong-cli auth status"));
1548
+ console.log(chalk5.dim("Next:"), chalk5.cyan("wukong-cli auth status"));
1533
1549
  console.log("");
1534
1550
  } catch (error) {
1535
1551
  console.log("");
1536
- console.log(chalk4.red(`\u2717 Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1552
+ console.log(chalk5.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1537
1553
  console.log("");
1538
1554
  }
1539
1555
  });
@@ -1541,18 +1557,18 @@ authCommands.command("logout").description("Logout and clear saved tokens").acti
1541
1557
  const env = getCurrentEnvironment();
1542
1558
  const allEnvs = getAllEnvironments();
1543
1559
  setCurrentEnvironment(env);
1544
- const envConfig = allEnvs[env];
1560
+ const envConfig2 = allEnvs[env];
1545
1561
  try {
1546
1562
  const accessToken = await getAccessToken();
1547
1563
  if (accessToken) {
1548
1564
  await logout(accessToken);
1549
1565
  }
1550
1566
  console.log("");
1551
- console.log(chalk4.green(`\u2713 Logged out from ${env}`), chalk4.dim(`(${envConfig.displayName})`));
1567
+ console.log(chalk5.green(`[OK] Logged out from ${env}`), chalk5.dim(`(${envConfig2.displayName})`));
1552
1568
  console.log("");
1553
1569
  } catch {
1554
1570
  console.log("");
1555
- console.log(chalk4.yellow(`\u25CB Already logged out from ${env}`), chalk4.dim(`(${envConfig.displayName})`));
1571
+ console.log(chalk5.yellow(`\u25CB Already logged out from ${env}`), chalk5.dim(`(${envConfig2.displayName})`));
1556
1572
  console.log("");
1557
1573
  }
1558
1574
  });
@@ -1563,10 +1579,10 @@ authCommands.command("refresh").description("Manually refresh access token").act
1563
1579
  const accessToken = await getAccessToken();
1564
1580
  if (!accessToken) {
1565
1581
  console.log("");
1566
- console.log(chalk4.yellow("\u2717 Not authenticated"));
1567
- console.log(chalk4.dim(`Environment: ${env}`));
1582
+ console.log(chalk5.yellow("[ERROR] Not authenticated"));
1583
+ printEnvironmentInfo(env, envConfig.displayName);
1568
1584
  console.log("");
1569
- console.log(chalk4.dim(`Run: wukong-cli auth login`));
1585
+ console.log(chalk5.dim(`Run: wukong-cli auth login`));
1570
1586
  console.log("");
1571
1587
  return;
1572
1588
  }
@@ -1576,8 +1592,8 @@ authCommands.command("refresh").description("Manually refresh access token").act
1576
1592
  await client.refreshToken();
1577
1593
  spinner.succeed("Token refreshed successfully!");
1578
1594
  console.log("");
1579
- console.log(chalk4.dim("Environment:"), chalk4.cyan(env));
1580
- console.log(chalk4.dim("New tokens saved securely"));
1595
+ printEnvironmentInfo(env, envConfig.displayName);
1596
+ console.log(chalk5.dim("New tokens saved securely"));
1581
1597
  console.log("");
1582
1598
  } catch (error) {
1583
1599
  spinner.fail("Token refresh failed");
@@ -1585,11 +1601,11 @@ authCommands.command("refresh").description("Manually refresh access token").act
1585
1601
  }
1586
1602
  } catch (error) {
1587
1603
  console.log("");
1588
- console.log(chalk4.red(`\u2717 Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1604
+ console.log(chalk5.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1589
1605
  console.log("");
1590
- console.log(chalk4.dim(`Environment: ${env}`));
1591
- console.log(chalk4.dim(`Your session may have expired. Please run:`));
1592
- console.log(chalk4.dim(` wukong-cli auth login`));
1606
+ printEnvironmentInfo(env, envConfig.displayName);
1607
+ console.log(chalk5.dim(`Your session may have expired. Please run:`));
1608
+ console.log(chalk5.dim(` wukong-cli auth login`));
1593
1609
  console.log("");
1594
1610
  }
1595
1611
  });
@@ -1598,15 +1614,15 @@ authCommands.command("status").description("Show authentication status").action(
1598
1614
  const env = getCurrentEnvironment();
1599
1615
  const allEnvs = getAllEnvironments();
1600
1616
  setCurrentEnvironment(env);
1601
- const envConfig = allEnvs[env];
1617
+ const envConfig2 = allEnvs[env];
1602
1618
  const config = getOceanetConfig();
1603
1619
  try {
1604
1620
  const accessToken = await getAccessToken();
1605
1621
  if (!accessToken) {
1606
- console.log(chalk4.yellow(`\u2717 Not authenticated`));
1622
+ console.log(chalk5.yellow(`[ERROR] Not authenticated`));
1607
1623
  console.log("");
1608
- console.log(chalk4.dim(`Environment: ${env} - ${envConfig.displayName}`));
1609
- console.log(chalk4.dim(`Run: wukong-cli auth login`));
1624
+ printEnvironmentInfo(env, envConfig2.displayName);
1625
+ console.log(chalk5.dim(`Run: wukong-cli auth login`));
1610
1626
  console.log("");
1611
1627
  return;
1612
1628
  }
@@ -1614,30 +1630,30 @@ authCommands.command("status").description("Show authentication status").action(
1614
1630
  const client = getClient();
1615
1631
  const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;
1616
1632
  const userInfo = await client.get(userInfoUrl);
1617
- console.log(chalk4.green(`\u2713 Authenticated`));
1633
+ console.log(chalk5.green("[OK] Authenticated"));
1618
1634
  console.log("");
1619
1635
  const displayUser = userInfo.firstName ? `${userInfo.firstName} (${userInfo.username})` : userInfo.username || "N/A";
1620
- console.log(chalk4.dim("Environment:"), chalk4.cyan(`${env} - ${envConfig.displayName}`));
1621
- console.log(chalk4.dim("User:"), chalk4.cyan(displayUser));
1622
- console.log(chalk4.dim("Email:"), chalk4.cyan(userInfo.email || "N/A"));
1623
- console.log(chalk4.dim("OrgCode:"), chalk4.cyan(userInfo.ouCode || "N/A"));
1624
- console.log(chalk4.dim("OrgName:"), chalk4.cyan(userInfo.ouName || "N/A"));
1636
+ printEnvironmentInfo(env, envConfig2.displayName);
1637
+ console.log(chalk5.dim("User:"), chalk5.cyan(displayUser));
1638
+ console.log(chalk5.dim("Email:"), chalk5.cyan(userInfo.email || "N/A"));
1639
+ console.log(chalk5.dim("OrgCode:"), chalk5.cyan(userInfo.ouCode || "N/A"));
1640
+ console.log(chalk5.dim("OrgName:"), chalk5.cyan(userInfo.ouName || "N/A"));
1625
1641
  console.log("");
1626
1642
  } catch (error) {
1627
1643
  const errorMsg = error instanceof Error ? error.message : String(error);
1628
- console.log(chalk4.yellow(`\u2717 Not authenticated`));
1644
+ console.log(chalk5.yellow(`[ERROR] Not authenticated`));
1629
1645
  console.log("");
1630
- console.log(chalk4.red("Error:"), chalk4.dim(errorMsg));
1646
+ console.log(chalk5.red("Error:"), chalk5.dim(errorMsg));
1631
1647
  console.log("");
1632
- console.log(chalk4.dim(`Environment: ${env} - ${envConfig.displayName}`));
1633
- console.log(chalk4.dim(`Run: wukong-cli auth login`));
1648
+ printEnvironmentInfo(env, envConfig2.displayName);
1649
+ console.log(chalk5.dim(`Run: wukong-cli auth login`));
1634
1650
  console.log("");
1635
1651
  }
1636
1652
  } catch (error) {
1637
- console.log(chalk4.yellow(`\u2717 Not authenticated`));
1653
+ console.log(chalk5.yellow(`\u2717 Not authenticated`));
1638
1654
  console.log("");
1639
- console.log(chalk4.dim(`Environment: ${env} - ${envConfig.displayName}`));
1640
- console.log(chalk4.dim(`Run: wukong-cli auth login`));
1655
+ printEnvironmentInfo(env, envConfig2.displayName);
1656
+ console.log(chalk5.dim(`Run: wukong-cli auth login`));
1641
1657
  console.log("");
1642
1658
  }
1643
1659
  });
@@ -1646,15 +1662,15 @@ authCommands.command("status").description("Show authentication status").action(
1646
1662
  init_esm_shims();
1647
1663
  import { Command as Command2 } from "commander";
1648
1664
  import ora4 from "ora";
1649
- import chalk5 from "chalk";
1665
+ import chalk6 from "chalk";
1650
1666
  var testCommand = new Command2("test").description("Test API request with saved token").action(async () => {
1651
1667
  try {
1652
1668
  const accessToken = await getAccessToken();
1653
1669
  if (!accessToken) {
1654
1670
  console.log("");
1655
- console.log(chalk5.red("\u2717 Not authenticated"));
1671
+ console.log(chalk6.red("[ERROR] Not authenticated"));
1656
1672
  console.log("");
1657
- console.log(chalk5.dim("Please run: wukong-cli auth login"));
1673
+ console.log(chalk6.dim("Please run: wukong-cli auth login"));
1658
1674
  console.log("");
1659
1675
  process.exit(1);
1660
1676
  }
@@ -1664,15 +1680,15 @@ var testCommand = new Command2("test").description("Test API request with saved
1664
1680
  const userInfo = await client.get("/oceanet-auth/web/userInfo");
1665
1681
  spinner.succeed("API request successful");
1666
1682
  console.log("");
1667
- console.log(chalk5.green("User Info:"));
1668
- console.log(chalk5.dim(JSON.stringify(userInfo, null, 2)));
1683
+ console.log(chalk6.green("User Info:"));
1684
+ console.log(chalk6.dim(JSON.stringify(userInfo, null, 2)));
1669
1685
  console.log("");
1670
1686
  } catch (error) {
1671
1687
  spinner.fail("API request failed");
1672
1688
  if (error.message.includes("401") || error.message.includes("expired")) {
1673
1689
  console.log("");
1674
- console.log(chalk5.yellow("Token expired or invalid"));
1675
- console.log(chalk5.dim("Try: wukong-cli auth refresh"));
1690
+ console.log(chalk6.yellow("Token expired or invalid"));
1691
+ console.log(chalk6.dim("Try: wukong-cli auth refresh"));
1676
1692
  console.log("");
1677
1693
  } else {
1678
1694
  throw error;
@@ -1680,7 +1696,7 @@ var testCommand = new Command2("test").description("Test API request with saved
1680
1696
  }
1681
1697
  } catch (error) {
1682
1698
  console.log("");
1683
- console.log(chalk5.red(`\u2717 Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1699
+ console.log(chalk6.red(`[ERROR] ${error instanceof Error ? error.message : "Unknown error"}`));
1684
1700
  console.log("");
1685
1701
  process.exit(1);
1686
1702
  }
@@ -1690,7 +1706,7 @@ var testCommand = new Command2("test").description("Test API request with saved
1690
1706
  init_esm_shims();
1691
1707
  import { Command as Command3 } from "commander";
1692
1708
  import ora5 from "ora";
1693
- import chalk6 from "chalk";
1709
+ import chalk7 from "chalk";
1694
1710
  init_oceanet();
1695
1711
  function fixGitBashPath(url) {
1696
1712
  if (url.includes(":") && !url.startsWith("http")) {
@@ -1727,7 +1743,7 @@ async function executeRequest(method, url, options) {
1727
1743
  const accessToken = await getAccessToken();
1728
1744
  if (!accessToken) {
1729
1745
  spinner.fail("Not authenticated");
1730
- console.error(chalk6.red("Please run: wukong-cli auth login"));
1746
+ console.error(chalk7.red("Please run: wukong-cli auth login"));
1731
1747
  process.exit(1);
1732
1748
  }
1733
1749
  const fullUrl = buildUrl2(url, options.baseUrl);
@@ -1744,7 +1760,7 @@ async function executeRequest(method, url, options) {
1744
1760
  headers["Content-Type"] = "application/json";
1745
1761
  }
1746
1762
  }
1747
- spinner.text = `${method} ${chalk6.cyan(fullUrl)}`;
1763
+ spinner.text = `${method} ${chalk7.cyan(fullUrl)}`;
1748
1764
  const response = await fetch(fullUrl, {
1749
1765
  method,
1750
1766
  headers,
@@ -1753,14 +1769,14 @@ async function executeRequest(method, url, options) {
1753
1769
  const data = await response.json();
1754
1770
  spinner.succeed("Response received");
1755
1771
  console.log("");
1756
- console.log(chalk6.dim("Status:"), response.status, response.statusText);
1772
+ console.log(chalk7.dim("Status:"), response.status, response.statusText);
1757
1773
  console.log("");
1758
- console.log(chalk6.dim("Response:"));
1774
+ console.log(chalk7.dim("Response:"));
1759
1775
  console.log(JSON.stringify(data, null, 2));
1760
1776
  } catch (error) {
1761
1777
  spinner.fail("Request failed");
1762
1778
  if (error instanceof Error) {
1763
- console.error(chalk6.red(error.message));
1779
+ console.error(chalk7.red(error.message));
1764
1780
  }
1765
1781
  process.exit(1);
1766
1782
  }
@@ -1781,7 +1797,7 @@ httpCommand.command("delete <url>").description("Send DELETE request").option("-
1781
1797
 
1782
1798
  // src/cli.ts
1783
1799
  var program = new Command4();
1784
- program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.1.4").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
1800
+ program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.1.6").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
1785
1801
  const options = thisCommand.opts();
1786
1802
  if (options.debug === true) {
1787
1803
  setDebugMode(true, true);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/constants/config.ts","../src/config/environments.ts","../src/config/config-loader.ts","../src/config/oceanet.ts","../src/core/auth/device-flow-service.ts","../src/adapters/ora-ui-callbacks.ts","../src/core/auth/keytar-adapter.ts","../src/providers/file-credential-store.ts","../src/providers/credential-store.ts","../src/core/auth/token-cache.ts","../src/cli.ts","../src/utils/debug.ts","../src/commands/auth.ts","../src/core/auth/device-flow.ts","../src/adapters/cli-device-flow.ts","../src/adapters/ui-callbacks.ts","../src/core/auth/token-manager.ts","../src/core/http/client.ts","../src/core/http/base-http-client.ts","../src/core/http/authenticating-http-client.ts","../src/core/http/api-error-handler.ts","../src/core/http/interceptors.ts","../src/commands/test.ts","../src/commands/http.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * 配置常量\n * 只包含常量定义,不包含环境配置\n */\n\n/**\n * 配置文件名\n */\nexport const CONFIG_FILE = '.wukong-cli.json';\n\n/**\n * Keytar 服务名\n */\nexport const KEYTAR_SERVICE = 'wukong-cli';\n\n/**\n * Keytar 账户名\n */\nexport const KEYTAR_ACCOUNTS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n} as const;\n\n/**\n * API 端点路径\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\n LOGOUT: '/oceanet-auth/manage/logout',\n },\n API: {\n USER_INFO: '/oceanet-auth/web/userInfo',\n },\n} as const;\n\n/**\n * 轮询配置\n */\nexport const POLL_CONFIG = {\n INTERVAL: 3, // 轮询间隔(秒)\n TIMEOUT: 300, // 轮询超时(秒)\n} as const;\n","/**\n * 多环境配置支持\n * 支持 dev/beta/uat/prod 四套环境\n */\n\nexport type Environment = 'dev' | 'beta' | 'uat' | 'prod';\n\nexport interface EnvironmentConfig {\n name: Environment;\n displayName: string;\n authBaseUrl: string;\n apiBaseUrl: string;\n clientId: string;\n}\n\n/**\n * 环境配置表(默认值)\n * 可通过配置文件或环境变量覆盖\n */\nexport const ENVIRONMENTS: Record<Environment, EnvironmentConfig> = {\n dev: {\n name: 'dev',\n displayName: '开发环境 (Development)',\n authBaseUrl: 'https://portal-dev.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode-dev.zrhsh.com',\n clientId: 'wukong-cli-dev',\n },\n beta: {\n name: 'beta',\n displayName: '测试环境 (Testing)',\n authBaseUrl: 'https://portal-beta.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode.zrhsh.com',\n clientId: 'wukong-cli-beta',\n },\n uat: {\n name: 'uat',\n displayName: 'UAT环境 (User Acceptance Testing)',\n authBaseUrl: 'https://portal-uat.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode-uat.zrhsh.com',\n clientId: 'wukong-cli-uat',\n },\n prod: {\n name: 'prod',\n displayName: '生产环境 (Production)',\n authBaseUrl: 'https://portal.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode-prod.zrhsh.com',\n clientId: 'wukong-cli-prod',\n },\n};\n\n/**\n * 默认环境\n */\nexport const DEFAULT_ENVIRONMENT: Environment = 'prod';\n\n/**\n * 验证环境名称\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env in ENVIRONMENTS;\n}","/**\n * 配置文件加载器\n * 支持从 wukong-cli.json 加载环境配置\n * 首次运行时自动创建默认配置文件\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport { Environment, EnvironmentConfig, ENVIRONMENTS, DEFAULT_ENVIRONMENT, isValidEnvironment } from './environments.js';\n\n/**\n * 用户自定义环境配置\n */\nexport interface CustomEnvironmentConfig {\n authBaseUrl?: string;\n apiBaseUrl?: string;\n clientId?: string;\n}\n\nexport interface WukongCliConfig {\n /** 默认环境 */\n defaultEnv?: Environment;\n /** 环境配置覆盖 */\n environments?: Record<string, CustomEnvironmentConfig>;\n /** 自定义环境(非标准环境) */\n customEnvironments?: Record<string, EnvironmentConfig & { displayName: string }>;\n}\n\nconst CONFIG_FILENAMES = [\n 'wukong-cli.json',\n '.wukong-cli.json',\n '.wukongclirc',\n];\n\n/**\n * 获取用户主目录下的配置文件路径\n */\nexport function getUserConfigPath(): string {\n return join(homedir(), 'wukong-cli.json');\n}\n\n/**\n * 创建默认配置文件\n * 从模板文件读取默认配置\n */\nexport function createDefaultConfig(): void {\n const configPath = getUserConfigPath();\n\n // 如果配置文件已存在,不覆盖\n if (existsSync(configPath)) {\n return;\n }\n\n try {\n // 读取模板文件\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n if (!existsSync(templatePath)) {\n console.warn(`Warning: Template config not found: ${templatePath}`);\n return;\n }\n\n const templateContent = readFileSync(templatePath, 'utf-8');\n const defaultConfig = JSON.parse(templateContent) as WukongCliConfig;\n\n // 确保目录存在\n const dir = dirname(configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // 写入配置文件\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');\n } catch (error) {\n // 静默失败,不影响程序运行\n // console.warn(`Warning: Failed to create default config: ${error}`);\n }\n}\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n // 从当前文件的路径向上查找,直到找到 package.json\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n // 如果找不到,返回当前工作目录\n return process.cwd();\n}\n\n/**\n * 查找配置文件\n * 优先级:当前目录 > 用户主目录\n */\nfunction findConfigFile(): string | null {\n // 1. 当前工作目录\n for (const filename of CONFIG_FILENAMES) {\n const localPath = join(process.cwd(), filename);\n if (existsSync(localPath)) {\n return localPath;\n }\n }\n\n // 2. 用户主目录\n const userConfigPath = getUserConfigPath();\n if (existsSync(userConfigPath)) {\n return userConfigPath;\n }\n\n return null;\n}\n\n/**\n * 加载配置文件\n * 如果用户主目录下没有配置文件,自动创建默认配置\n */\nexport function loadConfig(): WukongCliConfig {\n const configPath = findConfigFile();\n\n if (!configPath) {\n // 首次运行,创建默认配置\n createDefaultConfig();\n return {};\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content) as WukongCliConfig;\n return config;\n } catch (error) {\n console.warn(`Warning: Failed to load config from ${configPath}: ${error}`);\n return {};\n }\n}\n\n/**\n * 获取环境配置(合并配置文件和默认值)\n * 优先级:环境变量 > 配置文件 > 默认值\n */\nexport function getMergedEnvironmentConfig(env: Environment): EnvironmentConfig {\n const config = loadConfig();\n const defaultConfig = ENVIRONMENTS[env] || ENVIRONMENTS[DEFAULT_ENVIRONMENT];\n\n // 环境变量覆盖(最高优先级)\n const envAuthUrl = process.env[`OCEANET_${env.toUpperCase()}_AUTH_URL`];\n const envApiUrl = process.env[`OCEANET_${env.toUpperCase()}_API_URL`];\n const envClientId = process.env[`OCEANET_${env.toUpperCase()}_CLIENT_ID`];\n\n // 配置文件覆盖\n const customConfig = config.environments?.[env] || {};\n\n return {\n name: env,\n displayName: defaultConfig.displayName,\n authBaseUrl: envAuthUrl || customConfig.authBaseUrl || defaultConfig.authBaseUrl,\n apiBaseUrl: envApiUrl || customConfig.apiBaseUrl || defaultConfig.apiBaseUrl,\n clientId: envClientId || customConfig.clientId || defaultConfig.clientId,\n };\n}\n\n/**\n * 获取所有可用环境(包括自定义环境)\n */\nexport function getAllEnvironments(): Record<string, EnvironmentConfig & { displayName: string }> {\n const config = loadConfig();\n const result: Record<string, EnvironmentConfig & { displayName: string }> = { ...ENVIRONMENTS };\n\n // 添加自定义环境\n if (config.customEnvironments) {\n for (const [name, customEnv] of Object.entries(config.customEnvironments)) {\n result[name] = {\n name: name as Environment,\n displayName: customEnv.displayName || name,\n authBaseUrl: customEnv.authBaseUrl,\n apiBaseUrl: customEnv.apiBaseUrl,\n clientId: customEnv.clientId,\n };\n }\n }\n\n return result;\n}\n\n/**\n * 获取默认环境\n */\nexport function getDefaultEnvironment(): Environment {\n // 优先级:环境变量 > 配置文件 > 默认值\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n\n const config = loadConfig();\n if (config.defaultEnv && isValidEnvironment(config.defaultEnv)) {\n return config.defaultEnv;\n }\n\n return DEFAULT_ENVIRONMENT;\n}","/**\n * Oceanet Auth 配置\n * 支持多环境:dev/beta/uat/prod\n * 配置优先级:环境变量 > 配置文件 > 默认值\n */\n\nimport type { Environment, EnvironmentConfig } from '../types/config.js';\nimport {\n API_ENDPOINTS,\n POLL_CONFIG,\n} from '../constants/config.js';\nimport { isValidEnvironment } from './environments.js';\nimport { getMergedEnvironmentConfig, getDefaultEnvironment } from './config-loader.js';\n\n// 当前环境(运行时设置)\nlet currentEnv: Environment = getDefaultEnvironment();\n\n/**\n * 设置当前环境\n */\nexport function setCurrentEnvironment(env: Environment): void {\n currentEnv = env;\n}\n\n/**\n * 获取当前环境\n */\nexport function getCurrentEnvironment(): Environment {\n // 优先使用环境变量\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n return currentEnv;\n}\n\n/**\n * 获取当前环境的配置\n * 合并配置文件和默认值\n */\nexport function getEnvironmentConfig(): EnvironmentConfig {\n return getMergedEnvironmentConfig(getCurrentEnvironment());\n}\n\nconst getEnv = (key: string, defaultValue: string): string => {\n return process.env[key] || defaultValue;\n};\n\n/**\n * 动态配置(根据当前环境变化)\n */\nexport function getOceanetConfig() {\n const envConfig = getEnvironmentConfig();\n const env = getCurrentEnvironment();\n\n return {\n // 认证服务基础地址 (设备码授权、登录、登出等)\n AUTH_BASE_URL: getEnv('OCEANET_AUTH_BASE_URL', envConfig.authBaseUrl),\n\n // 业务 API 基础地址\n API_BASE_URL: getEnv('OCEANET_API_BASE_URL', envConfig.apiBaseUrl),\n\n // 客户端 ID\n CLIENT_ID: getEnv('OCEANET_CLIENT_ID', envConfig.clientId),\n\n // Token 存储服务名(不同环境分开存储)\n SERVICE_NAME: `wukong-cli-${env}`,\n\n // 轮询配置\n POLL: POLL_CONFIG,\n\n // 认证服务端点\n AUTH_ENDPOINTS: API_ENDPOINTS.AUTH,\n\n // 业务 API 端点\n API_ENDPOINTS: API_ENDPOINTS.API,\n\n // 调试模式\n DEBUG: getEnv('WUKONG_CLI_DEBUG', 'false') === 'true',\n\n // 当前环境信息\n ENVIRONMENT: env,\n ENVIRONMENT_DISPLAY: envConfig.displayName,\n };\n}\n\n// 向后兼容:导出静态配置对象(使用默认环境)\nexport const OCEANET_CONFIG = getOceanetConfig();\n","/**\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\n * 从 device-flow.ts 提取,移除 UI 依赖\n */\n\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\n\n/**\n * 设备流程服务接口\n * 定义设备码授权流程的核心操作\n */\nexport interface IDeviceFlowService {\n /**\n * 获取设备授权码\n * @returns 设备授权响应,包含验证 URL 和设备码\n */\n getDeviceCode(): Promise<DeviceCodeResponse>;\n\n /**\n * 轮询获取 token\n * @param deviceCode 设备码\n * @returns Token 对\n */\n pollToken(deviceCode: string): Promise<TokenPair>;\n}\n\n/**\n * 设备流程服务实现\n * 纯业务逻辑,不包含 UI 依赖\n */\nexport class DeviceFlowService implements IDeviceFlowService {\n /**\n * 获取设备授权码\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n },\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n throw new Error(\n `(${data.code}) ${data.message || 'Failed to get device code'}`\n );\n }\n\n const { verificationUri, expiresIn, interval } = data.result;\n\n // 从 URL 中提取 deviceCode\n const urlObj = new URL(verificationUri);\n const deviceCode = urlObj.searchParams.get('code') || '';\n\n return {\n verificationUri,\n deviceCode,\n expiresIn,\n interval: interval || config.POLL.INTERVAL,\n };\n }\n\n /**\n * 轮询获取 token\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n const startTime = Date.now();\n const config = getOceanetConfig();\n\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n deviceCode,\n },\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n const data = await response.json();\n\n // 检查 API 错误(忽略 PENDING 状态)\n if (data.code !== 200) {\n // 静默跳过错误状态,继续轮询\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // result 为 null 或空表示 PENDING,继续轮询\n if (!data.result) {\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // 成功获取 token\n const {\n access_token,\n refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n return {\n accessToken: access_token,\n refreshToken: refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n }\n\n // 超时\n throw new Error('Authorization timed out. Please try again.');\n }\n}\n\n/**\n * 获取设备流程服务实例\n */\nexport function getDeviceFlowService(): IDeviceFlowService {\n return new DeviceFlowService();\n}\n","/**\n * Ora UI 回调实现 - 使用 ora spinner\n * CLI 特定的 UI 实现\n */\n\nimport ora, { Ora } from 'ora';\nimport type { IUICallbacks } from './ui-callbacks.js';\n\n/**\n * Ora Spinner UI 回调实现\n * 使用 ora 库提供 CLI 进度显示\n */\nexport class OraUICallbacks implements IUICallbacks {\n private spinner: Ora | null = null;\n\n onStart(message: string): void {\n this.spinner = ora(message).start();\n }\n\n onSuccess(message: string): void {\n if (this.spinner) {\n this.spinner.succeed(message);\n this.spinner = null;\n }\n }\n\n onError(message: string): void {\n if (this.spinner) {\n this.spinner.fail(message);\n this.spinner = null;\n }\n }\n\n onUpdate(message: string): void {\n if (this.spinner) {\n this.spinner.text = message;\n }\n }\n}\n","/**\n * keytar 适配器 - 处理 ESM/CommonJS 互操作\n * keytar 是可选依赖,如果不可用则返回 null\n */\n\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\nlet keytarModule: any = null;\n\ntry {\n keytarModule = require('keytar');\n} catch (error) {\n // keytar 未安装或编译失败\n keytarModule = null;\n}\n\n/**\n * 检查 keytar 是否可用\n */\nexport function isKeytarAvailable(): boolean {\n return keytarModule !== null;\n}\n\n/**\n * 设置密码\n */\nexport async function setPassword(service: string, account: string, password: string): Promise<void> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n await keytarModule.setPassword(service, account, password);\n}\n\n/**\n * 获取密码\n */\nexport async function getPassword(service: string, account: string): Promise<string | null> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.getPassword(service, account);\n}\n\n/**\n * 删除密码\n */\nexport async function deletePassword(service: string, account: string): Promise<boolean> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.deletePassword(service, account);\n}\n","/**\n * 文件凭据存储 - 作为 keytar 不可用时的降级方案\n * 将 token 存储在用户主目录的加密文件中\n */\n\nimport { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\n\n/**\n * 文件凭据存储实现\n */\nexport class FileCredentialStore {\n private configDir: string;\n\n constructor() {\n this.configDir = join(homedir(), '.wukong-cli');\n this.ensureConfigDir();\n }\n\n private ensureConfigDir(): void {\n if (!existsSync(this.configDir)) {\n mkdirSync(this.configDir, { recursive: true, mode: 0o700 });\n }\n }\n\n private getTokenPath(service: string, account: string): string {\n // 简单的文件命名:service_account.token\n const filename = `${service}_${account}.token`;\n return join(this.configDir, filename);\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n const filePath = this.getTokenPath(service, account);\n writeFileSync(filePath, password, { mode: 0o600 });\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 清除所有 token\n */\n clear(): void {\n // 简单实现:删除整个配置目录\n // 更精细的实现可以只删除 .token 文件\n }\n}\n","/**\n * 凭据存储提供者 - 抽象凭据存储接口\n * 优先使用 keytar,不可用时降级到文件存储\n */\n\nimport * as keytarAdapter from '../core/auth/keytar-adapter.js';\nimport { FileCredentialStore } from './file-credential-store.js';\n\n/**\n * 凭据存储接口\n */\nexport interface ICredentialStore {\n setPassword(service: string, account: string, password: string): Promise<void>;\n getPassword(service: string, account: string): Promise<string | null>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\n/**\n * Keytar 凭据存储实现\n */\nclass KeytarCredentialStore implements ICredentialStore {\n async setPassword(service: string, account: string, password: string): Promise<void> {\n await keytarAdapter.setPassword(service, account, password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return await keytarAdapter.getPassword(service, account);\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return await keytarAdapter.deletePassword(service, account);\n }\n}\n\n/**\n * 内存凭据存储实现(用于测试)\n */\nexport class InMemoryCredentialStore implements ICredentialStore {\n private store: Map<string, string> = new Map();\n\n private getKey(service: string, account: string): string {\n return `${service}:${account}`;\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n this.store.set(this.getKey(service, account), password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return this.store.get(this.getKey(service, account)) || null;\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return this.store.delete(this.getKey(service, account));\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * 获取凭据存储实例\n * 自动选择:keytar 可用时使用 keytar,否则降级到文件存储\n */\nexport function getCredentialStore(): ICredentialStore {\n // 优先使用 keytar\n if (keytarAdapter.isKeytarAvailable()) {\n return new KeytarCredentialStore();\n }\n\n // 降级到文件存储\n return new FileCredentialStore();\n}\n\n/**\n * 获取测试用凭据存储实例\n */\nexport function getTestCredentialStore(): ICredentialStore {\n return new InMemoryCredentialStore();\n}\n\n/**\n * 检查是否使用安全存储(keytar)\n */\nexport function isUsingSecureStorage(): boolean {\n return keytarAdapter.isKeytarAvailable();\n}\n","/**\n * Token Cache 接口 - Token 缓存抽象\n * 用于替代全局变量 (global as any).__cachedAccessToken\n */\n\n/**\n * Token 缓存接口\n * 定义了 token 的读取、设置和清除操作\n */\nexport interface ITokenCache {\n /**\n * 获取访问令牌\n */\n getAccessToken(): string | null;\n\n /**\n * 获取刷新令牌\n */\n getRefreshToken(): string | null;\n\n /**\n * 设置令牌对\n */\n setTokens(accessToken: string, refreshToken: string): void;\n\n /**\n * 清除所有令牌\n */\n clear(): void;\n\n /**\n * 检查是否有有效的访问令牌\n */\n hasAccessToken(): boolean;\n\n /**\n * 检查是否有有效的刷新令牌\n */\n hasRefreshToken(): boolean;\n}\n\n/**\n * 内存 Token 缓存实现\n * 将 token 存储在内存中,适用于单次 CLI 会话\n */\nexport class MemoryTokenCache implements ITokenCache {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n getRefreshToken(): string | null {\n return this.refreshToken;\n }\n\n setTokens(accessToken: string, refreshToken: string): void {\n this.accessToken = accessToken;\n this.refreshToken = refreshToken;\n }\n\n clear(): void {\n this.accessToken = null;\n this.refreshToken = null;\n }\n\n hasAccessToken(): boolean {\n return this.accessToken !== null && this.accessToken.length > 0;\n }\n\n hasRefreshToken(): boolean {\n return this.refreshToken !== null && this.refreshToken.length > 0;\n }\n}\n\n/**\n * 全局 Token 缓存实例(单例)\n * 用于在整个 CLI 会话中共享同一个缓存实例\n */\nlet globalCacheInstance: ITokenCache | null = null;\n\n/**\n * 获取全局 Token 缓存实例\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\n */\nexport function getGlobalTokenCache(): ITokenCache {\n if (!globalCacheInstance) {\n globalCacheInstance = new MemoryTokenCache();\n }\n return globalCacheInstance;\n}\n\n/**\n * 重置全局 Token 缓存实例\n * 用于测试或环境切换\n */\nexport function resetGlobalTokenCache(): void {\n globalCacheInstance = null;\n}\n\n/**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\nexport async function initializeTokenCache(\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\n): Promise<void> {\n const cache = getGlobalTokenCache();\n const { accessToken, refreshToken } = await loadTokens();\n\n if (accessToken && refreshToken) {\n cache.setTokens(accessToken, refreshToken);\n }\n}\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { authCommands } from './commands/auth.js';\nimport { testCommand } from './commands/test.js';\nimport { httpCommand } from './commands/http.js';\n\nconst program = new Command();\n\n// 根命令配置\nprogram\n .name('wukong-cli')\n .description('Wukong CLI - TypeScript implementation')\n .version(CLI_VERSION)\n // 添加全局 --debug 选项\n .option('--debug', 'Enable debug mode (show HTTP requests)')\n // 在每个命令执行前设置调试模式\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n // 只有显式传递 --debug 时才设置为 true,否则允许环境变量生效\n if (options.debug === true) {\n setDebugMode(true, true);\n } else {\n // 不显式设置,允许环境变量生效\n setDebugMode(false, false);\n }\n });\n\n// 添加 auth 命令组\nprogram.addCommand(authCommands);\n\n// 添加 test 命令\nprogram.addCommand(testCommand);\n\n// 添加 http 命令组\nprogram.addCommand(httpCommand);\n\n// 如果没有参数,显示帮助\nif (process.argv.length === 2) {\n program.help();\n}\n\nprogram.parse();\n","/**\n * Debug utilities for HTTP request/response logging\n */\n\nimport chalk from 'chalk';\n\nlet debugMode: boolean | null = null;\nlet explicitSet = false; // 标记是否显式设置过\n\n/**\n * 启用调试模式\n * @param enabled 是否启用调试模式\n * @param explicit 是否显式设置(命令行参数),默认为 true\n */\nexport function setDebugMode(enabled: boolean, explicit: boolean = true): void {\n if (explicit) {\n debugMode = enabled;\n explicitSet = true;\n }\n // 同时设置全局变量供其他模块使用\n (global as any).__debugMode = enabled;\n}\n\n/**\n * 检查是否在调试模式\n * 优先级:命令行参数(显式设置)> 环境变量 > 默认关闭\n */\nexport function isDebugMode(): boolean {\n // 如果已显式通过命令行参数设置,优先使用\n if (explicitSet) {\n return debugMode === true;\n }\n\n // 检查全局变量\n if ((global as any).__debugMode === true) {\n return true;\n }\n\n // 检查环境变量 WUKONG_CLI_DEBUG\n return process.env.WUKONG_CLI_DEBUG === 'true';\n}\n\n/**\n * 打印 HTTP 请求\n */\nexport function debugRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n): void {\n if (!isDebugMode()) return;\n\n console.log('');\n console.log(chalk.dim('=== HTTP Request ==='));\n console.log(chalk.cyan(`${method} ${url}`));\n\n if (headers) {\n console.log(chalk.dim('Headers:'));\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization') {\n // 只显示 token 的前 50 个字符\n const truncated = value.length > 50\n ? value.substring(0, 50) + '...'\n : value;\n console.log(chalk.dim(` ${key}: ${truncated}`));\n } else {\n console.log(chalk.dim(` ${key}: ${value}`));\n }\n }\n }\n\n if (body) {\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n }\n console.log('');\n}\n\n/**\n * 打印 HTTP 响应\n */\nexport function debugResponse(\n status: number,\n statusText: string,\n body: any,\n duration: number\n): void {\n if (!isDebugMode()) return;\n\n const statusColor = status >= 200 && status < 300 ? chalk.green : chalk.red;\n\n console.log(chalk.dim('=== HTTP Response') + chalk.dim(` (${duration}ms) ===`));\n console.log(statusColor(`Status: ${status} ${statusText}`));\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n console.log('');\n}\n","/**\n * Auth 命令组 - 基于 Oceanet Auth\n * wukong-cli auth <subcommand>\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n getDeviceCode,\n pollToken,\n} from '../core/auth/device-flow.js';\nimport {\n saveToken,\n getAccessToken,\n logout,\n} from '../core/auth/token-manager.js';\nimport { getClient } from '../core/http/client.js';\nimport {\n Environment,\n ENVIRONMENTS,\n} from '../config/environments.js';\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\nimport { getAllEnvironments } from '../config/config-loader.js';\n\nexport const authCommands = new Command('auth')\n .description('Authentication commands');\n\n// 登录命令\nauthCommands\n .command('login')\n .description('Login using Device Authorization Flow')\n .action(async () => {\n try {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n // 设置当前环境\n setCurrentEnvironment(env as Environment);\n const config = getOceanetConfig();\n const envConfig = allEnvs[env];\n\n console.log('');\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\n console.log('');\n console.log(chalk.dim(`Environment: ${chalk.cyan(env)} - ${envConfig.displayName}`));\n console.log('');\n\n // 步骤 1: 获取设备授权链接\n const { verificationUri, deviceCode, expiresIn, interval } =\n await getDeviceCode();\n\n // 显示授权信息\n console.log('');\n console.log(chalk.bold('═'.repeat(50)));\n console.log(chalk.bold(' 请完成授权 / Please complete authorization'));\n console.log(chalk.bold('═'.repeat(50)));\n console.log('');\n console.log(chalk.green(' 授权链接 / Authorization URL:'));\n console.log('');\n\n // 用多种方式显示链接,确保用户能看到\n console.log(chalk.cyan(` ${verificationUri}`));\n console.log('');\n\n // 同时输出到 stderr(Claude Code 能捕获)\n console.error(chalk.yellow.bold('>>> 请在浏览器中打开此链接完成授权 <<<'));\n console.error(chalk.cyan(verificationUri));\n console.error('');\n\n // 尝试自动打开浏览器(如果环境支持)\n const open = await import('open').catch(() => null);\n if (open) {\n try {\n await open.default(verificationUri);\n console.log(chalk.dim(' 浏览器已自动打开 / Browser opened automatically'));\n } catch {\n console.log(chalk.dim(' 请手动复制链接到浏览器 / Please copy link to browser'));\n }\n } else {\n console.log(chalk.dim(' 请手动复制链接到浏览器 / Please copy link to browser'));\n }\n console.log('');\n\n console.log(chalk.dim('═'.repeat(50)));\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\n console.log(chalk.dim('═'.repeat(50)));\n console.log('');\n\n // 步骤 2: 轮询获取 Token\n const tokens = await pollToken(deviceCode);\n\n // 步骤 3: 保存 Token\n await saveToken(tokens.accessToken, tokens.refreshToken);\n\n console.log('');\n console.log(chalk.bgGreen.black.bold(' ✓ 登录成功 / Login Successful '));\n console.log('');\n console.log(chalk.green('✓ Tokens saved securely'));\n console.log(chalk.dim(`Environment: ${env} - ${envConfig.displayName}`));\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\n console.log('');\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\n console.log('');\n\n } catch (error) {\n console.log('');\n console.log(chalk.red(`✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n }\n });\n\n// 登出命令\nauthCommands\n .command('logout')\n .description('Logout and clear saved tokens')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const accessToken = await getAccessToken();\n\n if (accessToken) {\n await logout(accessToken);\n }\n\n console.log('');\n console.log(chalk.green(`✓ Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n } catch {\n console.log('');\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n }\n });\n\n// 刷新 token 命令\nauthCommands\n .command('refresh')\n .description('Manually refresh access token')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const config = getOceanetConfig();\n\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.yellow('✗ Not authenticated'));\n console.log(chalk.dim(`Environment: ${env}`));\n console.log('');\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return; // 不使用 process.exit,让程序自然退出\n }\n\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const client = getClient();\n await client.refreshToken();\n\n spinner.succeed('Token refreshed successfully!');\n\n console.log('');\n console.log(chalk.dim('Environment:'), chalk.cyan(env));\n console.log(chalk.dim('New tokens saved securely'));\n console.log('');\n } catch (error) {\n spinner.fail('Token refresh failed');\n throw error;\n }\n } catch (error) {\n console.log('');\n console.log(chalk.red(`✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n console.log(chalk.dim(`Environment: ${env}`));\n console.log(chalk.dim(`Your session may have expired. Please run:`));\n console.log(chalk.dim(` wukong-cli auth login`));\n console.log('');\n // 不使用 process.exit,让程序自然退出\n }\n });\n\n// 状态命令\nauthCommands\n .command('status')\n .description('Show authentication status')\n .action(async () => {\n console.log('');\n\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n const config = getOceanetConfig();\n\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n console.log(chalk.dim(`Environment: ${env} - ${envConfig.displayName}`));\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return;\n }\n\n // 尝试获取用户信息来验证 token 是否真的有效\n try {\n const client = getClient();\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\n const userInfo = await client.get(userInfoUrl);\n\n // 只有 API 调用成功才显示已认证\n console.log(chalk.green(`✓ Authenticated`));\n console.log('');\n\n const displayUser = userInfo.firstName\n ? `${userInfo.firstName} (${userInfo.username})`\n : userInfo.username || 'N/A';\n console.log(chalk.dim('Environment:'), chalk.cyan(`${env} - ${envConfig.displayName}`));\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\n console.log('');\n } catch (error: any) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\n console.log('');\n console.log(chalk.dim(`Environment: ${env} - ${envConfig.displayName}`));\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n } catch (error) {\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n console.log(chalk.dim(`Environment: ${env} - ${envConfig.displayName}`));\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n });\n","/**\n * Device PKCE Flow - 设备码授权流程\n * 从 oceanet.ts 提取的设备授权逻辑\n *\n * @deprecated 请直接使用 device-flow-service.ts 和 cli-device-flow.ts\n * 此文件保留以向后兼容\n */\n\nimport chalk from 'chalk';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\nimport { createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\n\n// 重新导出类型和接口\nexport type { DeviceCodeResponse, TokenPair };\nexport type { IDeviceFlowService } from './device-flow-service.js';\n\n/**\n * 发起授权请求 - 获取设备授权链接\n * @deprecated 使用 CliDeviceFlowAdapter.getDeviceCode() 代替\n */\nexport async function getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const adapter = createCliDeviceFlowAdapter();\n\n // 调试信息\n if (config.DEBUG) {\n console.log('');\n console.log(chalk.dim('=== Debug Info ==='));\n console.log(chalk.dim('Getting device authorization...'));\n console.log(chalk.dim('Client ID:'), chalk.yellow(config.CLIENT_ID));\n console.log('');\n }\n\n const result = await adapter.getDeviceCode();\n\n // 调试响应\n if (config.DEBUG) {\n console.log(chalk.dim('=== Response ==='));\n console.log(chalk.dim('Device Code:'), chalk.yellow(result.deviceCode));\n console.log(chalk.dim('Verification URI:'), chalk.cyan(result.verificationUri));\n console.log(chalk.dim('Expires In:'), chalk.yellow(result.expiresIn));\n console.log('');\n }\n\n return result;\n}\n\n/**\n * 轮询获取 Token\n * @deprecated 使用 CliDeviceFlowAdapter.pollToken() 代替\n */\nexport async function pollToken(deviceCode: string): Promise<TokenPair> {\n const adapter = createCliDeviceFlowAdapter();\n return adapter.pollToken(deviceCode);\n}\n\n// 重新导出新的服务和适配器\nexport { DeviceFlowService, getDeviceFlowService } from './device-flow-service.js';\nexport { CliDeviceFlowAdapter, createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\nexport { IUICallbacks } from '../../adapters/ui-callbacks.js';\nexport { OraUICallbacks } from '../../adapters/ora-ui-callbacks.js';\n\n","/**\n * CLI 设备流程适配器 - 为设备流程添加 CLI UI 支持\n * 连接纯业务逻辑和 CLI UI 表现层\n */\n\nimport type { IDeviceFlowService } from '../core/auth/device-flow-service.js';\nimport type { IUICallbacks } from './ui-callbacks.js';\nimport type { DeviceCodeResponse, TokenPair } from '../types/auth.js';\n\n/**\n * CLI 设备流程适配器\n * 为设备流程服务添加 UI 反馈\n */\nexport class CliDeviceFlowAdapter {\n /**\n * 构造函数\n * @param deviceFlow 设备流程服务实例\n * @param ui UI 回调实例\n */\n constructor(\n private deviceFlow: IDeviceFlowService,\n private ui: IUICallbacks\n ) {}\n\n /**\n * 获取设备授权码(带 UI)\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n this.ui.onStart('Getting device authorization...');\n\n try {\n const result = await this.deviceFlow.getDeviceCode();\n this.ui.onSuccess('Device code obtained');\n return result;\n } catch (error: any) {\n this.ui.onError('Failed to get device code');\n throw error;\n }\n }\n\n /**\n * 轮询获取 token(带 UI)\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n this.ui.onStart('Waiting for authorization...');\n\n try {\n const result = await this.deviceFlow.pollToken(deviceCode);\n this.ui.onSuccess('Authorization successful!');\n return result;\n } catch (error: any) {\n this.ui.onError('Authorization error');\n throw error;\n }\n }\n}\n\n/**\n * 创建 CLI 设备流程适配器(使用默认实现)\n */\nexport function createCliDeviceFlowAdapter(): CliDeviceFlowAdapter {\n const { getDeviceFlowService } = require('../core/auth/device-flow-service.js');\n const { OraUICallbacks } = require('./ora-ui-callbacks.js');\n\n const deviceFlow = getDeviceFlowService();\n const ui = new OraUICallbacks();\n\n return new CliDeviceFlowAdapter(deviceFlow, ui);\n}\n","/**\n * UI 回调接口 - 用于 CLI 适配器\n * 定义 UI 操作的抽象,便于测试和替换 UI 实现\n */\n\n/**\n * UI 回调接口\n * 用于解耦业务逻辑和 CLI UI 表现层\n */\nexport interface IUICallbacks {\n /**\n * 操作开始时调用\n * @param message 提示消息\n */\n onStart(message: string): void;\n\n /**\n * 操作成功时调用\n * @param message 成功消息\n */\n onSuccess(message: string): void;\n\n /**\n * 操作失败时调用\n * @param message 失败消息\n */\n onError(message: string): void;\n\n /**\n * 更新操作信息\n * @param message 更新消息\n */\n onUpdate(message: string): void;\n}\n","/**\n * Token Manager - Token 存储和刷新管理\n * 从 oceanet.ts 提取的 token 管理逻辑\n */\n\nimport ora from 'ora';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { TokenPair } from '../../types/auth.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from './token-cache.js';\n\n/**\n * Token Manager 类\n * 负责与底层凭据存储和 token 缓存的交互\n */\nexport class TokenManager {\n /**\n * 构造函数\n * @param credentialStore 凭据存储实例\n * @param tokenCache token 缓存实例\n */\n constructor(\n private credentialStore: ICredentialStore,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 保存 Token\n */\n async saveToken(\n accessToken: string,\n refreshToken: string\n ): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken);\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken);\n\n // 更新缓存\n this.tokenCache.setTokens(accessToken, refreshToken);\n }\n\n /**\n * 获取 Access Token\n */\n async getAccessToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getAccessToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(token, null); // 只更新 access token\n }\n\n return token;\n }\n\n /**\n * 获取 Refresh Token\n */\n async getRefreshToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getRefreshToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(null, token); // 只更新 refresh token\n }\n\n return token;\n }\n\n /**\n * 刷新 Token\n */\n async refreshAccessToken(\n refreshToken: string\n ): Promise<TokenPair> {\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ param: refreshToken }),\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n spinner.fail('Token refresh failed');\n throw new Error(data.message || 'Refresh token failed');\n }\n\n const {\n access_token,\n refresh_token: new_refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n spinner.succeed('Token refreshed');\n\n return {\n accessToken: access_token,\n refreshToken: new_refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n } catch (error) {\n spinner.fail('Token refresh error');\n throw error;\n }\n }\n\n /**\n * 清除本地 Token\n */\n async clearTokens(): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token');\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token');\n\n // 清除缓存\n this.tokenCache.clear();\n }\n\n /**\n * 退出登录\n */\n async logout(accessToken: string): Promise<void> {\n try {\n const config = getOceanetConfig();\n await fetch(`${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n });\n } catch (error) {\n // 忽略退出登录错误\n }\n\n // 清除本地存储\n await this.clearTokens();\n }\n\n /**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\n async initTokenCache(): Promise<void> {\n const config = getOceanetConfig();\n\n // 并行读取两个 token(避免循环依赖)\n const [accessToken, refreshToken] = await Promise.all([\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token')\n ]);\n\n // 同时更新缓存\n if (accessToken || refreshToken) {\n this.tokenCache.setTokens(accessToken || null, refreshToken || null);\n }\n }\n}\n\n// ============ 便利函数(向后兼容) ============\n\n/**\n * 全局 TokenManager 实例\n */\nlet tokenManagerInstance: TokenManager | null = null;\n\n/**\n * 获取 TokenManager 单例\n */\nexport function getTokenManager(): TokenManager {\n if (!tokenManagerInstance) {\n // 延迟导入以避免循环依赖\n const { getCredentialStore } = require('../../providers/credential-store.js');\n const { getGlobalTokenCache } = require('./token-cache.js');\n\n const credentialStore = getCredentialStore();\n const tokenCache = getGlobalTokenCache();\n\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\n }\n return tokenManagerInstance;\n}\n\n/**\n * 重置 TokenManager 实例\n */\nexport function resetTokenManager(): void {\n tokenManagerInstance = null;\n}\n\n/**\n * 保存 Token(便利函数)\n */\nexport async function saveToken(\n accessToken: string,\n refreshToken: string\n): Promise<void> {\n const manager = getTokenManager();\n await manager.saveToken(accessToken, refreshToken);\n}\n\n/**\n * 获取 Access Token(便利函数)\n */\nexport async function getAccessToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getAccessToken();\n}\n\n/**\n * 获取 Refresh Token(便利函数)\n */\nexport async function getRefreshToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getRefreshToken();\n}\n\n/**\n * 刷新 Token(便利函数)\n */\nexport async function refreshAccessToken(\n refreshToken: string\n): Promise<TokenPair> {\n const manager = getTokenManager();\n return await manager.refreshAccessToken(refreshToken);\n}\n\n/**\n * 清除本地 Token(便利函数)\n */\nexport async function clearTokens(): Promise<void> {\n const manager = getTokenManager();\n await manager.clearTokens();\n}\n\n/**\n * 退出登录(便利函数)\n */\nexport async function logout(accessToken: string): Promise<void> {\n const manager = getTokenManager();\n await manager.logout(accessToken);\n}\n\n/**\n * 初始化 Token 缓存(便利函数)\n */\nexport async function initTokenCache(): Promise<void> {\n const manager = getTokenManager();\n await manager.initTokenCache();\n}\n","/**\n * Oceanet HTTP Client - 自动 Token 刷新的 HTTP 客户端\n * 从 oceanet-client.ts 重构\n *\n * 架构:\n * - BaseHttpClient: 纯 HTTP 请求\n * - AuthenticatingHttpClient: 添加认证和自动刷新\n * - ApiErrorHandler: 业务错误处理\n * - OceanetClient: 便利包装器(向后兼容)\n */\n\nimport { BaseHttpClient } from './base-http-client.js';\nimport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * Oceanet HTTP 客户端类(向后兼容的便利包装器)\n * 组合基础客户端、认证客户端和错误处理器\n */\nexport class OceanetClient implements IHttpClient {\n private authenticatingClient: AuthenticatingHttpClient;\n\n /**\n * 构造函数\n * @param tokenCache token 缓存实例(可选)\n */\n constructor(tokenCache?: ITokenCache) {\n // 如果没有提供 tokenCache,从全局获取\n let cache: ITokenCache;\n if (tokenCache) {\n cache = tokenCache;\n } else {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n cache = getGlobalTokenCache();\n }\n\n // 组合客户端链:Base -> Authenticating\n const baseClient = new BaseHttpClient();\n this.authenticatingClient = new AuthenticatingHttpClient(baseClient, cache);\n }\n\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options?: any\n ): Promise<T> {\n return this.authenticatingClient.request<T>(endpoint, options);\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.authenticatingClient.get<T>(endpoint, params);\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.post<T>(endpoint, data, headers);\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.put<T>(endpoint, data, headers);\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.authenticatingClient.delete<T>(endpoint);\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.patch<T>(endpoint, data, headers);\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n return this.authenticatingClient.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n return this.authenticatingClient.refreshToken();\n }\n}\n\n// 单例实例\nlet clientInstance: OceanetClient | null = null;\nlet lastEnvironment: string | null = null;\n\n/**\n * 清除 token 缓存\n */\nexport function clearTokenCache(): void {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n const cache = getGlobalTokenCache();\n cache.clear();\n}\n\n/**\n * 获取 HTTP 客户端单例\n * 如果环境变化,会重新创建实例并清除缓存\n */\nexport function getClient(): OceanetClient {\n const currentEnv = getOceanetConfig().ENVIRONMENT;\n\n // 环境变化时,清除缓存并重新创建客户端实例\n if (!clientInstance || lastEnvironment !== currentEnv) {\n clearTokenCache();\n clientInstance = new OceanetClient();\n lastEnvironment = currentEnv;\n }\n return clientInstance;\n}\n\n// 重新导出新组件\nexport { BaseHttpClient } from './base-http-client.js';\nexport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nexport { ApiErrorHandler, getApiErrorHandler, ApiError } from './api-error-handler.js';\nexport type { IHttpClient, IReadOnlyHttpClient, IMutatingHttpClient } from './http-client-interface.js';\n","/**\n * 基础 HTTP 客户端 - 纯 HTTP 请求逻辑\n * 不包含认证和错误处理\n */\n\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { RequestOptions, OceanetApiResponse } from '../../types/oceanet.js';\n\n/**\n * 构建 URL(添加查询参数)\n * 如果 endpoint 已经是完整 URL(以 http:// 或 https:// 开头),直接使用\n */\nfunction buildUrl(endpoint: string, params?: Record<string, string>): string {\n // 如果是完整 URL,直接使用\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n let url = endpoint;\n if (params) {\n const searchParams = new URLSearchParams(params);\n const separator = url.includes('?') ? '&' : '?';\n url += `${separator}${searchParams.toString()}`;\n }\n return url;\n }\n\n // 否则,拼接 base URL\n const config = getOceanetConfig();\n let url = `${config.API_BASE_URL}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return url;\n}\n\n/**\n * 基础 HTTP 客户端实现\n * 提供纯 HTTP 请求功能,不包含认证逻辑\n */\nexport class BaseHttpClient implements IHttpClient {\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n } = options;\n\n const url = buildUrl(endpoint, params);\n const requestHeaders = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest(method, url, requestHeaders, body);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data: OceanetApiResponse<T> = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n return data as T;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n}\n","/**\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\n */\n\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\nimport { getRetoken } from './interceptors.js';\nimport { getTokenManager } from '../auth/token-manager.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\n\n/**\n * 认证 HTTP 客户端\n * 为基础 HTTP 客户端添加:\n * 1. 自动添加 Authorization 头\n * 2. 401 自动刷新 token 并重试\n * 3. 业务错误处理\n */\nexport class AuthenticatingHttpClient implements IHttpClient {\n private initialized = false;\n\n constructor(\n private baseClient: IHttpClient,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 确保 token 缓存已初始化\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n const tokenManager = getTokenManager();\n await tokenManager.initTokenCache();\n this.initialized = true;\n }\n }\n\n /**\n * 发起认证的 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: any = {}\n ): Promise<T> {\n await this.ensureInitialized();\n\n // 获取当前 token\n const accessToken = this.tokenCache.getAccessToken();\n if (!accessToken) {\n throw new Error(\n 'Not authenticated. Please run: wukong-cli auth login'\n );\n }\n\n // 添加认证头\n const headers = {\n ...options.headers,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 构建完整 URL\n const url = `${(global as any).__apiBaseUrl || ''}${endpoint}`;\n\n // 打印调试信息\n debugRequest(options.method || 'GET', url, headers, options.body);\n\n // 使用 ts-retoken 的 fetch 包装器\n const retoken = getRetoken();\n const startTime = Date.now();\n const response = await retoken.fetch(\n url,\n {\n method: options.method || 'GET',\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n\n const data: OceanetApiResponse<T> = await response.json();\n const duration = Date.now() - startTime;\n\n // 打印响应调试信息\n debugResponse(response.status, response.statusText, data, duration);\n\n // 处理业务错误\n const errorHandler = getApiErrorHandler();\n\n // 9913 = token不存在或已失效,尝试刷新后重试\n if (data.code === 9913) {\n return errorHandler.tryRecover(\n new ApiError(data.code, data.message || 'Token expired', true),\n async () => {\n await retoken.refreshToken();\n const newAccessToken = this.tokenCache.getAccessToken();\n if (newAccessToken) {\n const retryResponse = await fetch(\n `${(global as any).__apiBaseUrl || ''}${endpoint}`,\n {\n method: options.method || 'GET',\n headers: {\n ...headers,\n 'Authorization': `Bearer ${newAccessToken}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n const retryData: OceanetApiResponse<T> = await retryResponse.json();\n\n if (retryData.code === 200) {\n return retryData.result;\n }\n throw new Error(\n `API Error (${retryData.code}): ${retryData.message || 'Unknown error'}`\n );\n }\n throw new Error('Failed to refresh token');\n }\n );\n }\n\n // 检查其他业务错误\n errorHandler.handle(data);\n\n return data.result;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n return retoken.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n await retoken.refreshToken();\n }\n}\n","/**\n * API 错误处理器 - 处理 Oceanet API 特定错误\n */\n\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport chalk from 'chalk';\n\n/**\n * API 错误类\n */\nexport class ApiError extends Error {\n constructor(\n public code: number,\n message: string,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/**\n * 错误处理函数类型\n */\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\n\n/**\n * API 错误处理器\n * 负责处理 Oceanet API 的业务错误码\n */\nexport class ApiErrorHandler {\n private errorHandlers: Map<number, ErrorHandler> = new Map();\n\n constructor() {\n // 注册默认错误处理器\n this.registerDefaultHandlers();\n }\n\n /**\n * 注册默认的 Oceanet 错误处理器\n */\n private registerDefaultHandlers(): void {\n // 9913 = token 不存在或已失效\n this.register(9913, (response) => {\n const error = new ApiError(\n response.code,\n response.message || 'Token expired or invalid',\n true // 可重试\n );\n throw error;\n });\n\n // 其他认证错误\n [401, 403].forEach(code => {\n this.register(code, (response) => {\n throw new ApiError(\n response.code,\n response.message || 'Authentication failed',\n code === 401 // 401 可以尝试刷新 token\n );\n });\n });\n }\n\n /**\n * 注册错误处理器\n * @param code 错误码\n * @param handler 处理函数\n */\n register(code: number, handler: ErrorHandler): void {\n this.errorHandlers.set(code, handler);\n }\n\n /**\n * 处理 API 响应\n * @param response API 响应\n * @throws {ApiError} 当响应包含错误时\n */\n handle(response: OceanetApiResponse): void {\n if (response.code !== 200) {\n const handler = this.errorHandlers.get(response.code);\n\n if (handler) {\n handler(response);\n }\n\n // 没有特定处理器,使用默认处理\n throw new ApiError(\n response.code,\n response.message || 'Unknown API error'\n );\n }\n }\n\n /**\n * 检查响应是否为错误\n * @param response API 响应\n * @returns 是否为错误\n */\n isError(response: OceanetApiResponse): boolean {\n return response.code !== 200;\n }\n\n /**\n * 尝试从错误中恢复\n * @param error 错误对象\n * @param recoverFunction 恢复函数\n * @returns 恢复结果或抛出错误\n */\n async tryRecover<T>(\n error: unknown,\n recoverFunction: () => Promise<T>\n ): Promise<T> {\n if (error instanceof ApiError && error.retryable) {\n console.log('');\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\n try {\n return await recoverFunction();\n } catch (refreshError: any) {\n console.log('');\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\n throw new ApiError(\n error.code,\n `${error.message} (Auto-refresh failed)`\n );\n }\n }\n throw error;\n }\n}\n\n/**\n * 获取全局错误处理器实例\n */\nlet errorHandlerInstance: ApiErrorHandler | null = null;\n\nexport function getApiErrorHandler(): ApiErrorHandler {\n if (!errorHandlerInstance) {\n errorHandlerInstance = new ApiErrorHandler();\n }\n return errorHandlerInstance;\n}\n","/**\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\n * 使用 ts-retoken 实现\n */\n\nimport { createRetoken } from 'ts-retoken';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { Tokens } from '../../types/oceanet.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\n\n/**\n * 创建 retoken 实例(动态获取配置)\n * 处理主动刷新和 401 重试\n * @param credentialStore 凭据存储实例(可选)\n * @param tokenCache token 缓存实例(可选)\n */\nexport function createRetokenInstance(\n credentialStore?: ICredentialStore,\n tokenCache?: ITokenCache\n) {\n const config = getOceanetConfig();\n\n // 如果没有提供实例,使用默认实现\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\n\n return createRetoken({\n refreshEndpoint: {\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\n method: 'POST',\n // Oceanet API 要求: { \"param\": \"refresh_token_string\" }\n buildBody: (token) => JSON.stringify({ param: token }),\n headers: {\n 'Content-Type': 'application/json',\n },\n parseResponse: (data: any) => {\n // 调试:打印请求和响应\n if (config.DEBUG || (global as any).__debugMode) {\n console.log('');\n console.log('=== HTTP Request ===');\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\n console.log('Headers:');\n console.log(' Content-Type: application/json');\n console.log('Body:');\n const refreshToken = cache.getRefreshToken();\n const truncated = refreshToken && refreshToken.length > 50\n ? refreshToken.substring(0, 50) + '...'\n : refreshToken || '(none)';\n console.log(` {\"param\":\"${truncated}\"}`);\n console.log('');\n console.log('=== HTTP Response ===');\n console.log(JSON.stringify(data, null, 2));\n console.log('');\n }\n\n // 检查业务错误码 - refresh_token 过期或无效\n if (data.code === 401 || data.code === 403) {\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\n error.code = data.code;\n error.isAuthFailure = true;\n throw error;\n }\n\n // Oceanet API 返回格式: { code: 200, result: { access_token, refresh_token, ... } }\n const result = data.result || data;\n\n // 验证 token 字段存在\n if (!result.access_token && !result.accessToken) {\n throw new Error('Invalid token response: missing access_token field');\n }\n if (!result.refresh_token && !result.refreshToken) {\n throw new Error('Invalid token response: missing refresh_token field');\n }\n\n return {\n accessToken: result.access_token || result.accessToken,\n refreshToken: result.refresh_token || result.refreshToken,\n };\n },\n },\n // 从缓存获取 token(同步函数)\n getAccessToken: () => {\n return cache.getAccessToken();\n },\n getRefreshToken: () => {\n return cache.getRefreshToken();\n },\n // 保存 token 到持久化存储和缓存(异步)\n setTokens: async (tokens: Tokens) => {\n // 参数验证 - 支持驼峰和下划线命名\n const accessToken = tokens?.accessToken || tokens?.access_token;\n const refreshToken = tokens?.refreshToken || tokens?.refresh_token;\n\n if (!accessToken || !refreshToken) {\n throw new Error('Invalid tokens: missing access_token or refresh_token');\n }\n\n const cfg = getOceanetConfig();\n await store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken);\n await store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken);\n // 更新缓存\n cache.setTokens(accessToken, refreshToken);\n },\n // 清除 token\n clearTokens: async () => {\n const cfg = getOceanetConfig();\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n // 清除缓存\n cache.clear();\n },\n // 提前 1 分钟(60 秒)主动刷新\n expirationLeeway: 60,\n // 401 时触发重试\n retryStatuses: [401],\n // 认证完全失败时的回调\n onAuthFailure: async () => {\n const cfg = getOceanetConfig();\n try {\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n cache.clear();\n } catch {\n // 忽略清除错误\n }\n },\n });\n}\n\n// 缓存的 retoken 实例(按环境)\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\n\n/**\n * 获取当前环境的 retoken 实例\n */\nexport function getRetoken() {\n const config = getOceanetConfig();\n const env = config.ENVIRONMENT;\n\n if (!retokenInstances[env]) {\n retokenInstances[env] = createRetokenInstance();\n }\n\n return retokenInstances[env];\n}\n","/**\n * 测试命令 - 使用 Oceanet HTTP 客户端\n * wukong-cli test\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\n\nexport const testCommand = new Command('test')\n .description('Test API request with saved token')\n .action(async () => {\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.red('✗ Not authenticated'));\n console.log('');\n console.log(chalk.dim('Please run: wukong-cli auth login'));\n console.log('');\n process.exit(1);\n }\n\n const spinner = ora('Testing API connection...').start();\n\n try {\n // 使用 HTTP 客户端获取用户信息\n const client = getClient();\n const userInfo = await client.get<any>('/oceanet-auth/web/userInfo');\n\n spinner.succeed('API request successful');\n\n console.log('');\n console.log(chalk.green('User Info:'));\n console.log(chalk.dim(JSON.stringify(userInfo, null, 2)));\n console.log('');\n\n } catch (error: any) {\n spinner.fail('API request failed');\n\n if (error.message.includes('401') || error.message.includes('expired')) {\n console.log('');\n console.log(chalk.yellow('Token expired or invalid'));\n console.log(chalk.dim('Try: wukong-cli auth refresh'));\n console.log('');\n } else {\n throw error;\n }\n }\n\n } catch (error) {\n console.log('');\n console.log(chalk.red(`✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n process.exit(1);\n }\n });\n","/**\n * HTTP 测试命令\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\n\ninterface RequestOptions {\n baseUrl?: string;\n headers: string[];\n data?: string;\n}\n\n/**\n * 修复 Git Bash 路径转换问题\n */\nfunction fixGitBashPath(url: string): string {\n if (url.includes(':') && !url.startsWith('http')) {\n // 移除 Windows 路径前缀 (如 \"D:/Program Files/Git\")\n // 查找 \"/oceanet-\" 并从那里开始\n const oceanetIndex = url.indexOf('/oceanet-');\n if (oceanetIndex >= 0) {\n return url.substring(oceanetIndex);\n }\n }\n return url;\n}\n\n/**\n * 解析自定义头\n */\nfunction parseHeaders(headers: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n if (Array.isArray(headers)) {\n for (const h of headers) {\n const [key, ...valueParts] = h.split(':');\n if (key && valueParts.length > 0) {\n result[key.trim()] = valueParts.join(':').trim();\n }\n }\n }\n return result;\n}\n\n/**\n * 构建完整 URL\n */\nfunction buildUrl(url: string, baseUrl?: string): string {\n const cleanUrl = fixGitBashPath(url);\n if (cleanUrl.startsWith('http')) {\n return cleanUrl;\n }\n const base = baseUrl || OCEANET_CONFIG.API_BASE_URL;\n return `${base}${cleanUrl}`;\n}\n\n/**\n * 执行 HTTP 请求\n */\nasync function executeRequest(\n method: string,\n url: string,\n options: RequestOptions\n): Promise<void> {\n const spinner = ora('Sending request...').start();\n\n try {\n // 获取 Token\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n spinner.fail('Not authenticated');\n console.error(chalk.red('Please run: wukong-cli auth login'));\n process.exit(1);\n }\n\n // 构建完整 URL\n const fullUrl = buildUrl(url, options.baseUrl);\n\n // 解析自定义头\n const customHeaders = parseHeaders(options.headers);\n\n // 构建请求头\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n ...customHeaders,\n };\n\n // 构建请求体\n let body: string | undefined;\n if (options.data) {\n body = options.data;\n // 如果没有自定义 Content-Type,使用 application/json\n if (!customHeaders['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n }\n\n // 发起请求\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\n\n const response = await fetch(fullUrl, {\n method,\n headers,\n body: method !== 'GET' && method !== 'DELETE' ? body : undefined,\n });\n\n const data = await response.json();\n\n spinner.succeed('Response received');\n\n // 显示响应\n console.log('');\n console.log(chalk.dim('Status:'), response.status, response.statusText);\n console.log('');\n console.log(chalk.dim('Response:'));\n console.log(JSON.stringify(data, null, 2));\n\n } catch (error) {\n spinner.fail('Request failed');\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\nexport const httpCommand = new Command('http');\n\n// GET 请求\nhttpCommand\n .command('get <url>')\n .description('Send GET request (uses OCEANET_API_BASE_URL or override with -b)')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('GET', url, options);\n });\n\n// POST 请求\nhttpCommand\n .command('post <url>')\n .description('Send POST request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('POST', url, options);\n });\n\n// PUT 请求\nhttpCommand\n .command('put <url>')\n .description('Send PUT request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('PUT', url, options);\n });\n\n// DELETE 请求\nhttpCommand\n .command('delete <url>')\n .description('Send DELETE request')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('DELETE', url, options);\n });\n"],"mappings":"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","names":["fileURLToPath","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","chalk","ora","chalk","getDeviceFlowService","OraUICallbacks","chalk","ora","getCredentialStore","getGlobalTokenCache","url","chalk","getGlobalTokenCache","currentEnv","chalk","ora","Command","ora","chalk","Command","chalk","ora","Command","ora","chalk","buildUrl","ora","chalk","Command","Command"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/constants/config.ts","../src/config/environments.ts","../src/config/config-loader.ts","../src/config/oceanet.ts","../src/core/auth/device-flow-service.ts","../src/adapters/ora-ui-callbacks.ts","../src/core/auth/keytar-adapter.ts","../src/providers/file-credential-store.ts","../src/providers/credential-store.ts","../src/core/auth/token-cache.ts","../src/cli.ts","../src/utils/debug.ts","../src/commands/auth.ts","../src/utils/environment.ts","../src/core/auth/device-flow.ts","../src/adapters/cli-device-flow.ts","../src/adapters/ui-callbacks.ts","../src/core/auth/token-manager.ts","../src/core/http/client.ts","../src/core/http/base-http-client.ts","../src/core/http/authenticating-http-client.ts","../src/core/http/api-error-handler.ts","../src/core/http/interceptors.ts","../src/commands/test.ts","../src/commands/http.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * 配置常量\n * 只包含常量定义,不包含环境配置\n */\n\n/**\n * 配置文件名\n */\nexport const CONFIG_FILE = '.wukong-cli.json';\n\n/**\n * Keytar 服务名\n */\nexport const KEYTAR_SERVICE = 'wukong-cli';\n\n/**\n * Keytar 账户名\n */\nexport const KEYTAR_ACCOUNTS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n} as const;\n\n/**\n * API 端点路径\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n DEVICE_AUTHORIZE: '/oceanet-auth/pkce/device/authorize',\n DEVICE_TOKEN: '/oceanet-auth/pkce/device/token',\n REFRESH_TOKEN: '/oceanet-auth/manage/refreshToken',\n LOGOUT: '/oceanet-auth/manage/logout',\n },\n API: {\n USER_INFO: '/oceanet-auth/web/userInfo',\n },\n} as const;\n\n/**\n * 轮询配置\n */\nexport const POLL_CONFIG = {\n INTERVAL: 3, // 轮询间隔(秒)\n TIMEOUT: 300, // 轮询超时(秒)\n} as const;\n","/**\n * 多环境配置支持\n * 支持 dev/beta/uat/prod 四套环境\n */\n\nexport type Environment = 'dev' | 'beta' | 'uat' | 'prod';\n\nexport interface EnvironmentConfig {\n name: Environment;\n displayName: string;\n authBaseUrl: string;\n apiBaseUrl: string;\n clientId: string;\n}\n\n/**\n * 环境配置表(默认值)\n * 可通过配置文件或环境变量覆盖\n */\nexport const ENVIRONMENTS: Record<Environment, EnvironmentConfig> = {\n dev: {\n name: 'dev',\n displayName: 'Development',\n authBaseUrl: 'https://portal-dev.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode-dev.zrhsh.com',\n clientId: 'wukong-cli-dev',\n },\n beta: {\n name: 'beta',\n displayName: 'Testing',\n authBaseUrl: 'https://portal-beta.zrhsh.com',\n apiBaseUrl: 'https://nrp-recode.zrhsh.com',\n clientId: 'wukong-cli-beta',\n },\n uat: {\n name: 'uat',\n displayName: 'UAT (User Acceptance Testing)',\n authBaseUrl: 'https://portal-uat.zrhsh.com',\n apiBaseUrl: 'https://nrp-pd.zrhsh.com',\n clientId: 'wukong-cli-uat',\n },\n prod: {\n name: 'prod',\n displayName: 'Production',\n authBaseUrl: 'https://portal.zrhsh.com',\n apiBaseUrl: 'https://nrp.zrhsh.com',\n clientId: 'wukong-cli-prod',\n },\n};\n\n/**\n * 默认环境\n */\nexport const DEFAULT_ENVIRONMENT: Environment = 'prod';\n\n/**\n * 验证环境名称\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env in ENVIRONMENTS;\n}\n","/**\n * 配置文件加载器\n * 支持从 wukong-cli.json 加载环境配置\n * 首次运行时自动创建默认配置文件\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { fileURLToPath } from 'url';\nimport { Environment, EnvironmentConfig, ENVIRONMENTS, DEFAULT_ENVIRONMENT, isValidEnvironment } from './environments.js';\n\n/**\n * 用户自定义环境配置\n */\nexport interface CustomEnvironmentConfig {\n authBaseUrl?: string;\n apiBaseUrl?: string;\n clientId?: string;\n}\n\nexport interface WukongCliConfig {\n /** 默认环境 */\n defaultEnv?: Environment;\n /** 环境配置覆盖 */\n environments?: Record<string, CustomEnvironmentConfig>;\n /** 自定义环境(非标准环境) */\n customEnvironments?: Record<string, EnvironmentConfig & { displayName: string }>;\n}\n\nconst CONFIG_FILENAMES = [\n 'wukong-cli.json',\n '.wukong-cli.json',\n '.wukongclirc',\n];\n\n/**\n * 获取用户主目录下的配置文件路径\n */\nexport function getUserConfigPath(): string {\n return join(homedir(), 'wukong-cli.json');\n}\n\n/**\n * 创建默认配置文件\n * 从模板文件读取默认配置\n */\nexport function createDefaultConfig(): void {\n const configPath = getUserConfigPath();\n\n // 如果配置文件已存在,不覆盖\n if (existsSync(configPath)) {\n return;\n }\n\n try {\n // 读取模板文件\n const templatePath = join(getProjectRoot(), 'wukong-cli.json.template');\n\n if (!existsSync(templatePath)) {\n console.warn(`Warning: Template config not found: ${templatePath}`);\n return;\n }\n\n const templateContent = readFileSync(templatePath, 'utf-8');\n const defaultConfig = JSON.parse(templateContent) as WukongCliConfig;\n\n // 确保目录存在\n const dir = dirname(configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // 写入配置文件\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');\n } catch (error) {\n // 静默失败,不影响程序运行\n // console.warn(`Warning: Failed to create default config: ${error}`);\n }\n}\n\n/**\n * 获取项目根目录\n */\nfunction getProjectRoot(): string {\n // 从当前文件的路径向上查找,直到找到 package.json\n let currentDir = dirname(fileURLToPath(import.meta.url));\n\n while (currentDir !== dirname(currentDir)) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = dirname(currentDir);\n }\n\n // 如果找不到,返回当前工作目录\n return process.cwd();\n}\n\n/**\n * 查找配置文件\n * 优先级:当前目录 > 用户主目录\n */\nfunction findConfigFile(): string | null {\n // 1. 当前工作目录\n for (const filename of CONFIG_FILENAMES) {\n const localPath = join(process.cwd(), filename);\n if (existsSync(localPath)) {\n return localPath;\n }\n }\n\n // 2. 用户主目录\n const userConfigPath = getUserConfigPath();\n if (existsSync(userConfigPath)) {\n return userConfigPath;\n }\n\n return null;\n}\n\n/**\n * 加载配置文件\n * 如果用户主目录下没有配置文件,自动创建默认配置\n */\nexport function loadConfig(): WukongCliConfig {\n const configPath = findConfigFile();\n\n if (!configPath) {\n // 首次运行,创建默认配置\n createDefaultConfig();\n return {};\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content) as WukongCliConfig;\n return config;\n } catch (error) {\n console.warn(`Warning: Failed to load config from ${configPath}: ${error}`);\n return {};\n }\n}\n\n/**\n * 获取环境配置(合并配置文件和默认值)\n * 优先级:环境变量 > 配置文件 > 默认值\n */\nexport function getMergedEnvironmentConfig(env: Environment): EnvironmentConfig {\n const config = loadConfig();\n const defaultConfig = ENVIRONMENTS[env] || ENVIRONMENTS[DEFAULT_ENVIRONMENT];\n\n // 环境变量覆盖(最高优先级)\n const envAuthUrl = process.env[`OCEANET_${env.toUpperCase()}_AUTH_URL`];\n const envApiUrl = process.env[`OCEANET_${env.toUpperCase()}_API_URL`];\n const envClientId = process.env[`OCEANET_${env.toUpperCase()}_CLIENT_ID`];\n\n // 配置文件覆盖\n const customConfig = config.environments?.[env] || {};\n\n return {\n name: env,\n displayName: defaultConfig.displayName,\n authBaseUrl: envAuthUrl || customConfig.authBaseUrl || defaultConfig.authBaseUrl,\n apiBaseUrl: envApiUrl || customConfig.apiBaseUrl || defaultConfig.apiBaseUrl,\n clientId: envClientId || customConfig.clientId || defaultConfig.clientId,\n };\n}\n\n/**\n * 获取所有可用环境(包括自定义环境)\n */\nexport function getAllEnvironments(): Record<string, EnvironmentConfig & { displayName: string }> {\n const config = loadConfig();\n const result: Record<string, EnvironmentConfig & { displayName: string }> = { ...ENVIRONMENTS };\n\n // 添加自定义环境\n if (config.customEnvironments) {\n for (const [name, customEnv] of Object.entries(config.customEnvironments)) {\n result[name] = {\n name: name as Environment,\n displayName: customEnv.displayName || name,\n authBaseUrl: customEnv.authBaseUrl,\n apiBaseUrl: customEnv.apiBaseUrl,\n clientId: customEnv.clientId,\n };\n }\n }\n\n return result;\n}\n\n/**\n * 获取默认环境\n */\nexport function getDefaultEnvironment(): Environment {\n // 优先级:环境变量 > 配置文件 > 默认值\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n\n const config = loadConfig();\n if (config.defaultEnv && isValidEnvironment(config.defaultEnv)) {\n return config.defaultEnv;\n }\n\n return DEFAULT_ENVIRONMENT;\n}","/**\n * Oceanet Auth 配置\n * 支持多环境:dev/beta/uat/prod\n * 配置优先级:环境变量 > 配置文件 > 默认值\n */\n\nimport type { Environment, EnvironmentConfig } from '../types/config.js';\nimport {\n API_ENDPOINTS,\n POLL_CONFIG,\n} from '../constants/config.js';\nimport { isValidEnvironment } from './environments.js';\nimport { getMergedEnvironmentConfig, getDefaultEnvironment } from './config-loader.js';\n\n// 当前环境(运行时设置)\nlet currentEnv: Environment = getDefaultEnvironment();\n\n/**\n * 设置当前环境\n */\nexport function setCurrentEnvironment(env: Environment): void {\n currentEnv = env;\n}\n\n/**\n * 获取当前环境\n */\nexport function getCurrentEnvironment(): Environment {\n // 优先使用环境变量\n const envFromVar = process.env.WUKONG_CLI_ENV;\n if (envFromVar && isValidEnvironment(envFromVar)) {\n return envFromVar;\n }\n return currentEnv;\n}\n\n/**\n * 获取当前环境的配置\n * 合并配置文件和默认值\n */\nexport function getEnvironmentConfig(): EnvironmentConfig {\n return getMergedEnvironmentConfig(getCurrentEnvironment());\n}\n\nconst getEnv = (key: string, defaultValue: string): string => {\n return process.env[key] || defaultValue;\n};\n\n/**\n * 动态配置(根据当前环境变化)\n */\nexport function getOceanetConfig() {\n const envConfig = getEnvironmentConfig();\n const env = getCurrentEnvironment();\n\n return {\n // 认证服务基础地址 (设备码授权、登录、登出等)\n AUTH_BASE_URL: getEnv('OCEANET_AUTH_BASE_URL', envConfig.authBaseUrl),\n\n // 业务 API 基础地址\n API_BASE_URL: getEnv('OCEANET_API_BASE_URL', envConfig.apiBaseUrl),\n\n // 客户端 ID\n CLIENT_ID: getEnv('OCEANET_CLIENT_ID', envConfig.clientId),\n\n // Token 存储服务名(不同环境分开存储)\n SERVICE_NAME: `wukong-cli-${env}`,\n\n // 轮询配置\n POLL: POLL_CONFIG,\n\n // 认证服务端点\n AUTH_ENDPOINTS: API_ENDPOINTS.AUTH,\n\n // 业务 API 端点\n API_ENDPOINTS: API_ENDPOINTS.API,\n\n // 调试模式\n DEBUG: getEnv('WUKONG_CLI_DEBUG', 'false') === 'true',\n\n // 当前环境信息\n ENVIRONMENT: env,\n ENVIRONMENT_DISPLAY: envConfig.displayName,\n };\n}\n\n// 向后兼容:导出静态配置对象(使用默认环境)\nexport const OCEANET_CONFIG = getOceanetConfig();\n","/**\n * Device Flow Service - 设备码授权流程(纯业务逻辑)\n * 从 device-flow.ts 提取,移除 UI 依赖\n */\n\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\n\n/**\n * 设备流程服务接口\n * 定义设备码授权流程的核心操作\n */\nexport interface IDeviceFlowService {\n /**\n * 获取设备授权码\n * @returns 设备授权响应,包含验证 URL 和设备码\n */\n getDeviceCode(): Promise<DeviceCodeResponse>;\n\n /**\n * 轮询获取 token\n * @param deviceCode 设备码\n * @returns Token 对\n */\n pollToken(deviceCode: string): Promise<TokenPair>;\n}\n\n/**\n * 设备流程服务实现\n * 纯业务逻辑,不包含 UI 依赖\n */\nexport class DeviceFlowService implements IDeviceFlowService {\n /**\n * 获取设备授权码\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_AUTHORIZE}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n },\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n throw new Error(\n `(${data.code}) ${data.message || 'Failed to get device code'}`\n );\n }\n\n const { verificationUri, expiresIn, interval } = data.result;\n\n // 从 URL 中提取 deviceCode\n const urlObj = new URL(verificationUri);\n const deviceCode = urlObj.searchParams.get('code') || '';\n\n return {\n verificationUri,\n deviceCode,\n expiresIn,\n interval: interval || config.POLL.INTERVAL,\n };\n }\n\n /**\n * 轮询获取 token\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n const startTime = Date.now();\n const config = getOceanetConfig();\n\n while (Date.now() - startTime < config.POLL.TIMEOUT * 1000) {\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.DEVICE_TOKEN}`;\n const requestBody = {\n param: {\n clientId: config.CLIENT_ID,\n deviceCode,\n },\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n const data = await response.json();\n\n // 检查 API 错误(忽略 PENDING 状态)\n if (data.code !== 200) {\n // 静默跳过错误状态,继续轮询\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // result 为 null 或空表示 PENDING,继续轮询\n if (!data.result) {\n await new Promise((resolve) =>\n setTimeout(resolve, config.POLL.INTERVAL * 1000)\n );\n continue;\n }\n\n // 成功获取 token\n const {\n access_token,\n refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n return {\n accessToken: access_token,\n refreshToken: refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n }\n\n // 超时\n throw new Error('Authorization timed out. Please try again.');\n }\n}\n\n/**\n * 获取设备流程服务实例\n */\nexport function getDeviceFlowService(): IDeviceFlowService {\n return new DeviceFlowService();\n}\n","/**\n * Ora UI 回调实现 - 使用 ora spinner\n * CLI 特定的 UI 实现\n */\n\nimport ora, { Ora } from 'ora';\nimport type { IUICallbacks } from './ui-callbacks.js';\n\n/**\n * Ora Spinner UI 回调实现\n * 使用 ora 库提供 CLI 进度显示\n */\nexport class OraUICallbacks implements IUICallbacks {\n private spinner: Ora | null = null;\n\n onStart(message: string): void {\n this.spinner = ora(message).start();\n }\n\n onSuccess(message: string): void {\n if (this.spinner) {\n this.spinner.succeed(message);\n this.spinner = null;\n }\n }\n\n onError(message: string): void {\n if (this.spinner) {\n this.spinner.fail(message);\n this.spinner = null;\n }\n }\n\n onUpdate(message: string): void {\n if (this.spinner) {\n this.spinner.text = message;\n }\n }\n}\n","/**\n * keytar 适配器 - 处理 ESM/CommonJS 互操作\n * keytar 是可选依赖,如果不可用则返回 null\n */\n\nimport { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\nlet keytarModule: any = null;\n\ntry {\n keytarModule = require('keytar');\n} catch (error) {\n // keytar 未安装或编译失败\n keytarModule = null;\n}\n\n/**\n * 检查 keytar 是否可用\n */\nexport function isKeytarAvailable(): boolean {\n return keytarModule !== null;\n}\n\n/**\n * 设置密码\n */\nexport async function setPassword(service: string, account: string, password: string): Promise<void> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n await keytarModule.setPassword(service, account, password);\n}\n\n/**\n * 获取密码\n */\nexport async function getPassword(service: string, account: string): Promise<string | null> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.getPassword(service, account);\n}\n\n/**\n * 删除密码\n */\nexport async function deletePassword(service: string, account: string): Promise<boolean> {\n if (!keytarModule) {\n throw new Error('keytar is not available');\n }\n return await keytarModule.deletePassword(service, account);\n}\n","/**\n * 文件凭据存储 - 作为 keytar 不可用时的降级方案\n * 将 token 存储在用户主目录的加密文件中\n */\n\nimport { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\n\n/**\n * 文件凭据存储实现\n */\nexport class FileCredentialStore {\n private configDir: string;\n\n constructor() {\n this.configDir = join(homedir(), '.wukong-cli');\n this.ensureConfigDir();\n }\n\n private ensureConfigDir(): void {\n if (!existsSync(this.configDir)) {\n mkdirSync(this.configDir, { recursive: true, mode: 0o700 });\n }\n }\n\n private getTokenPath(service: string, account: string): string {\n // 简单的文件命名:service_account.token\n const filename = `${service}_${account}.token`;\n return join(this.configDir, filename);\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n const filePath = this.getTokenPath(service, account);\n writeFileSync(filePath, password, { mode: 0o600 });\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n const filePath = this.getTokenPath(service, account);\n\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 清除所有 token\n */\n clear(): void {\n // 简单实现:删除整个配置目录\n // 更精细的实现可以只删除 .token 文件\n }\n}\n","/**\n * 凭据存储提供者 - 抽象凭据存储接口\n * 优先使用 keytar,不可用时降级到文件存储\n */\n\nimport * as keytarAdapter from '../core/auth/keytar-adapter.js';\nimport { FileCredentialStore } from './file-credential-store.js';\n\n/**\n * 凭据存储接口\n */\nexport interface ICredentialStore {\n setPassword(service: string, account: string, password: string): Promise<void>;\n getPassword(service: string, account: string): Promise<string | null>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\n/**\n * Keytar 凭据存储实现\n */\nclass KeytarCredentialStore implements ICredentialStore {\n async setPassword(service: string, account: string, password: string): Promise<void> {\n await keytarAdapter.setPassword(service, account, password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return await keytarAdapter.getPassword(service, account);\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return await keytarAdapter.deletePassword(service, account);\n }\n}\n\n/**\n * 内存凭据存储实现(用于测试)\n */\nexport class InMemoryCredentialStore implements ICredentialStore {\n private store: Map<string, string> = new Map();\n\n private getKey(service: string, account: string): string {\n return `${service}:${account}`;\n }\n\n async setPassword(service: string, account: string, password: string): Promise<void> {\n this.store.set(this.getKey(service, account), password);\n }\n\n async getPassword(service: string, account: string): Promise<string | null> {\n return this.store.get(this.getKey(service, account)) || null;\n }\n\n async deletePassword(service: string, account: string): Promise<boolean> {\n return this.store.delete(this.getKey(service, account));\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * 获取凭据存储实例\n * 自动选择:keytar 可用时使用 keytar,否则降级到文件存储\n */\nexport function getCredentialStore(): ICredentialStore {\n // 优先使用 keytar\n if (keytarAdapter.isKeytarAvailable()) {\n return new KeytarCredentialStore();\n }\n\n // 降级到文件存储\n return new FileCredentialStore();\n}\n\n/**\n * 获取测试用凭据存储实例\n */\nexport function getTestCredentialStore(): ICredentialStore {\n return new InMemoryCredentialStore();\n}\n\n/**\n * 检查是否使用安全存储(keytar)\n */\nexport function isUsingSecureStorage(): boolean {\n return keytarAdapter.isKeytarAvailable();\n}\n","/**\n * Token Cache 接口 - Token 缓存抽象\n * 用于替代全局变量 (global as any).__cachedAccessToken\n */\n\n/**\n * Token 缓存接口\n * 定义了 token 的读取、设置和清除操作\n */\nexport interface ITokenCache {\n /**\n * 获取访问令牌\n */\n getAccessToken(): string | null;\n\n /**\n * 获取刷新令牌\n */\n getRefreshToken(): string | null;\n\n /**\n * 设置令牌对\n */\n setTokens(accessToken: string, refreshToken: string): void;\n\n /**\n * 清除所有令牌\n */\n clear(): void;\n\n /**\n * 检查是否有有效的访问令牌\n */\n hasAccessToken(): boolean;\n\n /**\n * 检查是否有有效的刷新令牌\n */\n hasRefreshToken(): boolean;\n}\n\n/**\n * 内存 Token 缓存实现\n * 将 token 存储在内存中,适用于单次 CLI 会话\n */\nexport class MemoryTokenCache implements ITokenCache {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n getRefreshToken(): string | null {\n return this.refreshToken;\n }\n\n setTokens(accessToken: string, refreshToken: string): void {\n this.accessToken = accessToken;\n this.refreshToken = refreshToken;\n }\n\n clear(): void {\n this.accessToken = null;\n this.refreshToken = null;\n }\n\n hasAccessToken(): boolean {\n return this.accessToken !== null && this.accessToken.length > 0;\n }\n\n hasRefreshToken(): boolean {\n return this.refreshToken !== null && this.refreshToken.length > 0;\n }\n}\n\n/**\n * 全局 Token 缓存实例(单例)\n * 用于在整个 CLI 会话中共享同一个缓存实例\n */\nlet globalCacheInstance: ITokenCache | null = null;\n\n/**\n * 获取全局 Token 缓存实例\n * 如果不存在则创建一个新的 MemoryTokenCache 实例\n */\nexport function getGlobalTokenCache(): ITokenCache {\n if (!globalCacheInstance) {\n globalCacheInstance = new MemoryTokenCache();\n }\n return globalCacheInstance;\n}\n\n/**\n * 重置全局 Token 缓存实例\n * 用于测试或环境切换\n */\nexport function resetGlobalTokenCache(): void {\n globalCacheInstance = null;\n}\n\n/**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\nexport async function initializeTokenCache(\n loadTokens: () => Promise<{ accessToken: string | null; refreshToken: string | null }>\n): Promise<void> {\n const cache = getGlobalTokenCache();\n const { accessToken, refreshToken } = await loadTokens();\n\n if (accessToken && refreshToken) {\n cache.setTokens(accessToken, refreshToken);\n }\n}\n","/**\n * Wukong CLI 主入口\n * 命令结构: wukong-cli <command> [subcommand] [options]\n */\n\nimport { Command } from 'commander';\nimport { setDebugMode } from './utils/debug.js';\nimport { authCommands } from './commands/auth.js';\nimport { testCommand } from './commands/test.js';\nimport { httpCommand } from './commands/http.js';\n\nconst program = new Command();\n\n// 根命令配置\nprogram\n .name('wukong-cli')\n .description('Wukong CLI - TypeScript implementation')\n .version(CLI_VERSION)\n // 添加全局 --debug 选项\n .option('--debug', 'Enable debug mode (show HTTP requests)')\n // 在每个命令执行前设置调试模式\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n // 只有显式传递 --debug 时才设置为 true,否则允许环境变量生效\n if (options.debug === true) {\n setDebugMode(true, true);\n } else {\n // 不显式设置,允许环境变量生效\n setDebugMode(false, false);\n }\n });\n\n// 添加 auth 命令组\nprogram.addCommand(authCommands);\n\n// 添加 test 命令\nprogram.addCommand(testCommand);\n\n// 添加 http 命令组\nprogram.addCommand(httpCommand);\n\n// 如果没有参数,显示帮助\nif (process.argv.length === 2) {\n program.help();\n}\n\nprogram.parse();\n","/**\n * Debug utilities for HTTP request/response logging\n */\n\nimport chalk from 'chalk';\n\nlet debugMode: boolean | null = null;\nlet explicitSet = false; // 标记是否显式设置过\n\n/**\n * 启用调试模式\n * @param enabled 是否启用调试模式\n * @param explicit 是否显式设置(命令行参数),默认为 true\n */\nexport function setDebugMode(enabled: boolean, explicit: boolean = true): void {\n if (explicit) {\n debugMode = enabled;\n explicitSet = true;\n }\n // 同时设置全局变量供其他模块使用\n (global as any).__debugMode = enabled;\n}\n\n/**\n * 检查是否在调试模式\n * 优先级:命令行参数(显式设置)> 环境变量 > 默认关闭\n */\nexport function isDebugMode(): boolean {\n // 如果已显式通过命令行参数设置,优先使用\n if (explicitSet) {\n return debugMode === true;\n }\n\n // 检查全局变量\n if ((global as any).__debugMode === true) {\n return true;\n }\n\n // 检查环境变量 WUKONG_CLI_DEBUG\n return process.env.WUKONG_CLI_DEBUG === 'true';\n}\n\n/**\n * 打印 HTTP 请求\n */\nexport function debugRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n): void {\n if (!isDebugMode()) return;\n\n console.log('');\n console.log(chalk.dim('=== HTTP Request ==='));\n console.log(chalk.cyan(`${method} ${url}`));\n\n if (headers) {\n console.log(chalk.dim('Headers:'));\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization') {\n // 只显示 token 的前 50 个字符\n const truncated = value.length > 50\n ? value.substring(0, 50) + '...'\n : value;\n console.log(chalk.dim(` ${key}: ${truncated}`));\n } else {\n console.log(chalk.dim(` ${key}: ${value}`));\n }\n }\n }\n\n if (body) {\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n }\n console.log('');\n}\n\n/**\n * 打印 HTTP 响应\n */\nexport function debugResponse(\n status: number,\n statusText: string,\n body: any,\n duration: number\n): void {\n if (!isDebugMode()) return;\n\n const statusColor = status >= 200 && status < 300 ? chalk.green : chalk.red;\n\n console.log(chalk.dim('=== HTTP Response') + chalk.dim(` (${duration}ms) ===`));\n console.log(statusColor(`Status: ${status} ${statusText}`));\n console.log(chalk.dim('Body:'));\n console.log(chalk.dim(JSON.stringify(body, null, 2)));\n console.log('');\n}\n","/**\n * Auth 命令组 - 基于 Oceanet Auth\n * wukong-cli auth <subcommand>\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { printEnvironmentInfo } from '../utils/environment.js';\nimport { success, error } from '../utils/symbols.js';\nimport {\n getDeviceCode,\n pollToken,\n} from '../core/auth/device-flow.js';\nimport {\n saveToken,\n getAccessToken,\n logout,\n} from '../core/auth/token-manager.js';\nimport { getClient } from '../core/http/client.js';\nimport {\n Environment,\n ENVIRONMENTS,\n} from '../config/environments.js';\nimport { setCurrentEnvironment, getOceanetConfig, getCurrentEnvironment } from '../config/oceanet.js';\nimport { getAllEnvironments } from '../config/config-loader.js';\n\nexport const authCommands = new Command('auth')\n .description('Authentication commands');\n\n// 登录命令\nauthCommands\n .command('login')\n .description('Login using Device Authorization Flow')\n .action(async () => {\n try {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n // 设置当前环境\n setCurrentEnvironment(env as Environment);\n const config = getOceanetConfig();\n const envConfig = allEnvs[env];\n\n console.log('');\n console.log(chalk.bgBlue.white.bold(' Wukong CLI Login '));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n\n // 步骤 1: 获取设备授权链接\n const { verificationUri, deviceCode, expiresIn, interval } =\n await getDeviceCode();\n\n // 显示授权信息\n console.log('');\n console.log(chalk.bold('='.repeat(50)));\n console.log(chalk.bold(' Please complete authorization'));\n console.log(chalk.bold('='.repeat(50)));\n console.log('');\n console.log(chalk.green(' Authorization URL:'));\n console.log('');\n\n // 用多种方式显示链接,确保用户能看到\n console.log(chalk.cyan(` ${verificationUri}`));\n console.log('');\n\n // 同时输出到 stderr(Claude Code 能捕获)\n console.error(chalk.yellow.bold('>>> Please open this link in your browser <<<'));\n console.error(chalk.cyan(verificationUri));\n console.error('');\n\n // 尝试自动打开浏览器(如果环境支持)\n const open = await import('open').catch(() => null);\n if (open) {\n try {\n await open.default(verificationUri);\n console.log(chalk.dim(' Browser opened automatically'));\n } catch {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n } else {\n console.log(chalk.dim(' Please copy link to browser'));\n }\n console.log('');\n\n console.log(chalk.dim('═'.repeat(50)));\n console.log(chalk.dim(` Device Code: ${deviceCode}`));\n console.log(chalk.dim(` Expires in: ${expiresIn} seconds`));\n console.log(chalk.dim('═'.repeat(50)));\n console.log('');\n\n // 步骤 2: 轮询获取 Token\n const tokens = await pollToken(deviceCode);\n\n // 步骤 3: 保存 Token\n await saveToken(tokens.accessToken, tokens.refreshToken);\n\n console.log('');\n console.log(chalk.bgGreen.black.bold(' [OK] Login Successful '));\n console.log('');\n console.log(chalk.green('[OK] Tokens saved securely'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Access Token expires in: ${Math.floor(tokens.expiresIn / 60)} minutes`));\n console.log('');\n console.log(chalk.dim('Next:'), chalk.cyan('wukong-cli auth status'));\n console.log('');\n\n } catch (error) {\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n }\n });\n\n// 登出命令\nauthCommands\n .command('logout')\n .description('Logout and clear saved tokens')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n\n try {\n const accessToken = await getAccessToken();\n\n if (accessToken) {\n await logout(accessToken);\n }\n\n console.log('');\n console.log(chalk.green(`[OK] Logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n } catch {\n console.log('');\n console.log(chalk.yellow(`○ Already logged out from ${env}`), chalk.dim(`(${envConfig.displayName})`));\n console.log('');\n }\n });\n\n// 刷新 token 命令\nauthCommands\n .command('refresh')\n .description('Manually refresh access token')\n .action(async () => {\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const config = getOceanetConfig();\n\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.yellow('[ERROR] Not authenticated'));\n printEnvironmentInfo(env, envConfig.displayName);\n console.log('');\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return; // 不使用 process.exit,让程序自然退出\n }\n\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const client = getClient();\n await client.refreshToken();\n\n spinner.succeed('Token refreshed successfully!');\n\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('New tokens saved securely'));\n console.log('');\n } catch (error) {\n spinner.fail('Token refresh failed');\n throw error;\n }\n } catch (error) {\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Your session may have expired. Please run:`));\n console.log(chalk.dim(` wukong-cli auth login`));\n console.log('');\n // 不使用 process.exit,让程序自然退出\n }\n });\n\n// 状态命令\nauthCommands\n .command('status')\n .description('Show authentication status')\n .action(async () => {\n console.log('');\n\n // 获取当前环境(从环境变量或配置文件)\n const env = getCurrentEnvironment();\n const allEnvs = getAllEnvironments();\n\n setCurrentEnvironment(env as Environment);\n const envConfig = allEnvs[env];\n const config = getOceanetConfig();\n\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n return;\n }\n\n // 尝试获取用户信息来验证 token 是否真的有效\n try {\n const client = getClient();\n const userInfoUrl = `${config.AUTH_BASE_URL}/oceanet-auth/web/userInfo`;\n const userInfo = await client.get(userInfoUrl);\n\n // 只有 API 调用成功才显示已认证\n console.log(chalk.green('[OK] Authenticated'));\n console.log('');\n\n const displayUser = userInfo.firstName\n ? `${userInfo.firstName} (${userInfo.username})`\n : userInfo.username || 'N/A';\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim('User:'), chalk.cyan(displayUser));\n console.log(chalk.dim('Email:'), chalk.cyan(userInfo.email || 'N/A'));\n console.log(chalk.dim('OrgCode:'), chalk.cyan(userInfo.ouCode || 'N/A'));\n console.log(chalk.dim('OrgName:'), chalk.cyan(userInfo.ouName || 'N/A'));\n console.log('');\n } catch (error: any) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n console.log(chalk.yellow(`[ERROR] Not authenticated`));\n console.log('');\n\n console.log(chalk.red('Error:'), chalk.dim(errorMsg));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n } catch (error) {\n console.log(chalk.yellow(`✗ Not authenticated`));\n console.log('');\n printEnvironmentInfo(env, envConfig.displayName);\n console.log(chalk.dim(`Run: wukong-cli auth login`));\n console.log('');\n }\n });\n","/**\n * 环境显示工具\n * prod 环境不显示环境名称,保持界面简洁\n */\n\nimport chalk from 'chalk';\n\n/**\n * 格式化环境显示(prod 环境不显示)\n */\nexport function formatEnvironmentDisplay(env: string, displayName: string): string {\n if (env === 'prod') {\n return ''; // prod 环境不显示\n }\n return `${env} - ${displayName}`;\n}\n\n/**\n * 输出环境信息(prod 环境跳过)\n */\nexport function printEnvironmentInfo(env: string, displayName: string): void {\n const display = formatEnvironmentDisplay(env, displayName);\n if (display) {\n console.log(chalk.dim(`Environment: ${chalk.cyan(display)}`));\n }\n}\n","/**\n * Device PKCE Flow - 设备码授权流程\n * 从 oceanet.ts 提取的设备授权逻辑\n *\n * @deprecated 请直接使用 device-flow-service.ts 和 cli-device-flow.ts\n * 此文件保留以向后兼容\n */\n\nimport chalk from 'chalk';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { DeviceCodeResponse, TokenPair } from '../../types/auth.js';\nimport { createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\n\n// 重新导出类型和接口\nexport type { DeviceCodeResponse, TokenPair };\nexport type { IDeviceFlowService } from './device-flow-service.js';\n\n/**\n * 发起授权请求 - 获取设备授权链接\n * @deprecated 使用 CliDeviceFlowAdapter.getDeviceCode() 代替\n */\nexport async function getDeviceCode(): Promise<DeviceCodeResponse> {\n const config = getOceanetConfig();\n const adapter = createCliDeviceFlowAdapter();\n\n // 调试信息\n if (config.DEBUG) {\n console.log('');\n console.log(chalk.dim('=== Debug Info ==='));\n console.log(chalk.dim('Getting device authorization...'));\n console.log(chalk.dim('Client ID:'), chalk.yellow(config.CLIENT_ID));\n console.log('');\n }\n\n const result = await adapter.getDeviceCode();\n\n // 调试响应\n if (config.DEBUG) {\n console.log(chalk.dim('=== Response ==='));\n console.log(chalk.dim('Device Code:'), chalk.yellow(result.deviceCode));\n console.log(chalk.dim('Verification URI:'), chalk.cyan(result.verificationUri));\n console.log(chalk.dim('Expires In:'), chalk.yellow(result.expiresIn));\n console.log('');\n }\n\n return result;\n}\n\n/**\n * 轮询获取 Token\n * @deprecated 使用 CliDeviceFlowAdapter.pollToken() 代替\n */\nexport async function pollToken(deviceCode: string): Promise<TokenPair> {\n const adapter = createCliDeviceFlowAdapter();\n return adapter.pollToken(deviceCode);\n}\n\n// 重新导出新的服务和适配器\nexport { DeviceFlowService, getDeviceFlowService } from './device-flow-service.js';\nexport { CliDeviceFlowAdapter, createCliDeviceFlowAdapter } from '../../adapters/cli-device-flow.js';\nexport { IUICallbacks } from '../../adapters/ui-callbacks.js';\nexport { OraUICallbacks } from '../../adapters/ora-ui-callbacks.js';\n\n","/**\n * CLI 设备流程适配器 - 为设备流程添加 CLI UI 支持\n * 连接纯业务逻辑和 CLI UI 表现层\n */\n\nimport type { IDeviceFlowService } from '../core/auth/device-flow-service.js';\nimport type { IUICallbacks } from './ui-callbacks.js';\nimport type { DeviceCodeResponse, TokenPair } from '../types/auth.js';\n\n/**\n * CLI 设备流程适配器\n * 为设备流程服务添加 UI 反馈\n */\nexport class CliDeviceFlowAdapter {\n /**\n * 构造函数\n * @param deviceFlow 设备流程服务实例\n * @param ui UI 回调实例\n */\n constructor(\n private deviceFlow: IDeviceFlowService,\n private ui: IUICallbacks\n ) {}\n\n /**\n * 获取设备授权码(带 UI)\n */\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n this.ui.onStart('Getting device authorization...');\n\n try {\n const result = await this.deviceFlow.getDeviceCode();\n this.ui.onSuccess('Device code obtained');\n return result;\n } catch (error: any) {\n this.ui.onError('Failed to get device code');\n throw error;\n }\n }\n\n /**\n * 轮询获取 token(带 UI)\n */\n async pollToken(deviceCode: string): Promise<TokenPair> {\n this.ui.onStart('Waiting for authorization...');\n\n try {\n const result = await this.deviceFlow.pollToken(deviceCode);\n this.ui.onSuccess('Authorization successful!');\n return result;\n } catch (error: any) {\n this.ui.onError('Authorization error');\n throw error;\n }\n }\n}\n\n/**\n * 创建 CLI 设备流程适配器(使用默认实现)\n */\nexport function createCliDeviceFlowAdapter(): CliDeviceFlowAdapter {\n const { getDeviceFlowService } = require('../core/auth/device-flow-service.js');\n const { OraUICallbacks } = require('./ora-ui-callbacks.js');\n\n const deviceFlow = getDeviceFlowService();\n const ui = new OraUICallbacks();\n\n return new CliDeviceFlowAdapter(deviceFlow, ui);\n}\n","/**\n * UI 回调接口 - 用于 CLI 适配器\n * 定义 UI 操作的抽象,便于测试和替换 UI 实现\n */\n\n/**\n * UI 回调接口\n * 用于解耦业务逻辑和 CLI UI 表现层\n */\nexport interface IUICallbacks {\n /**\n * 操作开始时调用\n * @param message 提示消息\n */\n onStart(message: string): void;\n\n /**\n * 操作成功时调用\n * @param message 成功消息\n */\n onSuccess(message: string): void;\n\n /**\n * 操作失败时调用\n * @param message 失败消息\n */\n onError(message: string): void;\n\n /**\n * 更新操作信息\n * @param message 更新消息\n */\n onUpdate(message: string): void;\n}\n","/**\n * Token Manager - Token 存储和刷新管理\n * 从 oceanet.ts 提取的 token 管理逻辑\n */\n\nimport ora from 'ora';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { TokenPair } from '../../types/auth.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from './token-cache.js';\n\n/**\n * Token Manager 类\n * 负责与底层凭据存储和 token 缓存的交互\n */\nexport class TokenManager {\n /**\n * 构造函数\n * @param credentialStore 凭据存储实例\n * @param tokenCache token 缓存实例\n */\n constructor(\n private credentialStore: ICredentialStore,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 保存 Token\n */\n async saveToken(\n accessToken: string,\n refreshToken: string\n ): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'access_token', accessToken);\n await this.credentialStore.setPassword(config.SERVICE_NAME, 'refresh_token', refreshToken);\n\n // 更新缓存\n this.tokenCache.setTokens(accessToken, refreshToken);\n }\n\n /**\n * 获取 Access Token\n */\n async getAccessToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getAccessToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(token, null); // 只更新 access token\n }\n\n return token;\n }\n\n /**\n * 获取 Refresh Token\n */\n async getRefreshToken(): Promise<string | null> {\n // 优先从缓存读取\n const cached = this.tokenCache.getRefreshToken();\n if (cached) {\n return cached;\n }\n\n // 缓存未命中,从持久化存储读取\n const config = getOceanetConfig();\n const token = await this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token');\n\n // 简单更新缓存(避免循环依赖)\n if (token) {\n this.tokenCache.setTokens(null, token); // 只更新 refresh token\n }\n\n return token;\n }\n\n /**\n * 刷新 Token\n */\n async refreshAccessToken(\n refreshToken: string\n ): Promise<TokenPair> {\n const spinner = ora('Refreshing access token...').start();\n\n try {\n const config = getOceanetConfig();\n const url = `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ param: refreshToken }),\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n spinner.fail('Token refresh failed');\n throw new Error(data.message || 'Refresh token failed');\n }\n\n const {\n access_token,\n refresh_token: new_refresh_token,\n expires_in,\n token_type,\n scope,\n } = data.result;\n\n spinner.succeed('Token refreshed');\n\n return {\n accessToken: access_token,\n refreshToken: new_refresh_token,\n expiresIn: expires_in,\n tokenType: token_type,\n scope: Array.isArray(scope) ? scope : [scope || ''],\n };\n } catch (error) {\n spinner.fail('Token refresh error');\n throw error;\n }\n }\n\n /**\n * 清除本地 Token\n */\n async clearTokens(): Promise<void> {\n const config = getOceanetConfig();\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'access_token');\n await this.credentialStore.deletePassword(config.SERVICE_NAME, 'refresh_token');\n\n // 清除缓存\n this.tokenCache.clear();\n }\n\n /**\n * 退出登录\n */\n async logout(accessToken: string): Promise<void> {\n try {\n const config = getOceanetConfig();\n await fetch(`${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.LOGOUT}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n });\n } catch (error) {\n // 忽略退出登录错误\n }\n\n // 清除本地存储\n await this.clearTokens();\n }\n\n /**\n * 初始化 Token 缓存\n * 从持久化存储加载 token 到内存缓存\n */\n async initTokenCache(): Promise<void> {\n const config = getOceanetConfig();\n\n // 并行读取两个 token(避免循环依赖)\n const [accessToken, refreshToken] = await Promise.all([\n this.credentialStore.getPassword(config.SERVICE_NAME, 'access_token'),\n this.credentialStore.getPassword(config.SERVICE_NAME, 'refresh_token')\n ]);\n\n // 同时更新缓存\n if (accessToken || refreshToken) {\n this.tokenCache.setTokens(accessToken || null, refreshToken || null);\n }\n }\n}\n\n// ============ 便利函数(向后兼容) ============\n\n/**\n * 全局 TokenManager 实例\n */\nlet tokenManagerInstance: TokenManager | null = null;\n\n/**\n * 获取 TokenManager 单例\n */\nexport function getTokenManager(): TokenManager {\n if (!tokenManagerInstance) {\n // 延迟导入以避免循环依赖\n const { getCredentialStore } = require('../../providers/credential-store.js');\n const { getGlobalTokenCache } = require('./token-cache.js');\n\n const credentialStore = getCredentialStore();\n const tokenCache = getGlobalTokenCache();\n\n tokenManagerInstance = new TokenManager(credentialStore, tokenCache);\n }\n return tokenManagerInstance;\n}\n\n/**\n * 重置 TokenManager 实例\n */\nexport function resetTokenManager(): void {\n tokenManagerInstance = null;\n}\n\n/**\n * 保存 Token(便利函数)\n */\nexport async function saveToken(\n accessToken: string,\n refreshToken: string\n): Promise<void> {\n const manager = getTokenManager();\n await manager.saveToken(accessToken, refreshToken);\n}\n\n/**\n * 获取 Access Token(便利函数)\n */\nexport async function getAccessToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getAccessToken();\n}\n\n/**\n * 获取 Refresh Token(便利函数)\n */\nexport async function getRefreshToken(): Promise<string | null> {\n const manager = getTokenManager();\n return await manager.getRefreshToken();\n}\n\n/**\n * 刷新 Token(便利函数)\n */\nexport async function refreshAccessToken(\n refreshToken: string\n): Promise<TokenPair> {\n const manager = getTokenManager();\n return await manager.refreshAccessToken(refreshToken);\n}\n\n/**\n * 清除本地 Token(便利函数)\n */\nexport async function clearTokens(): Promise<void> {\n const manager = getTokenManager();\n await manager.clearTokens();\n}\n\n/**\n * 退出登录(便利函数)\n */\nexport async function logout(accessToken: string): Promise<void> {\n const manager = getTokenManager();\n await manager.logout(accessToken);\n}\n\n/**\n * 初始化 Token 缓存(便利函数)\n */\nexport async function initTokenCache(): Promise<void> {\n const manager = getTokenManager();\n await manager.initTokenCache();\n}\n","/**\n * Oceanet HTTP Client - 自动 Token 刷新的 HTTP 客户端\n * 从 oceanet-client.ts 重构\n *\n * 架构:\n * - BaseHttpClient: 纯 HTTP 请求\n * - AuthenticatingHttpClient: 添加认证和自动刷新\n * - ApiErrorHandler: 业务错误处理\n * - OceanetClient: 便利包装器(向后兼容)\n */\n\nimport { BaseHttpClient } from './base-http-client.js';\nimport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\n\n/**\n * Oceanet HTTP 客户端类(向后兼容的便利包装器)\n * 组合基础客户端、认证客户端和错误处理器\n */\nexport class OceanetClient implements IHttpClient {\n private authenticatingClient: AuthenticatingHttpClient;\n\n /**\n * 构造函数\n * @param tokenCache token 缓存实例(可选)\n */\n constructor(tokenCache?: ITokenCache) {\n // 如果没有提供 tokenCache,从全局获取\n let cache: ITokenCache;\n if (tokenCache) {\n cache = tokenCache;\n } else {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n cache = getGlobalTokenCache();\n }\n\n // 组合客户端链:Base -> Authenticating\n const baseClient = new BaseHttpClient();\n this.authenticatingClient = new AuthenticatingHttpClient(baseClient, cache);\n }\n\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options?: any\n ): Promise<T> {\n return this.authenticatingClient.request<T>(endpoint, options);\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.authenticatingClient.get<T>(endpoint, params);\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.post<T>(endpoint, data, headers);\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.put<T>(endpoint, data, headers);\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.authenticatingClient.delete<T>(endpoint);\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.authenticatingClient.patch<T>(endpoint, data, headers);\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n return this.authenticatingClient.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n return this.authenticatingClient.refreshToken();\n }\n}\n\n// 单例实例\nlet clientInstance: OceanetClient | null = null;\nlet lastEnvironment: string | null = null;\n\n/**\n * 清除 token 缓存\n */\nexport function clearTokenCache(): void {\n const { getGlobalTokenCache } = require('../auth/token-cache.js');\n const cache = getGlobalTokenCache();\n cache.clear();\n}\n\n/**\n * 获取 HTTP 客户端单例\n * 如果环境变化,会重新创建实例并清除缓存\n */\nexport function getClient(): OceanetClient {\n const currentEnv = getOceanetConfig().ENVIRONMENT;\n\n // 环境变化时,清除缓存并重新创建客户端实例\n if (!clientInstance || lastEnvironment !== currentEnv) {\n clearTokenCache();\n clientInstance = new OceanetClient();\n lastEnvironment = currentEnv;\n }\n return clientInstance;\n}\n\n// 重新导出新组件\nexport { BaseHttpClient } from './base-http-client.js';\nexport { AuthenticatingHttpClient } from './authenticating-http-client.js';\nexport { ApiErrorHandler, getApiErrorHandler, ApiError } from './api-error-handler.js';\nexport type { IHttpClient, IReadOnlyHttpClient, IMutatingHttpClient } from './http-client-interface.js';\n","/**\n * 基础 HTTP 客户端 - 纯 HTTP 请求逻辑\n * 不包含认证和错误处理\n */\n\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { RequestOptions, OceanetApiResponse } from '../../types/oceanet.js';\n\n/**\n * 构建 URL(添加查询参数)\n * 如果 endpoint 已经是完整 URL(以 http:// 或 https:// 开头),直接使用\n */\nfunction buildUrl(endpoint: string, params?: Record<string, string>): string {\n // 如果是完整 URL,直接使用\n if (endpoint.startsWith('http://') || endpoint.startsWith('https://')) {\n let url = endpoint;\n if (params) {\n const searchParams = new URLSearchParams(params);\n const separator = url.includes('?') ? '&' : '?';\n url += `${separator}${searchParams.toString()}`;\n }\n return url;\n }\n\n // 否则,拼接 base URL\n const config = getOceanetConfig();\n let url = `${config.API_BASE_URL}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return url;\n}\n\n/**\n * 基础 HTTP 客户端实现\n * 提供纯 HTTP 请求功能,不包含认证逻辑\n */\nexport class BaseHttpClient implements IHttpClient {\n /**\n * 发起 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const {\n method = 'GET',\n headers = {},\n body,\n params,\n } = options;\n\n const url = buildUrl(endpoint, params);\n const requestHeaders = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n\n // 打印请求(调试模式)\n debugRequest(method, url, requestHeaders, body);\n\n const startTime = Date.now();\n\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const duration = Date.now() - startTime;\n const data: OceanetApiResponse<T> = await response.json();\n\n // 打印响应(调试模式)\n debugResponse(response.status, response.statusText, data, duration);\n\n return data as T;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n}\n","/**\n * 认证 HTTP 客户端 - 添加认证和自动刷新功能\n * 装饰器模式,为基础 HTTP 客户端添加认证能力\n */\n\nimport type { IHttpClient } from './http-client-interface.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport { getApiErrorHandler, ApiError } from './api-error-handler.js';\nimport { getRetoken } from './interceptors.js';\nimport { getTokenManager } from '../auth/token-manager.js';\nimport { debugRequest, debugResponse } from '../../utils/debug.js';\n\n/**\n * 认证 HTTP 客户端\n * 为基础 HTTP 客户端添加:\n * 1. 自动添加 Authorization 头\n * 2. 401 自动刷新 token 并重试\n * 3. 业务错误处理\n */\nexport class AuthenticatingHttpClient implements IHttpClient {\n private initialized = false;\n\n constructor(\n private baseClient: IHttpClient,\n private tokenCache: ITokenCache\n ) {}\n\n /**\n * 确保 token 缓存已初始化\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n const tokenManager = getTokenManager();\n await tokenManager.initTokenCache();\n this.initialized = true;\n }\n }\n\n /**\n * 发起认证的 HTTP 请求\n */\n async request<T = any>(\n endpoint: string,\n options: any = {}\n ): Promise<T> {\n await this.ensureInitialized();\n\n // 获取当前 token\n const accessToken = this.tokenCache.getAccessToken();\n if (!accessToken) {\n throw new Error(\n 'Not authenticated. Please run: wukong-cli auth login'\n );\n }\n\n // 添加认证头\n const headers = {\n ...options.headers,\n 'Authorization': `Bearer ${accessToken}`,\n };\n\n // 构建完整 URL\n const url = `${(global as any).__apiBaseUrl || ''}${endpoint}`;\n\n // 打印调试信息\n debugRequest(options.method || 'GET', url, headers, options.body);\n\n // 使用 ts-retoken 的 fetch 包装器\n const retoken = getRetoken();\n const startTime = Date.now();\n const response = await retoken.fetch(\n url,\n {\n method: options.method || 'GET',\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n\n const data: OceanetApiResponse<T> = await response.json();\n const duration = Date.now() - startTime;\n\n // 打印响应调试信息\n debugResponse(response.status, response.statusText, data, duration);\n\n // 处理业务错误\n const errorHandler = getApiErrorHandler();\n\n // 9913 = token不存在或已失效,尝试刷新后重试\n if (data.code === 9913) {\n return errorHandler.tryRecover(\n new ApiError(data.code, data.message || 'Token expired', true),\n async () => {\n await retoken.refreshToken();\n const newAccessToken = this.tokenCache.getAccessToken();\n if (newAccessToken) {\n const retryResponse = await fetch(\n `${(global as any).__apiBaseUrl || ''}${endpoint}`,\n {\n method: options.method || 'GET',\n headers: {\n ...headers,\n 'Authorization': `Bearer ${newAccessToken}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n }\n );\n const retryData: OceanetApiResponse<T> = await retryResponse.json();\n\n if (retryData.code === 200) {\n return retryData.result;\n }\n throw new Error(\n `API Error (${retryData.code}): ${retryData.message || 'Unknown error'}`\n );\n }\n throw new Error('Failed to refresh token');\n }\n );\n }\n\n // 检查其他业务错误\n errorHandler.handle(data);\n\n return data.result;\n }\n\n /**\n * GET 请求\n */\n async get<T = any>(endpoint: string, params?: Record<string, string>): Promise<T> {\n return this.request<T>(endpoint, { method: 'GET', params });\n }\n\n /**\n * POST 请求\n */\n async post<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: data,\n headers,\n });\n }\n\n /**\n * PUT 请求\n */\n async put<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: data,\n headers,\n });\n }\n\n /**\n * DELETE 请求\n */\n async delete<T = any>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * PATCH 请求\n */\n async patch<T = any>(\n endpoint: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PATCH',\n body: data,\n headers,\n });\n }\n\n /**\n * 检查 token 是否即将过期\n */\n async isTokenExpiringSoon(): Promise<boolean> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n return retoken.isTokenExpiringSoon();\n }\n\n /**\n * 手动刷新 token\n */\n async refreshToken(): Promise<void> {\n await this.ensureInitialized();\n const retoken = getRetoken();\n await retoken.refreshToken();\n }\n}\n","/**\n * API 错误处理器 - 处理 Oceanet API 特定错误\n */\n\nimport type { OceanetApiResponse } from '../../types/oceanet.js';\nimport chalk from 'chalk';\n\n/**\n * API 错误类\n */\nexport class ApiError extends Error {\n constructor(\n public code: number,\n message: string,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/**\n * 错误处理函数类型\n */\ntype ErrorHandler = (response: OceanetApiResponse) => void | never;\n\n/**\n * API 错误处理器\n * 负责处理 Oceanet API 的业务错误码\n */\nexport class ApiErrorHandler {\n private errorHandlers: Map<number, ErrorHandler> = new Map();\n\n constructor() {\n // 注册默认错误处理器\n this.registerDefaultHandlers();\n }\n\n /**\n * 注册默认的 Oceanet 错误处理器\n */\n private registerDefaultHandlers(): void {\n // 9913 = token 不存在或已失效\n this.register(9913, (response) => {\n const error = new ApiError(\n response.code,\n response.message || 'Token expired or invalid',\n true // 可重试\n );\n throw error;\n });\n\n // 其他认证错误\n [401, 403].forEach(code => {\n this.register(code, (response) => {\n throw new ApiError(\n response.code,\n response.message || 'Authentication failed',\n code === 401 // 401 可以尝试刷新 token\n );\n });\n });\n }\n\n /**\n * 注册错误处理器\n * @param code 错误码\n * @param handler 处理函数\n */\n register(code: number, handler: ErrorHandler): void {\n this.errorHandlers.set(code, handler);\n }\n\n /**\n * 处理 API 响应\n * @param response API 响应\n * @throws {ApiError} 当响应包含错误时\n */\n handle(response: OceanetApiResponse): void {\n if (response.code !== 200) {\n const handler = this.errorHandlers.get(response.code);\n\n if (handler) {\n handler(response);\n }\n\n // 没有特定处理器,使用默认处理\n throw new ApiError(\n response.code,\n response.message || 'Unknown API error'\n );\n }\n }\n\n /**\n * 检查响应是否为错误\n * @param response API 响应\n * @returns 是否为错误\n */\n isError(response: OceanetApiResponse): boolean {\n return response.code !== 200;\n }\n\n /**\n * 尝试从错误中恢复\n * @param error 错误对象\n * @param recoverFunction 恢复函数\n * @returns 恢复结果或抛出错误\n */\n async tryRecover<T>(\n error: unknown,\n recoverFunction: () => Promise<T>\n ): Promise<T> {\n if (error instanceof ApiError && error.retryable) {\n console.log('');\n console.log(chalk.yellow('⚠ Token expired, attempting refresh...'));\n try {\n return await recoverFunction();\n } catch (refreshError: any) {\n console.log('');\n console.log(chalk.yellow('⚠ Auto-refresh failed:'), chalk.dim(refreshError.message));\n throw new ApiError(\n error.code,\n `${error.message} (Auto-refresh failed)`\n );\n }\n }\n throw error;\n }\n}\n\n/**\n * 获取全局错误处理器实例\n */\nlet errorHandlerInstance: ApiErrorHandler | null = null;\n\nexport function getApiErrorHandler(): ApiErrorHandler {\n if (!errorHandlerInstance) {\n errorHandlerInstance = new ApiErrorHandler();\n }\n return errorHandlerInstance;\n}\n","/**\n * HTTP 拦截器 - Token 刷新和 401 重试逻辑\n * 使用 ts-retoken 实现\n */\n\nimport { createRetoken } from 'ts-retoken';\nimport { getOceanetConfig } from '../../config/oceanet.js';\nimport type { Tokens } from '../../types/oceanet.js';\nimport type { ICredentialStore } from '../../providers/credential-store.js';\nimport type { ITokenCache } from '../auth/token-cache.js';\n\n/**\n * 创建 retoken 实例(动态获取配置)\n * 处理主动刷新和 401 重试\n * @param credentialStore 凭据存储实例(可选)\n * @param tokenCache token 缓存实例(可选)\n */\nexport function createRetokenInstance(\n credentialStore?: ICredentialStore,\n tokenCache?: ITokenCache\n) {\n const config = getOceanetConfig();\n\n // 如果没有提供实例,使用默认实现\n const store = credentialStore || (require('../../providers/credential-store.js').getCredentialStore());\n const cache = tokenCache || (require('../auth/token-cache.js').getGlobalTokenCache());\n\n return createRetoken({\n refreshEndpoint: {\n url: `${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`,\n method: 'POST',\n // Oceanet API 要求: { \"param\": \"refresh_token_string\" }\n buildBody: (token) => JSON.stringify({ param: token }),\n headers: {\n 'Content-Type': 'application/json',\n },\n parseResponse: (data: any) => {\n // 调试:打印请求和响应\n if (config.DEBUG || (global as any).__debugMode) {\n console.log('');\n console.log('=== HTTP Request ===');\n console.log(`POST ${config.AUTH_BASE_URL}${config.AUTH_ENDPOINTS.REFRESH_TOKEN}`);\n console.log('Headers:');\n console.log(' Content-Type: application/json');\n console.log('Body:');\n const refreshToken = cache.getRefreshToken();\n const truncated = refreshToken && refreshToken.length > 50\n ? refreshToken.substring(0, 50) + '...'\n : refreshToken || '(none)';\n console.log(` {\"param\":\"${truncated}\"}`);\n console.log('');\n console.log('=== HTTP Response ===');\n console.log(JSON.stringify(data, null, 2));\n console.log('');\n }\n\n // 检查业务错误码 - refresh_token 过期或无效\n if (data.code === 401 || data.code === 403) {\n const error: any = new Error(data.message || 'Refresh token expired or invalid');\n error.code = data.code;\n error.isAuthFailure = true;\n throw error;\n }\n\n // Oceanet API 返回格式: { code: 200, result: { access_token, refresh_token, ... } }\n const result = data.result || data;\n\n // 验证 token 字段存在\n if (!result.access_token && !result.accessToken) {\n throw new Error('Invalid token response: missing access_token field');\n }\n if (!result.refresh_token && !result.refreshToken) {\n throw new Error('Invalid token response: missing refresh_token field');\n }\n\n return {\n accessToken: result.access_token || result.accessToken,\n refreshToken: result.refresh_token || result.refreshToken,\n };\n },\n },\n // 从缓存获取 token(同步函数)\n getAccessToken: () => {\n return cache.getAccessToken();\n },\n getRefreshToken: () => {\n return cache.getRefreshToken();\n },\n // 保存 token 到持久化存储和缓存(异步)\n setTokens: async (tokens: Tokens) => {\n // 参数验证 - 支持驼峰和下划线命名\n const accessToken = tokens?.accessToken || tokens?.access_token;\n const refreshToken = tokens?.refreshToken || tokens?.refresh_token;\n\n if (!accessToken || !refreshToken) {\n throw new Error('Invalid tokens: missing access_token or refresh_token');\n }\n\n const cfg = getOceanetConfig();\n await store.setPassword(cfg.SERVICE_NAME, 'access_token', accessToken);\n await store.setPassword(cfg.SERVICE_NAME, 'refresh_token', refreshToken);\n // 更新缓存\n cache.setTokens(accessToken, refreshToken);\n },\n // 清除 token\n clearTokens: async () => {\n const cfg = getOceanetConfig();\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n // 清除缓存\n cache.clear();\n },\n // 提前 1 分钟(60 秒)主动刷新\n expirationLeeway: 60,\n // 401 时触发重试\n retryStatuses: [401],\n // 认证完全失败时的回调\n onAuthFailure: async () => {\n const cfg = getOceanetConfig();\n try {\n await store.deletePassword(cfg.SERVICE_NAME, 'access_token');\n await store.deletePassword(cfg.SERVICE_NAME, 'refresh_token');\n cache.clear();\n } catch {\n // 忽略清除错误\n }\n },\n });\n}\n\n// 缓存的 retoken 实例(按环境)\nconst retokenInstances: Record<string, ReturnType<typeof createRetokenInstance>> = {};\n\n/**\n * 获取当前环境的 retoken 实例\n */\nexport function getRetoken() {\n const config = getOceanetConfig();\n const env = config.ENVIRONMENT;\n\n if (!retokenInstances[env]) {\n retokenInstances[env] = createRetokenInstance();\n }\n\n return retokenInstances[env];\n}\n","/**\n * 测试命令 - 使用 Oceanet HTTP 客户端\n * wukong-cli test\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\n\nexport const testCommand = new Command('test')\n .description('Test API request with saved token')\n .action(async () => {\n try {\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n console.log('');\n console.log(chalk.red('[ERROR] Not authenticated'));\n console.log('');\n console.log(chalk.dim('Please run: wukong-cli auth login'));\n console.log('');\n process.exit(1);\n }\n\n const spinner = ora('Testing API connection...').start();\n\n try {\n // 使用 HTTP 客户端获取用户信息\n const client = getClient();\n const userInfo = await client.get<any>('/oceanet-auth/web/userInfo');\n\n spinner.succeed('API request successful');\n\n console.log('');\n console.log(chalk.green('User Info:'));\n console.log(chalk.dim(JSON.stringify(userInfo, null, 2)));\n console.log('');\n\n } catch (error: any) {\n spinner.fail('API request failed');\n\n if (error.message.includes('401') || error.message.includes('expired')) {\n console.log('');\n console.log(chalk.yellow('Token expired or invalid'));\n console.log(chalk.dim('Try: wukong-cli auth refresh'));\n console.log('');\n } else {\n throw error;\n }\n }\n\n } catch (error) {\n console.log('');\n console.log(chalk.red(`[ERROR] ${error instanceof Error ? error.message : 'Unknown error'}`));\n console.log('');\n process.exit(1);\n }\n });\n","/**\n * HTTP 测试命令\n */\n\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { getClient } from '../core/http/client.js';\nimport { getAccessToken } from '../core/auth/token-manager.js';\nimport { OCEANET_CONFIG } from '../config/oceanet.js';\n\ninterface RequestOptions {\n baseUrl?: string;\n headers: string[];\n data?: string;\n}\n\n/**\n * 修复 Git Bash 路径转换问题\n */\nfunction fixGitBashPath(url: string): string {\n if (url.includes(':') && !url.startsWith('http')) {\n // 移除 Windows 路径前缀 (如 \"D:/Program Files/Git\")\n // 查找 \"/oceanet-\" 并从那里开始\n const oceanetIndex = url.indexOf('/oceanet-');\n if (oceanetIndex >= 0) {\n return url.substring(oceanetIndex);\n }\n }\n return url;\n}\n\n/**\n * 解析自定义头\n */\nfunction parseHeaders(headers: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n if (Array.isArray(headers)) {\n for (const h of headers) {\n const [key, ...valueParts] = h.split(':');\n if (key && valueParts.length > 0) {\n result[key.trim()] = valueParts.join(':').trim();\n }\n }\n }\n return result;\n}\n\n/**\n * 构建完整 URL\n */\nfunction buildUrl(url: string, baseUrl?: string): string {\n const cleanUrl = fixGitBashPath(url);\n if (cleanUrl.startsWith('http')) {\n return cleanUrl;\n }\n const base = baseUrl || OCEANET_CONFIG.API_BASE_URL;\n return `${base}${cleanUrl}`;\n}\n\n/**\n * 执行 HTTP 请求\n */\nasync function executeRequest(\n method: string,\n url: string,\n options: RequestOptions\n): Promise<void> {\n const spinner = ora('Sending request...').start();\n\n try {\n // 获取 Token\n const accessToken = await getAccessToken();\n\n if (!accessToken) {\n spinner.fail('Not authenticated');\n console.error(chalk.red('Please run: wukong-cli auth login'));\n process.exit(1);\n }\n\n // 构建完整 URL\n const fullUrl = buildUrl(url, options.baseUrl);\n\n // 解析自定义头\n const customHeaders = parseHeaders(options.headers);\n\n // 构建请求头\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n ...customHeaders,\n };\n\n // 构建请求体\n let body: string | undefined;\n if (options.data) {\n body = options.data;\n // 如果没有自定义 Content-Type,使用 application/json\n if (!customHeaders['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n }\n\n // 发起请求\n spinner.text = `${method} ${chalk.cyan(fullUrl)}`;\n\n const response = await fetch(fullUrl, {\n method,\n headers,\n body: method !== 'GET' && method !== 'DELETE' ? body : undefined,\n });\n\n const data = await response.json();\n\n spinner.succeed('Response received');\n\n // 显示响应\n console.log('');\n console.log(chalk.dim('Status:'), response.status, response.statusText);\n console.log('');\n console.log(chalk.dim('Response:'));\n console.log(JSON.stringify(data, null, 2));\n\n } catch (error) {\n spinner.fail('Request failed');\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\nexport const httpCommand = new Command('http');\n\n// GET 请求\nhttpCommand\n .command('get <url>')\n .description('Send GET request (uses OCEANET_API_BASE_URL or override with -b)')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('GET', url, options);\n });\n\n// POST 请求\nhttpCommand\n .command('post <url>')\n .description('Send POST request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('POST', url, options);\n });\n\n// PUT 请求\nhttpCommand\n .command('put <url>')\n .description('Send PUT request with JSON data')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .option('-d, --data <json>', 'Request body as JSON string')\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('PUT', url, options);\n });\n\n// DELETE 请求\nhttpCommand\n .command('delete <url>')\n .description('Send DELETE request')\n .option('-b, --base-url <url>', 'Override base URL')\n .option('-H, --header <key:value>', 'Custom header (can be used multiple times)', [])\n .action(async (url: string, options: RequestOptions) => {\n await executeRequest('DELETE', url, options);\n });\n"],"mappings":"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","names":["fileURLToPath","envConfig","require","writeFileSync","readFileSync","existsSync","mkdirSync","join","homedir","Command","chalk","ora","chalk","chalk","getDeviceFlowService","OraUICallbacks","chalk","ora","getCredentialStore","getGlobalTokenCache","url","chalk","getGlobalTokenCache","currentEnv","envConfig","chalk","ora","Command","ora","chalk","Command","chalk","ora","Command","ora","chalk","buildUrl","ora","chalk","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zrhsh/wukong-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Wukong CLI - TypeScript with auto token refresh",
5
5
  "private": false,
6
6
  "type": "module",