@vectorx/cloud-toolkit 0.0.0-beta-20260108133839 → 0.0.0-beta-20260320063305
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/lib/agent.kit.js +274 -56
- package/lib/cloud-dev.kit.js +36 -0
- package/lib/config/api.config.js +2 -8
- package/lib/container/container.js +10 -0
- package/lib/container/identifiers.js +5 -0
- package/lib/container/index.js +15 -0
- package/lib/database.kit.js +56 -0
- package/lib/env.kit.js +40 -0
- package/lib/fun.kit.js +34 -0
- package/lib/index.js +6 -0
- package/lib/services/agent-service.js +132 -0
- package/lib/services/auth-service.js +2 -1
- package/lib/services/cloud-dev-service.js +97 -0
- package/lib/services/cloud-env-service.js +166 -0
- package/lib/services/database-service.js +142 -0
- package/lib/services/fun-service.js +378 -0
- package/lib/services/index.js +5 -0
- package/lib/utils/cos-uploader.js +3 -1
- package/lib/utils/fun-project-validator.js +212 -0
- package/lib/utils/open-browser.js +7 -1
- package/lib/utils/openChrome.applescript +2 -2
- package/lib/utils/output.js +53 -19
- package/lib/utils/project-validator.js +3 -1
- package/lib/utils/request.js +21 -0
- package/lib/utils/table.js +17 -0
- package/lib/utils/tracker/ai-apm.js +62 -0
- package/lib/utils/tracker/apm.js +137 -0
- package/lib/utils/tracker/cli-apm.js +108 -0
- package/lib/utils/tracker/device.js +3 -1
- package/lib/utils/tracker/index.js +18 -131
- package/package.json +15 -7
- package/types/agent.kit.d.ts +45 -2
- package/types/cloud-dev.kit.d.ts +18 -0
- package/types/config/api.config.d.ts +1 -2
- package/types/container/identifiers.d.ts +6 -1
- package/types/container/index.d.ts +6 -1
- package/types/container/types.d.ts +124 -0
- package/types/database.kit.d.ts +54 -0
- package/types/env.kit.d.ts +43 -0
- package/types/fun.kit.d.ts +63 -0
- package/types/index.d.ts +6 -0
- package/types/services/agent-service.d.ts +11 -0
- package/types/services/cloud-dev-service.d.ts +23 -0
- package/types/services/cloud-env-service.d.ts +10 -0
- package/types/services/database-service.d.ts +33 -0
- package/types/services/fun-service.d.ts +23 -0
- package/types/services/index.d.ts +5 -0
- package/types/utils/fun-project-validator.d.ts +22 -0
- package/types/utils/table.d.ts +2 -0
- package/types/utils/tracker/ai-apm.d.ts +54 -0
- package/types/utils/tracker/apm.d.ts +28 -0
- package/types/utils/tracker/cli-apm.d.ts +27 -0
- package/types/utils/tracker/index.d.ts +5 -27
package/lib/utils/output.js
CHANGED
|
@@ -6,32 +6,66 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.outputHelpInfo = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const outputHelpInfo = () => {
|
|
9
|
+
const header = `
|
|
10
|
+
${chalk_1.default.cyan.bold("小红书云 CLI (rcb) — 命令一览")}
|
|
11
|
+
`;
|
|
9
12
|
const commands = `
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
${chalk_1.default.bold("命令")}
|
|
14
|
+
${chalk_1.default.cyan("login")} [options] 登录 / 管理小红书云账号
|
|
15
|
+
${chalk_1.default.cyan("logout")} [options] 退出当前登录账号
|
|
16
|
+
${chalk_1.default.cyan("agent")} [cmd] 开发与构建 AI Agent
|
|
17
|
+
${chalk_1.default.cyan("fun")} [cmd] 管理 Fun 云函数调试与部署
|
|
18
|
+
${chalk_1.default.cyan("env")} [cmd] 管理云环境(Environment)
|
|
19
|
+
`;
|
|
20
|
+
const agentCommands = `
|
|
21
|
+
${chalk_1.default.bold("Agent 子命令")}
|
|
22
|
+
${chalk_1.default.cyan("rcb agent new")} 创建 AI 智能体模板项目
|
|
23
|
+
${chalk_1.default.cyan("rcb agent dev")} 启动 AI Agent 本地开发服务器
|
|
24
|
+
${chalk_1.default.cyan("rcb agent build")} 打包 AI Agent 为可部署的云函数代码
|
|
25
|
+
`;
|
|
26
|
+
const funCommands = `
|
|
27
|
+
${chalk_1.default.bold("Fun 子命令")}
|
|
28
|
+
${chalk_1.default.cyan("rcb fun dev")} 本地启动 Fun 云函数调试服务
|
|
29
|
+
${chalk_1.default.cyan("rcb fun list")} 查看关联云环境 / 函数占位信息(待接入真实查询)
|
|
30
|
+
${chalk_1.default.cyan("rcb fun deploy")} 将打包好的函数代码部署到云端
|
|
31
|
+
`;
|
|
32
|
+
const envCommands = `
|
|
33
|
+
${chalk_1.default.bold("Env 子命令")}
|
|
34
|
+
${chalk_1.default.cyan("rcb env list")} 查看当前账号下的云环境列表
|
|
35
|
+
${chalk_1.default.cyan("rcb env info -e <envId>")} 查看指定云环境的详情信息
|
|
36
|
+
`;
|
|
37
|
+
const authCommands = `
|
|
38
|
+
${chalk_1.default.bold("登录与账号管理")}
|
|
39
|
+
${chalk_1.default.cyan("rcb login")} 交互式登录或配置密钥
|
|
40
|
+
${chalk_1.default.cyan("rcb logout")} 退出当前账号、清理本地凭证
|
|
41
|
+
`;
|
|
13
42
|
const options = `
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
43
|
+
${chalk_1.default.bold("全局选项")}
|
|
44
|
+
${chalk_1.default.cyan("-v, --version")} 输出当前 rcb 版本
|
|
45
|
+
${chalk_1.default.cyan("-h, --help")} 查看命令帮助信息
|
|
46
|
+
`;
|
|
17
47
|
const tips = `
|
|
18
|
-
|
|
48
|
+
${chalk_1.default.bold("使用示例")}
|
|
19
49
|
|
|
20
|
-
|
|
21
|
-
|
|
50
|
+
${chalk_1.default.gray("–")} 登录管理
|
|
51
|
+
${chalk_1.default.cyan("$ rcb login --secretId <secretId> --secretKey <secretKey>")}
|
|
52
|
+
${chalk_1.default.cyan("$ rcb logout")}
|
|
22
53
|
|
|
23
|
-
|
|
24
|
-
|
|
54
|
+
${chalk_1.default.gray("–")} 创建 AI 智能体模版项目
|
|
55
|
+
${chalk_1.default.cyan("$ rcb agent new -p my-agent")}
|
|
25
56
|
|
|
26
|
-
|
|
27
|
-
|
|
57
|
+
${chalk_1.default.gray("–")} 启动本地开发
|
|
58
|
+
${chalk_1.default.cyan("$ rcb agent dev")}
|
|
59
|
+
${chalk_1.default.cyan("$ rcb fun dev")}
|
|
28
60
|
|
|
29
|
-
|
|
30
|
-
|
|
61
|
+
${chalk_1.default.gray("–")} 管理云环境
|
|
62
|
+
${chalk_1.default.cyan("$ rcb env list")}
|
|
63
|
+
${chalk_1.default.cyan("$ rcb env info -e env-xxxxxx")}
|
|
31
64
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
65
|
+
${chalk_1.default.gray("–")} 打包与部署函数
|
|
66
|
+
${chalk_1.default.cyan("$ rcb agent build")}
|
|
67
|
+
${chalk_1.default.cyan("$ rcb fun deploy")}
|
|
68
|
+
`;
|
|
69
|
+
console.log(header.trimEnd(), "\n", commands.trimEnd(), "\n", agentCommands.trimEnd(), "\n", funCommands.trimEnd(), "\n", envCommands.trimEnd(), "\n", authCommands.trimEnd(), "\n", options.trimEnd(), "\n", tips.trimEnd());
|
|
36
70
|
};
|
|
37
71
|
exports.outputHelpInfo = outputHelpInfo;
|
|
@@ -88,7 +88,9 @@ class ProjectValidator {
|
|
|
88
88
|
return { valid: false, errors };
|
|
89
89
|
}
|
|
90
90
|
try {
|
|
91
|
-
const version = env_helper_1.isIDE
|
|
91
|
+
const version = env_helper_1.isIDE
|
|
92
|
+
? ((_a = this.uploadInfo) === null || _a === void 0 ? void 0 : _a.version) || projectConfig.version
|
|
93
|
+
: projectConfig.version;
|
|
92
94
|
const desc = env_helper_1.isIDE ? ((_b = this.uploadInfo) === null || _b === void 0 ? void 0 : _b.desc) || projectConfig.desc : projectConfig.desc;
|
|
93
95
|
const uploadService = container_1.container.get(container_1.SERVICE_IDENTIFIERS.UploadService);
|
|
94
96
|
const buildPreCheckResult = yield uploadService.buildPreCheck({
|
package/lib/utils/request.js
CHANGED
|
@@ -15,10 +15,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.request = exports.Request = void 0;
|
|
16
16
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
17
17
|
const env_helper_1 = require("./env-helper");
|
|
18
|
+
const cli_apm_1 = require("./tracker/cli-apm");
|
|
18
19
|
class Request {
|
|
19
20
|
fetch(options) {
|
|
20
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
22
|
const { method = "GET", url, data = {}, headers = {} } = options;
|
|
23
|
+
let requestUrlForReport = url;
|
|
22
24
|
try {
|
|
23
25
|
let requestUrl = url;
|
|
24
26
|
let requestBody;
|
|
@@ -34,6 +36,7 @@ class Request {
|
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
requestUrl = queryParams.toString() ? `${url}?${queryParams.toString()}` : url;
|
|
39
|
+
requestUrlForReport = requestUrl;
|
|
37
40
|
if (method === "POST" && data.body) {
|
|
38
41
|
requestBody = JSON.stringify(data.body);
|
|
39
42
|
const contentTypeKey = Object.keys(headers).find((key) => key.toLowerCase() === "content-type");
|
|
@@ -49,6 +52,20 @@ class Request {
|
|
|
49
52
|
timeout: 1000 * 20,
|
|
50
53
|
});
|
|
51
54
|
const responseData = yield response.json();
|
|
55
|
+
if (response.status >= 400) {
|
|
56
|
+
try {
|
|
57
|
+
(0, cli_apm_1.reportCliHttpError)({
|
|
58
|
+
method,
|
|
59
|
+
url: requestUrl,
|
|
60
|
+
status_code: response.status,
|
|
61
|
+
}, {
|
|
62
|
+
message: (responseData && (responseData.msg || responseData.message)) ||
|
|
63
|
+
`HTTP ${response.status}`,
|
|
64
|
+
status: response.status,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (e) { }
|
|
68
|
+
}
|
|
52
69
|
return {
|
|
53
70
|
status: response.status,
|
|
54
71
|
data: responseData,
|
|
@@ -56,6 +73,10 @@ class Request {
|
|
|
56
73
|
};
|
|
57
74
|
}
|
|
58
75
|
catch (error) {
|
|
76
|
+
try {
|
|
77
|
+
(0, cli_apm_1.reportCliHttpError)({ method, url: requestUrlForReport }, error);
|
|
78
|
+
}
|
|
79
|
+
catch (e) { }
|
|
59
80
|
throw new Error(`请求失败 ${error.message}`);
|
|
60
81
|
}
|
|
61
82
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.printHorizontalTable = printHorizontalTable;
|
|
7
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
8
|
+
function printHorizontalTable(head, data = [], options) {
|
|
9
|
+
if (!(data === null || data === void 0 ? void 0 : data.length)) {
|
|
10
|
+
console.log("列表数据为空");
|
|
11
|
+
}
|
|
12
|
+
const table = new cli_table3_1.default(Object.assign({ head, style: { head: ["yellow"] }, colAligns: new Array(head.length).fill("center") }, options));
|
|
13
|
+
data.forEach((item) => {
|
|
14
|
+
table.push(item);
|
|
15
|
+
});
|
|
16
|
+
console.log(table.toString());
|
|
17
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AI_MEASUREMENT_NAME = void 0;
|
|
4
|
+
exports.initAiApm = initAiApm;
|
|
5
|
+
exports.reportAiSessionRun = reportAiSessionRun;
|
|
6
|
+
exports.reportAiTurnCodeGenerated = reportAiTurnCodeGenerated;
|
|
7
|
+
exports.reportAiSessionComplete = reportAiSessionComplete;
|
|
8
|
+
exports.reportAiCodeChangeApplied = reportAiCodeChangeApplied;
|
|
9
|
+
exports.reportAiCodeChangeRejected = reportAiCodeChangeRejected;
|
|
10
|
+
exports.reportAiBulkResolve = reportAiBulkResolve;
|
|
11
|
+
exports.reportAiMessageSent = reportAiMessageSent;
|
|
12
|
+
const apm_1 = require("./apm");
|
|
13
|
+
exports.AI_MEASUREMENT_NAME = "vectorx_ai_chat_service_usage";
|
|
14
|
+
let _apm = null;
|
|
15
|
+
function initAiApm(options = {}) {
|
|
16
|
+
if (!_apm)
|
|
17
|
+
_apm = new apm_1.APM();
|
|
18
|
+
_apm.setContext(options.userId || "", {});
|
|
19
|
+
}
|
|
20
|
+
function reportAiSessionRun(meta) {
|
|
21
|
+
if (!_apm)
|
|
22
|
+
return;
|
|
23
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign(Object.assign({ event: "session_run", session_id: meta.session_id }, (meta.model ? { model: meta.model } : {})), (meta.dev_mode ? { dev_mode: meta.dev_mode } : {})), (typeof meta.is_new_session === "number" ? { is_new_session: meta.is_new_session } : {})), (typeof meta.message_length === "number" ? { message_length: meta.message_length } : {})));
|
|
24
|
+
}
|
|
25
|
+
function reportAiTurnCodeGenerated(meta) {
|
|
26
|
+
if (!_apm)
|
|
27
|
+
return;
|
|
28
|
+
if (!meta.files_changed && !meta.lines_added && !meta.lines_removed)
|
|
29
|
+
return;
|
|
30
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ event: "turn_code_generated" }, (meta.session_id ? { session_id: meta.session_id } : {})), (meta.model ? { model: meta.model } : {})), (meta.dev_mode ? { dev_mode: meta.dev_mode } : {})), (typeof meta.files_changed === "number" ? { files_changed: meta.files_changed } : {})), (typeof meta.lines_added === "number" ? { lines_added: meta.lines_added } : {})), (typeof meta.lines_removed === "number" ? { lines_removed: meta.lines_removed } : {})));
|
|
31
|
+
}
|
|
32
|
+
function reportAiSessionComplete(meta) {
|
|
33
|
+
if (!_apm)
|
|
34
|
+
return;
|
|
35
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ event: "session_complete", session_id: meta.session_id }, (meta.model ? { model: meta.model } : {})), (meta.dev_mode ? { dev_mode: meta.dev_mode } : {})), { duration_ms: meta.duration_ms, status: meta.status }), (typeof meta.total_files_changed === "number"
|
|
36
|
+
? { total_files_changed: meta.total_files_changed }
|
|
37
|
+
: {})), (typeof meta.total_lines_added === "number"
|
|
38
|
+
? { total_lines_added: meta.total_lines_added }
|
|
39
|
+
: {})), (typeof meta.total_lines_removed === "number"
|
|
40
|
+
? { total_lines_removed: meta.total_lines_removed }
|
|
41
|
+
: {})), (meta.error_type ? { error_type: meta.error_type } : {})));
|
|
42
|
+
}
|
|
43
|
+
function reportAiCodeChangeApplied(meta) {
|
|
44
|
+
if (!_apm)
|
|
45
|
+
return;
|
|
46
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign({ event: "code_change_applied" }, (meta.session_id ? { session_id: meta.session_id } : {})), (meta.tool_name ? { tool_name: meta.tool_name } : {})));
|
|
47
|
+
}
|
|
48
|
+
function reportAiCodeChangeRejected(meta) {
|
|
49
|
+
if (!_apm)
|
|
50
|
+
return;
|
|
51
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign({ event: "code_change_rejected" }, (meta.session_id ? { session_id: meta.session_id } : {})), (meta.tool_name ? { tool_name: meta.tool_name } : {})));
|
|
52
|
+
}
|
|
53
|
+
function reportAiBulkResolve(meta) {
|
|
54
|
+
if (!_apm)
|
|
55
|
+
return;
|
|
56
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign({ event: "bulk_resolve", action: meta.action }, (meta.session_id ? { session_id: meta.session_id } : {})), (typeof meta.files_count === "number" ? { files_count: meta.files_count } : {})));
|
|
57
|
+
}
|
|
58
|
+
function reportAiMessageSent(meta) {
|
|
59
|
+
if (!_apm)
|
|
60
|
+
return;
|
|
61
|
+
_apm.report(exports.AI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign(Object.assign({ event: "message_sent" }, (meta.session_id ? { session_id: meta.session_id } : {})), (meta.mode ? { mode: meta.mode } : {})), (meta.model ? { model: meta.model } : {})), (typeof meta.message_length === "number" ? { message_length: meta.message_length } : {})));
|
|
62
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.APM = void 0;
|
|
7
|
+
const endpoints_1 = require("@vectorx/endpoints");
|
|
8
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
10
|
+
const logger_1 = require("../logger");
|
|
11
|
+
const device_1 = require("./device");
|
|
12
|
+
const deviceInfo = (0, device_1.getDeviceInfo)();
|
|
13
|
+
const getUserAgent = () => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const electronStr = typeof ((_a = process === null || process === void 0 ? void 0 : process.versions) === null || _a === void 0 ? void 0 : _a.electron) !== "undefined"
|
|
16
|
+
? `Electron/${(_b = process === null || process === void 0 ? void 0 : process.versions) === null || _b === void 0 ? void 0 : _b.electron}`
|
|
17
|
+
: "";
|
|
18
|
+
const nodeStr = `Node/${process.version}`;
|
|
19
|
+
const osVersion = `${deviceInfo.os_platform}/${deviceInfo.os_version}`;
|
|
20
|
+
const cpu = `CPU/${deviceInfo.cpu_speed}mhz (${deviceInfo.cpu_model}; ${deviceInfo.os_arch})`;
|
|
21
|
+
const mem = `Memory/${deviceInfo.machine_memory}mb`;
|
|
22
|
+
return [electronStr, nodeStr, osVersion, cpu, mem]
|
|
23
|
+
.map((i) => { var _a; return (_a = i === null || i === void 0 ? void 0 : i.trim) === null || _a === void 0 ? void 0 : _a.call(i); })
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join(" ")
|
|
26
|
+
.trim();
|
|
27
|
+
};
|
|
28
|
+
const CONTEXT = {
|
|
29
|
+
context_nameTracker: "nodeT",
|
|
30
|
+
context_platform: deviceInfo.os_platform,
|
|
31
|
+
context_appVersion: (process === null || process === void 0 ? void 0 : process.CLI_VERSION) || "unknown",
|
|
32
|
+
context_osVersion: deviceInfo.os_version,
|
|
33
|
+
context_deviceModel: "",
|
|
34
|
+
context_deviceId: (0, device_1.machineId)(),
|
|
35
|
+
context_package: "",
|
|
36
|
+
context_networkType: "unknow",
|
|
37
|
+
context_matchedPath: "cli",
|
|
38
|
+
context_route: "xhsmp://cli",
|
|
39
|
+
context_userAgent: getUserAgent(),
|
|
40
|
+
context_artifactName: "miniprogram",
|
|
41
|
+
context_networkQuality: "UNKNOWN",
|
|
42
|
+
context_artifactVersion: "UNKNOWN",
|
|
43
|
+
context_userId: "",
|
|
44
|
+
};
|
|
45
|
+
const getApmEndpoint = () => (0, endpoints_1.resolveUrl)("@vectorx/cloud-toolkit", "apmDataEndpoint");
|
|
46
|
+
class APM {
|
|
47
|
+
constructor() {
|
|
48
|
+
this.reportQueue = [];
|
|
49
|
+
this.allowReport = false;
|
|
50
|
+
this.eventSeq = 1;
|
|
51
|
+
this.context = Object.assign({}, CONTEXT);
|
|
52
|
+
this.baseData = {};
|
|
53
|
+
this.timer = null;
|
|
54
|
+
}
|
|
55
|
+
setContext(userId, base = {}) {
|
|
56
|
+
this.context = Object.assign(Object.assign({}, this.context), { context_userId: userId });
|
|
57
|
+
this.baseData = base;
|
|
58
|
+
this.startReport();
|
|
59
|
+
}
|
|
60
|
+
setAppVersion(appVersion) {
|
|
61
|
+
var _a;
|
|
62
|
+
this.context = Object.assign(Object.assign({}, this.context), { context_appVersion: appVersion || ((_a = this.context) === null || _a === void 0 ? void 0 : _a.context_appVersion) });
|
|
63
|
+
}
|
|
64
|
+
startReport() {
|
|
65
|
+
this.allowReport = true;
|
|
66
|
+
this.batchReport();
|
|
67
|
+
}
|
|
68
|
+
getSequence() {
|
|
69
|
+
return {
|
|
70
|
+
context_sdkSeqId: this.eventSeq++,
|
|
71
|
+
context_sdkSessionId: (0, uuid_1.v4)(),
|
|
72
|
+
context_pageSessionId: (0, uuid_1.v4)(),
|
|
73
|
+
clientTime: Date.now(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
_request(params, retry = true) {
|
|
77
|
+
const list = Array.isArray(params) ? params : [params];
|
|
78
|
+
const merged = list.map((i) => {
|
|
79
|
+
return Object.assign(Object.assign(Object.assign({}, this.context), i.sequence), { measurement_name: i.measurement_name, measurement_data: Object.assign(Object.assign({}, this.baseData), i.measurement_data) });
|
|
80
|
+
});
|
|
81
|
+
return (0, node_fetch_1.default)(getApmEndpoint(), {
|
|
82
|
+
method: "post",
|
|
83
|
+
body: JSON.stringify(merged),
|
|
84
|
+
headers: {
|
|
85
|
+
accept: "*/*",
|
|
86
|
+
"accept-language": "zh-CN,zh;q=0.9",
|
|
87
|
+
batch: "true",
|
|
88
|
+
"biz-type": "apm_fe",
|
|
89
|
+
"cache-control": "no-cache",
|
|
90
|
+
"content-type": "application/json",
|
|
91
|
+
pragma: "no-cache",
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
.then((res) => res.json())
|
|
95
|
+
.then((res) => {
|
|
96
|
+
if (res === null || res === void 0 ? void 0 : res.success) {
|
|
97
|
+
logger_1.logger.debug("apm send success", "");
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
throw new Error(res === null || res === void 0 ? void 0 : res.msg);
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.catch((err) => {
|
|
104
|
+
if (retry) {
|
|
105
|
+
setTimeout(() => this._request(params, false), 1000);
|
|
106
|
+
}
|
|
107
|
+
logger_1.logger.log("apm send failed", `${(err === null || err === void 0 ? void 0 : err.message) || null}`, "error");
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
batchReport() {
|
|
111
|
+
const queue = [...this.reportQueue];
|
|
112
|
+
this.reportQueue = [];
|
|
113
|
+
while (queue.length) {
|
|
114
|
+
this._request(queue.splice(0, 5));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
report(measurement_name, measurement_data = {}) {
|
|
118
|
+
const params = {
|
|
119
|
+
sequence: this.getSequence(),
|
|
120
|
+
measurement_name,
|
|
121
|
+
measurement_data,
|
|
122
|
+
};
|
|
123
|
+
this.reportQueue.push(params);
|
|
124
|
+
clearTimeout(this.timer);
|
|
125
|
+
if (this.allowReport) {
|
|
126
|
+
if (this.reportQueue.length >= 10) {
|
|
127
|
+
this.batchReport();
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.timer = setTimeout(() => {
|
|
131
|
+
this.batchReport();
|
|
132
|
+
}, 300);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.APM = APM;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLI_MEASUREMENT_NAME = void 0;
|
|
4
|
+
exports.initCliApm = initCliApm;
|
|
5
|
+
exports.setCliApmCurrentCommand = setCliApmCurrentCommand;
|
|
6
|
+
exports.createCliCommandTracker = createCliCommandTracker;
|
|
7
|
+
exports.reportCliException = reportCliException;
|
|
8
|
+
exports.reportCliHttpError = reportCliHttpError;
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const apm_1 = require("./apm");
|
|
11
|
+
exports.CLI_MEASUREMENT_NAME = "vectorx_cloud_cli_usage";
|
|
12
|
+
let apm = null;
|
|
13
|
+
let currentCmdPath;
|
|
14
|
+
function safeTruncate(str, max = 200) {
|
|
15
|
+
if (!str)
|
|
16
|
+
return "";
|
|
17
|
+
const s = String(str);
|
|
18
|
+
if (s.length <= max)
|
|
19
|
+
return s;
|
|
20
|
+
return `${s.slice(0, max)}...`;
|
|
21
|
+
}
|
|
22
|
+
function hashError(input) {
|
|
23
|
+
try {
|
|
24
|
+
return (0, crypto_1.createHash)("sha256").update(input).digest("hex").slice(0, 16);
|
|
25
|
+
}
|
|
26
|
+
catch (_a) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function normalizeError(err) {
|
|
31
|
+
var _a, _b, _c, _d;
|
|
32
|
+
const msg = safeTruncate((err === null || err === void 0 ? void 0 : err.errMsg) ||
|
|
33
|
+
(err === null || err === void 0 ? void 0 : err.message) ||
|
|
34
|
+
(typeof (err === null || err === void 0 ? void 0 : err.toString) === "function" ? err.toString() : "") ||
|
|
35
|
+
"Unknown error");
|
|
36
|
+
const code = (_c = (_b = (_a = err === null || err === void 0 ? void 0 : err.code) !== null && _a !== void 0 ? _a : err === null || err === void 0 ? void 0 : err.statusCode) !== null && _b !== void 0 ? _b : err === null || err === void 0 ? void 0 : err.status) !== null && _c !== void 0 ? _c : (_d = err === null || err === void 0 ? void 0 : err.response) === null || _d === void 0 ? void 0 : _d.status;
|
|
37
|
+
const stack = (err === null || err === void 0 ? void 0 : err.stack) ? String(err.stack) : "";
|
|
38
|
+
const h = hashError(stack || msg);
|
|
39
|
+
const lower = msg.toLowerCase();
|
|
40
|
+
let type = "unknown";
|
|
41
|
+
if (typeof code === "number" && code >= 400)
|
|
42
|
+
type = "http";
|
|
43
|
+
if (lower.includes("http") || lower.includes("request") || lower.includes("fetch"))
|
|
44
|
+
type = "http";
|
|
45
|
+
if (lower.includes("token") || lower.includes("login") || lower.includes("auth"))
|
|
46
|
+
type = "auth";
|
|
47
|
+
if (lower.includes("invalid") || lower.includes("参数") || lower.includes("校验"))
|
|
48
|
+
type = "validation";
|
|
49
|
+
return Object.assign(Object.assign(Object.assign({ error_msg: msg }, (code !== undefined ? { error_code: code } : {})), (h ? { error_hash: h } : {})), { error_type: type });
|
|
50
|
+
}
|
|
51
|
+
function initCliApm(options = {}) {
|
|
52
|
+
if (!apm)
|
|
53
|
+
apm = new apm_1.APM();
|
|
54
|
+
if (options.cliVersion) {
|
|
55
|
+
apm.setAppVersion(options.cliVersion);
|
|
56
|
+
}
|
|
57
|
+
apm.setContext(options.userId || "", {});
|
|
58
|
+
}
|
|
59
|
+
function setCliApmCurrentCommand(cmdPath) {
|
|
60
|
+
currentCmdPath = cmdPath;
|
|
61
|
+
}
|
|
62
|
+
function createCliCommandTracker(meta) {
|
|
63
|
+
var _a, _b, _c;
|
|
64
|
+
setCliApmCurrentCommand(meta.cmd_path);
|
|
65
|
+
const base = Object.assign(Object.assign(Object.assign(Object.assign({ event: "command", cmd_path: meta.cmd_path }, (meta.cmd_root ? { cmd_root: meta.cmd_root } : {})), (typeof meta.params_count === "number" ? { params_count: meta.params_count } : {})), (Array.isArray(meta.options_keys)
|
|
66
|
+
? { options_keys: JSON.stringify(meta.options_keys) }
|
|
67
|
+
: {})), { cli_version: (process === null || process === void 0 ? void 0 : process.CLI_VERSION) || "unknown", node_major: Number((_c = (_b = (_a = process.versions) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.split(".")) === null || _c === void 0 ? void 0 : _c[0]) || undefined, is_ci: process.env.CI ? 1 : 0 });
|
|
68
|
+
return {
|
|
69
|
+
reportSuccess(durationMs) {
|
|
70
|
+
if (!apm)
|
|
71
|
+
return;
|
|
72
|
+
apm.report(exports.CLI_MEASUREMENT_NAME, Object.assign(Object.assign({}, base), { status: 1, duration: durationMs }));
|
|
73
|
+
setCliApmCurrentCommand(undefined);
|
|
74
|
+
},
|
|
75
|
+
reportFail(durationMs, err) {
|
|
76
|
+
if (!apm)
|
|
77
|
+
return;
|
|
78
|
+
const n = normalizeError(err);
|
|
79
|
+
apm.report(exports.CLI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign({}, base), { status: 0, duration: durationMs }), n));
|
|
80
|
+
setCliApmCurrentCommand(undefined);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function reportCliException(source, err) {
|
|
85
|
+
var _a, _b, _c;
|
|
86
|
+
if (!apm)
|
|
87
|
+
return;
|
|
88
|
+
const n = normalizeError(err);
|
|
89
|
+
apm.report(exports.CLI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign({ event: "exception", source }, (currentCmdPath ? { cmd_path: currentCmdPath } : {})), { cli_version: (process === null || process === void 0 ? void 0 : process.CLI_VERSION) || "unknown", node_major: Number((_c = (_b = (_a = process.versions) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.split(".")) === null || _c === void 0 ? void 0 : _c[0]) || undefined, is_ci: process.env.CI ? 1 : 0 }), n));
|
|
90
|
+
}
|
|
91
|
+
function reportCliHttpError(meta, err) {
|
|
92
|
+
var _a, _b, _c;
|
|
93
|
+
if (!apm)
|
|
94
|
+
return;
|
|
95
|
+
let host;
|
|
96
|
+
let path;
|
|
97
|
+
if (meta.url) {
|
|
98
|
+
try {
|
|
99
|
+
const u = new URL(meta.url);
|
|
100
|
+
host = u.host;
|
|
101
|
+
path = u.pathname;
|
|
102
|
+
}
|
|
103
|
+
catch (_d) {
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const n = err ? normalizeError(err) : undefined;
|
|
107
|
+
apm.report(exports.CLI_MEASUREMENT_NAME, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ event: "http_error" }, (meta.method ? { method: meta.method } : {})), (host ? { host } : {})), (path ? { path } : {})), (typeof meta.status_code === "number" ? { status_code: meta.status_code } : {})), (currentCmdPath ? { cmd_path: currentCmdPath } : {})), { cli_version: (process === null || process === void 0 ? void 0 : process.CLI_VERSION) || "unknown", node_major: Number((_c = (_b = (_a = process.versions) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.split(".")) === null || _c === void 0 ? void 0 : _c[0]) || undefined, is_ci: process.env.CI ? 1 : 0 }), (n ? n : {})));
|
|
108
|
+
}
|
|
@@ -44,7 +44,9 @@ function getOsVersion() {
|
|
|
44
44
|
var _a, _b;
|
|
45
45
|
try {
|
|
46
46
|
if (process.platform === "darwin") {
|
|
47
|
-
return (_a = (0, child_process_1.execSync)("sw_vers -productVersion", {
|
|
47
|
+
return (_a = (0, child_process_1.execSync)("sw_vers -productVersion", {
|
|
48
|
+
encoding: "utf-8",
|
|
49
|
+
})) === null || _a === void 0 ? void 0 : _a.trim();
|
|
48
50
|
}
|
|
49
51
|
return (_b = os_1.default.release()) === null || _b === void 0 ? void 0 : _b.trim();
|
|
50
52
|
}
|
|
@@ -1,134 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const deviceInfo = (0, device_1.getDeviceInfo)();
|
|
12
|
-
const getUserAgent = () => {
|
|
13
|
-
var _a, _b;
|
|
14
|
-
const electronStr = typeof ((_a = process === null || process === void 0 ? void 0 : process.versions) === null || _a === void 0 ? void 0 : _a.electron) !== "undefined" ? `Electron/${(_b = process === null || process === void 0 ? void 0 : process.versions) === null || _b === void 0 ? void 0 : _b.electron}` : "";
|
|
15
|
-
const nodeStr = `Node/${process.version}`;
|
|
16
|
-
const os_version = `${deviceInfo.os_platform}/${deviceInfo.os_version}`;
|
|
17
|
-
const cpu = `CPU/${deviceInfo.cpu_speed}mhz (${deviceInfo.cpu_model}; ${deviceInfo.os_arch})`;
|
|
18
|
-
const mem = `Memory/${deviceInfo.machine_memory}mb`;
|
|
19
|
-
return [electronStr, nodeStr, os_version, cpu, mem]
|
|
20
|
-
.map((i) => { var _a; return (_a = i === null || i === void 0 ? void 0 : i.trim) === null || _a === void 0 ? void 0 : _a.call(i); })
|
|
21
|
-
.filter(Boolean)
|
|
22
|
-
.join(" ")
|
|
23
|
-
.trim();
|
|
24
|
-
};
|
|
25
|
-
const CONTEXT = {
|
|
26
|
-
context_nameTracker: "nodeT",
|
|
27
|
-
context_platform: deviceInfo.os_platform,
|
|
28
|
-
context_appVersion: "0.0.1",
|
|
29
|
-
context_osVersion: deviceInfo.os_version,
|
|
30
|
-
context_deviceModel: "",
|
|
31
|
-
context_deviceId: (0, device_1.machineId)(),
|
|
32
|
-
context_package: "",
|
|
33
|
-
context_networkType: "unknow",
|
|
34
|
-
context_matchedPath: "cli",
|
|
35
|
-
context_route: "xhsmp://cli",
|
|
36
|
-
context_userAgent: getUserAgent(),
|
|
37
|
-
context_artifactName: "miniprogram",
|
|
38
|
-
context_networkQuality: "UNKNOWN",
|
|
39
|
-
context_artifactVersion: "UNKNOWN",
|
|
40
|
-
context_userId: "",
|
|
41
|
-
};
|
|
42
|
-
const ENDPOINT = {
|
|
43
|
-
development: "https://apm-fe.xiaohongshu.com/api/data",
|
|
44
|
-
production: "https://apm-fe.xiaohongshu.com/api/data",
|
|
45
|
-
};
|
|
46
|
-
class APM {
|
|
47
|
-
constructor() {
|
|
48
|
-
this.reportQueue = [];
|
|
49
|
-
this.allowReport = false;
|
|
50
|
-
this.eventSeq = 1;
|
|
51
|
-
this.context = Object.assign({}, CONTEXT);
|
|
52
|
-
this.baseData = {};
|
|
53
|
-
this.timer = null;
|
|
54
|
-
}
|
|
55
|
-
setContext(userId, base = {}) {
|
|
56
|
-
this.context = Object.assign(Object.assign({}, this.context), { context_userId: userId });
|
|
57
|
-
this.baseData = base;
|
|
58
|
-
this.startReport();
|
|
59
|
-
}
|
|
60
|
-
startReport() {
|
|
61
|
-
this.allowReport = true;
|
|
62
|
-
this.bactchReport();
|
|
63
|
-
}
|
|
64
|
-
getSequence() {
|
|
65
|
-
return {
|
|
66
|
-
context_sdkSeqId: this.eventSeq++,
|
|
67
|
-
context_sdkSessionId: uuid_1.default.v4(),
|
|
68
|
-
context_pageSessionId: uuid_1.default.v4(),
|
|
69
|
-
clientTime: Date.now(),
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
_request(params, retry = true) {
|
|
73
|
-
const list = Array.isArray(params) ? params : [params];
|
|
74
|
-
const merged = list.map((i) => {
|
|
75
|
-
return Object.assign(Object.assign(Object.assign({}, this.context), i.suquence), { measurement_name: i.measurement_name, measurement_data: Object.assign(Object.assign({}, this.baseData), i.measurement_data) });
|
|
76
|
-
});
|
|
77
|
-
logger_1.logger.debug(`apm before send`, `${JSON.stringify(merged)}`, "warning");
|
|
78
|
-
return (0, node_fetch_1.default)(ENDPOINT.development, {
|
|
79
|
-
method: "post",
|
|
80
|
-
body: JSON.stringify(merged),
|
|
81
|
-
headers: {
|
|
82
|
-
accept: "*/*",
|
|
83
|
-
"accept-language": "zh-CN,zh;q=0.9",
|
|
84
|
-
batch: "true",
|
|
85
|
-
"biz-type": "apm_fe",
|
|
86
|
-
"cache-control": "no-cache",
|
|
87
|
-
"content-type": "application/json",
|
|
88
|
-
pragma: "no-cache",
|
|
89
|
-
},
|
|
90
|
-
})
|
|
91
|
-
.then((res) => res.json())
|
|
92
|
-
.then((res) => {
|
|
93
|
-
if (res === null || res === void 0 ? void 0 : res.success) {
|
|
94
|
-
logger_1.logger.debug("apm send success", "");
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
throw new Error(res === null || res === void 0 ? void 0 : res.msg);
|
|
98
|
-
}
|
|
99
|
-
})
|
|
100
|
-
.catch((err) => {
|
|
101
|
-
if (retry) {
|
|
102
|
-
setTimeout(() => this._request(merged, false), 1000);
|
|
103
|
-
}
|
|
104
|
-
logger_1.logger.log(`apm send failed`, `${(err === null || err === void 0 ? void 0 : err.message) || null}`, "error");
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
bactchReport() {
|
|
108
|
-
const queue = [...this.reportQueue];
|
|
109
|
-
this.reportQueue = [];
|
|
110
|
-
while (queue.length) {
|
|
111
|
-
this._request(queue.splice(0, 5));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
report(measurement_name, measurement_data = {}) {
|
|
115
|
-
const params = {
|
|
116
|
-
suquence: this.getSequence(),
|
|
117
|
-
measurement_name,
|
|
118
|
-
measurement_data,
|
|
119
|
-
};
|
|
120
|
-
this.reportQueue.push(params);
|
|
121
|
-
clearTimeout(this.timer);
|
|
122
|
-
if (this.allowReport) {
|
|
123
|
-
if (this.reportQueue.length >= 10) {
|
|
124
|
-
this.bactchReport();
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
this.timer = setTimeout(() => {
|
|
128
|
-
this.bactchReport();
|
|
129
|
-
}, 200);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
exports.APM = APM;
|
|
17
|
+
__exportStar(require("./tracker"), exports);
|
|
18
|
+
__exportStar(require("./device"), exports);
|
|
19
|
+
__exportStar(require("./apm"), exports);
|
|
20
|
+
__exportStar(require("./cli-apm"), exports);
|
|
21
|
+
__exportStar(require("./ai-apm"), exports);
|