daodou-command 1.4.8 → 1.4.9
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/.daodourc +85 -0
- package/README.md +174 -157
- package/bin/daodou.js +9 -13
- package/lib/commands/config.js +149 -231
- package/lib/commands/lang.js +71 -115
- package/lib/commands/upgrade.js +47 -87
- package/lib/translation/TranslationService.js +6 -24
- package/lib/translation/engines/microsoft/services/EdgeAuthService.js +0 -2
- package/lib/utils/translation.js +4 -15
- package/lib/utils/update-checker.js +34 -113
- package/package.json +2 -2
package/lib/commands/config.js
CHANGED
|
@@ -11,11 +11,6 @@ class ConfigCommand {
|
|
|
11
11
|
this.configManager = new ConfigManager();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* 执行config命令
|
|
16
|
-
* @param {string} action - 操作类型 (init, show, edit, clear)
|
|
17
|
-
* @param {Object} options - 命令选项
|
|
18
|
-
*/
|
|
19
14
|
async execute(action, options = {}) {
|
|
20
15
|
switch (action) {
|
|
21
16
|
case 'init':
|
|
@@ -36,256 +31,224 @@ class ConfigCommand {
|
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
|
|
39
|
-
/**
|
|
40
|
-
* 初始化全局配置
|
|
41
|
-
*/
|
|
42
34
|
async initGlobalConfig() {
|
|
43
|
-
console.log(
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(chalk.bold(' ⚙ 初始化全局配置'));
|
|
37
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
44
38
|
|
|
45
|
-
// 检查是否已存在全局配置
|
|
46
39
|
if (fs.existsSync(this.configManager.configFile)) {
|
|
47
|
-
const { overwrite } = await inquirer.prompt([
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
]);
|
|
55
|
-
|
|
40
|
+
const { overwrite } = await inquirer.prompt([{
|
|
41
|
+
type: 'confirm',
|
|
42
|
+
name: 'overwrite',
|
|
43
|
+
message: '全局配置已存在,是否覆盖?',
|
|
44
|
+
default: false
|
|
45
|
+
}]);
|
|
56
46
|
if (!overwrite) {
|
|
57
|
-
console.log(chalk.yellow('
|
|
47
|
+
console.log(chalk.yellow(' ⚠ 已取消'));
|
|
48
|
+
console.log('');
|
|
58
49
|
return;
|
|
59
50
|
}
|
|
60
51
|
}
|
|
61
52
|
|
|
62
|
-
const spinner = ora('创建全局配置...').start();
|
|
63
|
-
|
|
53
|
+
const spinner = ora({ text: '创建全局配置...', indent: 2 }).start();
|
|
64
54
|
try {
|
|
65
|
-
// 创建全局配置目录
|
|
66
55
|
if (!fs.existsSync(this.configManager.configDir)) {
|
|
67
56
|
fs.mkdirSync(this.configManager.configDir, { recursive: true });
|
|
68
57
|
}
|
|
69
|
-
|
|
70
|
-
// 创建默认全局配置
|
|
71
58
|
await this.createDefaultGlobalConfig();
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
console.log(chalk.
|
|
75
|
-
console.log(chalk.
|
|
76
|
-
console.log(chalk.
|
|
77
|
-
console.log(
|
|
78
|
-
|
|
59
|
+
spinner.succeed('全局配置已创建');
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(' ' + chalk.dim('文件') + ' ' + this.configManager.configFile);
|
|
62
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
63
|
+
console.log(chalk.dim(' 请编辑配置文件填写实际信息'));
|
|
64
|
+
console.log('');
|
|
79
65
|
} catch (error) {
|
|
80
|
-
spinner.fail('创建失败');
|
|
81
|
-
throw new Error(`创建全局配置失败: ${error.message}`);
|
|
66
|
+
spinner.fail('创建失败 ' + chalk.dim(error.message));
|
|
82
67
|
}
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
/**
|
|
86
|
-
* 显示当前配置
|
|
87
|
-
*/
|
|
88
70
|
async showConfig() {
|
|
89
|
-
console.log(
|
|
71
|
+
console.log('');
|
|
72
|
+
console.log(chalk.bold(' ⚙ 配置信息'));
|
|
73
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
90
74
|
|
|
91
|
-
//
|
|
92
|
-
console.log(
|
|
75
|
+
// 全局配置
|
|
76
|
+
console.log('');
|
|
77
|
+
console.log(chalk.dim(' [全局配置]'));
|
|
93
78
|
if (fs.existsSync(this.configManager.configFile)) {
|
|
79
|
+
console.log(' ' + chalk.dim('文件') + ' ' + this.configManager.configFile);
|
|
94
80
|
const globalConfig = this.configManager.loadConfigFile(this.configManager.configFile);
|
|
95
|
-
|
|
96
|
-
console.log(chalk.gray(` 配置内容:`));
|
|
97
|
-
console.log(JSON.stringify(globalConfig, null, 4));
|
|
81
|
+
this._printConfig(globalConfig);
|
|
98
82
|
} else {
|
|
99
|
-
console.log(chalk.yellow('
|
|
100
|
-
console.log(chalk.blue(' 💡 使用 "dao config init" 创建全局配置'));
|
|
83
|
+
console.log(chalk.yellow(' ⚠ 不存在') + chalk.dim(' 运行 dao config init 创建'));
|
|
101
84
|
}
|
|
102
85
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
console.log(chalk.cyan('📁 项目配置:'));
|
|
86
|
+
// 项目配置
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(chalk.dim(' [项目配置]'));
|
|
107
89
|
if (fs.existsSync(this.configManager.projectConfigFile)) {
|
|
90
|
+
console.log(' ' + chalk.dim('文件') + ' ' + this.configManager.projectConfigFile);
|
|
108
91
|
const projectConfig = this.configManager.loadConfigFile(this.configManager.projectConfigFile);
|
|
109
|
-
|
|
110
|
-
console.log(chalk.gray(` 配置内容:`));
|
|
111
|
-
console.log(JSON.stringify(projectConfig, null, 4));
|
|
92
|
+
this._printConfig(projectConfig);
|
|
112
93
|
} else {
|
|
113
|
-
console.log(chalk.yellow('
|
|
114
|
-
console.log(chalk.blue(' 💡 运行 build 命令时会自动创建'));
|
|
94
|
+
console.log(chalk.yellow(' ⚠ 不存在') + chalk.dim(' 运行 build 命令时自动创建'));
|
|
115
95
|
}
|
|
116
96
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
console.log(chalk.cyan('🔀 合并后配置 (项目配置优先):'));
|
|
97
|
+
// 合并配置
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log(chalk.dim(' [合并结果] (项目优先)'));
|
|
121
100
|
const mergedConfig = this.configManager.getAll();
|
|
122
|
-
|
|
101
|
+
this._printConfig(mergedConfig);
|
|
102
|
+
console.log('');
|
|
123
103
|
}
|
|
124
104
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
type: 'list',
|
|
134
|
-
name: 'configType',
|
|
135
|
-
message: '选择要编辑的配置文件:',
|
|
136
|
-
choices: [
|
|
137
|
-
{
|
|
138
|
-
name: '全局配置 (推荐)',
|
|
139
|
-
value: 'global',
|
|
140
|
-
disabled: !fs.existsSync(this.configManager.configFile) ? '文件不存在' : false
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
name: '项目配置',
|
|
144
|
-
value: 'project',
|
|
145
|
-
disabled: !fs.existsSync(this.configManager.projectConfigFile) ? '文件不存在' : false
|
|
146
|
-
}
|
|
147
|
-
]
|
|
105
|
+
_printConfig(config, prefix = ' ') {
|
|
106
|
+
for (const [key, value] of Object.entries(config)) {
|
|
107
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
108
|
+
console.log(chalk.dim(`${prefix}${key}:`));
|
|
109
|
+
this._printConfig(value, prefix + ' ');
|
|
110
|
+
} else {
|
|
111
|
+
const display = Array.isArray(value) ? value.join(', ') : String(value);
|
|
112
|
+
console.log(`${prefix}${chalk.dim(key)} ${display}`);
|
|
148
113
|
}
|
|
149
|
-
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async editConfig() {
|
|
118
|
+
console.log('');
|
|
119
|
+
console.log(chalk.bold(' ⚙ 编辑配置'));
|
|
120
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
121
|
+
|
|
122
|
+
const { configType } = await inquirer.prompt([{
|
|
123
|
+
type: 'list',
|
|
124
|
+
name: 'configType',
|
|
125
|
+
message: '选择配置文件:',
|
|
126
|
+
choices: [
|
|
127
|
+
{
|
|
128
|
+
name: '全局配置',
|
|
129
|
+
value: 'global',
|
|
130
|
+
disabled: !fs.existsSync(this.configManager.configFile) ? '不存在' : false
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: '项目配置',
|
|
134
|
+
value: 'project',
|
|
135
|
+
disabled: !fs.existsSync(this.configManager.projectConfigFile) ? '不存在' : false
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}]);
|
|
150
139
|
|
|
151
|
-
const configFile = configType === 'global'
|
|
152
|
-
? this.configManager.configFile
|
|
140
|
+
const configFile = configType === 'global'
|
|
141
|
+
? this.configManager.configFile
|
|
153
142
|
: this.configManager.projectConfigFile;
|
|
154
143
|
|
|
155
|
-
console.log(chalk.
|
|
156
|
-
console.log(chalk.yellow('💡 请使用你喜欢的编辑器打开该文件进行编辑'));
|
|
144
|
+
console.log(' ' + chalk.dim('文件') + ' ' + configFile);
|
|
157
145
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
default: true
|
|
165
|
-
}
|
|
166
|
-
]);
|
|
146
|
+
const { openEditor } = await inquirer.prompt([{
|
|
147
|
+
type: 'confirm',
|
|
148
|
+
name: 'openEditor',
|
|
149
|
+
message: '使用默认编辑器打开?',
|
|
150
|
+
default: true
|
|
151
|
+
}]);
|
|
167
152
|
|
|
168
153
|
if (openEditor) {
|
|
169
154
|
const editor = process.env.EDITOR || process.env.VISUAL || 'vim';
|
|
170
155
|
const { spawn } = require('child_process');
|
|
171
|
-
|
|
172
156
|
try {
|
|
173
157
|
const child = spawn(editor, [configFile], { stdio: 'inherit' });
|
|
174
158
|
child.on('exit', (code) => {
|
|
175
159
|
if (code === 0) {
|
|
176
|
-
console.log(chalk.green('
|
|
160
|
+
console.log(chalk.green(' ✔ 编辑完成'));
|
|
177
161
|
} else {
|
|
178
|
-
console.log(chalk.yellow('
|
|
162
|
+
console.log(chalk.yellow(' ⚠ 编辑器已退出'));
|
|
179
163
|
}
|
|
164
|
+
console.log('');
|
|
180
165
|
});
|
|
181
166
|
} catch (error) {
|
|
182
|
-
console.log(chalk.red(
|
|
183
|
-
console.log(
|
|
167
|
+
console.log(chalk.red(' ✖ 无法打开编辑器 ') + chalk.dim(error.message));
|
|
168
|
+
console.log('');
|
|
184
169
|
}
|
|
185
170
|
}
|
|
186
171
|
}
|
|
187
172
|
|
|
188
|
-
/**
|
|
189
|
-
* 清除配置
|
|
190
|
-
*/
|
|
191
173
|
async clearConfig() {
|
|
192
|
-
console.log(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
]
|
|
215
|
-
}
|
|
216
|
-
]);
|
|
174
|
+
console.log('');
|
|
175
|
+
console.log(chalk.bold(' ⚙ 清除配置'));
|
|
176
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
177
|
+
|
|
178
|
+
const { configType } = await inquirer.prompt([{
|
|
179
|
+
type: 'list',
|
|
180
|
+
name: 'configType',
|
|
181
|
+
message: '选择要清除的配置:',
|
|
182
|
+
choices: [
|
|
183
|
+
{
|
|
184
|
+
name: '全局配置',
|
|
185
|
+
value: 'global',
|
|
186
|
+
disabled: !fs.existsSync(this.configManager.configFile) ? '不存在' : false
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: '项目配置',
|
|
190
|
+
value: 'project',
|
|
191
|
+
disabled: !fs.existsSync(this.configManager.projectConfigFile) ? '不存在' : false
|
|
192
|
+
},
|
|
193
|
+
{ name: '所有配置', value: 'all' }
|
|
194
|
+
]
|
|
195
|
+
}]);
|
|
217
196
|
|
|
218
|
-
const { confirm } = await inquirer.prompt([
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
]);
|
|
197
|
+
const { confirm } = await inquirer.prompt([{
|
|
198
|
+
type: 'confirm',
|
|
199
|
+
name: 'confirm',
|
|
200
|
+
message: '确定删除?此操作不可恢复',
|
|
201
|
+
default: false
|
|
202
|
+
}]);
|
|
226
203
|
|
|
227
204
|
if (!confirm) {
|
|
228
|
-
console.log(chalk.yellow('
|
|
205
|
+
console.log(chalk.yellow(' ⚠ 已取消'));
|
|
206
|
+
console.log('');
|
|
229
207
|
return;
|
|
230
208
|
}
|
|
231
209
|
|
|
232
|
-
const spinner = ora('清除配置...').start();
|
|
233
|
-
|
|
234
210
|
try {
|
|
235
211
|
if (configType === 'global' || configType === 'all') {
|
|
236
212
|
if (fs.existsSync(this.configManager.configFile)) {
|
|
237
213
|
fs.unlinkSync(this.configManager.configFile);
|
|
238
|
-
console.log(chalk.green('
|
|
214
|
+
console.log(chalk.green(' ✔ 全局配置已删除'));
|
|
239
215
|
}
|
|
240
216
|
}
|
|
241
|
-
|
|
242
217
|
if (configType === 'project' || configType === 'all') {
|
|
243
218
|
if (fs.existsSync(this.configManager.projectConfigFile)) {
|
|
244
219
|
fs.unlinkSync(this.configManager.projectConfigFile);
|
|
245
|
-
console.log(chalk.green('
|
|
220
|
+
console.log(chalk.green(' ✔ 项目配置已删除'));
|
|
246
221
|
}
|
|
247
222
|
}
|
|
248
|
-
|
|
249
|
-
spinner.succeed('配置清除完成');
|
|
250
|
-
|
|
223
|
+
console.log('');
|
|
251
224
|
} catch (error) {
|
|
252
|
-
|
|
253
|
-
|
|
225
|
+
console.log(chalk.red(' ✖ 清除失败 ') + chalk.dim(error.message));
|
|
226
|
+
console.log('');
|
|
254
227
|
}
|
|
255
228
|
}
|
|
256
229
|
|
|
257
|
-
/**
|
|
258
|
-
* 交互式配置向导
|
|
259
|
-
*/
|
|
260
230
|
async interactiveConfig() {
|
|
261
|
-
console.log(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
]);
|
|
277
|
-
|
|
278
|
-
if (action === 'exit')
|
|
279
|
-
console.log(chalk.yellow('👋 再见!'));
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
231
|
+
console.log('');
|
|
232
|
+
console.log(chalk.bold(' ⚙ 配置向导'));
|
|
233
|
+
console.log(chalk.dim(' ─────────────────────────'));
|
|
234
|
+
|
|
235
|
+
const { action } = await inquirer.prompt([{
|
|
236
|
+
type: 'list',
|
|
237
|
+
name: 'action',
|
|
238
|
+
message: '选择操作:',
|
|
239
|
+
choices: [
|
|
240
|
+
{ name: '初始化全局配置', value: 'init' },
|
|
241
|
+
{ name: '查看当前配置', value: 'show' },
|
|
242
|
+
{ name: '编辑配置文件', value: 'edit' },
|
|
243
|
+
{ name: '清除配置', value: 'clear' },
|
|
244
|
+
{ name: '退出', value: 'exit' }
|
|
245
|
+
]
|
|
246
|
+
}]);
|
|
247
|
+
|
|
248
|
+
if (action === 'exit') return;
|
|
283
249
|
await this.execute(action);
|
|
284
250
|
}
|
|
285
251
|
|
|
286
|
-
/**
|
|
287
|
-
* 创建默认全局配置
|
|
288
|
-
*/
|
|
289
252
|
async createDefaultGlobalConfig() {
|
|
290
253
|
const configContent = `{
|
|
291
254
|
// build 命令全局配置
|
|
@@ -297,76 +260,31 @@ class ConfigCommand {
|
|
|
297
260
|
// jenkinsUsername: "your-global-username",
|
|
298
261
|
// jenkinsPassword: "your-global-password"
|
|
299
262
|
},
|
|
300
|
-
|
|
263
|
+
|
|
301
264
|
// lang 命令全局配置
|
|
302
265
|
lang: {
|
|
303
266
|
defaultLang: "en",
|
|
304
267
|
defaultDir: "./public/locales",
|
|
305
268
|
fileName: "common.json",
|
|
306
|
-
|
|
269
|
+
|
|
307
270
|
// 翻译引擎配置
|
|
308
271
|
translation: {
|
|
309
|
-
// 默认翻译引擎 (microsoft, google, baidu, ali, youdao, deepl, openai)
|
|
310
272
|
defaultEngine: "microsoft",
|
|
311
|
-
|
|
312
|
-
// 引擎优先级列表(按顺序尝试)
|
|
313
273
|
enginePriority: ["microsoft", "google", "baidu", "ali", "youdao", "deepl", "openai"],
|
|
314
|
-
|
|
315
|
-
// 各引擎API配置
|
|
316
274
|
engines: {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
},
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
enabled: true
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
// 百度翻译(需要API密钥)
|
|
328
|
-
baidu: {
|
|
329
|
-
enabled: false,
|
|
330
|
-
appId: "", // 百度翻译API App ID
|
|
331
|
-
appKey: "" // 百度翻译API App Key
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
// 阿里云翻译(需要API密钥)
|
|
335
|
-
ali: {
|
|
336
|
-
enabled: false,
|
|
337
|
-
accessKeyId: "", // 阿里云AccessKey ID
|
|
338
|
-
accessKeySecret: "" // 阿里云AccessKey Secret
|
|
339
|
-
},
|
|
340
|
-
|
|
341
|
-
// 有道翻译(需要API密钥)
|
|
342
|
-
youdao: {
|
|
343
|
-
enabled: false,
|
|
344
|
-
appId: "", // 有道翻译API App ID
|
|
345
|
-
appKey: "" // 有道翻译API App Key
|
|
346
|
-
},
|
|
347
|
-
|
|
348
|
-
// DeepL翻译(需要API密钥)
|
|
349
|
-
deepl: {
|
|
350
|
-
enabled: false,
|
|
351
|
-
apiKey: "" // DeepL API Key
|
|
352
|
-
},
|
|
353
|
-
|
|
354
|
-
// OpenAI翻译(需要API密钥)
|
|
355
|
-
openai: {
|
|
356
|
-
enabled: false,
|
|
357
|
-
apiKey: "", // OpenAI API Key
|
|
358
|
-
model: "gpt-3.5-turbo", // 使用的模型
|
|
359
|
-
baseUrl: "https://api.openai.com/v1" // API基础URL
|
|
360
|
-
}
|
|
275
|
+
microsoft: { enabled: true },
|
|
276
|
+
google: { enabled: true },
|
|
277
|
+
baidu: { enabled: false, appId: "", appKey: "" },
|
|
278
|
+
ali: { enabled: false, accessKeyId: "", accessKeySecret: "" },
|
|
279
|
+
youdao: { enabled: false, appId: "", appKey: "" },
|
|
280
|
+
deepl: { enabled: false, apiKey: "" },
|
|
281
|
+
openai: { enabled: false, apiKey: "", model: "gpt-3.5-turbo", baseUrl: "https://api.openai.com/v1" }
|
|
361
282
|
}
|
|
362
283
|
}
|
|
363
284
|
}
|
|
364
285
|
}`;
|
|
365
|
-
|
|
366
286
|
fs.writeFileSync(this.configManager.configFile, configContent);
|
|
367
287
|
}
|
|
368
288
|
}
|
|
369
289
|
|
|
370
|
-
module.exports = {
|
|
371
|
-
ConfigCommand
|
|
372
|
-
};
|
|
290
|
+
module.exports = { ConfigCommand };
|