i18ntk 2.6.0 → 3.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.
- package/CHANGELOG.md +19 -0
- package/README.md +51 -18
- package/main/i18ntk-translate.js +502 -0
- package/main/manage/commands/CommandRouter.js +7 -1
- package/main/manage/commands/TranslateCommand.js +242 -0
- package/main/manage/index.js +11 -5
- package/package.json +12 -3
- package/ui-locales/de.json +3 -0
- package/ui-locales/en.json +3 -0
- package/ui-locales/es.json +3 -0
- package/ui-locales/fr.json +3 -0
- package/ui-locales/ja.json +3 -0
- package/ui-locales/ru.json +3 -1
- package/ui-locales/zh.json +3 -0
- package/utils/translate/api.js +168 -0
- package/utils/translate/cli.js +91 -0
- package/utils/translate/placeholder.js +93 -0
- package/utils/translate/report.js +90 -0
- package/utils/translate/traverse.js +148 -0
|
@@ -23,6 +23,7 @@ const BackupCommand = require('./BackupCommand');
|
|
|
23
23
|
const DoctorCommand = require('./DoctorCommand');
|
|
24
24
|
const FixerCommand = require('./FixerCommand');
|
|
25
25
|
const ScannerCommand = require('./ScannerCommand');
|
|
26
|
+
const TranslateCommand = require('./TranslateCommand');
|
|
26
27
|
|
|
27
28
|
class CommandRouter {
|
|
28
29
|
constructor(config = {}, ui = null, adminAuth = null) {
|
|
@@ -45,7 +46,8 @@ class CommandRouter {
|
|
|
45
46
|
'backup': new BackupCommand(config, ui),
|
|
46
47
|
'doctor': new DoctorCommand(config, ui),
|
|
47
48
|
'fix': new FixerCommand(config, ui),
|
|
48
|
-
'scanner': new ScannerCommand(config, ui)
|
|
49
|
+
'scanner': new ScannerCommand(config, ui),
|
|
50
|
+
'translate': new TranslateCommand(config, ui)
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -232,6 +234,9 @@ class CommandRouter {
|
|
|
232
234
|
case 'scanner':
|
|
233
235
|
return await this.commandHandlers.scanner.execute(options);
|
|
234
236
|
|
|
237
|
+
case 'translate':
|
|
238
|
+
return await this.commandHandlers.translate.execute(options);
|
|
239
|
+
|
|
235
240
|
case 'debug':
|
|
236
241
|
console.log('Debug functionality is not available in this version.');
|
|
237
242
|
return { success: false, message: 'Debug not available' };
|
|
@@ -278,6 +283,7 @@ class CommandRouter {
|
|
|
278
283
|
console.log(t('help.summaryCommand'));
|
|
279
284
|
console.log(t('help.debugCommand'));
|
|
280
285
|
console.log(t('help.scannerCommand'));
|
|
286
|
+
console.log(t('help.translateCommand'));
|
|
281
287
|
}
|
|
282
288
|
|
|
283
289
|
/**
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* I18NTK TRANSLATE COMMAND
|
|
5
|
+
*
|
|
6
|
+
* Interactive menu-driven auto-translation using Google Translate.
|
|
7
|
+
* Wraps i18ntk-translate.js behind a user-friendly menu flow.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const { getUnifiedConfig } = require('../../../utils/config-helper');
|
|
13
|
+
const { loadTranslations } = require('../../../utils/i18n-helper');
|
|
14
|
+
const SetupEnforcer = require('../../../utils/setup-enforcer');
|
|
15
|
+
|
|
16
|
+
class TranslateCommand {
|
|
17
|
+
constructor(config = {}, ui = null) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.ui = ui;
|
|
20
|
+
this.prompt = null;
|
|
21
|
+
this.isNonInteractiveMode = false;
|
|
22
|
+
this.safeClose = null;
|
|
23
|
+
this.sourceDir = null;
|
|
24
|
+
this.sourceLang = null;
|
|
25
|
+
this.targetLang = null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setRuntimeDependencies(prompt, isNonInteractiveMode, safeClose) {
|
|
29
|
+
this.prompt = prompt;
|
|
30
|
+
this.isNonInteractiveMode = isNonInteractiveMode;
|
|
31
|
+
this.safeClose = safeClose;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async execute(options = {}) {
|
|
35
|
+
try {
|
|
36
|
+
await SetupEnforcer.checkSetupCompleteAsync();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('Setup check failed:', error.message);
|
|
39
|
+
return { success: false, error: 'Setup required' };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
loadTranslations('en', path.resolve(__dirname, '..', '..', '..', 'ui-locales'));
|
|
43
|
+
|
|
44
|
+
const config = this.config || {};
|
|
45
|
+
const unified = getUnifiedConfig(config);
|
|
46
|
+
|
|
47
|
+
const defaultSourceDir = unified.sourceDir || unified.i18nDir || path.resolve(process.cwd(), 'locales', 'en');
|
|
48
|
+
this.sourceLang = unified.sourceLanguage || 'en';
|
|
49
|
+
|
|
50
|
+
console.log('\n============================================================');
|
|
51
|
+
console.log(' \u{1F310} AUTO TRANSLATE (BETA)');
|
|
52
|
+
console.log('============================================================');
|
|
53
|
+
|
|
54
|
+
if (this.isNonInteractiveMode) {
|
|
55
|
+
this.sourceDir = defaultSourceDir;
|
|
56
|
+
if (!fs.existsSync(this.sourceDir)) {
|
|
57
|
+
console.error(`Source locale directory not found: ${this.sourceDir}`);
|
|
58
|
+
return { success: false, error: 'Source directory not found' };
|
|
59
|
+
}
|
|
60
|
+
const jsonFiles = fs.readdirSync(this.sourceDir).filter(f => f.endsWith('.json')).sort();
|
|
61
|
+
return await this.nonInteractiveFlow(jsonFiles);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { ask } = require('../../../utils/cli');
|
|
65
|
+
|
|
66
|
+
// Step 1: Choose source directory
|
|
67
|
+
this.sourceDir = await this.promptSourceDir(ask, defaultSourceDir);
|
|
68
|
+
if (!this.sourceDir) return { success: false, error: 'No source directory selected' };
|
|
69
|
+
|
|
70
|
+
// Step 2: Choose source language
|
|
71
|
+
this.sourceLang = await this.promptSourceLang(ask);
|
|
72
|
+
if (!this.sourceLang) return { success: false, error: 'No source language selected' };
|
|
73
|
+
|
|
74
|
+
const jsonFiles = fs.readdirSync(this.sourceDir)
|
|
75
|
+
.filter(f => f.endsWith('.json'))
|
|
76
|
+
.sort();
|
|
77
|
+
|
|
78
|
+
if (jsonFiles.length === 0) {
|
|
79
|
+
console.error(`No JSON files found in: ${this.sourceDir}`);
|
|
80
|
+
return { success: false, error: 'No source files found' };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return await this.interactiveFlow(jsonFiles, ask);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async promptSourceDir(ask, defaultDir) {
|
|
87
|
+
while (true) {
|
|
88
|
+
console.log(`\n Source directory [default: ${defaultDir}]`);
|
|
89
|
+
console.log(' Press Enter for default, or type a custom path.');
|
|
90
|
+
const input = await ask(' > ');
|
|
91
|
+
|
|
92
|
+
if (!input.trim()) {
|
|
93
|
+
if (!fs.existsSync(defaultDir)) {
|
|
94
|
+
console.log(` Default directory not found: ${defaultDir}`);
|
|
95
|
+
console.log(' Please enter an existing directory with JSON locale files.');
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
console.log(` Using default: ${defaultDir}`);
|
|
99
|
+
return defaultDir;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const resolved = path.resolve(process.cwd(), input.trim());
|
|
103
|
+
if (!fs.existsSync(resolved)) {
|
|
104
|
+
console.log(` Directory not found: ${resolved}`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (!fs.statSync(resolved).isDirectory()) {
|
|
108
|
+
console.log(` Not a directory: ${resolved}`);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
return resolved;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async promptSourceLang(ask) {
|
|
116
|
+
while (true) {
|
|
117
|
+
console.log(`\n Source language code [default: ${this.sourceLang}]`);
|
|
118
|
+
const input = await ask(' > ');
|
|
119
|
+
|
|
120
|
+
if (!input.trim()) {
|
|
121
|
+
return this.sourceLang;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const lang = input.trim().toLowerCase();
|
|
125
|
+
if (lang.length >= 2) {
|
|
126
|
+
return lang;
|
|
127
|
+
}
|
|
128
|
+
console.log(' Invalid language code. Use 2+ characters (e.g. en, de, fr).');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async interactiveFlow(jsonFiles, ask) {
|
|
133
|
+
|
|
134
|
+
console.log('\n Target language code(s)');
|
|
135
|
+
console.log(' Enter one or more comma/space-separated codes');
|
|
136
|
+
console.log(' (e.g. de, es, fr or de es fr or de):');
|
|
137
|
+
const langInput = await ask(' > ');
|
|
138
|
+
|
|
139
|
+
const targetLangs = langInput
|
|
140
|
+
.trim()
|
|
141
|
+
.split(/[,;\s]+/)
|
|
142
|
+
.map(s => s.toLowerCase().trim())
|
|
143
|
+
.filter(s => s.length >= 2);
|
|
144
|
+
|
|
145
|
+
if (targetLangs.length === 0) {
|
|
146
|
+
console.log(' No valid language codes entered. Aborting.');
|
|
147
|
+
return { success: false, error: 'Invalid language code' };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
console.log(`\n Target languages: ${targetLangs.join(', ')}`);
|
|
151
|
+
|
|
152
|
+
console.log(`\n Which file(s) to translate?`);
|
|
153
|
+
console.log(` a) All files (${jsonFiles.join(', ')})`);
|
|
154
|
+
jsonFiles.forEach((f, i) => {
|
|
155
|
+
console.log(` ${i + 1}) ${f}`);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const fileChoice = await ask('\n Choice [a/1-9]: ');
|
|
159
|
+
let sourceFiles;
|
|
160
|
+
|
|
161
|
+
if (fileChoice.toLowerCase() === 'a') {
|
|
162
|
+
sourceFiles = jsonFiles.map(f => path.join(this.sourceDir, f));
|
|
163
|
+
} else {
|
|
164
|
+
const idx = parseInt(fileChoice, 10) - 1;
|
|
165
|
+
if (isNaN(idx) || idx < 0 || idx >= jsonFiles.length) {
|
|
166
|
+
console.log(' Invalid choice. Aborting.');
|
|
167
|
+
return { success: false, error: 'Invalid file choice' };
|
|
168
|
+
}
|
|
169
|
+
sourceFiles = [path.join(this.sourceDir, jsonFiles[idx])];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Dry-run for first language only (all languages use same source so same keys)
|
|
173
|
+
const firstLang = targetLangs[0];
|
|
174
|
+
console.log(`\n Dry-run preview for "${firstLang}"...\n`);
|
|
175
|
+
await this.runTranslate(sourceFiles, firstLang, { dryRun: true });
|
|
176
|
+
|
|
177
|
+
console.log('\n Proceed with actual translation?');
|
|
178
|
+
const answer = await ask(' [y]es / [n]o: ');
|
|
179
|
+
if (!/^y|yes$/i.test(answer.trim())) {
|
|
180
|
+
console.log(' Translation cancelled.');
|
|
181
|
+
return { success: true, cancelled: true };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
let results = [];
|
|
185
|
+
for (const lang of targetLangs) {
|
|
186
|
+
console.log(`\n Translating to "${lang}"...\n`);
|
|
187
|
+
try {
|
|
188
|
+
await this.runTranslate(sourceFiles, lang, { dryRun: false });
|
|
189
|
+
results.push({ lang, ok: true });
|
|
190
|
+
} catch (e) {
|
|
191
|
+
console.error(` Failed for "${lang}": ${e.message}`);
|
|
192
|
+
results.push({ lang, ok: false, error: e.message });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log('\n Summary:');
|
|
197
|
+
for (const r of results) {
|
|
198
|
+
console.log(` ${r.ok ? '\u{2705}' : '\u{274C}'} ${r.lang}${r.error ? ' (' + r.error + ')' : ''}`);
|
|
199
|
+
}
|
|
200
|
+
console.log('\n Translation complete!');
|
|
201
|
+
return { success: true, results };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async nonInteractiveFlow(jsonFiles) {
|
|
205
|
+
console.log('\n Non-interactive mode. Use direct CLI instead:');
|
|
206
|
+
console.log(' i18ntk-translate <source> <lang> [options]');
|
|
207
|
+
return { success: false, error: 'Non-interactive mode not supported from menu' };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async runTranslate(sourceFiles, targetLang, opts = {}) {
|
|
211
|
+
const { spawn } = require('child_process');
|
|
212
|
+
|
|
213
|
+
for (const src of sourceFiles) {
|
|
214
|
+
const args = [
|
|
215
|
+
path.resolve(__dirname, '..', '..', 'i18ntk-translate.js'),
|
|
216
|
+
src,
|
|
217
|
+
targetLang,
|
|
218
|
+
'--no-confirm',
|
|
219
|
+
'--skip-placeholders',
|
|
220
|
+
'--report-stdout'
|
|
221
|
+
];
|
|
222
|
+
|
|
223
|
+
if (opts.dryRun) {
|
|
224
|
+
args.push('--dry-run');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
await new Promise((resolve, reject) => {
|
|
228
|
+
const proc = spawn('node', args, {
|
|
229
|
+
stdio: 'inherit',
|
|
230
|
+
cwd: process.cwd()
|
|
231
|
+
});
|
|
232
|
+
proc.on('close', (code) => {
|
|
233
|
+
if (code === 0) resolve();
|
|
234
|
+
else reject(new Error(`Exit code ${code}`));
|
|
235
|
+
});
|
|
236
|
+
proc.on('error', reject);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = TranslateCommand;
|
package/main/manage/index.js
CHANGED
|
@@ -878,6 +878,7 @@ class I18nManager {
|
|
|
878
878
|
console.log(`11. ${t('menu.options.help')}`);
|
|
879
879
|
console.log(`12. ${t('menu.options.language')}`);
|
|
880
880
|
console.log(`13. ${t('menu.options.scanner')}`);
|
|
881
|
+
console.log(`14. ${t('menu.options.translate')}`);
|
|
881
882
|
console.log(`0. ${t('menu.options.exit')}`);
|
|
882
883
|
|
|
883
884
|
console.log('\n' + t('menu.nonInteractiveModeWarning'));
|
|
@@ -903,6 +904,7 @@ class I18nManager {
|
|
|
903
904
|
console.log(`11. ${t('menu.options.help')}`);
|
|
904
905
|
console.log(`12. ${t('menu.options.language')}`);
|
|
905
906
|
console.log(`13. ${t('menu.options.scanner')}`);
|
|
907
|
+
console.log(`14. ${t('menu.options.translate')}`);
|
|
906
908
|
console.log(`0. ${t('menu.options.exit')}`);
|
|
907
909
|
|
|
908
910
|
const choice = await this.prompt('\n' + t('menu.selectOptionPrompt'));
|
|
@@ -1007,11 +1009,15 @@ class I18nManager {
|
|
|
1007
1009
|
case '12':
|
|
1008
1010
|
await this.showLanguageMenu();
|
|
1009
1011
|
break;
|
|
1010
|
-
case '13':
|
|
1011
|
-
await this.executeCommand('scanner', {fromMenu: true});
|
|
1012
|
-
await this.showInteractiveMenu();
|
|
1013
|
-
return;
|
|
1014
|
-
case '
|
|
1012
|
+
case '13':
|
|
1013
|
+
await this.executeCommand('scanner', {fromMenu: true});
|
|
1014
|
+
await this.showInteractiveMenu();
|
|
1015
|
+
return;
|
|
1016
|
+
case '14':
|
|
1017
|
+
await this.executeCommand('translate', {fromMenu: true});
|
|
1018
|
+
await this.showInteractiveMenu();
|
|
1019
|
+
return;
|
|
1020
|
+
case '0':
|
|
1015
1021
|
console.log(t('menu.goodbye'));
|
|
1016
1022
|
this.safeClose();
|
|
1017
1023
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18ntk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Zero-dependency internationalization toolkit for setup, scanning, analysis, validation,
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Zero-dependency internationalization toolkit for setup, scanning, analysis, validation, auto translation, fixing, reporting, and runtime translation loading.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
7
7
|
"internationalization",
|
|
8
8
|
"localization",
|
|
9
9
|
"translation",
|
|
10
|
+
"auto-translation",
|
|
11
|
+
"google-translate",
|
|
10
12
|
"l10n",
|
|
11
13
|
"multilingual",
|
|
12
14
|
"i18next",
|
|
@@ -76,12 +78,14 @@
|
|
|
76
78
|
"i18ntk-doctor": "main/i18ntk-doctor.js",
|
|
77
79
|
"i18ntk-fixer": "main/i18ntk-fixer.js",
|
|
78
80
|
"i18ntk-scanner": "main/i18ntk-scanner.js",
|
|
79
|
-
"i18ntk-backup": "main/i18ntk-backup.js"
|
|
81
|
+
"i18ntk-backup": "main/i18ntk-backup.js",
|
|
82
|
+
"i18ntk-translate": "main/i18ntk-translate.js"
|
|
80
83
|
},
|
|
81
84
|
"files": [
|
|
82
85
|
"main/i18ntk-analyze.js",
|
|
83
86
|
"main/i18ntk-backup-class.js",
|
|
84
87
|
"main/i18ntk-backup.js",
|
|
88
|
+
"main/i18ntk-translate.js",
|
|
85
89
|
"main/i18ntk-complete.js",
|
|
86
90
|
"main/i18ntk-doctor.js",
|
|
87
91
|
"main/i18ntk-fixer.js",
|
|
@@ -114,6 +118,11 @@
|
|
|
114
118
|
"utils/extractors/regex.js",
|
|
115
119
|
"utils/format-manager.js",
|
|
116
120
|
"utils/formats/json.js",
|
|
121
|
+
"utils/translate/placeholder.js",
|
|
122
|
+
"utils/translate/api.js",
|
|
123
|
+
"utils/translate/traverse.js",
|
|
124
|
+
"utils/translate/report.js",
|
|
125
|
+
"utils/translate/cli.js",
|
|
117
126
|
"utils/framework-detector.js",
|
|
118
127
|
"utils/i18n-helper.js",
|
|
119
128
|
"utils/init-helper.js",
|
package/ui-locales/de.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - Projektstatus anzeigen",
|
|
923
923
|
"debugCommand": "debug - Übersetzungsfehler debuggen",
|
|
924
924
|
"scannerCommand": "scanner - Projekt für i18n-Schlüssel scannen",
|
|
925
|
+
"translateCommand": "translate - Auto-Übersetzung (Beta)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "Drücken Sie die Eingabetaste, um fortzufahren...",
|
|
927
928
|
"title": "🌐 I18NTK VERWALTUNGSMENÜ",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 Größenanalyse",
|
|
1147
1148
|
"fix": "🛠️ Platzhalterübersetzungen reparieren",
|
|
1148
1149
|
"scanner": "🔍 i18n-Probleme scannen",
|
|
1150
|
+
"translate": "🌐 Auto-Übersetzung (Beta)",
|
|
1149
1151
|
"workflow": "🔄 Gesamten Workflow ausführen",
|
|
1150
1152
|
"status": "📋 Projektstatus anzeigen",
|
|
1151
1153
|
"delete": "🗑️ Alle Berichte löschen",
|
|
@@ -2111,6 +2113,7 @@
|
|
|
2111
2113
|
"completeCommand": "complete - Übersetzungen vervollständigen (100% Abdeckung)",
|
|
2112
2114
|
"summaryCommand": "summary - Projektstatus anzeigen",
|
|
2113
2115
|
"scannerCommand": "scanner - i18n-Probleme scannen",
|
|
2116
|
+
"translateCommand": "translate - Auto-Übersetzung (Beta)",
|
|
2114
2117
|
"debugCommand": "debug - Übersetzungsprobleme debuggen"
|
|
2115
2118
|
},
|
|
2116
2119
|
"test_complete_system": {
|
package/ui-locales/en.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - Show project status",
|
|
923
923
|
"debugCommand": "debug - Debug translation issues",
|
|
924
924
|
"scannerCommand": "scanner - Scan for keys",
|
|
925
|
+
"translateCommand": "translate - Auto-translate locale files (Beta)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "Press Enter to continue...",
|
|
927
928
|
"title": "🌐 I18NTK MANAGEMENT MENU",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 Analyze sizing",
|
|
1147
1148
|
"fix": "🛠️ Fix placeholder translations",
|
|
1148
1149
|
"scanner": "🔍 Scan for i18n issues",
|
|
1150
|
+
"translate": "🌐 Auto Translate (Beta)",
|
|
1149
1151
|
"workflow": "🔄 Run full workflow",
|
|
1150
1152
|
"status": "📋 Show project status",
|
|
1151
1153
|
"delete": "🗑️ Delete all reports",
|
|
@@ -2109,6 +2111,7 @@
|
|
|
2109
2111
|
"completeCommand": "complete - Complete translations (100% coverage)",
|
|
2110
2112
|
"summaryCommand": "summary - Show project status",
|
|
2111
2113
|
"scannerCommand": "scanner - Scan for i18n issues",
|
|
2114
|
+
"translateCommand": "translate - Auto-translate locale files (Beta)",
|
|
2112
2115
|
"debugCommand": "debug - Debug translation issues"
|
|
2113
2116
|
},
|
|
2114
2117
|
"test_complete_system": {
|
package/ui-locales/es.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - Mostrar estado del proyecto",
|
|
923
923
|
"debugCommand": "debug - Depurar problemas de traducción",
|
|
924
924
|
"scannerCommand": "scanner - Escanear proyecto para claves i18n",
|
|
925
|
+
"translateCommand": "translate - Traducción automática (Beta)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "Presiona Enter para continuar...",
|
|
927
928
|
"title": "🌐 MENÚ DE GESTIÓN I18NTK",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 Analizar dimensionamiento",
|
|
1147
1148
|
"fix": "🛠️ Corregir traducciones provisionales",
|
|
1148
1149
|
"scanner": "🔍 Buscar problemas de i18n",
|
|
1150
|
+
"translate": "🌐 Traducción Automática (Beta)",
|
|
1149
1151
|
"workflow": "🔄 Ejecutar flujo completo",
|
|
1150
1152
|
"status": "📋 Mostrar estado del proyecto",
|
|
1151
1153
|
"delete": "🗑️ Eliminar todos los informes",
|
|
@@ -2111,6 +2113,7 @@
|
|
|
2111
2113
|
"completeCommand": "complete - Completar traducciones (100% cobertura)",
|
|
2112
2114
|
"summaryCommand": "summary - Mostrar estado del proyecto",
|
|
2113
2115
|
"scannerCommand": "scanner - Escanear problemas i18n",
|
|
2116
|
+
"translateCommand": "translate - Traducción automática (Beta)",
|
|
2114
2117
|
"debugCommand": "debug - Depurar problemas de traducción"
|
|
2115
2118
|
},
|
|
2116
2119
|
"test_complete_system": {
|
package/ui-locales/fr.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - Afficher le statut du projet",
|
|
923
923
|
"debugCommand": "debug - Déboguer les problèmes de traduction",
|
|
924
924
|
"scannerCommand": "scanner - Rechercher des clés",
|
|
925
|
+
"translateCommand": "translate - Traduction automatique (Bêta)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "Appuyez sur Entrée pour continuer...",
|
|
927
928
|
"title": "🌐 MENU DE GESTION I18NTK",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 Analyser le dimensionnement",
|
|
1147
1148
|
"fix": "🛠️ Corriger les traductions de remplacement",
|
|
1148
1149
|
"scanner": "🔍 Analyser les problèmes i18n",
|
|
1150
|
+
"translate": "🌐 Traduction Automatique (Bêta)",
|
|
1149
1151
|
"workflow": "🔄 Exécuter le flux complet",
|
|
1150
1152
|
"status": "📋 Afficher le statut du projet",
|
|
1151
1153
|
"delete": "🗑️ Supprimer tous les rapports",
|
|
@@ -2111,6 +2113,7 @@
|
|
|
2111
2113
|
"completeCommand": "complete - Compléter les traductions (couverture 100%)",
|
|
2112
2114
|
"summaryCommand": "summary - Afficher l'état du projet",
|
|
2113
2115
|
"scannerCommand": "scanner - Scanner le projet pour les clés i18n",
|
|
2116
|
+
"translateCommand": "translate - Traduction automatique (Bêta)",
|
|
2114
2117
|
"debugCommand": "debug - Déboguer les problèmes de traduction"
|
|
2115
2118
|
},
|
|
2116
2119
|
"test_complete_system": {
|
package/ui-locales/ja.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - プロジェクトのステータスを表示",
|
|
923
923
|
"debugCommand": "debug - 翻訳の問題をデバッグ",
|
|
924
924
|
"scannerCommand": "scanner - プロジェクトをスキャン",
|
|
925
|
+
"translateCommand": "translate - 自動翻訳 (ベータ版)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "Enterキーを押して続行してください…",
|
|
927
928
|
"title": "🌐 I18NTK 管理メニュー",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 サイズを分析",
|
|
1147
1148
|
"fix": "🛠️ プレースホルダー翻訳を修正",
|
|
1148
1149
|
"scanner": "🔍 i18n問題をスキャン",
|
|
1150
|
+
"translate": "🌐 自動翻訳 (ベータ版)",
|
|
1149
1151
|
"workflow": "🔄 フルワークフローを実行",
|
|
1150
1152
|
"status": "📋 プロジェクトステータスを表示",
|
|
1151
1153
|
"delete": "🗑️ すべてのレポートを削除",
|
|
@@ -2111,6 +2113,7 @@
|
|
|
2111
2113
|
"completeCommand": "complete - 翻訳を完了 (100% カバレッジ)",
|
|
2112
2114
|
"summaryCommand": "summary - プロジェクトステータスを表示",
|
|
2113
2115
|
"scannerCommand": "scanner - 🔍 i18nの問題をスキャン",
|
|
2116
|
+
"translateCommand": "translate - 自動翻訳 (ベータ版)",
|
|
2114
2117
|
"debugCommand": "debug - 翻訳の問題をデバッグ"
|
|
2115
2118
|
},
|
|
2116
2119
|
"test_complete_system": {
|
package/ui-locales/ru.json
CHANGED
|
@@ -1146,6 +1146,7 @@
|
|
|
1146
1146
|
"sizing": "📏 Анализ размеров",
|
|
1147
1147
|
"fix": "🛠️ Исправить переводы-заглушки",
|
|
1148
1148
|
"scanner": "🔍 Сканировать проблемы i18n",
|
|
1149
|
+
"translate": "🌐 Автоперевод (Бета)",
|
|
1149
1150
|
"workflow": "🔄 Запустить полный рабочий процесс",
|
|
1150
1151
|
"status": "📋 Показать статус проекта",
|
|
1151
1152
|
"delete": "🗑️ Удалить все отчёты",
|
|
@@ -2110,7 +2111,8 @@
|
|
|
2110
2111
|
"sizingCommand": "Оценка команды",
|
|
2111
2112
|
"completeCommand": "Завершение команды",
|
|
2112
2113
|
"summaryCommand": "Сводка команды",
|
|
2113
|
-
|
|
2114
|
+
"scannerCommand": "scanner - 🔍 Сканирование проблем i18n",
|
|
2115
|
+
"translateCommand": "translate - Автоперевод (Бета)",
|
|
2114
2116
|
"debugCommand": "Отладка команды"
|
|
2115
2117
|
},
|
|
2116
2118
|
"test_complete_system": {
|
package/ui-locales/zh.json
CHANGED
|
@@ -922,6 +922,7 @@
|
|
|
922
922
|
"summaryCommand": "summary - 显示项目状态",
|
|
923
923
|
"debugCommand": "debug - 调试翻译问题",
|
|
924
924
|
"scannerCommand": "scanner - 扫描项目中的 i18n 键",
|
|
925
|
+
"translateCommand": "translate - 自动翻译 (测试版)",
|
|
925
926
|
"menu": {
|
|
926
927
|
"pressEnterToContinue": "按 Enter 继续...",
|
|
927
928
|
"title": "🌐 国际化管理菜单",
|
|
@@ -1146,6 +1147,7 @@
|
|
|
1146
1147
|
"sizing": "📏 分析大小差异",
|
|
1147
1148
|
"fix": "🛠️ 修复占位翻译",
|
|
1148
1149
|
"scanner": "🔍 扫描i18n问题",
|
|
1150
|
+
"translate": "🌐 自动翻译 (测试版)",
|
|
1149
1151
|
"workflow": "🔄 运行完整工作流",
|
|
1150
1152
|
"status": "📋 显示项目状态",
|
|
1151
1153
|
"delete": "🗑️ 删除全部报告",
|
|
@@ -2111,6 +2113,7 @@
|
|
|
2111
2113
|
"completeCommand": "complete - 完成翻译(100% 覆盖)",
|
|
2112
2114
|
"summaryCommand": "summary - 显示项目状态",
|
|
2113
2115
|
"scannerCommand": "scanner - 🔍 扫描i18n问题",
|
|
2116
|
+
"translateCommand": "translate - 自动翻译 (测试版)",
|
|
2114
2117
|
"debugCommand": "debug - 调试翻译问题"
|
|
2115
2118
|
},
|
|
2116
2119
|
"test_complete_system": {
|