@hecom/codearts 0.2.0 → 0.2.2
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/README.md +45 -168
- package/dist/bin/cli.js +46 -28
- package/dist/commands/bug.command.d.ts +0 -2
- package/dist/commands/bug.command.js +105 -61
- package/dist/commands/config.command.d.ts +25 -0
- package/dist/commands/config.command.js +425 -78
- package/dist/commands/daily.command.d.ts +0 -5
- package/dist/commands/daily.command.js +265 -99
- package/dist/commands/work-hour.command.js +189 -131
- package/dist/services/api.service.d.ts +9 -2
- package/dist/services/api.service.js +12 -4
- package/dist/services/business.service.d.ts +21 -1
- package/dist/services/business.service.js +66 -1
- package/dist/types/index.d.ts +47 -0
- package/dist/types/index.js +34 -1
- package/dist/utils/config-loader.d.ts +31 -9
- package/dist/utils/config-loader.js +201 -32
- package/dist/utils/csv-writer.d.ts +12 -0
- package/dist/utils/csv-writer.js +60 -0
- package/dist/utils/logger.d.ts +62 -0
- package/dist/utils/logger.js +98 -0
- package/package.json +1 -3
- package/.env.example +0 -20
- package/dist/utils/global-config.d.ts +0 -24
- package/dist/utils/global-config.js +0 -153
|
@@ -1,56 +1,225 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getConfigPath = getConfigPath;
|
|
37
|
+
exports.configExists = configExists;
|
|
38
|
+
exports.readConfig = readConfig;
|
|
39
|
+
exports.writeConfig = writeConfig;
|
|
40
|
+
exports.deleteConfig = deleteConfig;
|
|
6
41
|
exports.loadConfig = loadConfig;
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
42
|
+
exports.getConfig = getConfig;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const types_1 = require("../types");
|
|
47
|
+
/**
|
|
48
|
+
* 全局配置管理工具
|
|
49
|
+
* 配置文件存储在用户主目录下的 .hecom-codearts 目录
|
|
50
|
+
*/
|
|
51
|
+
const CONFIG_DIR = path.join(os.homedir(), '.hecom-codearts');
|
|
52
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.env');
|
|
53
|
+
/**
|
|
54
|
+
* 确保配置目录存在
|
|
55
|
+
*/
|
|
56
|
+
function ensureConfigDir() {
|
|
57
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
58
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 获取全局配置文件路径
|
|
63
|
+
*/
|
|
64
|
+
function getConfigPath() {
|
|
65
|
+
return CONFIG_FILE;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 检查全局配置文件是否存在
|
|
69
|
+
*/
|
|
70
|
+
function configExists() {
|
|
71
|
+
return fs.existsSync(CONFIG_FILE);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 读取全局配置
|
|
75
|
+
*/
|
|
76
|
+
function readConfig() {
|
|
77
|
+
if (!configExists()) {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
const config = {};
|
|
81
|
+
try {
|
|
82
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
83
|
+
const lines = content.split('\n');
|
|
84
|
+
for (const line of lines) {
|
|
85
|
+
const trimmedLine = line.trim();
|
|
86
|
+
if (!trimmedLine || trimmedLine.startsWith('#')) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const equalIndex = trimmedLine.indexOf('=');
|
|
90
|
+
if (equalIndex > 0) {
|
|
91
|
+
const key = trimmedLine.substring(0, equalIndex).trim();
|
|
92
|
+
const value = trimmedLine.substring(equalIndex + 1).trim();
|
|
93
|
+
// 只保存合法的配置键
|
|
94
|
+
if (Object.values(types_1.ConfigKey).includes(key)) {
|
|
95
|
+
config[key] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error('读取全局配置文件失败:', error);
|
|
102
|
+
}
|
|
103
|
+
return config;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 配置项分组和顺序定义
|
|
107
|
+
*/
|
|
108
|
+
const CONFIG_GROUPS = [
|
|
109
|
+
{
|
|
110
|
+
title: '华为云IAM认证端点(根据区域调整)',
|
|
111
|
+
keys: [types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT, types_1.ConfigKey.HUAWEI_CLOUD_REGION],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
title: 'IAM用户凭证',
|
|
115
|
+
keys: [
|
|
116
|
+
types_1.ConfigKey.HUAWEI_CLOUD_USERNAME,
|
|
117
|
+
types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD,
|
|
118
|
+
types_1.ConfigKey.HUAWEI_CLOUD_DOMAIN,
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
title: '项目配置',
|
|
123
|
+
keys: [types_1.ConfigKey.CODEARTS_BASE_URL, types_1.ConfigKey.PROJECT_ID, types_1.ConfigKey.ROLE_ID],
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
/**
|
|
127
|
+
* 写入全局配置
|
|
128
|
+
* 支持动态配置项,自动按分组组织配置文件
|
|
129
|
+
*/
|
|
130
|
+
function writeConfig(config) {
|
|
131
|
+
ensureConfigDir();
|
|
132
|
+
// 构建配置文件头部
|
|
133
|
+
let content = `# Hecom CodeArts 全局配置文件`;
|
|
134
|
+
// 记录已写入的配置项
|
|
135
|
+
const writtenKeys = new Set();
|
|
136
|
+
// 按分组写入配置
|
|
137
|
+
for (const group of CONFIG_GROUPS) {
|
|
138
|
+
content += `\n# ${group.title}\n`;
|
|
139
|
+
for (const key of group.keys) {
|
|
140
|
+
const value = config[key] || '';
|
|
141
|
+
content += `${key}=${value}\n`;
|
|
142
|
+
writtenKeys.add(key);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// 写入未分组的其他配置项(支持未来扩展)
|
|
146
|
+
const otherKeys = Object.keys(config).filter((key) => !writtenKeys.has(key));
|
|
147
|
+
if (otherKeys.length > 0) {
|
|
148
|
+
content += `\n# 其他配置\n`;
|
|
149
|
+
for (const key of otherKeys) {
|
|
150
|
+
const value = config[key] || '';
|
|
151
|
+
content += `${key}=${value}\n`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
fs.writeFileSync(CONFIG_FILE, content, 'utf-8');
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
throw new Error(`写入全局配置文件失败: ${error}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 删除全局配置
|
|
163
|
+
*/
|
|
164
|
+
function deleteConfig() {
|
|
165
|
+
if (configExists()) {
|
|
166
|
+
try {
|
|
167
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
throw new Error(`删除全局配置文件失败: ${error}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
11
174
|
// 加载全局配置
|
|
12
|
-
const globalConfig = (
|
|
175
|
+
const globalConfig = configExists() ? readConfig() : {};
|
|
13
176
|
/**
|
|
14
|
-
* 加载配置,优先级:命令行参数 >
|
|
177
|
+
* 加载配置,优先级:命令行参数 > 全局配置
|
|
15
178
|
* @param cliOptions 命令行选项
|
|
16
179
|
* @returns 加载的配置
|
|
17
180
|
*/
|
|
18
181
|
function loadConfig(cliOptions = {}) {
|
|
19
|
-
// 命令行参数 >
|
|
20
|
-
const projectId =
|
|
21
|
-
const roleIdStr = cliOptions.roleId ||
|
|
182
|
+
// 命令行参数 > 全局配置
|
|
183
|
+
const projectId = globalConfig[types_1.ConfigKey.PROJECT_ID];
|
|
184
|
+
const roleIdStr = cliOptions.roleId || globalConfig[types_1.ConfigKey.ROLE_ID];
|
|
22
185
|
if (!projectId) {
|
|
23
|
-
throw new Error('
|
|
186
|
+
throw new Error('缺少项目 ID');
|
|
24
187
|
}
|
|
25
188
|
if (!roleIdStr) {
|
|
26
|
-
throw new Error('
|
|
189
|
+
throw new Error('缺少角色 ID');
|
|
27
190
|
}
|
|
28
191
|
const roleIds = roleIdStr.split(',').map((id) => parseInt(id.trim()));
|
|
29
192
|
if (roleIds.some((id) => isNaN(id))) {
|
|
30
193
|
throw new Error('ROLE_ID 格式不正确,应为数字或逗号分隔的数字列表');
|
|
31
194
|
}
|
|
32
|
-
const username =
|
|
33
|
-
const password =
|
|
34
|
-
const domain =
|
|
35
|
-
|
|
36
|
-
|
|
195
|
+
const username = globalConfig[types_1.ConfigKey.HUAWEI_CLOUD_USERNAME];
|
|
196
|
+
const password = globalConfig[types_1.ConfigKey.HUAWEI_CLOUD_PASSWORD];
|
|
197
|
+
const domain = globalConfig[types_1.ConfigKey.HUAWEI_CLOUD_DOMAIN];
|
|
198
|
+
const iamEndpoint = globalConfig[types_1.ConfigKey.HUAWEI_CLOUD_IAM_ENDPOINT];
|
|
199
|
+
const region = globalConfig[types_1.ConfigKey.HUAWEI_CLOUD_REGION];
|
|
200
|
+
const endpoint = globalConfig[types_1.ConfigKey.CODEARTS_BASE_URL];
|
|
201
|
+
if (!username || !password || !domain || !iamEndpoint || !region || !endpoint) {
|
|
202
|
+
throw new Error('缺少华为云认证信息,请先运行 `npx @hecom/codearts config` 创建配置');
|
|
203
|
+
}
|
|
204
|
+
// 处理输出格式
|
|
205
|
+
const outputFormat = (cliOptions.output || 'console');
|
|
206
|
+
if (!['console', 'csv', 'json'].includes(outputFormat)) {
|
|
207
|
+
throw new Error('输出格式必须是 console、csv 或 json 之一');
|
|
37
208
|
}
|
|
38
209
|
const config = {
|
|
39
|
-
iamEndpoint
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
'https://iam.cn-north-4.myhuaweicloud.com',
|
|
43
|
-
region: cliOptions.region ||
|
|
44
|
-
process.env.HUAWEI_CLOUD_REGION ||
|
|
45
|
-
globalConfig.HUAWEI_CLOUD_REGION ||
|
|
46
|
-
'cn-north-4',
|
|
47
|
-
endpoint: cliOptions.codeartsUrl ||
|
|
48
|
-
process.env.CODEARTS_BASE_URL ||
|
|
49
|
-
globalConfig.CODEARTS_BASE_URL ||
|
|
50
|
-
'https://projectman-ext.cn-north-4.myhuaweicloud.cn',
|
|
210
|
+
iamEndpoint,
|
|
211
|
+
region,
|
|
212
|
+
endpoint,
|
|
51
213
|
username,
|
|
52
214
|
password,
|
|
53
215
|
domainName: domain,
|
|
54
216
|
};
|
|
55
|
-
return { projectId, roleIds, config };
|
|
217
|
+
return { projectId, roleIds, config, outputFormat };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 获取最终合并后的配置(用于显示)
|
|
221
|
+
* @returns 合并后的配置映射
|
|
222
|
+
*/
|
|
223
|
+
function getConfig() {
|
|
224
|
+
return globalConfig;
|
|
56
225
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Logger } from './logger';
|
|
2
|
+
/**
|
|
3
|
+
* CSV 转义函数:处理双引号
|
|
4
|
+
*/
|
|
5
|
+
export declare function escapeCsv(value: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* 写入 CSV 文件到当前工作目录
|
|
8
|
+
* @param filename 文件名
|
|
9
|
+
* @param lines CSV 行数组
|
|
10
|
+
* @param logger 日志记录器(可选)
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeCsvFile(filename: string, lines: string[], logger?: Logger): void;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.escapeCsv = escapeCsv;
|
|
37
|
+
exports.writeCsvFile = writeCsvFile;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* CSV 转义函数:处理双引号
|
|
42
|
+
*/
|
|
43
|
+
function escapeCsv(value) {
|
|
44
|
+
if (!value)
|
|
45
|
+
return '';
|
|
46
|
+
return value.replace(/"/g, '""');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 写入 CSV 文件到当前工作目录
|
|
50
|
+
* @param filename 文件名
|
|
51
|
+
* @param lines CSV 行数组
|
|
52
|
+
* @param logger 日志记录器(可选)
|
|
53
|
+
*/
|
|
54
|
+
function writeCsvFile(filename, lines, logger) {
|
|
55
|
+
const filepath = path.join(process.cwd(), filename);
|
|
56
|
+
fs.writeFileSync(filepath, lines.join('\n'), 'utf-8');
|
|
57
|
+
if (logger) {
|
|
58
|
+
logger.success(`CSV 文件已生成: ${filepath}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export type OutputFormat = 'console' | 'csv' | 'json';
|
|
2
|
+
/**
|
|
3
|
+
* 日志工具类(单例模式)
|
|
4
|
+
* 根据输出格式自动控制日志输出:
|
|
5
|
+
* - console/csv: 正常输出所有日志
|
|
6
|
+
* - json: 静默所有用户日志,只输出纯 JSON
|
|
7
|
+
*/
|
|
8
|
+
export declare class Logger {
|
|
9
|
+
private static instance;
|
|
10
|
+
private silent;
|
|
11
|
+
private constructor();
|
|
12
|
+
/**
|
|
13
|
+
* 获取 Logger 单例实例
|
|
14
|
+
*/
|
|
15
|
+
static getInstance(): Logger;
|
|
16
|
+
/**
|
|
17
|
+
* 设置输出格式,更新静默状态
|
|
18
|
+
* @param outputFormat 输出格式
|
|
19
|
+
*/
|
|
20
|
+
setOutputFormat(outputFormat: string | null | undefined): void;
|
|
21
|
+
/**
|
|
22
|
+
* 信息日志(输出到 stdout)
|
|
23
|
+
* json 模式下会被静默
|
|
24
|
+
*/
|
|
25
|
+
info(message: string, ...optionalParams: any[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* 警告日志(输出到 stdout)
|
|
28
|
+
* json 模式下会被静默
|
|
29
|
+
*/
|
|
30
|
+
warn(message: string, ...optionalParams: any[]): void;
|
|
31
|
+
/**
|
|
32
|
+
* 成功日志(输出到 stdout)
|
|
33
|
+
* json 模式下会被静默
|
|
34
|
+
*/
|
|
35
|
+
success(message: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* 错误日志(输出到 stderr)
|
|
38
|
+
* 始终输出,不受 silent 影响
|
|
39
|
+
*/
|
|
40
|
+
error(message: string, ...optionalParams: any[]): void;
|
|
41
|
+
/**
|
|
42
|
+
* 调试日志(输出到 stdout)
|
|
43
|
+
* json 模式下会被静默
|
|
44
|
+
*/
|
|
45
|
+
debug(message: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* JSON 数据输出(输出到 stdout)
|
|
48
|
+
* 输出格式化的 JSON 字符串
|
|
49
|
+
* @param data 要输出的数据对象
|
|
50
|
+
*/
|
|
51
|
+
json(data: any): void;
|
|
52
|
+
/**
|
|
53
|
+
* 表格输出(输出到 stdout)
|
|
54
|
+
* json 模式下会被静默
|
|
55
|
+
*/
|
|
56
|
+
table(data: any): void;
|
|
57
|
+
/**
|
|
58
|
+
* 检查是否处于静默模式
|
|
59
|
+
*/
|
|
60
|
+
isSilent(): boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare const logger: Logger;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logger = exports.Logger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 日志工具类(单例模式)
|
|
6
|
+
* 根据输出格式自动控制日志输出:
|
|
7
|
+
* - console/csv: 正常输出所有日志
|
|
8
|
+
* - json: 静默所有用户日志,只输出纯 JSON
|
|
9
|
+
*/
|
|
10
|
+
class Logger {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.silent = false;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 获取 Logger 单例实例
|
|
16
|
+
*/
|
|
17
|
+
static getInstance() {
|
|
18
|
+
if (!Logger.instance) {
|
|
19
|
+
Logger.instance = new Logger();
|
|
20
|
+
}
|
|
21
|
+
return Logger.instance;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 设置输出格式,更新静默状态
|
|
25
|
+
* @param outputFormat 输出格式
|
|
26
|
+
*/
|
|
27
|
+
setOutputFormat(outputFormat) {
|
|
28
|
+
this.silent = outputFormat === 'json';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 信息日志(输出到 stdout)
|
|
32
|
+
* json 模式下会被静默
|
|
33
|
+
*/
|
|
34
|
+
info(message, ...optionalParams) {
|
|
35
|
+
if (!this.silent) {
|
|
36
|
+
console.log(message, ...optionalParams);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 警告日志(输出到 stdout)
|
|
41
|
+
* json 模式下会被静默
|
|
42
|
+
*/
|
|
43
|
+
warn(message, ...optionalParams) {
|
|
44
|
+
if (!this.silent) {
|
|
45
|
+
console.warn(message, ...optionalParams);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 成功日志(输出到 stdout)
|
|
50
|
+
* json 模式下会被静默
|
|
51
|
+
*/
|
|
52
|
+
success(message) {
|
|
53
|
+
if (!this.silent) {
|
|
54
|
+
console.log(message);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 错误日志(输出到 stderr)
|
|
59
|
+
* 始终输出,不受 silent 影响
|
|
60
|
+
*/
|
|
61
|
+
error(message, ...optionalParams) {
|
|
62
|
+
console.error(message, ...optionalParams);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 调试日志(输出到 stdout)
|
|
66
|
+
* json 模式下会被静默
|
|
67
|
+
*/
|
|
68
|
+
debug(message) {
|
|
69
|
+
if (!this.silent) {
|
|
70
|
+
console.log(message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* JSON 数据输出(输出到 stdout)
|
|
75
|
+
* 输出格式化的 JSON 字符串
|
|
76
|
+
* @param data 要输出的数据对象
|
|
77
|
+
*/
|
|
78
|
+
json(data) {
|
|
79
|
+
console.log(JSON.stringify(data, null, 2));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 表格输出(输出到 stdout)
|
|
83
|
+
* json 模式下会被静默
|
|
84
|
+
*/
|
|
85
|
+
table(data) {
|
|
86
|
+
if (!this.silent) {
|
|
87
|
+
console.table(data);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 检查是否处于静默模式
|
|
92
|
+
*/
|
|
93
|
+
isSilent() {
|
|
94
|
+
return this.silent;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.Logger = Logger;
|
|
98
|
+
exports.logger = Logger.getInstance();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hecom/codearts",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "华为云 CodeArts 统计分析工具",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"bin",
|
|
13
|
-
".env.example",
|
|
14
13
|
"README.md"
|
|
15
14
|
],
|
|
16
15
|
"scripts": {
|
|
@@ -47,7 +46,6 @@
|
|
|
47
46
|
"dependencies": {
|
|
48
47
|
"axios": "^1.5.0",
|
|
49
48
|
"commander": "^12.1.0",
|
|
50
|
-
"dotenv": "^16.3.1",
|
|
51
49
|
"inquirer": "^9.3.8"
|
|
52
50
|
},
|
|
53
51
|
"devDependencies": {
|
package/.env.example
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# 华为云CodeArts API 环境变量配置
|
|
2
|
-
# 复制此文件为 .env 并填入真实的配置值
|
|
3
|
-
|
|
4
|
-
# 华为云IAM认证端点(根据区域调整)
|
|
5
|
-
HUAWEI_CLOUD_IAM_ENDPOINT=https://iam.cn-north-4.myhuaweicloud.com
|
|
6
|
-
HUAWEI_CLOUD_REGION=cn-north-4
|
|
7
|
-
|
|
8
|
-
# IAM用户凭证
|
|
9
|
-
HUAWEI_CLOUD_USERNAME=your-iam-username
|
|
10
|
-
HUAWEI_CLOUD_PASSWORD=your-iam-password
|
|
11
|
-
HUAWEI_CLOUD_DOMAIN=your-domain-name
|
|
12
|
-
|
|
13
|
-
# CodeArts API基础URL(可选,默认根据区域自动生成)
|
|
14
|
-
CODEARTS_BASE_URL=https://projectman-ext.cn-north-4.myhuaweicloud.cn
|
|
15
|
-
|
|
16
|
-
PROJECT_ID=your-project-id
|
|
17
|
-
|
|
18
|
-
# 角色ID(支持多个,逗号分隔)
|
|
19
|
-
ROLE_ID=your-role-id
|
|
20
|
-
# 示例:ROLE_ID=1,2,3
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 获取全局配置文件路径
|
|
3
|
-
*/
|
|
4
|
-
export declare function getGlobalConfigPath(): string;
|
|
5
|
-
/**
|
|
6
|
-
* 检查全局配置文件是否存在
|
|
7
|
-
*/
|
|
8
|
-
export declare function globalConfigExists(): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* 读取全局配置
|
|
11
|
-
*/
|
|
12
|
-
export declare function readGlobalConfig(): Record<string, string>;
|
|
13
|
-
/**
|
|
14
|
-
* 写入全局配置
|
|
15
|
-
*/
|
|
16
|
-
export declare function writeGlobalConfig(config: Record<string, string>): void;
|
|
17
|
-
/**
|
|
18
|
-
* 删除全局配置
|
|
19
|
-
*/
|
|
20
|
-
export declare function deleteGlobalConfig(): void;
|
|
21
|
-
/**
|
|
22
|
-
* 获取配置信息(用于显示)
|
|
23
|
-
*/
|
|
24
|
-
export declare function getConfigInfo(): string;
|