edgeone-cli 1.0.0

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.
Files changed (42) hide show
  1. package/README.md +104 -0
  2. package/dist/api/client.d.ts +54 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +196 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/api/signer.d.ts +47 -0
  7. package/dist/api/signer.d.ts.map +1 -0
  8. package/dist/api/signer.js +100 -0
  9. package/dist/api/signer.js.map +1 -0
  10. package/dist/commands/config.d.ts +19 -0
  11. package/dist/commands/config.d.ts.map +1 -0
  12. package/dist/commands/config.js +265 -0
  13. package/dist/commands/config.js.map +1 -0
  14. package/dist/commands/edgeone.d.ts +14 -0
  15. package/dist/commands/edgeone.d.ts.map +1 -0
  16. package/dist/commands/edgeone.js +415 -0
  17. package/dist/commands/edgeone.js.map +1 -0
  18. package/dist/edgeone/tasks/prefetch.d.ts +23 -0
  19. package/dist/edgeone/tasks/prefetch.d.ts.map +1 -0
  20. package/dist/edgeone/tasks/prefetch.js +16 -0
  21. package/dist/edgeone/tasks/prefetch.js.map +1 -0
  22. package/dist/edgeone/tasks/purge.d.ts +23 -0
  23. package/dist/edgeone/tasks/purge.d.ts.map +1 -0
  24. package/dist/edgeone/tasks/purge.js +16 -0
  25. package/dist/edgeone/tasks/purge.js.map +1 -0
  26. package/dist/errors/codes.d.ts +67 -0
  27. package/dist/errors/codes.d.ts.map +1 -0
  28. package/dist/errors/codes.js +134 -0
  29. package/dist/errors/codes.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +29 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/utils/crypto.d.ts +13 -0
  35. package/dist/utils/crypto.d.ts.map +1 -0
  36. package/dist/utils/crypto.js +86 -0
  37. package/dist/utils/crypto.js.map +1 -0
  38. package/dist/utils/signature.d.ts +14 -0
  39. package/dist/utils/signature.d.ts.map +1 -0
  40. package/dist/utils/signature.js +48 -0
  41. package/dist/utils/signature.js.map +1 -0
  42. package/package.json +42 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * 错误码模块
