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,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置管理菜单
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
import { EdgeOneClient } from "../api/client.js";
|
|
7
|
+
import { readConfig, writeConfig } from "../commands/config.js";
|
|
8
|
+
import { maskString } from "../utils/display.js";
|
|
9
|
+
import { pauseToContinue } from "./ui.js";
|
|
10
|
+
/**
|
|
11
|
+
* 配置管理菜单
|
|
12
|
+
*/
|
|
13
|
+
export async function configMenu() {
|
|
14
|
+
const answers = await inquirer.prompt([
|
|
15
|
+
{
|
|
16
|
+
type: "list",
|
|
17
|
+
name: "action",
|
|
18
|
+
message: "配置管理:",
|
|
19
|
+
choices: [
|
|
20
|
+
{ name: "查看配置", value: "show" },
|
|
21
|
+
{ name: "编辑配置", value: "edit" },
|
|
22
|
+
{ name: "删除配置", value: "remove" },
|
|
23
|
+
{ name: "初始化配置", value: "init" },
|
|
24
|
+
new inquirer.Separator(),
|
|
25
|
+
{ name: "← 返回", value: "back" },
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
if (answers.action === "back")
|
|
30
|
+
return;
|
|
31
|
+
if (answers.action === "init") {
|
|
32
|
+
await initConfig();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const config = readConfig();
|
|
36
|
+
if (!config) {
|
|
37
|
+
console.log(chalk.yellow("\n⚠️ 配置不存在,请先初始化\n"));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// 调用原有的 config 命令
|
|
41
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "ap-guangzhou", config.mode);
|
|
42
|
+
switch (answers.action) {
|
|
43
|
+
case "show":
|
|
44
|
+
await showConfigInfo(config);
|
|
45
|
+
break;
|
|
46
|
+
case "edit":
|
|
47
|
+
await editConfig(config);
|
|
48
|
+
break;
|
|
49
|
+
case "remove":
|
|
50
|
+
await removeConfig();
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 初始化配置
|
|
56
|
+
*/
|
|
57
|
+
export async function initConfig() {
|
|
58
|
+
const existingConfig = readConfig();
|
|
59
|
+
if (existingConfig) {
|
|
60
|
+
const { overwrite } = await inquirer.prompt([
|
|
61
|
+
{ type: "confirm", name: "overwrite", message: "配置已存在,是否覆盖?", default: false },
|
|
62
|
+
]);
|
|
63
|
+
if (!overwrite) {
|
|
64
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
65
|
+
await pauseToContinue();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 构建默认值
|
|
70
|
+
const defaultDomainList = existingConfig?.domainIdList
|
|
71
|
+
? existingConfig.domainIdList.map((z) => (z.name ? `${z.id}:${z.name}` : z.id)).join(", ")
|
|
72
|
+
: "";
|
|
73
|
+
const answers = await inquirer.prompt([
|
|
74
|
+
{
|
|
75
|
+
type: "input",
|
|
76
|
+
name: "secretId",
|
|
77
|
+
message: "请输入 SecretId:",
|
|
78
|
+
default: existingConfig?.secretId || "",
|
|
79
|
+
validate: input => (input.trim() ? true : "SecretId 不能为空"),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "password",
|
|
83
|
+
name: "secretKey",
|
|
84
|
+
message: "请输入 SecretKey:",
|
|
85
|
+
mask: "*",
|
|
86
|
+
validate: input => (input.trim() ? true : "SecretKey 不能为空"),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
type: "input",
|
|
90
|
+
name: "endpoint",
|
|
91
|
+
message: "请输入接口请求域名:",
|
|
92
|
+
default: existingConfig?.endpoint || "teo.tencentcloudapi.com",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: "list",
|
|
96
|
+
name: "mode",
|
|
97
|
+
message: "请选择运行模式:",
|
|
98
|
+
choices: [
|
|
99
|
+
{ name: "生产模式 (不显示调试信息)", value: "production" },
|
|
100
|
+
{ name: "调试模式 (显示详细请求信息)", value: "debug" },
|
|
101
|
+
],
|
|
102
|
+
default: existingConfig?.mode || "production",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: "input",
|
|
106
|
+
name: "domainIdList",
|
|
107
|
+
message: "请输入站点列表,格式: id:备注(多个用逗号分隔,留空跳过):",
|
|
108
|
+
default: defaultDomainList,
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
// 保存配置 - 处理 id:name 格式
|
|
112
|
+
let domainIdList = [];
|
|
113
|
+
if (answers.domainIdList && answers.domainIdList.trim()) {
|
|
114
|
+
domainIdList = answers.domainIdList
|
|
115
|
+
.split(",")
|
|
116
|
+
.map((item) => {
|
|
117
|
+
item = item.trim();
|
|
118
|
+
if (item.includes(":")) {
|
|
119
|
+
const [id, name] = item.split(":");
|
|
120
|
+
return { id: id.trim(), name: name.trim() };
|
|
121
|
+
}
|
|
122
|
+
return { id: item };
|
|
123
|
+
})
|
|
124
|
+
.filter((zone) => zone.id !== "");
|
|
125
|
+
}
|
|
126
|
+
writeConfig({
|
|
127
|
+
secretId: answers.secretId,
|
|
128
|
+
secretKey: answers.secretKey,
|
|
129
|
+
endpoint: answers.endpoint,
|
|
130
|
+
mode: answers.mode,
|
|
131
|
+
domainIdList: domainIdList,
|
|
132
|
+
});
|
|
133
|
+
const action = existingConfig ? "更新" : "保存";
|
|
134
|
+
console.log(chalk.green(`\n✅ 配置已${action}\n`));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 显示配置信息
|
|
138
|
+
*/
|
|
139
|
+
async function showConfigInfo(config) {
|
|
140
|
+
const modeText = config.mode === "debug" ? "调试模式" : "生产模式";
|
|
141
|
+
const modeColor = config.mode === "debug" ? chalk.yellow : chalk.green;
|
|
142
|
+
console.log(chalk.cyan("\n📋 当前配置:\n"));
|
|
143
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
144
|
+
console.log(` SecretId: ${chalk.green(maskString(config.secretId))}`);
|
|
145
|
+
console.log(` SecretKey: ${chalk.green(maskString(config.secretKey))}`);
|
|
146
|
+
console.log(` 接口请求域名: ${chalk.yellow(config.endpoint || "teo.tencentcloudapi.com")}`);
|
|
147
|
+
console.log(` 运行模式: ${modeColor(modeText)}`);
|
|
148
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
149
|
+
console.log(` 站点列表:`);
|
|
150
|
+
config.domainIdList.forEach((zone, idx) => {
|
|
151
|
+
const display = zone.name ? `${zone.name} (${zone.id})` : zone.id;
|
|
152
|
+
console.log(` ${idx + 1}. ${chalk.yellow(display)}`);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
156
|
+
console.log("");
|
|
157
|
+
await pauseToContinue();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 编辑配置
|
|
161
|
+
*/
|
|
162
|
+
async function editConfig(config) {
|
|
163
|
+
const answers = await inquirer.prompt([
|
|
164
|
+
{
|
|
165
|
+
type: "list",
|
|
166
|
+
name: "action",
|
|
167
|
+
message: "选择要修改的配置项:",
|
|
168
|
+
choices: [
|
|
169
|
+
{ name: "SecretId", value: "secretId" },
|
|
170
|
+
{ name: "SecretKey", value: "secretKey" },
|
|
171
|
+
{ name: "接口请求域名", value: "endpoint" },
|
|
172
|
+
{ name: "运行模式", value: "mode" },
|
|
173
|
+
{ name: "站点列表", value: "domainIdList" },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
]);
|
|
177
|
+
let newValue;
|
|
178
|
+
if (answers.action === "secretId") {
|
|
179
|
+
newValue = await inquirer.prompt([
|
|
180
|
+
{ type: "input", name: "value", message: "请输入新的 SecretId:", validate: i => i.trim() || "不能为空" },
|
|
181
|
+
]);
|
|
182
|
+
config.secretId = newValue.value;
|
|
183
|
+
}
|
|
184
|
+
else if (answers.action === "secretKey") {
|
|
185
|
+
newValue = await inquirer.prompt([
|
|
186
|
+
{ type: "password", name: "value", message: "请输入新的 SecretKey:", mask: "*", validate: i => i.trim() || "不能为空" },
|
|
187
|
+
]);
|
|
188
|
+
config.secretKey = newValue.value;
|
|
189
|
+
}
|
|
190
|
+
else if (answers.action === "endpoint") {
|
|
191
|
+
newValue = await inquirer.prompt([{ type: "input", name: "value", message: "请输入新的接口请求域名:" }]);
|
|
192
|
+
config.endpoint = newValue.value;
|
|
193
|
+
}
|
|
194
|
+
else if (answers.action === "mode") {
|
|
195
|
+
newValue = await inquirer.prompt([
|
|
196
|
+
{
|
|
197
|
+
type: "list",
|
|
198
|
+
name: "value",
|
|
199
|
+
message: "请选择运行模式:",
|
|
200
|
+
choices: [
|
|
201
|
+
{ name: "生产模式 (不显示调试信息)", value: "production" },
|
|
202
|
+
{ name: "调试模式 (显示详细请求信息)", value: "debug" },
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
]);
|
|
206
|
+
config.mode = newValue.value;
|
|
207
|
+
}
|
|
208
|
+
else if (answers.action === "domainIdList") {
|
|
209
|
+
// 显示当前列表
|
|
210
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
211
|
+
console.log(chalk.gray("\n当前站点列表:"));
|
|
212
|
+
config.domainIdList.forEach((zone, idx) => {
|
|
213
|
+
const display = zone.name ? `${zone.name} (${zone.id})` : zone.id;
|
|
214
|
+
console.log(` ${idx + 1}. ${chalk.yellow(display)}`);
|
|
215
|
+
});
|
|
216
|
+
console.log("");
|
|
217
|
+
}
|
|
218
|
+
newValue = await inquirer.prompt([{ type: "input", name: "value", message: "请输入站点列表,格式: id:备注(多个用逗号分隔):" }]);
|
|
219
|
+
if (newValue.value) {
|
|
220
|
+
config.domainIdList = newValue.value
|
|
221
|
+
.split(",")
|
|
222
|
+
.map((item) => {
|
|
223
|
+
item = item.trim();
|
|
224
|
+
if (item.includes(":")) {
|
|
225
|
+
const [id, name] = item.split(":");
|
|
226
|
+
return { id: id.trim(), name: name.trim() };
|
|
227
|
+
}
|
|
228
|
+
return { id: item };
|
|
229
|
+
})
|
|
230
|
+
.filter((zone) => zone.id !== "");
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
config.domainIdList = [];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// 确保传递完整的 Config 对象
|
|
237
|
+
const fullConfig = {
|
|
238
|
+
secretId: config.secretId,
|
|
239
|
+
secretKey: config.secretKey,
|
|
240
|
+
endpoint: config.endpoint || "teo.tencentcloudapi.com",
|
|
241
|
+
mode: config.mode,
|
|
242
|
+
domainIdList: config.domainIdList || [],
|
|
243
|
+
};
|
|
244
|
+
writeConfig(fullConfig);
|
|
245
|
+
console.log(chalk.green("\n✅ 配置已更新\n"));
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* 删除配置
|
|
249
|
+
*/
|
|
250
|
+
async function removeConfig() {
|
|
251
|
+
const { confirm } = await inquirer.prompt([
|
|
252
|
+
{ type: "confirm", name: "confirm", message: "确定要删除配置文件吗?", default: false },
|
|
253
|
+
]);
|
|
254
|
+
if (confirm) {
|
|
255
|
+
const fs = await import("fs");
|
|
256
|
+
const path = await import("path");
|
|
257
|
+
const os = await import("os");
|
|
258
|
+
const CONFIG_FILE = path.join(os.homedir(), ".edgeone-cli", "config.json");
|
|
259
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
260
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
261
|
+
console.log(chalk.green("\n✅ 配置文件已删除\n"));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repl/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYtD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互式菜单 - 主入口
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
import { readConfig } from "../commands/config.js";
|
|
7
|
+
import { showBanner, clearScreenWithBanner } from "./ui.js";
|
|
8
|
+
import { configMenu, initConfig } from "./config-menu.js";
|
|
9
|
+
import { purgeMenu } from "./purge-menu.js";
|
|
10
|
+
import { prefetchMenu } from "./prefetch-menu.js";
|
|
11
|
+
import { zoneStatusMenu } from "./zone-menu.js";
|
|
12
|
+
/**
|
|
13
|
+
* 启动交互式菜单
|
|
14
|
+
*/
|
|
15
|
+
export async function startInteractive() {
|
|
16
|
+
// 检查配置状态
|
|
17
|
+
const config = readConfig();
|
|
18
|
+
if (!config) {
|
|
19
|
+
// 未配置,直接进入初始化流程
|
|
20
|
+
showBanner();
|
|
21
|
+
await initConfig();
|
|
22
|
+
}
|
|
23
|
+
// 主循环
|
|
24
|
+
await mainMenu();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 主菜单
|
|
28
|
+
*/
|
|
29
|
+
async function mainMenu() {
|
|
30
|
+
while (true) {
|
|
31
|
+
// 清屏并显示横幅
|
|
32
|
+
clearScreenWithBanner();
|
|
33
|
+
const answers = await inquirer.prompt([
|
|
34
|
+
{
|
|
35
|
+
type: "list",
|
|
36
|
+
name: "action",
|
|
37
|
+
message: "请选择操作:",
|
|
38
|
+
choices: [
|
|
39
|
+
{ name: "🔓 配置管理", value: "config" },
|
|
40
|
+
{ name: "🧹 清除缓存", value: "purge" },
|
|
41
|
+
{ name: "🚀 内容预热", value: "prefetch" },
|
|
42
|
+
{ name: "🌐 站点状态", value: "zone-status" },
|
|
43
|
+
new inquirer.Separator("─────────────────"),
|
|
44
|
+
{ name: "❌ 退出", value: "exit" },
|
|
45
|
+
],
|
|
46
|
+
pageSize: 10,
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
if (answers.action === "exit") {
|
|
50
|
+
console.log(chalk.gray("\n👋 再见!\n"));
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
if (answers.action) {
|
|
54
|
+
await handleAction(answers.action);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 处理用户选择
|
|
60
|
+
*/
|
|
61
|
+
async function handleAction(action) {
|
|
62
|
+
const config = readConfig();
|
|
63
|
+
switch (action) {
|
|
64
|
+
case "config":
|
|
65
|
+
await configMenu();
|
|
66
|
+
break;
|
|
67
|
+
case "purge":
|
|
68
|
+
if (!config) {
|
|
69
|
+
console.log(chalk.yellow("\n⚠️ 请先初始化配置\n"));
|
|
70
|
+
await initConfig();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
await purgeMenu(config);
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case "prefetch":
|
|
77
|
+
if (!config) {
|
|
78
|
+
console.log(chalk.yellow("\n⚠️ 请先初始化配置\n"));
|
|
79
|
+
await initConfig();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await prefetchMenu(config);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case "zone-status":
|
|
86
|
+
if (!config) {
|
|
87
|
+
console.log(chalk.yellow("\n⚠️ 请先初始化配置\n"));
|
|
88
|
+
await initConfig();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
await zoneStatusMenu(config);
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 预热菜单
|
|
3
|
+
*/
|
|
4
|
+
import type { ZoneConfig } from "../types/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* 内容预热菜单
|
|
7
|
+
*/
|
|
8
|
+
export declare function prefetchMenu(config: {
|
|
9
|
+
secretId: string;
|
|
10
|
+
secretKey: string;
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
mode: "debug" | "production";
|
|
13
|
+
domainIdList?: ZoneConfig[];
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=prefetch-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefetch-menu.d.ts","sourceRoot":"","sources":["../../src/repl/prefetch-menu.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAA4C,MAAM,mBAAmB,CAAC;AAG9F;;GAEG;AACH,wBAAsB,YAAY,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,CAuE/K"}
|
|
@@ -0,0 +1,192 @@
|
|
|
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 prefetchMenu(config) {
|
|
12
|
+
const actionAnswers = await inquirer.prompt([
|
|
13
|
+
{
|
|
14
|
+
type: "list",
|
|
15
|
+
name: "type",
|
|
16
|
+
message: "选择操作:",
|
|
17
|
+
choices: [
|
|
18
|
+
{ name: "内容预热", value: "prefetch" },
|
|
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 queryPrefetchHistoryMenu(config);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const answers = await inquirer.prompt([
|
|
32
|
+
{
|
|
33
|
+
type: "input",
|
|
34
|
+
name: "urls",
|
|
35
|
+
message: "请输入要预热的 URL (多个用空格分隔,留空取消):",
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
38
|
+
if (!answers.urls || !answers.urls.trim()) {
|
|
39
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
40
|
+
await pauseToContinue();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const urls = answers.urls.split(/\s+/).filter(u => u.trim());
|
|
44
|
+
// 选择 Zone ID
|
|
45
|
+
let zoneId = "*";
|
|
46
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
47
|
+
const zoneChoices = config.domainIdList.map((zone) => ({
|
|
48
|
+
name: zone.name || zone.id,
|
|
49
|
+
value: zone.id,
|
|
50
|
+
}));
|
|
51
|
+
const zoneAnswers = await inquirer.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: "list",
|
|
54
|
+
name: "zone",
|
|
55
|
+
message: "选择站点:",
|
|
56
|
+
choices: ["* (全部站点)", ...zoneChoices],
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
if (zoneAnswers.zone !== "* (全部站点)") {
|
|
60
|
+
zoneId = zoneAnswers.zone;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// 确认
|
|
64
|
+
const confirm = await inquirer.prompt([
|
|
65
|
+
{ type: "confirm", name: "confirm", message: `确认预热以下 URL?\n ${urls.join("\n ")}\n`, default: true },
|
|
66
|
+
]);
|
|
67
|
+
if (!confirm.confirm) {
|
|
68
|
+
console.log(chalk.gray("\n❌️ 已取消"));
|
|
69
|
+
await pauseToContinue();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// 执行预热
|
|
73
|
+
await executePrefetch(config, urls, zoneId);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 执行预热
|
|
77
|
+
*/
|
|
78
|
+
async function executePrefetch(config, urls, zoneId) {
|
|
79
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "ap-guangzhou", config.mode);
|
|
80
|
+
const isDebug = config.mode === "debug";
|
|
81
|
+
if (isDebug) {
|
|
82
|
+
console.log(chalk.cyan("\n🔥 预热任务\n"));
|
|
83
|
+
console.log(chalk.gray("URL列表:"));
|
|
84
|
+
urls.forEach(u => console.log(` - ${chalk.yellow(u)}`));
|
|
85
|
+
console.log(`\nZone ID: ${chalk.green(zoneId)}`);
|
|
86
|
+
console.log("");
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const result = await client.createPrefetchTask({ zoneId, urls });
|
|
90
|
+
if ("Error" in result.Response) {
|
|
91
|
+
const error = result.Response.Error;
|
|
92
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
93
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
94
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log(chalk.green("\n✅ 预热任务已提交!"));
|
|
98
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
99
|
+
if (result.Response.JobId) {
|
|
100
|
+
console.log(` JobId: ${chalk.yellow(result.Response.JobId)}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
106
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
107
|
+
console.log(` ${errMsg}`);
|
|
108
|
+
}
|
|
109
|
+
console.log("");
|
|
110
|
+
await pauseToContinue();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 查询预热任务历史菜单
|
|
114
|
+
*/
|
|
115
|
+
async function queryPrefetchHistoryMenu(config) {
|
|
116
|
+
// 选择 Zone ID
|
|
117
|
+
let zoneIds = [];
|
|
118
|
+
if (config.domainIdList && config.domainIdList.length > 0) {
|
|
119
|
+
const zoneChoices = config.domainIdList.map((zone) => ({
|
|
120
|
+
name: zone.name || zone.id,
|
|
121
|
+
value: zone.id,
|
|
122
|
+
short: zone.name || zone.id,
|
|
123
|
+
}));
|
|
124
|
+
const zoneAnswers = await inquirer.prompt([
|
|
125
|
+
{
|
|
126
|
+
type: "checkbox",
|
|
127
|
+
name: "zones",
|
|
128
|
+
message: "选择站点 (可多选):",
|
|
129
|
+
choices: zoneChoices,
|
|
130
|
+
validate: input => input.length > 0 || "请至少选择一个站点",
|
|
131
|
+
},
|
|
132
|
+
]);
|
|
133
|
+
zoneIds = zoneAnswers.zones;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
console.log(chalk.yellow("\n⚠️ 未配置站点列表,请使用 --zone 参数指定或在配置中添加\n"));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
await queryPrefetchHistory(config, zoneIds);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 查询预热任务历史
|
|
143
|
+
*/
|
|
144
|
+
async function queryPrefetchHistory(config, zoneIds) {
|
|
145
|
+
const { default: Table } = await import("cli-table3");
|
|
146
|
+
const client = new EdgeOneClient(config.secretId, config.secretKey, config.endpoint || "teo.tencentcloudapi.com", "", config.mode);
|
|
147
|
+
const isDebug = config.mode === "debug";
|
|
148
|
+
if (isDebug) {
|
|
149
|
+
console.log(chalk.cyan("\n📋 预热任务历史记录\n"));
|
|
150
|
+
console.log(chalk.gray("ZoneIds: " + zoneIds.join(", ")));
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const result = await client.describePrefetchTasks(zoneIds);
|
|
154
|
+
if ("Error" in result.Response) {
|
|
155
|
+
const error = result.Response.Error;
|
|
156
|
+
console.log(chalk.red("\n❌ 请求失败:"));
|
|
157
|
+
console.log(` 错误码: ${chalk.yellow(error.Code)}`);
|
|
158
|
+
console.log(` 错误信息: ${chalk.yellow(error.Message)}`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(chalk.green("\n✅ 查询成功!"));
|
|
162
|
+
console.log(` RequestId: ${chalk.yellow(result.Response.RequestId)}`);
|
|
163
|
+
const tasks = result.Response.PrefetchTasks || [];
|
|
164
|
+
if (tasks.length > 0) {
|
|
165
|
+
const table = new Table({
|
|
166
|
+
head: [chalk.gray("状态"), chalk.gray("预热地址"), chalk.gray("时间")],
|
|
167
|
+
colWidths: [8, 60, 30],
|
|
168
|
+
chars: { mid: "", "left-mid": "", "mid-mid": "", "right-mid": "" },
|
|
169
|
+
});
|
|
170
|
+
tasks.forEach(task => {
|
|
171
|
+
const status = task.Status === "success" ? chalk.green("✓") : task.Status === "processing" ? chalk.yellow("⏳") : chalk.red("✗");
|
|
172
|
+
const target = task.Target || "unknown";
|
|
173
|
+
const displayTarget = target.length > 57 ? target.slice(0, 54) + "..." : target;
|
|
174
|
+
table.push([status, chalk.yellow(displayTarget), chalk.gray(task.CreateTime.slice(0, 19).replace("T", " "))]);
|
|
175
|
+
});
|
|
176
|
+
console.log(chalk.cyan("\n📋 预热任务记录:\n"));
|
|
177
|
+
console.log(table.toString());
|
|
178
|
+
console.log(` 总计: ${chalk.yellow(result.Response.TotalCount || tasks.length)} 条记录`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(chalk.gray("\n 暂无预热记录\n"));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
187
|
+
console.log(chalk.red("\n❌ 请求异常:"));
|
|
188
|
+
console.log(` ${errMsg}`);
|
|
189
|
+
}
|
|
190
|
+
console.log("");
|
|
191
|
+
await pauseToContinue();
|
|
192
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 清除缓存菜单
|
|
3
|
+
*/
|
|
4
|
+
import type { ZoneConfig } from "../types/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* 清除缓存菜单
|
|
7
|
+
*/
|
|
8
|
+
export declare function purgeMenu(config: {
|
|
9
|
+
secretId: string;
|
|
10
|
+
secretKey: string;
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
mode: "debug" | "production";
|
|
13
|
+
domainIdList?: ZoneConfig[];
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=purge-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-menu.d.ts","sourceRoot":"","sources":["../../src/repl/purge-menu.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,mBAAmB,CAAC;AAG3F;;GAEG;AACH,wBAAsB,SAAS,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,CAkG5K"}
|