edgeone-cli 1.0.11 → 1.0.13
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/api/client.d.ts +46 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +210 -1
- package/dist/api/signer.js +1 -1
- package/dist/commands/config.d.ts +19 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +312 -1
- package/dist/commands/edgeone.d.ts +14 -0
- package/dist/commands/edgeone.d.ts.map +1 -0
- package/dist/commands/edgeone.js +414 -1
- package/dist/constants/index.d.ts +36 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +60 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -1
- package/dist/repl/config-menu.d.ts +12 -0
- package/dist/repl/config-menu.d.ts.map +1 -0
- package/dist/repl/config-menu.js +264 -0
- package/dist/repl/index.d.ts +8 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/repl/index.js +95 -0
- package/dist/repl/prefetch-menu.d.ts +15 -0
- package/dist/repl/prefetch-menu.d.ts.map +1 -0
- package/dist/repl/prefetch-menu.js +192 -0
- package/dist/repl/purge-menu.d.ts +15 -0
- package/dist/repl/purge-menu.d.ts.map +1 -0
- package/dist/repl/purge-menu.js +228 -0
- package/dist/repl/ui.d.ts +16 -0
- package/dist/repl/ui.d.ts.map +1 -0
- package/dist/repl/ui.js +29 -0
- package/dist/repl/zone-menu.d.ts +15 -0
- package/dist/repl/zone-menu.d.ts.map +1 -0
- package/dist/repl/zone-menu.js +219 -0
- package/dist/repl.js +1 -1
- package/dist/types/index.d.ts +241 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/utils/crypto.d.ts +13 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +85 -1
- package/dist/utils/date.d.ts +26 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +52 -0
- package/dist/utils/display.d.ts +38 -0
- package/dist/utils/display.d.ts.map +1 -0
- package/dist/utils/display.js +72 -0
- package/dist/utils/signature.d.ts +6 -0
- package/dist/utils/signature.d.ts.map +1 -0
- package/dist/utils/signature.js +49 -1
- package/package.json +1 -1
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 清除缓存菜单
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
import { EdgeOneClient } from "../api/client.js";
|
|
7
|
+
import { pauseToContinue } from "./ui.js";
|
|
8
|
+
/**
|
|
9
|
+
* 清除缓存菜单
|
|
10
|
+
*/
|
|
11
|
+
export async function purgeMenu(config) {
|
|
12
|
+
const actionAnswers = await inquirer.prompt([
|
|
13
|
+
{
|
|
14
|
+
type: "list",
|
|
15
|
+
name: "type",
|
|
16
|
+
message: "选择操作:",
|
|
17
|
+
choices: [
|
|
18
|
+
{ name: "清除缓存", value: "purge" },
|
|
19
|
+
{ name: "查询历史", value: "history" },
|
|
20
|
+
new inquirer.Separator(),
|
|
21
|
+
{ name: "← 返回", value: "back" },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
if (actionAnswers.type === "back")
|
|
26
|
+
return;
|
|
27
|
+
if (actionAnswers.type === "history") {
|
|
28
|
+
await queryPurgeHistoryMenu(config);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const answers = await inquirer.prompt([
|
|
32
|
+
{
|
|
33
|
+
type: "list",
|
|
34
|
+
name: "type",
|
|
35
|
+
message: "选择清除类型:",
|
|
36
|
+
choices: [
|
|
37
|
+
{ name: "清除全部缓存", value: "all" },
|
|
38
|
+
{ name: "清除指定目录缓存", value: "dir" },
|
|
39
|
+
{ name: "清除指定 URL 缓存", value: "url" },
|
|
40
|
+
new inquirer.Separator(),
|
|
41
|
+
{ name: "← 返回", value: "back" },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
if (answers.type === "back")
|
|
46
|
+
return;
|
|
47
|
+
let targets = [];
|
|
48
|
+
let purgeType = "purge_all";
|
|
49
|
+
let zoneId = "*";
|
|
50
|
+
// 选择 Zone ID
|
|
51
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
52
|
+
const zoneChoices = config.domainIdList.map((zone) => ({
|
|
53
|
+
name: zone.name || zone.id,
|
|
54
|
+
value: zone.id,
|
|
55
|
+
}));
|
|
56
|
+
const zoneAnswers = await inquirer.prompt([
|
|
57
|
+
{
|
|
58
|
+
type: "list",
|
|
59
|
+
name: "zone",
|
|
60
|
+
message: "选择站点:",
|
|
61
|
+
choices: ["* (全部站点)", ...zoneChoices],
|
|
62
|
+
},
|
|
63
|
+
]);
|
|
64
|
+
if (zoneAnswers.zone !== "* (全部站点)") {
|
|
65
|
+
zoneId = zoneAnswers.zone;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (answers.type === "all") {
|
|
69
|
+
const confirm = await inquirer.prompt([
|
|
70
|
+
{ type: "confirm", name: "confirm", message: `确认清除全部缓存? (Zone: ${zoneId})`, default: false },
|
|
71
|
+
]);
|
|
72
|
+
if (!confirm.confirm) {
|
|
73
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
74
|
+
await pauseToContinue();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
purgeType = "purge_all";
|
|
78
|
+
}
|
|
79
|
+
else if (answers.type === "dir") {
|
|
80
|
+
const dirAnswers = await inquirer.prompt([
|
|
81
|
+
{ type: "input", name: "dir", message: "请输入目录路径 (留空取消):" },
|
|
82
|
+
]);
|
|
83
|
+
if (!dirAnswers.dir || !dirAnswers.dir.trim()) {
|
|
84
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
85
|
+
await pauseToContinue();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
targets = [dirAnswers.dir];
|
|
89
|
+
purgeType = "purge_prefix";
|
|
90
|
+
}
|
|
91
|
+
else if (answers.type === "url") {
|
|
92
|
+
const urlAnswers = await inquirer.prompt([
|
|
93
|
+
{ type: "input", name: "urls", message: "请输入 URL (多个用空格分隔,留空取消):" },
|
|
94
|
+
]);
|
|
95
|
+
if (!urlAnswers.urls || !urlAnswers.urls.trim()) {
|
|
96
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
97
|
+
await pauseToContinue();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
targets = urlAnswers.urls.split(/\s+/).filter(u => u.trim());
|
|
101
|
+
purgeType = "purge_url";
|
|
102
|
+
}
|
|
103
|
+
// 执行清除缓存
|
|
104
|
+
await executePurge(config, purgeType, targets, zoneId);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 执行清除缓存
|
|
108
|
+
*/
|
|
109
|
+
async function executePurge(config, type, targets, zoneId) {
|
|
110
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "ap-guangzhou", config.mode);
|
|
111
|
+
const isDebug = config.mode === "debug";
|
|
112
|
+
if (isDebug) {
|
|
113
|
+
console.log(chalk.cyan("\n🔄 清除缓存任务\n"));
|
|
114
|
+
console.log(chalk.gray("API 参数:"));
|
|
115
|
+
console.log(` ZoneId: ${chalk.green(zoneId)}`);
|
|
116
|
+
console.log(` Type: ${chalk.green(type)}`);
|
|
117
|
+
if (targets.length > 0) {
|
|
118
|
+
console.log(` Targets: ${chalk.green(JSON.stringify(targets))}`);
|
|
119
|
+
}
|
|
120
|
+
console.log("");
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const result = await client.createPurgeTask({ zoneId, type, targets });
|
|
124
|
+
if ("Error" in result.Response) {
|
|
125
|
+
const error = result.Response.Error;
|
|
126
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
127
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
128
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
console.log(chalk.green("\n✅ 请求成功!"));
|
|
132
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
133
|
+
if (result.Response.JobId) {
|
|
134
|
+
console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
140
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
141
|
+
console.log(` ${errMsg}`);
|
|
142
|
+
}
|
|
143
|
+
console.log("");
|
|
144
|
+
await pauseToContinue();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 查询清除缓存历史菜单
|
|
148
|
+
*/
|
|
149
|
+
async function queryPurgeHistoryMenu(config) {
|
|
150
|
+
// 选择 Zone ID
|
|
151
|
+
let zoneIds = [];
|
|
152
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
153
|
+
const zoneChoices = config.domainIdList.map((zone) => ({
|
|
154
|
+
name: zone.name || zone.id,
|
|
155
|
+
value: zone.id,
|
|
156
|
+
short: zone.name || zone.id,
|
|
157
|
+
}));
|
|
158
|
+
const zoneAnswers = await inquirer.prompt([
|
|
159
|
+
{
|
|
160
|
+
type: "checkbox",
|
|
161
|
+
name: "zones",
|
|
162
|
+
message: "选择站点 (可多选):",
|
|
163
|
+
choices: zoneChoices,
|
|
164
|
+
validate: input => input.length > 0 || "请至少选择一个站点",
|
|
165
|
+
},
|
|
166
|
+
]);
|
|
167
|
+
zoneIds = zoneAnswers.zones;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
await queryPurgeHistory(config, zoneIds);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 查询清除缓存历史
|
|
177
|
+
*/
|
|
178
|
+
async function queryPurgeHistory(config, zoneIds) {
|
|
179
|
+
const { default: Table } = await import("cli-table3");
|
|
180
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "", config.mode);
|
|
181
|
+
const isDebug = config.mode === "debug";
|
|
182
|
+
if (isDebug) {
|
|
183
|
+
console.log(chalk.cyan("\n📋 清除缓存历史记录\n"));
|
|
184
|
+
console.log(chalk.gray("ZoneIds: " + zoneIds.join(", ")));
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const result = await client.describePurgeTasks(zoneIds);
|
|
188
|
+
if ("Error" in result.Response) {
|
|
189
|
+
const error = result.Response.Error;
|
|
190
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
191
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
192
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
console.log(chalk.green("\n✅ 查询成功!"));
|
|
196
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
197
|
+
const tasks = result.Response.Tasks || [];
|
|
198
|
+
if (tasks.length > 0) {
|
|
199
|
+
const table = new Table({
|
|
200
|
+
head: [chalk.gray("状态"), chalk.gray("清除地址"), chalk.gray("时间"), chalk.gray("类型")],
|
|
201
|
+
colWidths: [8, 50, 30, 8],
|
|
202
|
+
chars: { mid: "", "left-mid": "", "mid-mid": "", "right-mid": "" },
|
|
203
|
+
});
|
|
204
|
+
tasks.forEach(task => {
|
|
205
|
+
const status = task.Status === "success" ? chalk.green("✓") : chalk.red("✗");
|
|
206
|
+
const target = task.Target || "all";
|
|
207
|
+
const type = task.Type === "purge_url" ? "URL" : task.Type === "purge_prefix" ? "目录" : "全部";
|
|
208
|
+
// 截断过长的目标地址
|
|
209
|
+
const displayTarget = target.length > 47 ? target.slice(0, 44) + "..." : target;
|
|
210
|
+
table.push([status, chalk.yellow(displayTarget), chalk.gray(task.CreateTime.slice(0, 19).replace("T", " ")), type]);
|
|
211
|
+
});
|
|
212
|
+
console.log(chalk.cyan("\n📋 清除缓存记录:\n"));
|
|
213
|
+
console.log(table.toString());
|
|
214
|
+
console.log(` 总计: ${chalk.yellow(result.Response.TotalCount || tasks.length)} 条记录`);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.log(chalk.gray("\n 暂无清除记录\n"));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
223
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
224
|
+
console.log(` ${errMsg}`);
|
|
225
|
+
}
|
|
226
|
+
console.log("");
|
|
227
|
+
await pauseToContinue();
|
|
228
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互式菜单 UI 工具函数
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 暂停等待用户确认后返回
|
|
6
|
+
*/
|
|
7
|
+
export declare function pauseToContinue(): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* 显示欢迎横幅
|
|
10
|
+
*/
|
|
11
|
+
export declare function showBanner(): void;
|
|
12
|
+
/**
|
|
13
|
+
* 清屏并显示横幅
|
|
14
|
+
*/
|
|
15
|
+
export declare function clearScreenWithBanner(): void;
|
|
16
|
+
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/repl/ui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAOjC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|
package/dist/repl/ui.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互式菜单 UI 工具函数
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
/**
|
|
7
|
+
* 暂停等待用户确认后返回
|
|
8
|
+
*/
|
|
9
|
+
export async function pauseToContinue() {
|
|
10
|
+
await inquirer.prompt([{ type: "input", name: "continue", message: "按 Enter 键返回..." }]);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 显示欢迎横幅
|
|
14
|
+
*/
|
|
15
|
+
export function showBanner() {
|
|
16
|
+
console.log("");
|
|
17
|
+
console.log(chalk.cyan("╔════════════════════════════════════╗"));
|
|
18
|
+
console.log(chalk.cyan("║") + " " + chalk.white.bold("EdgeOne CLI") + " " + chalk.cyan("║"));
|
|
19
|
+
console.log(chalk.cyan("║") + " " + chalk.gray("本地化 EdgeOne 服务管理工具") + " " + chalk.cyan("║"));
|
|
20
|
+
console.log(chalk.cyan("╚════════════════════════════════════╝"));
|
|
21
|
+
console.log("");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 清屏并显示横幅
|
|
25
|
+
*/
|
|
26
|
+
export function clearScreenWithBanner() {
|
|
27
|
+
console.clear();
|
|
28
|
+
showBanner();
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 站点状态菜单
|
|
3
|
+
*/
|
|
4
|
+
import type { ZoneConfig } from "../types/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* 站点状态菜单
|
|
7
|
+
*/
|
|
8
|
+
export declare function zoneStatusMenu(config: {
|
|
9
|
+
secretId: string;
|
|
10
|
+
secretKey: string;
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
mode: "debug" | "production";
|
|
13
|
+
domainIdList?: ZoneConfig[];
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=zone-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zone-menu.d.ts","sourceRoot":"","sources":["../../src/repl/zone-menu.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,mBAAmB,CAAC;AAGlE;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;IAAC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCjL"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 站点状态菜单
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
import { EdgeOneClient } from "../api/client.js";
|
|
7
|
+
import { pauseToContinue } from "./ui.js";
|
|
8
|
+
/**
|
|
9
|
+
* 站点状态菜单
|
|
10
|
+
*/
|
|
11
|
+
export async function zoneStatusMenu(config) {
|
|
12
|
+
// 检查是否配置了站点列表
|
|
13
|
+
if (!config.domainIdList || config.domainIdList.length === 0) {
|
|
14
|
+
console.log(chalk.yellow("\n⚠️ 未配置站点列表,请先在配置中添加站点\n"));
|
|
15
|
+
await pauseToContinue();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const answers = await inquirer.prompt([
|
|
19
|
+
{
|
|
20
|
+
type: "list",
|
|
21
|
+
name: "action",
|
|
22
|
+
message: "站点状态管理:",
|
|
23
|
+
choices: [
|
|
24
|
+
{ name: "🔍 查看站点状态", value: "view" },
|
|
25
|
+
{ name: "🔘 修改站点状态", value: "modify" },
|
|
26
|
+
new inquirer.Separator(),
|
|
27
|
+
{ name: "← 返回", value: "back" },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
if (answers.action === "back")
|
|
32
|
+
return;
|
|
33
|
+
if (answers.action === "view") {
|
|
34
|
+
if (config.domainIdList) {
|
|
35
|
+
await viewZoneStatus({ ...config, domainIdList: config.domainIdList });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (answers.action === "modify") {
|
|
39
|
+
if (config.domainIdList) {
|
|
40
|
+
await modifyZoneStatus({ ...config, domainIdList: config.domainIdList });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 选择站点
|
|
46
|
+
*/
|
|
47
|
+
async function selectZone(config, message) {
|
|
48
|
+
const zoneChoices = config.domainIdList.map((zone) => ({
|
|
49
|
+
name: zone.name || zone.id,
|
|
50
|
+
value: zone.id,
|
|
51
|
+
}));
|
|
52
|
+
const zoneAnswers = await inquirer.prompt([
|
|
53
|
+
{
|
|
54
|
+
type: "list",
|
|
55
|
+
name: "zone",
|
|
56
|
+
message,
|
|
57
|
+
choices: [...zoneChoices, new inquirer.Separator(), { name: "← 返回", value: "back" }],
|
|
58
|
+
},
|
|
59
|
+
]);
|
|
60
|
+
if (zoneAnswers.zone === "back")
|
|
61
|
+
return null;
|
|
62
|
+
return zoneAnswers.zone;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 查看站点状态
|
|
66
|
+
*/
|
|
67
|
+
async function viewZoneStatus(config) {
|
|
68
|
+
const selectedZoneId = await selectZone(config, "选择要查看的站点:");
|
|
69
|
+
if (!selectedZoneId)
|
|
70
|
+
return;
|
|
71
|
+
const selectedZone = config.domainIdList.find(z => z.id === selectedZoneId);
|
|
72
|
+
const zoneDisplay = selectedZone?.name || selectedZoneId;
|
|
73
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "ap-guangzhou", config.mode);
|
|
74
|
+
const isDebug = config.mode === "debug";
|
|
75
|
+
if (isDebug) {
|
|
76
|
+
console.log(chalk.cyan("\n🔍 查看站点状态\n"));
|
|
77
|
+
console.log(chalk.gray("API 参数:"));
|
|
78
|
+
console.log(` Action: ${chalk.green("DescribeZones")}`);
|
|
79
|
+
console.log(` ZoneIds: ${chalk.green([selectedZoneId])}`);
|
|
80
|
+
console.log("");
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const result = await client.describeZoneStatus({ zoneId: selectedZoneId });
|
|
84
|
+
if ("Error" in result.Response) {
|
|
85
|
+
const error = result.Response.Error;
|
|
86
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
87
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
88
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log(chalk.green("\n✅ 查询成功!"));
|
|
92
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
93
|
+
// 显示站点状态信息
|
|
94
|
+
const zones = result.Response.Zones || [];
|
|
95
|
+
if (zones.length > 0) {
|
|
96
|
+
const zone = zones[0];
|
|
97
|
+
const paused = zone.Paused;
|
|
98
|
+
const statusText = paused ? "关闭" : "开启";
|
|
99
|
+
const statusColor = paused ? chalk.red : chalk.green;
|
|
100
|
+
// 获取接入方式
|
|
101
|
+
let accessType = "未知";
|
|
102
|
+
if (zone.NSDetail && !zone.CNAMEDetail && !zone.DNSPodDetail) {
|
|
103
|
+
accessType = "NS";
|
|
104
|
+
}
|
|
105
|
+
else if (zone.CNAMEDetail && !zone.NSDetail && !zone.DNSPodDetail) {
|
|
106
|
+
accessType = "CNAME";
|
|
107
|
+
}
|
|
108
|
+
else if (zone.DNSPodDetail && !zone.NSDetail && !zone.CNAMEDetail) {
|
|
109
|
+
accessType = "DNSPod";
|
|
110
|
+
}
|
|
111
|
+
// 获取 DNS 服务器
|
|
112
|
+
const nameServers = zone.NameServers || [];
|
|
113
|
+
const dnsServers = nameServers.length > 0 ? nameServers.join(", ") : "无";
|
|
114
|
+
// 获取加速区域
|
|
115
|
+
const areaMap = {
|
|
116
|
+
global: "全球加速",
|
|
117
|
+
mainland: "中国大陆",
|
|
118
|
+
overseas: "境外",
|
|
119
|
+
};
|
|
120
|
+
const area = areaMap[zone.Area] || zone.Area || "未知";
|
|
121
|
+
console.log(chalk.cyan("\n📋 站点状态:\n"));
|
|
122
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
123
|
+
console.log(` 站点名称: ${chalk.yellow(zoneDisplay)}`);
|
|
124
|
+
console.log(` 站点ID: ${chalk.yellow(selectedZoneId)}`);
|
|
125
|
+
console.log(` 状态: ${statusColor(statusText)} (${paused})`);
|
|
126
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
127
|
+
console.log(` 接入方式: ${chalk.yellow(accessType)}`);
|
|
128
|
+
console.log(` DNS服务器: ${chalk.yellow(dnsServers)}`);
|
|
129
|
+
console.log(` 加速区域: ${chalk.yellow(area)}`);
|
|
130
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log(chalk.gray("\n 未找到站点信息\n"));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
139
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
140
|
+
console.log(` ${errMsg}`);
|
|
141
|
+
}
|
|
142
|
+
console.log("");
|
|
143
|
+
await pauseToContinue();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 修改站点状态
|
|
147
|
+
*/
|
|
148
|
+
async function modifyZoneStatus(config) {
|
|
149
|
+
const selectedZoneId = await selectZone(config, "选择要修改的站点:");
|
|
150
|
+
if (!selectedZoneId)
|
|
151
|
+
return;
|
|
152
|
+
const selectedZone = config.domainIdList.find(z => z.id === selectedZoneId);
|
|
153
|
+
const zoneDisplay = selectedZone?.name || selectedZoneId;
|
|
154
|
+
// 选择状态
|
|
155
|
+
const statusAnswers = await inquirer.prompt([
|
|
156
|
+
{
|
|
157
|
+
type: "list",
|
|
158
|
+
name: "paused",
|
|
159
|
+
message: `选择站点状态 (${zoneDisplay}):`,
|
|
160
|
+
choices: [
|
|
161
|
+
{ name: "开启 (Paused: false)", value: false },
|
|
162
|
+
{ name: "关闭 (Paused: true)", value: true },
|
|
163
|
+
new inquirer.Separator(),
|
|
164
|
+
{ name: "← 返回", value: "back" },
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
]);
|
|
168
|
+
if (statusAnswers.paused === "back")
|
|
169
|
+
return;
|
|
170
|
+
const paused = statusAnswers.paused;
|
|
171
|
+
const statusText = paused ? "关闭" : "开启";
|
|
172
|
+
// 确认
|
|
173
|
+
const confirmAnswers = await inquirer.prompt([
|
|
174
|
+
{ type: "confirm", name: "confirm", message: `确认将站点 ${zoneDisplay} 设置为 ${statusText}?`, default: true },
|
|
175
|
+
]);
|
|
176
|
+
if (!confirmAnswers.confirm) {
|
|
177
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
178
|
+
await pauseToContinue();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// 执行状态切换
|
|
182
|
+
await executeZoneStatusChange(config, selectedZoneId, paused, statusText);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 执行站点状态切换
|
|
186
|
+
*/
|
|
187
|
+
async function executeZoneStatusChange(config, zoneId, paused, statusText) {
|
|
188
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "ap-guangzhou", config.mode);
|
|
189
|
+
const isDebug = config.mode === "debug";
|
|
190
|
+
if (isDebug) {
|
|
191
|
+
console.log(chalk.cyan("\n🔘 修改站点状态\n"));
|
|
192
|
+
console.log(chalk.gray("API 参数:"));
|
|
193
|
+
console.log(` Action: ${chalk.green("ModifyZoneStatus")}`);
|
|
194
|
+
console.log(` ZoneId: ${chalk.green(zoneId)}`);
|
|
195
|
+
console.log(` Paused: ${chalk.green(paused)}`);
|
|
196
|
+
console.log("");
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const result = await client.modifyZoneStatus({ zoneId, paused });
|
|
200
|
+
if ("Error" in result.Response) {
|
|
201
|
+
const error = result.Response.Error;
|
|
202
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
203
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
204
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
console.log(chalk.green("\n✅ 站点状态已更新!"));
|
|
208
|
+
console.log(` 状态: ${chalk.yellow(statusText)}`);
|
|
209
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
214
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
215
|
+
console.log(` ${errMsg}`);
|
|
216
|
+
}
|
|
217
|
+
console.log("");
|
|
218
|
+
await pauseToContinue();
|
|
219
|
+
}
|
package/dist/repl.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import chalk from"chalk";import inquirer from"inquirer";import{EdgeOneClient}from"./api/client.js";import{readConfig}from"./commands/config.js";function utcToBeijingTime(utcTime){if(!utcTime)return"";const date=new Date(utcTime),beijingTime=new Date(date.getTime()+288e5);return`${beijingTime.getUTCFullYear()}-${String(beijingTime.getUTCMonth()+1).padStart(2,"0")}-${String(beijingTime.getUTCDate()).padStart(2,"0")} ${String(beijingTime.getUTCHours()).padStart(2,"0")}:${String(beijingTime.getUTCMinutes()).padStart(2,"0")}:${String(beijingTime.getUTCSeconds()).padStart(2,"0")}`}async function pauseToContinue(){await inquirer.prompt([{type:"input",name:"continue",message:"按 Enter 键返回..."}])}function showBanner(){console.log(""),console.log(chalk.cyan("╔════════════════════════════════════╗")),console.log(chalk.cyan("║")+" "+chalk.white.bold("EdgeOne CLI")+" "+chalk.cyan("║")),console.log(chalk.cyan("║")+" "+chalk.gray("本地化 EdgeOne 服务管理工具")+" "+chalk.cyan("║")),console.log(chalk.cyan("╚════════════════════════════════════╝")),console.log("")}export async function startInteractive(){readConfig()||(showBanner(),await initConfig()),await async function(){for(;;){console.clear(),showBanner();const answers=await inquirer.prompt([{type:"list",name:"action",message:"请选择操作:",choices:[{name:"🔓 配置管理",value:"config"},{name:"🧹 清除缓存",value:"purge"},{name:"🚀 内容预热",value:"prefetch"},{name:"🌐 站点状态",value:"zone-status"},new inquirer.Separator("─────────────────"),{name:"❌ 退出",value:"exit"}],pageSize:10}]);"exit"===answers.action&&(console.log(chalk.gray("\n👋 再见!\n")),process.exit(0)),answers.action&&await handleAction(answers.action)}}()}async function handleAction(action){const config=readConfig();switch(action){case"config":await async function(){const answers=await inquirer.prompt([{type:"list",name:"action",message:"配置管理:",choices:[{name:"查看配置",value:"show"},{name:"编辑配置",value:"edit"},{name:"删除配置",value:"remove"},{name:"初始化配置",value:"init"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===answers.action)return;if("init"===answers.action)return void await initConfig();const config=readConfig();if(!config)return void console.log(chalk.yellow("\n⚠️ 配置不存在,请先初始化\n"));const{EdgeOneClient}=await import("./api/client.js");new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode);switch(answers.action){case"show":await async function(config){const modeText="debug"===config.mode?"调试模式":"生产模式",modeColor="debug"===config.mode?chalk.yellow:chalk.green;console.log(chalk.cyan("\n📋 当前配置:\n")),console.log(chalk.gray("─".repeat(40))),console.log(` SecretId: ${chalk.green(maskString(config.secretId))}`),console.log(` SecretKey: ${chalk.green(maskString(config.secretKey))}`),console.log(` 接口请求域名: ${chalk.yellow(config.endpoint||"teo.tencentcloudapi.com")}`),console.log(` 运行模式: ${modeColor(modeText)}`),config.domainIdList&&config.domainIdList.length>0&&(console.log(" 站点列表:"),config.domainIdList.forEach((zone,idx)=>{const display=zone.name?`${zone.name} (${zone.id})`:zone.id;console.log(` ${idx+1}. ${chalk.yellow(display)}`)}));console.log(chalk.gray("─".repeat(40))),console.log(""),await pauseToContinue()}(config);break;case"edit":await async function(config){const answers=await inquirer.prompt([{type:"list",name:"action",message:"选择要修改的配置项:",choices:[{name:"SecretId",value:"secretId"},{name:"SecretKey",value:"secretKey"},{name:"接口请求域名",value:"endpoint"},{name:"运行模式",value:"mode"},{name:"站点列表",value:"domainIdList"}]}]);let newValue;"secretId"===answers.action?(newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入新的 SecretId:",validate:i=>i.trim()||"不能为空"}]),config.secretId=newValue.value):"secretKey"===answers.action?(newValue=await inquirer.prompt([{type:"password",name:"value",message:"请输入新的 SecretKey:",mask:"*",validate:i=>i.trim()||"不能为空"}]),config.secretKey=newValue.value):"endpoint"===answers.action?(newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入新的接口请求域名:"}]),config.endpoint=newValue.value):"mode"===answers.action?(newValue=await inquirer.prompt([{type:"list",name:"value",message:"请选择运行模式:",choices:[{name:"生产模式 (不显示调试信息)",value:"production"},{name:"调试模式 (显示详细请求信息)",value:"debug"}]}]),config.mode=newValue.value):"domainIdList"===answers.action&&(config.domainIdList&&config.domainIdList.length>0&&(console.log(chalk.gray("\n当前站点列表:")),config.domainIdList.forEach((zone,idx)=>{const display=zone.name?`${zone.name} (${zone.id})`:zone.id;console.log(` ${idx+1}. ${chalk.yellow(display)}`)}),console.log("")),newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入站点列表,格式: id:备注(多个用逗号分隔):"}]),newValue.value?config.domainIdList=newValue.value.split(",").map(item=>{if((item=item.trim()).includes(":")){const[id,name]=item.split(":");return{id:id.trim(),name:name.trim()}}return{id:item}}).filter(zone=>""!==zone.id):config.domainIdList=[]);const{writeConfig}=await import("./commands/config.js");writeConfig(config),console.log(chalk.green("\n✅ 配置已更新\n"))}(config);break;case"remove":await async function(){const{confirm}=await inquirer.prompt([{type:"confirm",name:"confirm",message:"确定要删除配置文件吗?",default:!1}]);if(confirm){const fs=await import("fs"),path=await import("path"),os=await import("os"),CONFIG_FILE=path.join(os.homedir(),".edgeone-cli","config.json");fs.existsSync(CONFIG_FILE)&&(fs.unlinkSync(CONFIG_FILE),console.log(chalk.green("\n✅ 配置文件已删除\n")))}}()}}();break;case"purge":config?await async function(config){const actionAnswers=await inquirer.prompt([{type:"list",name:"type",message:"选择操作:",choices:[{name:"清除缓存",value:"purge"},{name:"查询历史",value:"history"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===actionAnswers.type)return;if("history"===actionAnswers.type)return void await async function(config){let zoneIds=[];if(!(config.domainIdList&&config.domainIdList.length>0))return void console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"));{const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id,short:zone.name||zone.id}));zoneIds=(await inquirer.prompt([{type:"checkbox",name:"zones",message:"选择站点 (可多选):",choices:zoneChoices,validate:input=>input.length>0||"请至少选择一个站点"}])).zones}await async function(config,zoneIds){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n📋 清除缓存历史记录\n")),console.log(chalk.gray("ZoneIds: "+zoneIds.join(", "))));try{const result=await client.describePurgeTasks(zoneIds);if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const tasks=result.Response?.Tasks||[];if(tasks.length>0){const{default:Table}=await import("cli-table3"),table=new Table({head:[chalk.gray("状态"),chalk.gray("清除地址"),chalk.gray("时间"),chalk.gray("类型")],colWidths:[8,50,30,8],chars:{mid:"","left-mid":"","mid-mid":"","right-mid":""}});tasks.forEach(task=>{const status="success"===task.Status?chalk.green("✓"):chalk.red("✗"),target=task.Target||"all",type="purge_url"===task.Type?"URL":"purge_prefix"===task.Type?"目录":"全部",createTime=utcToBeijingTime(task.CreateTime),displayTarget=target.length>47?target.slice(0,44)+"...":target;table.push([status,chalk.yellow(displayTarget),chalk.gray(createTime),type])}),console.log(chalk.cyan("\n📋 清除缓存记录:\n")),console.log(table.toString()),console.log(` 总计: ${chalk.yellow(result.Response?.TotalCount||tasks.length)} 条记录`)}else console.log(chalk.gray("\n 暂无清除记录\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,zoneIds)}(config);const answers=await inquirer.prompt([{type:"list",name:"type",message:"选择清除类型:",choices:[{name:"清除全部缓存",value:"all"},{name:"清除指定目录缓存",value:"dir"},{name:"清除指定 URL 缓存",value:"url"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===answers.type)return;let targets=[],purgeType="purge_all",zoneId="*";if(config.domainIdList&&config.domainIdList.length>0){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message:"选择站点:",choices:["* (全部站点)",...zoneChoices]}]);"* (全部站点)"!==zoneAnswers.zone&&(zoneId=zoneAnswers.zone)}if("all"===answers.type){if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认清除全部缓存? (Zone: ${zoneId})`,default:!1}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();purgeType="purge_all"}else if("dir"===answers.type){const dirAnswers=await inquirer.prompt([{type:"input",name:"dir",message:"请输入目录路径 (留空取消):"}]);if(!dirAnswers.dir||!dirAnswers.dir.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();targets=[dirAnswers.dir],purgeType="purge_prefix"}else if("url"===answers.type){const urlAnswers=await inquirer.prompt([{type:"input",name:"urls",message:"请输入 URL (多个用空格分隔,留空取消):"}]);if(!urlAnswers.urls||!urlAnswers.urls.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();targets=urlAnswers.urls.split(/\s+/).filter(u=>u.trim()),purgeType="purge_url"}await async function(config,type,targets,zoneId){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n🔄 清除缓存任务\n")),console.log(chalk.gray("API 参数:")),console.log(` ZoneId: ${chalk.green(zoneId)}`),console.log(` Type: ${chalk.green(type)}`),targets.length>0&&console.log(` Targets: ${chalk.green(JSON.stringify(targets))}`),console.log(""));try{const result=await client.createPurgeTask({zoneId,type,targets});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 请求成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`),result.Response?.JobId&&console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,purgeType,targets,zoneId)}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig());break;case"prefetch":config?await async function(config){const actionAnswers=await inquirer.prompt([{type:"list",name:"type",message:"选择操作:",choices:[{name:"内容预热",value:"prefetch"},{name:"查询历史",value:"history"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===actionAnswers.type)return;if("history"===actionAnswers.type)return void await async function(config){let zoneIds=[];if(!(config.domainIdList&&config.domainIdList.length>0))return void console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"));{const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id,short:zone.name||zone.id}));zoneIds=(await inquirer.prompt([{type:"checkbox",name:"zones",message:"选择站点 (可多选):",choices:zoneChoices,validate:input=>input.length>0||"请至少选择一个站点"}])).zones}await async function(config,zoneIds){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n📋 预热任务历史记录\n")),console.log(chalk.gray("ZoneIds: "+zoneIds.join(", "))));try{const result=await client.describePrefetchTasks(zoneIds);if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const tasks=result.Response?.PrefetchTasks||[];if(tasks.length>0){const{default:Table}=await import("cli-table3"),table=new Table({head:[chalk.gray("状态"),chalk.gray("预热地址"),chalk.gray("时间")],colWidths:[8,60,30],chars:{mid:"","left-mid":"","mid-mid":"","right-mid":""}});tasks.forEach(task=>{const status="success"===task.Status?chalk.green("✓"):"processing"===task.Status?chalk.yellow("⏳"):chalk.red("✗"),target=task.Target||"unknown",createTime=utcToBeijingTime(task.CreateTime),displayTarget=target.length>57?target.slice(0,54)+"...":target;table.push([status,chalk.yellow(displayTarget),chalk.gray(createTime)])}),console.log(chalk.cyan("\n📋 预热任务记录:\n")),console.log(table.toString()),console.log(` 总计: ${chalk.yellow(result.Response?.TotalCount||tasks.length)} 条记录`)}else console.log(chalk.gray("\n 暂无预热记录\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,zoneIds)}(config);const answers=await inquirer.prompt([{type:"input",name:"urls",message:"请输入要预热的 URL (多个用空格分隔,留空取消):"}]);if(!answers.urls||!answers.urls.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();const urls=answers.urls.split(/\s+/).filter(u=>u.trim());let zoneId="*";if(config.domainIdList&&config.domainIdList.length>0){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message:"选择站点:",choices:["* (全部站点)",...zoneChoices]}]);"* (全部站点)"!==zoneAnswers.zone&&(zoneId=zoneAnswers.zone)}if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认预热以下 URL?\n ${urls.join("\n ")}\n`,default:!0}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();await async function(config,urls,zoneId){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n🔥 预热任务\n")),console.log(chalk.gray("URL列表:")),urls.forEach(u=>console.log(` - ${chalk.yellow(u)}`)),console.log(`\nZone ID: ${chalk.green(zoneId)}`),console.log(""));try{const result=await client.createPrefetchTask({zoneId,urls});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 预热任务已提交!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`),result.Response?.JobId&&console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,urls,zoneId)}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig());break;case"zone-status":config?await async function(config){if(!config.domainIdList||0===config.domainIdList.length)return console.log(chalk.yellow("\n⚠️ 未配置站点列表,请先在配置中添加站点\n")),void await pauseToContinue();const answers=await inquirer.prompt([{type:"list",name:"action",message:"站点状态管理:",choices:[{name:"🔍 查看站点状态",value:"view"},{name:"🔘 修改站点状态",value:"modify"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===answers.action)return;"view"===answers.action?await async function(config){const selectedZoneId=await selectZone(config,"选择要查看的站点:");if(!selectedZoneId)return;const selectedZone=config.domainIdList.find(z=>z.id===selectedZoneId),zoneDisplay=selectedZone?.name||selectedZoneId,client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n🔍 查看站点状态\n")),console.log(chalk.gray("API 参数:")),console.log(` Action: ${chalk.green("DescribeZones")}`),console.log(` ZoneIds: ${chalk.green([selectedZoneId])}`),console.log(""));try{const result=await client.describeZoneStatus({zoneId:selectedZoneId});if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const zones=result.Response?.Zones||[];if(zones.length>0){const zone=zones[0],paused=zone.Paused,statusText=paused?"关闭":"开启",statusColor=paused?chalk.red:chalk.green;let accessType="未知";!zone.NSDetail||zone.CNAMEDetail||zone.DNSPodDetail?!zone.CNAMEDetail||zone.NSDetail||zone.DNSPodDetail?!zone.DNSPodDetail||zone.NSDetail||zone.CNAMEDetail||(accessType="DNSPod"):accessType="CNAME":accessType="NS";const nameServers=zone.NameServers||[],dnsServers=nameServers.length>0?nameServers.join(", "):"无",area={global:"全球加速",mainland:"中国大陆",overseas:"境外"}[zone.Area]||zone.Area||"未知";console.log(chalk.cyan("\n📋 站点状态:\n")),console.log(chalk.gray("─".repeat(40))),console.log(` 站点名称: ${chalk.yellow(zoneDisplay)}`),console.log(` 站点ID: ${chalk.yellow(selectedZoneId)}`),console.log(` 状态: ${statusColor(statusText)} (${paused})`),console.log(chalk.gray("─".repeat(40))),console.log(` 接入方式: ${chalk.yellow(accessType)}`),console.log(` DNS服务器: ${chalk.yellow(dnsServers)}`),console.log(` 加速区域: ${chalk.yellow(area)}`),console.log(chalk.gray("─".repeat(40)))}else console.log(chalk.gray("\n 未找到站点信息\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config):"modify"===answers.action&&await async function(config){const selectedZoneId=await selectZone(config,"选择要修改的站点:");if(!selectedZoneId)return;const selectedZone=config.domainIdList.find(z=>z.id===selectedZoneId),zoneDisplay=selectedZone?.name||selectedZoneId,statusAnswers=await inquirer.prompt([{type:"list",name:"paused",message:`选择站点状态 (${zoneDisplay}):`,choices:[{name:"开启 (Paused: false)",value:!1},{name:"关闭 (Paused: true)",value:!0},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===statusAnswers.paused)return;const paused=statusAnswers.paused,statusText=paused?"关闭":"开启";if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认将站点 ${zoneDisplay} 设置为 ${statusText}?`,default:!0}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();await async function(config,zoneId,paused,statusText){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode),isDebug="debug"===config.mode;isDebug&&(console.log(chalk.cyan("\n🔘 修改站点状态\n")),console.log(chalk.gray("API 参数:")),console.log(` Action: ${chalk.green("ModifyZoneStatus")}`),console.log(` ZoneId: ${chalk.green(zoneId)}`),console.log(` Paused: ${chalk.green(paused)}`),console.log(""));try{const result=await client.modifyZoneStatus({zoneId,paused});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 站点状态已更新!")),console.log(` 状态: ${chalk.yellow(statusText)}`),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,selectedZoneId,paused,statusText)}(config)}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig())}}async function initConfig(){const existingConfig=readConfig();if(existingConfig){const{overwrite}=await inquirer.prompt([{type:"confirm",name:"overwrite",message:"配置已存在,是否覆盖?",default:!1}]);if(!overwrite)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue()}const defaultDomainList=existingConfig?.domainIdList?existingConfig.domainIdList.map(z=>z.name?`${z.id}:${z.name}`:z.id).join(", "):"",answers=await inquirer.prompt([{type:"input",name:"secretId",message:"请输入 SecretId:",default:existingConfig?.secretId||"",validate:input=>!!input.trim()||"SecretId 不能为空"},{type:"password",name:"secretKey",message:"请输入 SecretKey:",mask:"*",validate:input=>!!input.trim()||"SecretKey 不能为空"},{type:"input",name:"endpoint",message:"请输入接口请求域名:",default:existingConfig?.endpoint||"teo.tencentcloudapi.com"},{type:"list",name:"mode",message:"请选择运行模式:",choices:[{name:"生产模式 (不显示调试信息)",value:"production"},{name:"调试模式 (显示详细请求信息)",value:"debug"}],default:existingConfig?.mode||"production"},{type:"input",name:"domainIdList",message:"请输入站点列表,格式: id:备注(多个用逗号分隔,留空跳过):",default:defaultDomainList}]),{writeConfig}=await import("./commands/config.js");let domainIdList=[];answers.domainIdList&&answers.domainIdList.trim()&&(domainIdList=answers.domainIdList.split(",").map(item=>{if((item=item.trim()).includes(":")){const[id,name]=item.split(":");return{id:id.trim(),name:name.trim()}}return{id:item}}).filter(zone=>""!==zone.id)),writeConfig({secretId:answers.secretId,secretKey:answers.secretKey,endpoint:answers.endpoint,mode:answers.mode,domainIdList});const action=existingConfig?"更新":"保存";console.log(chalk.green(`\n✅ 配置已${action}\n`))}function maskString(str,showLength=4){return str?str.length<=2*showLength?str:str.slice(0,showLength)+"****"+str.slice(-showLength):"N/A"}async function selectZone(config,message){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message,choices:[...zoneChoices,new inquirer.Separator,{name:"← 返回",value:"back"}]}]);return"back"===zoneAnswers.zone?null:zoneAnswers.zone}
|
|
1
|
+
import chalk from"chalk";import inquirer from"inquirer";import{EdgeOneClient}from"./api/client.js";import{readConfig}from"./commands/config.js";function utcToBeijingTime(utcTime){if(!utcTime)return"";const date=new Date(utcTime),beijingTime=new Date(date.getTime()+288e5);return`${beijingTime.getUTCFullYear()}-${String(beijingTime.getUTCMonth()+1).padStart(2,"0")}-${String(beijingTime.getUTCDate()).padStart(2,"0")} ${String(beijingTime.getUTCHours()).padStart(2,"0")}:${String(beijingTime.getUTCMinutes()).padStart(2,"0")}:${String(beijingTime.getUTCSeconds()).padStart(2,"0")}`}async function pauseToContinue(){await inquirer.prompt([{type:"input",name:"continue",message:"按 Enter 键返回..."}])}function showBanner(){console.log(""),console.log(chalk.cyan("╔════════════════════════════════════╗")),console.log(chalk.cyan("║")+" "+chalk.white.bold("EdgeOne CLI")+" "+chalk.cyan("║")),console.log(chalk.cyan("║")+" "+chalk.gray("本地化 EdgeOne 服务管理工具")+" "+chalk.cyan("║")),console.log(chalk.cyan("╚════════════════════════════════════╝")),console.log("")}export async function startInteractive(){readConfig()||(showBanner(),await initConfig()),await async function(){for(;;){console.clear(),showBanner();const answers=await inquirer.prompt([{type:"list",name:"action",message:"请选择操作:",choices:[{name:"🔓 配置管理",value:"config"},{name:"🧹 清除缓存",value:"purge"},{name:"🚀 内容预热",value:"prefetch"},{name:"🌐 站点状态",value:"zone-status"},new inquirer.Separator("─────────────────"),{name:"❌ 退出",value:"exit"}],pageSize:10}]);"exit"===answers.action&&(console.log(chalk.gray("\n👋 再见!\n")),process.exit(0)),answers.action&&await handleAction(answers.action)}}()}async function handleAction(action){const config=readConfig();switch(action){case"config":await async function(){const answers=await inquirer.prompt([{type:"list",name:"action",message:"配置管理:",choices:[{name:"查看配置",value:"show"},{name:"编辑配置",value:"edit"},{name:"删除配置",value:"remove"},{name:"初始化配置",value:"init"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===answers.action)return;if("init"===answers.action)return void await initConfig();const config=readConfig();if(!config)return void console.log(chalk.yellow("\n⚠️ 配置不存在,请先初始化\n"));const{EdgeOneClient}=await import("./api/client.js");switch(new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode),answers.action){case"show":await async function(config){const modeText="debug"===config.mode?"调试模式":"生产模式",modeColor="debug"===config.mode?chalk.yellow:chalk.green;console.log(chalk.cyan("\n📋 当前配置:\n")),console.log(chalk.gray("─".repeat(40))),console.log(` SecretId: ${chalk.green(maskString(config.secretId))}`),console.log(` SecretKey: ${chalk.green(maskString(config.secretKey))}`),console.log(` 接口请求域名: ${chalk.yellow(config.endpoint||"teo.tencentcloudapi.com")}`),console.log(` 运行模式: ${modeColor(modeText)}`),config.domainIdList&&config.domainIdList.length>0&&(console.log(" 站点列表:"),config.domainIdList.forEach((zone,idx)=>{const display=zone.name?`${zone.name} (${zone.id})`:zone.id;console.log(` ${idx+1}. ${chalk.yellow(display)}`)})),console.log(chalk.gray("─".repeat(40))),console.log(""),await pauseToContinue()}(config);break;case"edit":await async function(config){const answers=await inquirer.prompt([{type:"list",name:"action",message:"选择要修改的配置项:",choices:[{name:"SecretId",value:"secretId"},{name:"SecretKey",value:"secretKey"},{name:"接口请求域名",value:"endpoint"},{name:"运行模式",value:"mode"},{name:"站点列表",value:"domainIdList"}]}]);let newValue;"secretId"===answers.action?(newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入新的 SecretId:",validate:i=>i.trim()||"不能为空"}]),config.secretId=newValue.value):"secretKey"===answers.action?(newValue=await inquirer.prompt([{type:"password",name:"value",message:"请输入新的 SecretKey:",mask:"*",validate:i=>i.trim()||"不能为空"}]),config.secretKey=newValue.value):"endpoint"===answers.action?(newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入新的接口请求域名:"}]),config.endpoint=newValue.value):"mode"===answers.action?(newValue=await inquirer.prompt([{type:"list",name:"value",message:"请选择运行模式:",choices:[{name:"生产模式 (不显示调试信息)",value:"production"},{name:"调试模式 (显示详细请求信息)",value:"debug"}]}]),config.mode=newValue.value):"domainIdList"===answers.action&&(config.domainIdList&&config.domainIdList.length>0&&(console.log(chalk.gray("\n当前站点列表:")),config.domainIdList.forEach((zone,idx)=>{const display=zone.name?`${zone.name} (${zone.id})`:zone.id;console.log(` ${idx+1}. ${chalk.yellow(display)}`)}),console.log("")),newValue=await inquirer.prompt([{type:"input",name:"value",message:"请输入站点列表,格式: id:备注(多个用逗号分隔):"}]),newValue.value?config.domainIdList=newValue.value.split(",").map(item=>{if((item=item.trim()).includes(":")){const[id,name]=item.split(":");return{id:id.trim(),name:name.trim()}}return{id:item}}).filter(zone=>""!==zone.id):config.domainIdList=[]);const{writeConfig}=await import("./commands/config.js");writeConfig(config),console.log(chalk.green("\n✅ 配置已更新\n"))}(config);break;case"remove":await async function(){const{confirm}=await inquirer.prompt([{type:"confirm",name:"confirm",message:"确定要删除配置文件吗?",default:!1}]);if(confirm){const fs=await import("fs"),path=await import("path"),os=await import("os"),CONFIG_FILE=path.join(os.homedir(),".edgeone-cli","config.json");fs.existsSync(CONFIG_FILE)&&(fs.unlinkSync(CONFIG_FILE),console.log(chalk.green("\n✅ 配置文件已删除\n")))}}()}}();break;case"purge":config?await async function(config){const actionAnswers=await inquirer.prompt([{type:"list",name:"type",message:"选择操作:",choices:[{name:"清除缓存",value:"purge"},{name:"查询历史",value:"history"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===actionAnswers.type)return;if("history"===actionAnswers.type)return void await async function(config){let zoneIds=[];if(config.domainIdList&&config.domainIdList.length>0){{const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id,short:zone.name||zone.id}));zoneIds=(await inquirer.prompt([{type:"checkbox",name:"zones",message:"选择站点 (可多选):",choices:zoneChoices,validate:input=>input.length>0||"请至少选择一个站点"}])).zones}await async function(config,zoneIds){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n📋 清除缓存历史记录\n")),console.log(chalk.gray("ZoneIds: "+zoneIds.join(", "))));try{const result=await client.describePurgeTasks(zoneIds);if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const tasks=result.Response?.Tasks||[];if(tasks.length>0){const{default:Table}=await import("cli-table3"),table=new Table({head:[chalk.gray("状态"),chalk.gray("清除地址"),chalk.gray("时间"),chalk.gray("类型")],colWidths:[8,50,30,8],chars:{mid:"","left-mid":"","mid-mid":"","right-mid":""}});tasks.forEach(task=>{const status="success"===task.Status?chalk.green("✓"):chalk.red("✗"),target=task.Target||"all",type="purge_url"===task.Type?"URL":"purge_prefix"===task.Type?"目录":"全部",createTime=utcToBeijingTime(task.CreateTime),displayTarget=target.length>47?target.slice(0,44)+"...":target;table.push([status,chalk.yellow(displayTarget),chalk.gray(createTime),type])}),console.log(chalk.cyan("\n📋 清除缓存记录:\n")),console.log(table.toString()),console.log(` 总计: ${chalk.yellow(result.Response?.TotalCount||tasks.length)} 条记录`)}else console.log(chalk.gray("\n 暂无清除记录\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,zoneIds)}else console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"))}(config);const answers=await inquirer.prompt([{type:"list",name:"type",message:"选择清除类型:",choices:[{name:"清除全部缓存",value:"all"},{name:"清除指定目录缓存",value:"dir"},{name:"清除指定 URL 缓存",value:"url"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===answers.type)return;let targets=[],purgeType="purge_all",zoneId="*";if(config.domainIdList&&config.domainIdList.length>0){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message:"选择站点:",choices:["* (全部站点)",...zoneChoices]}]);"* (全部站点)"!==zoneAnswers.zone&&(zoneId=zoneAnswers.zone)}if("all"===answers.type){if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认清除全部缓存? (Zone: ${zoneId})`,default:!1}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();purgeType="purge_all"}else if("dir"===answers.type){const dirAnswers=await inquirer.prompt([{type:"input",name:"dir",message:"请输入目录路径 (留空取消):"}]);if(!dirAnswers.dir||!dirAnswers.dir.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();targets=[dirAnswers.dir],purgeType="purge_prefix"}else if("url"===answers.type){const urlAnswers=await inquirer.prompt([{type:"input",name:"urls",message:"请输入 URL (多个用空格分隔,留空取消):"}]);if(!urlAnswers.urls||!urlAnswers.urls.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();targets=urlAnswers.urls.split(/\s+/).filter(u=>u.trim()),purgeType="purge_url"}await async function(config,type,targets,zoneId){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n🔄 清除缓存任务\n")),console.log(chalk.gray("API 参数:")),console.log(` ZoneId: ${chalk.green(zoneId)}`),console.log(` Type: ${chalk.green(type)}`),targets.length>0&&console.log(` Targets: ${chalk.green(JSON.stringify(targets))}`),console.log(""));try{const result=await client.createPurgeTask({zoneId,type,targets});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 请求成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`),result.Response?.JobId&&console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,purgeType,targets,zoneId)}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig());break;case"prefetch":config?await async function(config){const actionAnswers=await inquirer.prompt([{type:"list",name:"type",message:"选择操作:",choices:[{name:"内容预热",value:"prefetch"},{name:"查询历史",value:"history"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===actionAnswers.type)return;if("history"===actionAnswers.type)return void await async function(config){let zoneIds=[];if(config.domainIdList&&config.domainIdList.length>0){{const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id,short:zone.name||zone.id}));zoneIds=(await inquirer.prompt([{type:"checkbox",name:"zones",message:"选择站点 (可多选):",choices:zoneChoices,validate:input=>input.length>0||"请至少选择一个站点"}])).zones}await async function(config,zoneIds){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n📋 预热任务历史记录\n")),console.log(chalk.gray("ZoneIds: "+zoneIds.join(", "))));try{const result=await client.describePrefetchTasks(zoneIds);if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const tasks=result.Response?.PrefetchTasks||[];if(tasks.length>0){const{default:Table}=await import("cli-table3"),table=new Table({head:[chalk.gray("状态"),chalk.gray("预热地址"),chalk.gray("时间")],colWidths:[8,60,30],chars:{mid:"","left-mid":"","mid-mid":"","right-mid":""}});tasks.forEach(task=>{const status="success"===task.Status?chalk.green("✓"):"processing"===task.Status?chalk.yellow("⏳"):chalk.red("✗"),target=task.Target||"unknown",createTime=utcToBeijingTime(task.CreateTime),displayTarget=target.length>57?target.slice(0,54)+"...":target;table.push([status,chalk.yellow(displayTarget),chalk.gray(createTime)])}),console.log(chalk.cyan("\n📋 预热任务记录:\n")),console.log(table.toString()),console.log(` 总计: ${chalk.yellow(result.Response?.TotalCount||tasks.length)} 条记录`)}else console.log(chalk.gray("\n 暂无预热记录\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,zoneIds)}else console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"))}(config);const answers=await inquirer.prompt([{type:"input",name:"urls",message:"请输入要预热的 URL (多个用空格分隔,留空取消):"}]);if(!answers.urls||!answers.urls.trim())return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();const urls=answers.urls.split(/\s+/).filter(u=>u.trim());let zoneId="*";if(config.domainIdList&&config.domainIdList.length>0){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message:"选择站点:",choices:["* (全部站点)",...zoneChoices]}]);"* (全部站点)"!==zoneAnswers.zone&&(zoneId=zoneAnswers.zone)}if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认预热以下 URL?\n ${urls.join("\n ")}\n`,default:!0}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();await async function(config,urls,zoneId){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n🔥 预热任务\n")),console.log(chalk.gray("URL列表:")),urls.forEach(u=>console.log(` - ${chalk.yellow(u)}`)),console.log(`\nZone ID: ${chalk.green(zoneId)}`),console.log(""));try{const result=await client.createPrefetchTask({zoneId,urls});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 预热任务已提交!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`),result.Response?.JobId&&console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,urls,zoneId)}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig());break;case"zone-status":config?await async function(config){if(!config.domainIdList||0===config.domainIdList.length)return console.log(chalk.yellow("\n⚠️ 未配置站点列表,请先在配置中添加站点\n")),void await pauseToContinue();const answers=await inquirer.prompt([{type:"list",name:"action",message:"站点状态管理:",choices:[{name:"🔍 查看站点状态",value:"view"},{name:"🔘 修改站点状态",value:"modify"},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);"back"!==answers.action&&("view"===answers.action?await async function(config){const selectedZoneId=await selectZone(config,"选择要查看的站点:");if(!selectedZoneId)return;const selectedZone=config.domainIdList.find(z=>z.id===selectedZoneId),zoneDisplay=selectedZone?.name||selectedZoneId,client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n🔍 查看站点状态\n")),console.log(chalk.gray("API 参数:")),console.log(` Action: ${chalk.green("DescribeZones")}`),console.log(` ZoneIds: ${chalk.green([selectedZoneId])}`),console.log(""));try{const result=await client.describeZoneStatus({zoneId:selectedZoneId});if(result.Response?.Error)console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`);else{console.log(chalk.green("\n✅ 查询成功!")),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`);const zones=result.Response?.Zones||[];if(zones.length>0){const zone=zones[0],paused=zone.Paused,statusText=paused?"关闭":"开启",statusColor=paused?chalk.red:chalk.green;let accessType="未知";!zone.NSDetail||zone.CNAMEDetail||zone.DNSPodDetail?!zone.CNAMEDetail||zone.NSDetail||zone.DNSPodDetail?!zone.DNSPodDetail||zone.NSDetail||zone.CNAMEDetail||(accessType="DNSPod"):accessType="CNAME":accessType="NS";const nameServers=zone.NameServers||[],dnsServers=nameServers.length>0?nameServers.join(", "):"无",area={global:"全球加速",mainland:"中国大陆",overseas:"境外"}[zone.Area]||zone.Area||"未知";console.log(chalk.cyan("\n📋 站点状态:\n")),console.log(chalk.gray("─".repeat(40))),console.log(` 站点名称: ${chalk.yellow(zoneDisplay)}`),console.log(` 站点ID: ${chalk.yellow(selectedZoneId)}`),console.log(` 状态: ${statusColor(statusText)} (${paused})`),console.log(chalk.gray("─".repeat(40))),console.log(` 接入方式: ${chalk.yellow(accessType)}`),console.log(` DNS服务器: ${chalk.yellow(dnsServers)}`),console.log(` 加速区域: ${chalk.yellow(area)}`),console.log(chalk.gray("─".repeat(40)))}else console.log(chalk.gray("\n 未找到站点信息\n"))}}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config):"modify"===answers.action&&await async function(config){const selectedZoneId=await selectZone(config,"选择要修改的站点:");if(!selectedZoneId)return;const selectedZone=config.domainIdList.find(z=>z.id===selectedZoneId),zoneDisplay=selectedZone?.name||selectedZoneId,statusAnswers=await inquirer.prompt([{type:"list",name:"paused",message:`选择站点状态 (${zoneDisplay}):`,choices:[{name:"开启 (Paused: false)",value:!1},{name:"关闭 (Paused: true)",value:!0},new inquirer.Separator,{name:"← 返回",value:"back"}]}]);if("back"===statusAnswers.paused)return;const paused=statusAnswers.paused,statusText=paused?"关闭":"开启";if(!(await inquirer.prompt([{type:"confirm",name:"confirm",message:`确认将站点 ${zoneDisplay} 设置为 ${statusText}?`,default:!0}])).confirm)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue();await async function(config,zoneId,paused,statusText){const client=new EdgeOneClient(config.secretId,config.secretKey,config.endpoint||"teo.tencentcloudapi.com","ap-guangzhou",config.mode);"debug"===config.mode&&(console.log(chalk.cyan("\n🔘 修改站点状态\n")),console.log(chalk.gray("API 参数:")),console.log(` Action: ${chalk.green("ModifyZoneStatus")}`),console.log(` ZoneId: ${chalk.green(zoneId)}`),console.log(` Paused: ${chalk.green(paused)}`),console.log(""));try{const result=await client.modifyZoneStatus({zoneId,paused});result.Response?.Error?(console.log(chalk.red("\n❌ 请求失败:")),console.log(` 错误码: ${chalk.yellow(result.Response.Error.Code)}`),console.log(` 错误信息: ${chalk.yellow(result.Response.Error.Message)}`)):(console.log(chalk.green("\n✅ 站点状态已更新!")),console.log(` 状态: ${chalk.yellow(statusText)}`),console.log(` RequestId: ${chalk.yellow(result.Response?.RequestId)}`))}catch(error){console.log(chalk.red("\n❌ 请求异常:")),console.log(` ${error.message}`)}console.log(""),await pauseToContinue()}(config,selectedZoneId,paused,statusText)}(config))}(config):(console.log(chalk.yellow("\n⚠️ 请先初始化配置\n")),await initConfig())}}async function initConfig(){const existingConfig=readConfig();if(existingConfig){const{overwrite}=await inquirer.prompt([{type:"confirm",name:"overwrite",message:"配置已存在,是否覆盖?",default:!1}]);if(!overwrite)return console.log(chalk.gray("\n❌️ 已取消")),void await pauseToContinue()}const defaultDomainList=existingConfig?.domainIdList?existingConfig.domainIdList.map(z=>z.name?`${z.id}:${z.name}`:z.id).join(", "):"",answers=await inquirer.prompt([{type:"input",name:"secretId",message:"请输入 SecretId:",default:existingConfig?.secretId||"",validate:input=>!!input.trim()||"SecretId 不能为空"},{type:"password",name:"secretKey",message:"请输入 SecretKey:",mask:"*",validate:input=>!!input.trim()||"SecretKey 不能为空"},{type:"input",name:"endpoint",message:"请输入接口请求域名:",default:existingConfig?.endpoint||"teo.tencentcloudapi.com"},{type:"list",name:"mode",message:"请选择运行模式:",choices:[{name:"生产模式 (不显示调试信息)",value:"production"},{name:"调试模式 (显示详细请求信息)",value:"debug"}],default:existingConfig?.mode||"production"},{type:"input",name:"domainIdList",message:"请输入站点列表,格式: id:备注(多个用逗号分隔,留空跳过):",default:defaultDomainList}]),{writeConfig}=await import("./commands/config.js");let domainIdList=[];answers.domainIdList&&answers.domainIdList.trim()&&(domainIdList=answers.domainIdList.split(",").map(item=>{if((item=item.trim()).includes(":")){const[id,name]=item.split(":");return{id:id.trim(),name:name.trim()}}return{id:item}}).filter(zone=>""!==zone.id)),writeConfig({secretId:answers.secretId,secretKey:answers.secretKey,endpoint:answers.endpoint,mode:answers.mode,domainIdList});const action=existingConfig?"更新":"保存";console.log(chalk.green(`\n✅ 配置已${action}\n`))}function maskString(str,showLength=4){return str?str.length<=2*showLength?str:str.slice(0,showLength)+"****"+str.slice(-showLength):"N/A"}async function selectZone(config,message){const zoneChoices=config.domainIdList.map(zone=>({name:zone.name||zone.id,value:zone.id})),zoneAnswers=await inquirer.prompt([{type:"list",name:"zone",message,choices:[...zoneChoices,new inquirer.Separator,{name:"← 返回",value:"back"}]}]);return"back"===zoneAnswers.zone?null:zoneAnswers.zone}
|