3
+ * 提供错误码和描述互相转换的功能
4
+ */
5
+ /**
6
+ * EdgeOne 错误码枚举
7
+ */
8
+ export var ErrorCode;
9
+ (function (ErrorCode) {
10
+ // 内部错误
11
+ ErrorCode["InternalError_BackendError"] = "InternalError.BackendError";
12
+ ErrorCode["InternalError_DomainConfig"] = "InternalError.DomainConfig";
13
+ ErrorCode["InternalError_ProxyServer"] = "InternalError.ProxyServer";
14
+ ErrorCode["InternalError_QuotaSystem"] = "InternalError.QuotaSystem";
15
+ // 参数错误
16
+ ErrorCode["InvalidParameter_DomainNotFound"] = "InvalidParameter.DomainNotFound";
17
+ ErrorCode["InvalidParameter_ParameterError"] = "InvalidParameter.ParameterError";
18
+ ErrorCode["InvalidParameter_Target"] = "InvalidParameter.Target";
19
+ ErrorCode["InvalidParameter_TaskNotGenerated"] = "InvalidParameter.TaskNotGenerated";
20
+ ErrorCode["InvalidParameter_UploadUrl"] = "InvalidParameter.UploadUrl";
21
+ // 配额限制
22
+ ErrorCode["LimitExceeded_BatchQuota"] = "LimitExceeded.BatchQuota";
23
+ ErrorCode["LimitExceeded_DailyQuota"] = "LimitExceeded.DailyQuota";
24
+ ErrorCode["LimitExceeded_PackNotAllow"] = "LimitExceeded.PackNotAllow";
25
+ // 未授权操作
26
+ ErrorCode["UnauthorizedOperation_CamUnauthorized"] = "UnauthorizedOperation.CamUnauthorized";
27
+ ErrorCode["UnauthorizedOperation_NoPermission"] = "UnauthorizedOperation.NoPermission";
28
+ ErrorCode["UnauthorizedOperation_Unknown"] = "UnauthorizedOperation.Unknown";
29
+ })(ErrorCode || (ErrorCode = {}));
30
+ /**
31
+ * 错误描述映射
32
+ */
33
+ const ErrorMessages = {
34
+ [ErrorCode.InternalError_BackendError]: '后台处理出错。',
35
+ [ErrorCode.InternalError_DomainConfig]: '获取配置失败。',
36
+ [ErrorCode.InternalError_ProxyServer]: '后端服务器发生未知错误。',
37
+ [ErrorCode.InternalError_QuotaSystem]: '配额系统处理失败。',
38
+ [ErrorCode.InvalidParameter_DomainNotFound]: '域名不存在或不属于该账号。',
39
+ [ErrorCode.InvalidParameter_ParameterError]: '参数错误: 无效 "结束时间", 不在允许的查询范围内: [开始时间, 开始+ 7天]',
40
+ [ErrorCode.InvalidParameter_Target]: '资源存在错误。',
41
+ [ErrorCode.InvalidParameter_TaskNotGenerated]: '任务无法生成。',
42
+ [ErrorCode.InvalidParameter_UploadUrl]: '文件上传链接存在问题。',
43
+ [ErrorCode.LimitExceeded_BatchQuota]: '本次提交的资源数超过上限。',
44
+ [ErrorCode.LimitExceeded_DailyQuota]: '当天提交的资源数超过上限。',
45
+ [ErrorCode.LimitExceeded_PackNotAllow]: '计费套餐不支持。',
46
+ [ErrorCode.UnauthorizedOperation_CamUnauthorized]: 'Cam 未授权。',
47
+ [ErrorCode.UnauthorizedOperation_NoPermission]: '子账户没有操作权限,请添加权限后继续操作。',
48
+ [ErrorCode.UnauthorizedOperation_Unknown]: '后端服务器发生未知错误。',
49
+ };
50
+ /**
51
+ * 错误码工具类
52
+ */
53
+ export class ErrorCodeUtil {
54
+ /**
55
+ * 根据错误码获取描述
56
+ */
57
+ static getMessage(code) {
58
+ return ErrorMessages[code] || '未知错误';
59
+ }
60
+ /**
61
+ * 根据描述获取错误码(支持模糊匹配)
62
+ */
63
+ static getCode(message) {
64
+ // 精确匹配
65
+ const exactMatch = Object.entries(ErrorMessages).find(([, msg]) => msg === message);
66
+ if (exactMatch) {
67
+ return exactMatch[0];
68
+ }
69
+ // 模糊匹配
70
+ const fuzzyMatch = Object.entries(ErrorMessages).find(([, msg]) => msg.includes(message) || message.includes(msg));
71
+ return fuzzyMatch ? fuzzyMatch[0] : null;
72
+ }
73
+ /**
74
+ * 获取所有错误码列表
75
+ */
76
+ static getAllCodes() {
77
+ return Object.values(ErrorCode);
78
+ }
79
+ /**
80
+ * 检查是否为有效错误码
81
+ */
82
+ static isValidCode(code) {
83
+ return Object.values(ErrorCode).includes(code);
84
+ }
85
+ /**
86
+ * 格式化错误信息
87
+ */
88
+ static format(code, customMessage) {
89
+ const message = this.getMessage(code);
90
+ return customMessage ? `[${code}] ${customMessage}` : `[${code}] ${message}`;
91
+ }
92
+ /**
93
+ * 获取错误码分类
94
+ */
95
+ static getCategory(code) {
96
+ const codeStr = code;
97
+ if (codeStr.startsWith('InternalError')) {
98
+ return '内部错误';
99
+ }
100
+ if (codeStr.startsWith('InvalidParameter')) {
101
+ return '参数错误';
102
+ }
103
+ if (codeStr.startsWith('LimitExceeded')) {
104
+ return '配额限制';
105
+ }
106
+ if (codeStr.startsWith('UnauthorizedOperation')) {
107
+ return '未授权操作';
108
+ }
109
+ return '未知分类';
110
+ }
111
+ }
112
+ /**
113
+ * 错误类
114
+ */
115
+ export class EdgeOneError extends Error {
116
+ code;
117
+ details;
118
+ constructor(code, message, details) {
119
+ super(message || ErrorCodeUtil.getMessage(code));
120
+ this.name = 'EdgeOneError';
121
+ this.code = code;
122
+ this.details = details;
123
+ }
124
+ toString() {
125
+ return ErrorCodeUtil.format(this.code, this.message);
126
+ }
127
+ /**
128
+ * 获取错误分类
129
+ */
130
+ getCategory() {
131
+ return ErrorCodeUtil.getCategory(this.code);
132
+ }
133
+ }
134
+ //# sourceMappingURL=codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codes.js","sourceRoot":"","sources":["../../src/errors/codes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import chalk from "chalk";
3
+ import { program } from "commander";
4
+ import configCmd from "./commands/config.js";
5
+ import { createHistoryCommand, createPrefetchCommand, createPurgeCommand } from "./commands/edgeone.js";
6
+ import packageJson from "../package.json" with { type: "json" };
7
+ // CLI 版本
8
+ const version = packageJson.version;
9
+ // 程序信息
10
+ program.name("edgeone-cli").description("EdgeOne CLI - 本地化 EdgeOne 服务管理工具").version(version, "-v, --version", "显示版本号");
11
+ // 欢迎信息
12
+ program.addHelpText("beforeAll", `
13
+ ${chalk.cyan.bold("╔══════════════════════════════════════╗")}
14
+ ${chalk.cyan.bold("║")} ${chalk.white.bold("EdgeOne CLI")} ${chalk.cyan.bold(" ║")}
15
+ ${chalk.cyan.bold("║")} ${chalk.gray("本地化 EdgeOne 服务管理工具")} ${chalk.cyan.bold(" ║")}
16
+ ${chalk.cyan.bold("╚══════════════════════════════════════╝")}
17
+ `);
18
+ // 注册命令
19
+ program.addCommand(configCmd);
20
+ program.addCommand(createPurgeCommand());
21
+ program.addCommand(createPrefetchCommand());
22
+ program.addCommand(createHistoryCommand());
23
+ // 解析命令行参数
24
+ program.parse();
25
+ // 默认显示帮助(如果没有提供参数)
26
+ if (!process.argv.slice(2).length) {
27
+ program.outputHelp();
28
+ }
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,SAAS,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAExG,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhE,SAAS;AACT,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAEpC,OAAO;AACP,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,kCAAkC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;AAEvH,OAAO;AACP,OAAO,CAAC,WAAW,CACjB,WAAW,EACX;EACA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAAC;EAC3D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC;EACxG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;EACzF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAAC;CAC5D,CACA,CAAC;AAEF,OAAO;AACP,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAE3C,UAAU;AACV,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,mBAAmB;AACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 加密文本
3
+ */
4
+ export declare function encrypt(text: string): string;
5
+ /**
6
+ * 解密文本
7
+ */
8
+ export declare function decrypt(encryptedText: string): string;
9
+ /**
10
+ * 检查文本是否为加密格式
11
+ */
12
+ export declare function isEncrypted(text: string): boolean;
13
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAmCA;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsB5C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAsBrD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOjD"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 加密工具模块
3
+ * 使用 AES-256-GCM 加密敏感信息
4
+ */
5
+ import crypto from 'crypto';
6
+ import os from 'os';
7
+ const ALGORITHM = 'aes-256-gcm';
8
+ const KEY_LENGTH = 32;
9
+ const IV_LENGTH = 16;
10
+ const SALT_LENGTH = 64;
11
+ const TAG_LENGTH = 16;
12
+ /**
13
+ * 获取机器标识(用于生成加密密钥)
14
+ */
15
+ function getMachineId() {
16
+ const platform = os.platform();
17
+ const arch = os.arch();
18
+ const hostname = os.hostname();
19
+ const cpus = os.cpus();
20
+ const cpuModel = cpus.length > 0 ? cpus[0].model : '';
21
+ // 组合多个机器特征生成唯一标识
22
+ const machineInfo = `${platform}-${arch}-${hostname}-${cpuModel}`;
23
+ return crypto.createHash('sha256').update(machineInfo).digest('hex');
24
+ }
25
+ /**
26
+ * 生成加密密钥
27
+ */
28
+ function deriveKey(password, salt) {
29
+ return crypto.pbkdf2Sync(password, salt, 100000, KEY_LENGTH, 'sha256');
30
+ }
31
+ /**
32
+ * 加密文本
33
+ */
34
+ export function encrypt(text) {
35
+ const machineId = getMachineId();
36
+ const salt = crypto.randomBytes(SALT_LENGTH);
37
+ const key = deriveKey(machineId, salt);
38
+ const iv = crypto.randomBytes(IV_LENGTH);
39
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
40
+ let encrypted = cipher.update(text, 'utf8', 'hex');
41
+ encrypted += cipher.final('hex');
42
+ const tag = cipher.getAuthTag();
43
+ // 格式: salt(128) + iv(32) + tag(32) + encrypted
44
+ const combined = Buffer.concat([
45
+ salt,
46
+ iv,
47
+ tag,
48
+ Buffer.from(encrypted, 'hex')
49
+ ]);
50
+ return combined.toString('base64');
51
+ }
52
+ /**
53
+ * 解密文本
54
+ */
55
+ export function decrypt(encryptedText) {
56
+ try {
57
+ const combined = Buffer.from(encryptedText, 'base64');
58
+ const salt = combined.subarray(0, SALT_LENGTH);
59
+ const iv = combined.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
60
+ const tag = combined.subarray(SALT_LENGTH + IV_LENGTH, SALT_LENGTH + IV_LENGTH + TAG_LENGTH);
61
+ const encrypted = combined.subarray(SALT_LENGTH + IV_LENGTH + TAG_LENGTH);
62
+ const machineId = getMachineId();
63
+ const key = deriveKey(machineId, salt);
64
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
65
+ decipher.setAuthTag(tag);
66
+ let decrypted = decipher.update(encrypted);
67
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
68
+ return decrypted.toString('utf8');
69
+ }
70
+ catch (error) {
71
+ throw new Error('解密失败,配置文件可能已损坏或在其他机器上生成');
72
+ }
73
+ }
74
+ /**
75
+ * 检查文本是否为加密格式
76
+ */
77
+ export function isEncrypted(text) {
78
+ try {
79
+ const combined = Buffer.from(text, 'base64');
80
+ return combined.length >= SALT_LENGTH + IV_LENGTH + TAG_LENGTH;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ interface SignatureOptions {
2
+ secretId: string;
3
+ secretKey: string;
4
+ endpoint: string;
5
+ action: string;
6
+ requestBody: string;
7
+ timestamp: string;
8
+ }
9
+ /**
10
+ * 计算 TC3-HMAC-SHA256 签名
11
+ */
12
+ export declare function calculateSignature(options: SignatureOptions): string;
13
+ export {};
14
+ //# sourceMappingURL=signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../src/utils/signature.ts"],"names":[],"mappings":"AAKA,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAoDpE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * TC3-HMAC-SHA256 签名工具
3
+ */
4
+ import crypto from 'crypto';
5
+ /**
6
+ * 计算 TC3-HMAC-SHA256 签名
7
+ */
8
+ export function calculateSignature(options) {
9
+ const { secretId, secretKey, endpoint, action, requestBody, timestamp } = options;
10
+ const host = new URL(`https://${endpoint}`).host;
11
+ // 第一步:拼接规范请求串 CanonicalRequest
12
+ const HTTPRequestMethod = 'POST';
13
+ const CanonicalURI = '/';
14
+ const CanonicalQueryString = '';
15
+ // CanonicalHeaders 按照小写 key 的 ASCII 升序排列
16
+ const CanonicalHeaders = `content-type:application/json; charset=utf-8\n` +
17
+ `host:${host}\n` +
18
+ `x-tc-action:${action.toLowerCase()}\n`;
19
+ const SignedHeaders = 'content-type;host;x-tc-action';
20
+ const HashedRequestPayload = crypto.createHash('sha256').update(requestBody).digest('hex').toLowerCase();
21
+ const CanonicalRequest = HTTPRequestMethod + '\n' +
22
+ CanonicalURI + '\n' +
23
+ CanonicalQueryString + '\n' +
24
+ CanonicalHeaders + '\n' +
25
+ SignedHeaders + '\n' +
26
+ HashedRequestPayload;
27
+ // 第二步:拼接待签名字符串 StringToSign
28
+ const Algorithm = 'TC3-HMAC-SHA256';
29
+ // 将时间戳转换为 UTC 日期格式 YYYY-MM-DD
30
+ const dateStr = new Date(parseInt(timestamp) * 1000).toISOString().slice(0, 10);
31
+ const CredentialScope = `${dateStr}/teo/tc3_request`;
32
+ const HashedCanonicalRequest = crypto.createHash('sha256').update(CanonicalRequest).digest('hex').toLowerCase();
33
+ const StringToSign = Algorithm + '\n' +
34
+ timestamp + '\n' +
35
+ CredentialScope + '\n' +
36
+ HashedCanonicalRequest;
37
+ // 第三步:计算签名 Signature
38
+ // 派生签名密钥
39
+ const secretDate = crypto.createHmac('sha256', 'TC3' + secretKey).update(dateStr).digest();
40
+ const secretService = crypto.createHmac('sha256', secretDate).update('teo').digest();
41
+ const secretSigning = crypto.createHmac('sha256', secretService).update('tc3_request').digest();
42
+ // 计算签名
43
+ const signature = crypto.createHmac('sha256', secretSigning).update(StringToSign).digest('hex');
44
+ // 第四步:拼接 Authorization 值
45
+ const authorization = `${Algorithm} Credential=${secretId}/${CredentialScope}, SignedHeaders=${SignedHeaders}, Signature=${signature}`;
46
+ return authorization;
47
+ }
48
+ //# sourceMappingURL=signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../../src/utils/signature.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAW5B;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAyB;IAC1D,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAClF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;IAEjD,+BAA+B;IAC/B,MAAM,iBAAiB,GAAG,MAAM,CAAC;IACjC,MAAM,YAAY,GAAG,GAAG,CAAC;IACzB,MAAM,oBAAoB,GAAG,EAAE,CAAC;IAEhC,yCAAyC;IACzC,MAAM,gBAAgB,GACpB,gDAAgD;QAChD,QAAQ,IAAI,IAAI;QAChB,eAAe,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;IAE1C,MAAM,aAAa,GAAG,+BAA+B,CAAC;IACtD,MAAM,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAEzG,MAAM,gBAAgB,GACpB,iBAAiB,GAAG,IAAI;QACxB,YAAY,GAAG,IAAI;QACnB,oBAAoB,GAAG,IAAI;QAC3B,gBAAgB,GAAG,IAAI;QACvB,aAAa,GAAG,IAAI;QACpB,oBAAoB,CAAC;IAEvB,4BAA4B;IAC5B,MAAM,SAAS,GAAG,iBAAiB,CAAC;IACpC,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,eAAe,GAAG,GAAG,OAAO,kBAAkB,CAAC;IACrD,MAAM,sBAAsB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAEhH,MAAM,YAAY,GAChB,SAAS,GAAG,IAAI;QAChB,SAAS,GAAG,IAAI;QAChB,eAAe,GAAG,IAAI;QACtB,sBAAsB,CAAC;IAEzB,qBAAqB;IACrB,SAAS;IACT,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3F,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;IACrF,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC;IAEhG,OAAO;IACP,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhG,yBAAyB;IACzB,MAAM,aAAa,GAAG,GAAG,SAAS,eAAe,QAAQ,IAAI,eAAe,mBAAmB,aAAa,eAAe,SAAS,EAAE,CAAC;IAEvI,OAAO,aAAa,CAAC;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "edgeone-cli",
3
+ "version": "1.0.0",
4
+ "description": "EdgeOne CLI - 本地化 EdgeOne 服务管理工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "edgeone-cli": "dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "dev": "tsx src/index.ts",
13
+ "build": "tsc",
14
+ "start": "node dist/index.js"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "keywords": [
20
+ "edgeone",
21
+ "cli",
22
+ "cdn",
23
+ "tencent-cloud",
24
+ "edge"
25
+ ],
26
+ "license": "ISC",
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "dependencies": {
31
+ "chalk": "^5.6.2",
32
+ "cli-table3": "^0.6.5",
33
+ "commander": "^14.0.3",
34
+ "inquirer": "^9.3.8"
35
+ },
36
+ "devDependencies": {
37
+ "@types/inquirer": "^9.0.9",
38
+ "@types/node": "^25.3.5",
39
+ "tsx": "^4.21.0",
40
+ "typescript": "^5.9.3"
41
+ }
42
+ }