@oinone/cli 7.2.3 → 7.2.5
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/bin/cli.js +106 -44
- package/bin/i18n.js +134 -0
- package/package.json +5 -2
package/bin/cli.js
CHANGED
|
@@ -11,12 +11,16 @@ const os = require('os');
|
|
|
11
11
|
const AdmZip = require('adm-zip');
|
|
12
12
|
const cliProgress = require('cli-progress');
|
|
13
13
|
const packageJson = require('../package.json');
|
|
14
|
+
const { t } = require('./i18n');
|
|
14
15
|
|
|
15
16
|
const downloadAndExtractZip = (url, targetDir) => {
|
|
16
17
|
return new Promise((resolve, reject) => {
|
|
17
18
|
const req = https.request(url, { method: 'HEAD' }, (headRes) => {
|
|
19
|
+
// 必须调用 resume() 消费响应数据,否则 Node 19+ 默认开启 keepAlive 会导致 socket 保持连接,进程卡住 60 秒
|
|
20
|
+
headRes.resume();
|
|
21
|
+
|
|
18
22
|
if (headRes.statusCode !== 200) {
|
|
19
|
-
reject(new Error(
|
|
23
|
+
reject(new Error(t('fetchFileInfoFailed', { status: headRes.statusCode })));
|
|
20
24
|
return;
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -33,7 +37,7 @@ const downloadAndExtractZip = (url, targetDir) => {
|
|
|
33
37
|
const cachedZipPath = path.join(cacheDir, `static-resources-${etag}.zip`);
|
|
34
38
|
|
|
35
39
|
if (fs.existsSync(cachedZipPath)) {
|
|
36
|
-
console.log(chalk.cyan('
|
|
40
|
+
console.log(chalk.cyan(t('usingCached')));
|
|
37
41
|
try {
|
|
38
42
|
const zip = new AdmZip(cachedZipPath);
|
|
39
43
|
zip.extractAllTo(targetDir, true);
|
|
@@ -49,7 +53,8 @@ const downloadAndExtractZip = (url, targetDir) => {
|
|
|
49
53
|
|
|
50
54
|
https.get(url, (response) => {
|
|
51
55
|
if (response.statusCode !== 200) {
|
|
52
|
-
|
|
56
|
+
response.resume(); // 消费响应数据释放 socket
|
|
57
|
+
reject(new Error(t('downloadFailed', { status: response.statusCode })));
|
|
53
58
|
return;
|
|
54
59
|
}
|
|
55
60
|
|
|
@@ -70,7 +75,7 @@ const downloadAndExtractZip = (url, targetDir) => {
|
|
|
70
75
|
let startTime = Date.now();
|
|
71
76
|
|
|
72
77
|
const progressBar = new cliProgress.SingleBar({
|
|
73
|
-
format: chalk.cyan('
|
|
78
|
+
format: chalk.cyan(t('fetchingAwesomeness')) + `[{bar}] {percentage}% | ⏳ {eta}s ${t('progressLeft')} | 📦 {value}/{total} ${unit} | 💨 {speed} {speedUnit}/s`,
|
|
74
79
|
barCompleteChar: '\u2588',
|
|
75
80
|
barIncompleteChar: '\u2591',
|
|
76
81
|
hideCursor: true,
|
|
@@ -135,14 +140,14 @@ const downloadAndExtractZip = (url, targetDir) => {
|
|
|
135
140
|
};
|
|
136
141
|
|
|
137
142
|
program
|
|
138
|
-
.version(packageJson.version)
|
|
139
|
-
.description('
|
|
140
|
-
.helpOption('-h, --help', '
|
|
143
|
+
.version(packageJson.version, '-V, --version', t('versionOption'))
|
|
144
|
+
.description(t('description'))
|
|
145
|
+
.helpOption('-h, --help', t('helpOption'));
|
|
141
146
|
|
|
142
147
|
// Cache Command
|
|
143
148
|
const cacheCmd = program
|
|
144
149
|
.command('cache')
|
|
145
|
-
.description('
|
|
150
|
+
.description(t('cacheCmdDesc'))
|
|
146
151
|
.action(() => {
|
|
147
152
|
// If just "cache" is typed without subcommands, show cache help
|
|
148
153
|
cacheCmd.help();
|
|
@@ -150,29 +155,29 @@ const cacheCmd = program
|
|
|
150
155
|
|
|
151
156
|
cacheCmd
|
|
152
157
|
.command('clean')
|
|
153
|
-
.description('
|
|
158
|
+
.description(t('cacheCleanDesc'))
|
|
154
159
|
.action(() => {
|
|
155
160
|
const cacheDir = path.join(os.tmpdir(), 'oinone-cli-cache');
|
|
156
161
|
if (fs.existsSync(cacheDir)) {
|
|
157
162
|
fs.removeSync(cacheDir);
|
|
158
|
-
console.log(chalk.green(
|
|
163
|
+
console.log(chalk.green(t('cacheCleaned', { dir: cacheDir })));
|
|
159
164
|
} else {
|
|
160
|
-
console.log(chalk.yellow(
|
|
165
|
+
console.log(chalk.yellow(t('cacheAlreadyEmpty', { dir: cacheDir })));
|
|
161
166
|
}
|
|
162
167
|
});
|
|
163
168
|
|
|
164
169
|
cacheCmd
|
|
165
170
|
.command('info')
|
|
166
|
-
.description('
|
|
171
|
+
.description(t('cacheInfoDesc'))
|
|
167
172
|
.action(async () => {
|
|
168
173
|
const cacheDir = path.join(os.tmpdir(), 'oinone-cli-cache');
|
|
169
|
-
console.log(chalk.cyan('
|
|
174
|
+
console.log(chalk.cyan(t('cacheDir')) + cacheDir);
|
|
170
175
|
|
|
171
176
|
if (fs.existsSync(cacheDir)) {
|
|
172
177
|
const files = await fs.readdir(cacheDir);
|
|
173
178
|
let totalSize = 0;
|
|
174
179
|
|
|
175
|
-
console.log(chalk.cyan('
|
|
180
|
+
console.log(chalk.cyan(t('cachedFiles')));
|
|
176
181
|
for (const file of files) {
|
|
177
182
|
const filePath = path.join(cacheDir, file);
|
|
178
183
|
const stat = await fs.stat(filePath);
|
|
@@ -195,23 +200,47 @@ cacheCmd
|
|
|
195
200
|
totalDisplaySize = `${Math.round(totalSize / 1024)} KB`;
|
|
196
201
|
}
|
|
197
202
|
|
|
198
|
-
console.log(chalk.cyan(
|
|
203
|
+
console.log(chalk.cyan(t('totalCacheSize')) + totalDisplaySize);
|
|
199
204
|
} else {
|
|
200
|
-
console.log(chalk.yellow('
|
|
205
|
+
console.log(chalk.yellow(t('cacheEmpty')));
|
|
201
206
|
}
|
|
202
207
|
});
|
|
203
208
|
|
|
204
209
|
// Create Command (Default Behavior)
|
|
205
210
|
program
|
|
206
|
-
.argument('[project-name]', '
|
|
207
|
-
.option('--download-static-resource <value>', '
|
|
208
|
-
.option('--oinone-version <value>', '
|
|
209
|
-
.option('--edition <value>', '
|
|
211
|
+
.argument('[project-name]', t('projectNameArg'))
|
|
212
|
+
.option('--download-static-resource <value>', t('downloadOpt'), 'true')
|
|
213
|
+
.option('--oinone-version <value>', t('versionOpt'), '7.2.0')
|
|
214
|
+
.option('--edition <value>', t('editionOpt'), 'community')
|
|
210
215
|
.action(async (projectNameArg, options) => {
|
|
211
216
|
// If command is 'cache', skip create logic
|
|
212
217
|
if (projectNameArg === 'cache') {
|
|
213
218
|
return;
|
|
214
219
|
}
|
|
220
|
+
|
|
221
|
+
// Trigger version check without blocking
|
|
222
|
+
let checkReq = null;
|
|
223
|
+
const versionCheckPromise = new Promise((resolve) => {
|
|
224
|
+
checkReq = https.get('https://registry.npmjs.org/-/package/@oinone/cli/dist-tags', { timeout: 3000 }, (res) => {
|
|
225
|
+
let data = '';
|
|
226
|
+
res.on('data', chunk => data += chunk);
|
|
227
|
+
res.on('end', () => {
|
|
228
|
+
try {
|
|
229
|
+
const parsed = JSON.parse(data);
|
|
230
|
+
resolve(parsed.latest);
|
|
231
|
+
} catch (e) {
|
|
232
|
+
resolve(null);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
checkReq.on('timeout', () => {
|
|
237
|
+
checkReq.destroy();
|
|
238
|
+
resolve(null);
|
|
239
|
+
});
|
|
240
|
+
checkReq.on('error', () => {
|
|
241
|
+
resolve(null);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
215
244
|
|
|
216
245
|
try {
|
|
217
246
|
let prefix;
|
|
@@ -238,47 +267,47 @@ program
|
|
|
238
267
|
{
|
|
239
268
|
type: 'input',
|
|
240
269
|
name: 'companyName',
|
|
241
|
-
message: '
|
|
270
|
+
message: t('promptCompany'),
|
|
242
271
|
default: 'ss',
|
|
243
272
|
validate: (input) => {
|
|
244
|
-
if (input.trim() === '') return '
|
|
273
|
+
if (input.trim() === '') return t('errorCompanyEmpty');
|
|
245
274
|
return true;
|
|
246
275
|
},
|
|
247
276
|
},
|
|
248
277
|
{
|
|
249
278
|
type: 'input',
|
|
250
279
|
name: 'projectName',
|
|
251
|
-
message: '
|
|
280
|
+
message: t('promptProject'),
|
|
252
281
|
default: 'oms',
|
|
253
282
|
validate: (input) => {
|
|
254
|
-
if (input.trim() === '') return '
|
|
283
|
+
if (input.trim() === '') return t('errorProjectEmpty');
|
|
255
284
|
return true;
|
|
256
285
|
},
|
|
257
286
|
},
|
|
258
287
|
{
|
|
259
288
|
type: 'list',
|
|
260
289
|
name: 'edition',
|
|
261
|
-
message: '
|
|
290
|
+
message: t('promptEdition'),
|
|
262
291
|
choices: [
|
|
263
|
-
{ name: '
|
|
264
|
-
{ name: '
|
|
292
|
+
{ name: t('editionCommunity'), value: 'community' },
|
|
293
|
+
{ name: t('editionEnterprise'), value: 'enterprise' }
|
|
265
294
|
],
|
|
266
295
|
default: 'community'
|
|
267
296
|
},
|
|
268
297
|
{
|
|
269
298
|
type: 'list',
|
|
270
299
|
name: 'oinoneVersion',
|
|
271
|
-
message: '
|
|
300
|
+
message: t('promptVersion'),
|
|
272
301
|
choices: [
|
|
273
|
-
{ name: '
|
|
274
|
-
{ name: '
|
|
302
|
+
{ name: t('version720'), value: '~7.2.0' },
|
|
303
|
+
{ name: t('version640'), value: '~6.4.0' }
|
|
275
304
|
],
|
|
276
305
|
default: '~7.2.0'
|
|
277
306
|
},
|
|
278
307
|
{
|
|
279
308
|
type: 'confirm',
|
|
280
309
|
name: 'downloadStaticResources',
|
|
281
|
-
message: '
|
|
310
|
+
message: t('promptDownload'),
|
|
282
311
|
default: true
|
|
283
312
|
}
|
|
284
313
|
]);
|
|
@@ -293,17 +322,17 @@ program
|
|
|
293
322
|
const targetPath = path.resolve(process.cwd(), fullProjectName);
|
|
294
323
|
|
|
295
324
|
if (fs.existsSync(targetPath)) {
|
|
296
|
-
console.log(chalk.red(
|
|
325
|
+
console.log(chalk.red(t('errorDirExists', { name: fullProjectName })));
|
|
297
326
|
process.exit(1);
|
|
298
327
|
}
|
|
299
328
|
|
|
300
|
-
const spinner = ora('
|
|
329
|
+
const spinner = ora(t('weavingMagic')).start();
|
|
301
330
|
|
|
302
331
|
const versionDir = oinoneVersion.replace(/[^0-9.]/g, ''); // Extract '7.2.0' or '6.4.0'
|
|
303
332
|
const templatePath = path.resolve(__dirname, `../template-${versionDir}-${edition}`);
|
|
304
333
|
|
|
305
334
|
if (!fs.existsSync(templatePath)) {
|
|
306
|
-
spinner.fail(chalk.red(
|
|
335
|
+
spinner.fail(chalk.red(t('errorTemplateMissing', { version: oinoneVersion, edition })));
|
|
307
336
|
process.exit(1);
|
|
308
337
|
}
|
|
309
338
|
|
|
@@ -394,35 +423,68 @@ program
|
|
|
394
423
|
}
|
|
395
424
|
|
|
396
425
|
if (downloadStaticResources) {
|
|
397
|
-
spinner.succeed(chalk.green('
|
|
398
|
-
console.log(chalk.cyan('
|
|
426
|
+
spinner.succeed(chalk.green(t('structureReady')));
|
|
427
|
+
console.log(chalk.cyan(t('haulingStatic')));
|
|
399
428
|
try {
|
|
400
429
|
const ossDir = path.join(targetPath, 'packages', `${prefix}-boot`, 'public', 'oss');
|
|
401
430
|
await fs.ensureDir(ossDir);
|
|
402
431
|
await downloadAndExtractZip('https://pamirs.oss-cn-hangzhou.aliyuncs.com/oinone/installer/static-resources.zip', ossDir);
|
|
403
|
-
console.log(chalk.green('
|
|
432
|
+
console.log(chalk.green(t('staticDownloaded')));
|
|
404
433
|
} catch (err) {
|
|
405
|
-
console.log(chalk.yellow(
|
|
434
|
+
console.log(chalk.yellow(t('staticHiccup', { msg: err.message })));
|
|
406
435
|
}
|
|
407
436
|
} else {
|
|
408
|
-
spinner.succeed(chalk.green('
|
|
437
|
+
spinner.succeed(chalk.green(t('projectCreated')));
|
|
409
438
|
const relativeOssDir = `packages/${prefix}-boot/public/oss`;
|
|
410
|
-
console.log(chalk.yellow(
|
|
411
|
-
console.log(chalk.yellow(
|
|
439
|
+
console.log(chalk.yellow(t('skipStaticWarning')));
|
|
440
|
+
console.log(chalk.yellow(t('manualStaticInstructions')));
|
|
412
441
|
console.log(chalk.cyan(` mkdir -p ${fullProjectName}/${relativeOssDir}`));
|
|
413
442
|
console.log(chalk.cyan(` curl -L https://pamirs.oss-cn-hangzhou.aliyuncs.com/oinone/installer/static-resources.zip -o static-resources.zip`));
|
|
414
443
|
console.log(chalk.cyan(` unzip static-resources.zip -d ${fullProjectName}/${relativeOssDir}`));
|
|
415
444
|
console.log(chalk.cyan(` rm static-resources.zip`));
|
|
416
445
|
}
|
|
417
446
|
|
|
418
|
-
console.log(
|
|
447
|
+
console.log(t('partyStarted'));
|
|
419
448
|
console.log(chalk.cyan(` cd ${fullProjectName}`));
|
|
420
449
|
console.log(chalk.cyan(` pnpm install`));
|
|
421
450
|
console.log(chalk.cyan(` pnpm run dev\n`));
|
|
422
|
-
console.log(chalk.magenta(
|
|
451
|
+
console.log(chalk.magenta(t('happyCoding')));
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
const latestVersion = await Promise.race([
|
|
455
|
+
versionCheckPromise,
|
|
456
|
+
new Promise(resolve => setTimeout(() => {
|
|
457
|
+
if (checkReq) checkReq.destroy();
|
|
458
|
+
resolve(null);
|
|
459
|
+
}, 1000))
|
|
460
|
+
]);
|
|
461
|
+
|
|
462
|
+
if (latestVersion) {
|
|
463
|
+
const isNewerVersion = (current, latest) => {
|
|
464
|
+
const c = current.replace(/[^0-9.]/g, '').split('.').map(Number);
|
|
465
|
+
const l = latest.replace(/[^0-9.]/g, '').split('.').map(Number);
|
|
466
|
+
for (let i = 0; i < Math.max(c.length, l.length); i++) {
|
|
467
|
+
const numC = c[i] || 0;
|
|
468
|
+
const numL = l[i] || 0;
|
|
469
|
+
if (numL > numC) return true;
|
|
470
|
+
if (numL < numC) return false;
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
if (isNewerVersion(packageJson.version, latestVersion)) {
|
|
476
|
+
console.log(chalk.yellow(`====================================================`));
|
|
477
|
+
console.log(chalk.yellow(t('updateAvailable', { current: chalk.red(packageJson.version), latest: chalk.green(latestVersion) })));
|
|
478
|
+
console.log(chalk.yellow(t('runUpdate', { cmd: chalk.cyan('npm install -g @oinone/cli') })));
|
|
479
|
+
console.log(chalk.yellow(`====================================================\n`));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
} catch (e) {
|
|
483
|
+
// ignore errors
|
|
484
|
+
}
|
|
423
485
|
|
|
424
486
|
} catch (error) {
|
|
425
|
-
console.error(chalk.red(
|
|
487
|
+
console.error(chalk.red(t('somethingBroke', { msg: error.message })));
|
|
426
488
|
process.exit(1);
|
|
427
489
|
}
|
|
428
490
|
});
|
package/bin/i18n.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const detectLanguage = () => {
|
|
2
|
+
try {
|
|
3
|
+
const locale = new Intl.DateTimeFormat().resolvedOptions().locale;
|
|
4
|
+
if (locale.toLowerCase().startsWith('zh')) {
|
|
5
|
+
return 'zh-CN';
|
|
6
|
+
}
|
|
7
|
+
} catch (e) {
|
|
8
|
+
// Ignore error
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Also check environment variables for language
|
|
12
|
+
const envLang = process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || '';
|
|
13
|
+
if (envLang.toLowerCase().startsWith('zh')) {
|
|
14
|
+
return 'zh-CN';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return 'en-US';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const currentLang = detectLanguage();
|
|
21
|
+
|
|
22
|
+
const locales = {
|
|
23
|
+
'en-US': {
|
|
24
|
+
usingCached: '⚡ Zap! Using cached static resources...',
|
|
25
|
+
fetchFileInfoFailed: 'Failed to fetch file info: {status}',
|
|
26
|
+
downloadFailed: 'Failed to download: {status}',
|
|
27
|
+
fetchingAwesomeness: '🚀 Fetching awesomeness ',
|
|
28
|
+
progressLeft: 'left',
|
|
29
|
+
cacheCleaned: '✨ Whoosh! Cache swept clean at {dir}',
|
|
30
|
+
cacheAlreadyEmpty: '🤷 Cache directory already vanished (or never existed): {dir}',
|
|
31
|
+
cacheDir: '📂 Cache Directory: ',
|
|
32
|
+
cachedFiles: '📦 Cached Files:',
|
|
33
|
+
totalCacheSize: '\n📊 Total Cache Size: ',
|
|
34
|
+
cacheEmpty: '🍃 Cache is currently as empty as space.',
|
|
35
|
+
description: 'Oinone Frontend Template CLI',
|
|
36
|
+
cacheCmdDesc: 'Manage the local static resources cache',
|
|
37
|
+
cacheCleanDesc: 'Clean the local static resources cache',
|
|
38
|
+
cacheInfoDesc: 'Print cache directory information',
|
|
39
|
+
versionOption: 'output the version number',
|
|
40
|
+
helpOption: 'display help for command',
|
|
41
|
+
projectNameArg: 'Name of the project to create silently',
|
|
42
|
+
downloadOpt: 'Download static resources (true/false)',
|
|
43
|
+
versionOpt: 'Oinone version to use (e.g. 7.2.0, 6.4.0)',
|
|
44
|
+
editionOpt: 'Oinone edition to use (community/enterprise)',
|
|
45
|
+
promptCompany: '🏢 What is your awesome company/org name? (e.g. ss):',
|
|
46
|
+
errorCompanyEmpty: 'Oops! Company name cannot be empty 🙈',
|
|
47
|
+
promptProject: '🚀 Name your epic project (e.g. oms):',
|
|
48
|
+
errorProjectEmpty: 'Hold on! Project name cannot be empty 🛑',
|
|
49
|
+
promptEdition: '💎 Choose your Oinone flavor:',
|
|
50
|
+
editionCommunity: '🌱 Community Edition (Default)',
|
|
51
|
+
editionEnterprise: '👑 Enterprise Edition',
|
|
52
|
+
promptVersion: '📦 Which Oinone version are we rocking today?',
|
|
53
|
+
version720: '✨ 7.2.0 (Default)',
|
|
54
|
+
version640: '🕰️ 6.4.0',
|
|
55
|
+
promptDownload: '📥 Shall we fetch the latest static resources for you? (Highly recommended! 🌟)',
|
|
56
|
+
errorDirExists: '\n🚫 Yikes! The directory {name} already exists. Try a different name or clear the path.\n',
|
|
57
|
+
weavingMagic: '✨ Weaving magic to create your project...',
|
|
58
|
+
errorTemplateMissing: '😢 Uh-oh! Template for version {version} ({edition} edition) went missing in action.',
|
|
59
|
+
structureReady: '🎉 Boom! Project structure is ready!',
|
|
60
|
+
haulingStatic: '🚚 Hauling in the static resources...',
|
|
61
|
+
staticDownloaded: '🎯 Bullseye! Static resources downloaded and ready to roll!',
|
|
62
|
+
staticHiccup: '⚠️ Project is ready, but the static resources had a hiccup: {msg}',
|
|
63
|
+
projectCreated: '🎉 Boom! Project created successfully!',
|
|
64
|
+
skipStaticWarning: '\n⚠️ You chose to skip the static resources download.',
|
|
65
|
+
manualStaticInstructions: 'Don\'t forget to grab them manually before you fire up the project:',
|
|
66
|
+
partyStarted: '\n🚀 Let\'s get this party started:\n',
|
|
67
|
+
happyCoding: 'Happy coding! 💻☕\n',
|
|
68
|
+
updateAvailable: '📦 Update available! {current} → {latest}',
|
|
69
|
+
runUpdate: 'Run {cmd} to update.',
|
|
70
|
+
somethingBroke: '\n💥 Oops! Something broke: {msg}\n'
|
|
71
|
+
},
|
|
72
|
+
'zh-CN': {
|
|
73
|
+
usingCached: '⚡ 嗖!正在使用本地缓存的静态资源...',
|
|
74
|
+
fetchFileInfoFailed: '获取文件信息失败: {status}',
|
|
75
|
+
downloadFailed: '下载失败: {status}',
|
|
76
|
+
fetchingAwesomeness: '🚀 正在获取静态资源 ',
|
|
77
|
+
progressLeft: '剩余',
|
|
78
|
+
cacheCleaned: '✨ 呼!缓存清理完毕,位置:{dir}',
|
|
79
|
+
cacheAlreadyEmpty: '🤷 缓存目录已消失(或从未存在):{dir}',
|
|
80
|
+
cacheDir: '📂 缓存目录: ',
|
|
81
|
+
cachedFiles: '📦 缓存文件:',
|
|
82
|
+
totalCacheSize: '\n📊 总缓存大小: ',
|
|
83
|
+
cacheEmpty: '🍃 当前缓存空空如也。',
|
|
84
|
+
description: 'Oinone 前端脚手架',
|
|
85
|
+
cacheCmdDesc: '管理本地静态资源缓存',
|
|
86
|
+
cacheCleanDesc: '清理本地静态资源缓存',
|
|
87
|
+
cacheInfoDesc: '打印缓存目录信息',
|
|
88
|
+
versionOption: '输出版本号',
|
|
89
|
+
helpOption: '显示命令帮助',
|
|
90
|
+
projectNameArg: '静默创建时的项目名称',
|
|
91
|
+
downloadOpt: '是否下载静态资源 (true/false)',
|
|
92
|
+
versionOpt: '使用的 Oinone 版本 (例如 7.2.0, 6.4.0)',
|
|
93
|
+
editionOpt: '使用的 Oinone 版本类型 (community/enterprise)',
|
|
94
|
+
promptCompany: '🏢 您的公司/组织名称是?(例如 ss):',
|
|
95
|
+
errorCompanyEmpty: '哎呀!公司名称不能为空 🙈',
|
|
96
|
+
promptProject: '🚀 给您的项目起个名字吧 (例如 oms):',
|
|
97
|
+
errorProjectEmpty: '稍等!项目名称不能为空 🛑',
|
|
98
|
+
promptEdition: '💎 请选择 Oinone 版本类型:',
|
|
99
|
+
editionCommunity: '🌱 社区版 (默认)',
|
|
100
|
+
editionEnterprise: '👑 企业版',
|
|
101
|
+
promptVersion: '📦 今天我们要使用哪个 Oinone 版本?',
|
|
102
|
+
version720: '✨ 7.2.0 (默认)',
|
|
103
|
+
version640: '🕰️ 6.4.0',
|
|
104
|
+
promptDownload: '📥 是否为您获取最新的静态资源?(强烈推荐!🌟)',
|
|
105
|
+
errorDirExists: '\n🚫 哎呀!目录 {name} 已存在。请尝试其他名称或清理该路径。\n',
|
|
106
|
+
weavingMagic: '✨ 正在施展魔法为您创建项目...',
|
|
107
|
+
errorTemplateMissing: '😢 糟糕!未找到 {version} 版本 ({edition}版) 的模板。',
|
|
108
|
+
structureReady: '🎉 棒!项目结构已准备就绪!',
|
|
109
|
+
haulingStatic: '🚚 正在搬运静态资源...',
|
|
110
|
+
staticDownloaded: '🎯 太准了!静态资源下载完毕,随时可以起飞!',
|
|
111
|
+
staticHiccup: '⚠️ 项目已就绪,但静态资源遇到点小麻烦: {msg}',
|
|
112
|
+
projectCreated: '🎉 棒!项目创建成功!',
|
|
113
|
+
skipStaticWarning: '\n⚠️ 您选择了跳过静态资源下载。',
|
|
114
|
+
manualStaticInstructions: '启动项目前,别忘了手动获取它们:',
|
|
115
|
+
partyStarted: '\n🚀 让我们开始狂欢吧:\n',
|
|
116
|
+
happyCoding: '编码愉快!💻☕\n',
|
|
117
|
+
updateAvailable: '📦 发现新版本!{current} → {latest}',
|
|
118
|
+
runUpdate: '运行 {cmd} 进行更新。',
|
|
119
|
+
somethingBroke: '\n💥 糟糕!出了点问题: {msg}\n'
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const t = (key, params = {}) => {
|
|
124
|
+
let str = locales[currentLang][key] || locales['en-US'][key] || key;
|
|
125
|
+
Object.keys(params).forEach((k) => {
|
|
126
|
+
str = str.replace(new RegExp(`{${k}}`, 'g'), params[k]);
|
|
127
|
+
});
|
|
128
|
+
return str;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
module.exports = {
|
|
132
|
+
currentLang,
|
|
133
|
+
t
|
|
134
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oinone/cli",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.5",
|
|
4
4
|
"description": "CLI tool to generate Oinone Frontend Template",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"oinone-frontend": "./bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "
|
|
10
|
+
"test": "vitest run"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"oinone",
|
|
@@ -25,5 +25,8 @@
|
|
|
25
25
|
"fs-extra": "^11.3.4",
|
|
26
26
|
"inquirer": "^8.2.6",
|
|
27
27
|
"ora": "^5.4.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"vitest": "^4.1.4"
|
|
28
31
|
}
|
|
29
32
|
}
|