i18ntk 1.10.2 ā 2.0.3
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/LICENSE +1 -1
- package/README.md +141 -1191
- package/main/i18ntk-analyze.js +65 -84
- package/main/i18ntk-backup-class.js +420 -0
- package/main/i18ntk-backup.js +3 -3
- package/main/i18ntk-complete.js +90 -65
- package/main/i18ntk-doctor.js +123 -103
- package/main/i18ntk-fixer.js +61 -725
- package/main/i18ntk-go.js +14 -15
- package/main/i18ntk-init.js +77 -26
- package/main/i18ntk-java.js +27 -32
- package/main/i18ntk-js.js +70 -68
- package/main/i18ntk-manage.js +129 -30
- package/main/i18ntk-php.js +75 -75
- package/main/i18ntk-py.js +55 -56
- package/main/i18ntk-scanner.js +59 -57
- package/main/i18ntk-setup.js +9 -404
- package/main/i18ntk-sizing.js +6 -6
- package/main/i18ntk-summary.js +21 -18
- package/main/i18ntk-ui.js +11 -10
- package/main/i18ntk-usage.js +54 -18
- package/main/i18ntk-validate.js +13 -13
- package/main/manage/commands/AnalyzeCommand.js +1124 -0
- package/main/manage/commands/BackupCommand.js +62 -0
- package/main/manage/commands/CommandRouter.js +295 -0
- package/main/manage/commands/CompleteCommand.js +61 -0
- package/main/manage/commands/DoctorCommand.js +60 -0
- package/main/manage/commands/FixerCommand.js +624 -0
- package/main/manage/commands/InitCommand.js +62 -0
- package/main/manage/commands/ScannerCommand.js +654 -0
- package/main/manage/commands/SizingCommand.js +60 -0
- package/main/manage/commands/SummaryCommand.js +61 -0
- package/main/manage/commands/UsageCommand.js +60 -0
- package/main/manage/commands/ValidateCommand.js +978 -0
- package/main/manage/index-fixed.js +1447 -0
- package/main/manage/index.js +1462 -0
- package/main/manage/managers/DebugMenu.js +140 -0
- package/main/manage/managers/InteractiveMenu.js +177 -0
- package/main/manage/managers/LanguageMenu.js +62 -0
- package/main/manage/managers/SettingsMenu.js +53 -0
- package/main/manage/services/AuthenticationService.js +263 -0
- package/main/manage/services/ConfigurationService-fixed.js +449 -0
- package/main/manage/services/ConfigurationService.js +449 -0
- package/main/manage/services/FileManagementService.js +368 -0
- package/main/manage/services/FrameworkDetectionService.js +458 -0
- package/main/manage/services/InitService.js +1051 -0
- package/main/manage/services/SetupService.js +462 -0
- package/main/manage/services/SummaryService.js +450 -0
- package/main/manage/services/UsageService.js +1502 -0
- package/package.json +32 -29
- package/runtime/enhanced.d.ts +221 -221
- package/runtime/index.d.ts +29 -29
- package/runtime/index.full.d.ts +331 -331
- package/runtime/index.js +7 -6
- package/scripts/build-lite.js +17 -17
- package/scripts/deprecate-versions.js +23 -6
- package/scripts/export-translations.js +5 -5
- package/scripts/fix-all-i18n.js +3 -3
- package/scripts/fix-and-purify-i18n.js +3 -2
- package/scripts/fix-locale-control-chars.js +110 -0
- package/scripts/lint-locales.js +80 -0
- package/scripts/locale-optimizer.js +8 -8
- package/scripts/prepublish.js +21 -21
- package/scripts/security-check.js +117 -117
- package/scripts/sync-translations.js +4 -4
- package/scripts/sync-ui-locales.js +9 -8
- package/scripts/validate-all-translations.js +8 -7
- package/scripts/verify-deprecations.js +157 -161
- package/scripts/verify-translations.js +6 -5
- package/settings/i18ntk-config.json +282 -282
- package/settings/language-config.json +5 -5
- package/settings/settings-cli.js +9 -9
- package/settings/settings-manager.js +18 -18
- package/ui-locales/de.json +2417 -2348
- package/ui-locales/en.json +2415 -2352
- package/ui-locales/es.json +2425 -2353
- package/ui-locales/fr.json +2418 -2348
- package/ui-locales/ja.json +2463 -2361
- package/ui-locales/ru.json +2463 -2359
- package/ui-locales/zh.json +2418 -2351
- package/utils/admin-auth.js +2 -2
- package/utils/admin-cli.js +297 -297
- package/utils/admin-pin.js +9 -9
- package/utils/cli-helper.js +9 -9
- package/utils/config-helper.js +73 -104
- package/utils/config-manager.js +204 -171
- package/utils/config.js +5 -4
- package/utils/env-manager.js +249 -263
- package/utils/framework-detector.js +27 -24
- package/utils/i18n-helper.js +85 -41
- package/utils/init-helper.js +152 -94
- package/utils/json-output.js +98 -98
- package/utils/mini-commander.js +179 -0
- package/utils/missing-key-validator.js +5 -5
- package/utils/plugin-loader.js +40 -29
- package/utils/prompt.js +14 -44
- package/utils/safe-json.js +40 -0
- package/utils/secure-errors.js +3 -3
- package/utils/security-check-improved.js +390 -0
- package/utils/security-config.js +5 -5
- package/utils/security-fixed.js +607 -0
- package/utils/security.js +652 -602
- package/utils/setup-enforcer.js +136 -44
- package/utils/setup-validator.js +33 -32
- package/utils/ultra-performance-optimizer.js +11 -9
- package/utils/watch-locales.js +2 -1
- package/utils/prompt-fixed.js +0 -55
- package/utils/security-check.js +0 -454
package/main/i18ntk-js.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* i18ntk JavaScript/TypeScript Command
|
|
5
5
|
* Specialized command for JavaScript and TypeScript i18n management
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* Usage: i18ntk-js [options]
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ const SecurityUtils = require(path.join(__dirname, '../utils/security.js'));
|
|
|
13
13
|
const { getConfig, saveConfig } = require(path.join(__dirname, '../utils/config-helper.js'));
|
|
14
14
|
const I18nHelper = require(path.join(__dirname, '../utils/i18n-helper.js'));
|
|
15
15
|
const SetupEnforcer = require(path.join(__dirname, '../utils/setup-enforcer'));
|
|
16
|
-
const { program } = require('commander');
|
|
16
|
+
const { program } = require('../utils/mini-commander');
|
|
17
17
|
|
|
18
18
|
(async () => {
|
|
19
19
|
try {
|
|
@@ -37,29 +37,29 @@ class I18ntkJavaScriptCommand {
|
|
|
37
37
|
/intl\.formatMessage\s*\(\s*{[^}]*id:\s*["'`]([^"'`]+)["'`]/g,
|
|
38
38
|
/useTranslations?\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
39
39
|
/getTranslations?\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
// React patterns
|
|
42
42
|
/FormattedMessage\s+id=["'`]([^"'`]+)["'`]/g,
|
|
43
43
|
/<FormattedMessage[^>]*id={["'`]([^"'`]+)["'`]}/g,
|
|
44
44
|
/useTranslation\(\)\s*\.t\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
// Angular patterns
|
|
47
47
|
/translate\s*\|\s*translate/g,
|
|
48
48
|
/\{\{\s*["'`]([^"'`]+)["'`]\s*\|\s*translate\s*}}/g,
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
// Vue patterns
|
|
51
51
|
/\$t\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
52
52
|
/this\.\$t\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
// Node.js patterns
|
|
55
55
|
/__\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
56
56
|
/gettext\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
// Template literal patterns
|
|
59
59
|
/i18n\.t\s*\(\s*`([^`]+)`/g,
|
|
60
60
|
/t\s*\(\s*`([^`]+)`/g
|
|
61
61
|
];
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
this.frameworks = {
|
|
64
64
|
react: {
|
|
65
65
|
indicators: ['package.json', 'react', 'react-dom'],
|
|
@@ -82,7 +82,7 @@ class I18ntkJavaScriptCommand {
|
|
|
82
82
|
|
|
83
83
|
async init() {
|
|
84
84
|
console.log('š§ Initializing i18ntk JavaScript/TypeScript command...');
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
program
|
|
87
87
|
.name('i18ntk-js')
|
|
88
88
|
.description('i18ntk specialized for JavaScript and TypeScript applications')
|
|
@@ -104,13 +104,13 @@ class I18ntkJavaScriptCommand {
|
|
|
104
104
|
this.options = program.opts();
|
|
105
105
|
this.sourceDir = path.resolve(this.options.sourceDir);
|
|
106
106
|
this.localesDir = path.resolve(this.options.localesDir);
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
await this.validateSourceDir();
|
|
109
109
|
await this.loadConfig();
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
async validateSourceDir() {
|
|
113
|
-
if (!
|
|
113
|
+
if (!SecurityUtils.safeExistsSync(this.sourceDir, path.dirname(this.sourceDir))) {
|
|
114
114
|
console.error(`ā Source directory not found: ${this.sourceDir}`);
|
|
115
115
|
process.exit(1);
|
|
116
116
|
}
|
|
@@ -137,16 +137,17 @@ class I18ntkJavaScriptCommand {
|
|
|
137
137
|
if (this.options.vue) return 'vue';
|
|
138
138
|
if (this.options.angular) return 'angular';
|
|
139
139
|
if (this.options.node) return 'node';
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
console.log('š Detecting JavaScript framework...');
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
let framework = 'generic';
|
|
144
144
|
|
|
145
145
|
try {
|
|
146
146
|
const packageJsonPath = path.join(this.sourceDir, 'package.json');
|
|
147
|
-
if (
|
|
148
|
-
const
|
|
149
|
-
|
|
147
|
+
if (SecurityUtils.safeExistsSync(packageJsonPath, this.sourceDir)) {
|
|
148
|
+
const packageJsonContent = SecurityUtils.safeReadFileSync(packageJsonPath, this.sourceDir, 'utf8');
|
|
149
|
+
const packageJson = SecurityUtils.safeParseJSON(packageJsonContent);
|
|
150
|
+
|
|
150
151
|
const dependencies = {
|
|
151
152
|
...packageJson.dependencies || {},
|
|
152
153
|
...packageJson.devDependencies || {}
|
|
@@ -183,72 +184,72 @@ class I18ntkJavaScriptCommand {
|
|
|
183
184
|
findFiles(pattern, extensions = []) {
|
|
184
185
|
const results = [];
|
|
185
186
|
const validExtensions = extensions.length > 0 ? extensions : ['.js', '.jsx', '.ts', '.tsx'];
|
|
186
|
-
|
|
187
|
+
|
|
187
188
|
function scanDir(dir) {
|
|
188
|
-
if (!
|
|
189
|
-
|
|
189
|
+
if (!SecurityUtils.safeExistsSync(dir, path.dirname(dir))) return;
|
|
190
|
+
|
|
190
191
|
const items = fs.readdirSync(dir);
|
|
191
192
|
for (const item of items) {
|
|
192
193
|
const fullPath = path.join(dir, item);
|
|
193
194
|
const stat = fs.statSync(fullPath);
|
|
194
|
-
|
|
195
|
+
|
|
195
196
|
if (stat.isDirectory()) {
|
|
196
197
|
// Skip node_modules and hidden directories
|
|
197
198
|
if (item === 'node_modules' || item.startsWith('.')) continue;
|
|
198
|
-
|
|
199
|
+
|
|
199
200
|
// Skip test directories unless explicitly included
|
|
200
|
-
if (!this.options.includeTests &&
|
|
201
|
+
if (!this.options.includeTests &&
|
|
201
202
|
(item === '__tests__' || item === 'test' || item === 'tests' || item.includes('.test.'))) {
|
|
202
203
|
continue;
|
|
203
204
|
}
|
|
204
|
-
|
|
205
|
+
|
|
205
206
|
scanDir.call(this, fullPath);
|
|
206
207
|
} else {
|
|
207
208
|
// Check file extension
|
|
208
209
|
const ext = path.extname(item);
|
|
209
210
|
if (validExtensions.includes(ext)) {
|
|
210
211
|
// Skip test files unless explicitly included
|
|
211
|
-
if (!this.options.includeTests &&
|
|
212
|
+
if (!this.options.includeTests &&
|
|
212
213
|
(item.includes('.test.') || item.includes('.spec.') || item.includes('__test__'))) {
|
|
213
214
|
continue;
|
|
214
215
|
}
|
|
215
|
-
|
|
216
|
+
|
|
216
217
|
results.push(fullPath);
|
|
217
218
|
}
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
|
-
|
|
222
|
+
|
|
222
223
|
scanDir.call(this, this.sourceDir);
|
|
223
224
|
return results;
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
async extractTranslations() {
|
|
227
228
|
console.log('š¦ Extracting JavaScript/TypeScript translations...');
|
|
228
|
-
|
|
229
|
-
const extensions = this.options.typescript
|
|
230
|
-
? ['.js', '.jsx', '.ts', '.tsx']
|
|
229
|
+
|
|
230
|
+
const extensions = this.options.typescript
|
|
231
|
+
? ['.js', '.jsx', '.ts', '.tsx']
|
|
231
232
|
: ['.js', '.jsx'];
|
|
232
|
-
|
|
233
|
+
|
|
233
234
|
const jsFiles = this.findFiles('', extensions);
|
|
234
235
|
const translations = new Set();
|
|
235
|
-
|
|
236
|
+
|
|
236
237
|
for (const file of jsFiles) {
|
|
237
238
|
try {
|
|
238
|
-
const content =
|
|
239
|
-
|
|
239
|
+
const content = SecurityUtils.safeReadFileSync(file, path.dirname(file), 'utf8');
|
|
240
|
+
|
|
240
241
|
for (const pattern of this.jsPatterns) {
|
|
241
242
|
let match;
|
|
242
243
|
while ((match = pattern.exec(content)) !== null) {
|
|
243
244
|
translations.add(match[1]);
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
|
-
|
|
247
|
+
|
|
247
248
|
// Reset regex state for next file
|
|
248
249
|
for (const pattern of this.jsPatterns) {
|
|
249
250
|
pattern.lastIndex = 0;
|
|
250
251
|
}
|
|
251
|
-
|
|
252
|
+
|
|
252
253
|
} catch (error) {
|
|
253
254
|
if (this.options.debug) {
|
|
254
255
|
console.error(`Error reading ${file}:`, error.message);
|
|
@@ -261,28 +262,28 @@ class I18ntkJavaScriptCommand {
|
|
|
261
262
|
}
|
|
262
263
|
|
|
263
264
|
async createLocaleStructure() {
|
|
264
|
-
if (!
|
|
265
|
+
if (!SecurityUtils.safeExistsSync(this.localesDir, path.dirname(this.localesDir))) {
|
|
265
266
|
if (this.options.dryRun) {
|
|
266
267
|
console.log(`š Would create directory: ${this.localesDir}`);
|
|
267
268
|
return;
|
|
268
269
|
}
|
|
269
|
-
|
|
270
|
+
|
|
270
271
|
fs.mkdirSync(this.localesDir, { recursive: true });
|
|
271
272
|
console.log(`š Created locales directory: ${this.localesDir}`);
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
const languages = ['en', 'es', 'fr', 'de', 'ja', 'ru', 'zh'];
|
|
275
|
-
|
|
276
|
+
|
|
276
277
|
for (const lang of languages) {
|
|
277
278
|
const langDir = path.join(this.localesDir, lang);
|
|
278
|
-
if (!
|
|
279
|
+
if (!SecurityUtils.safeExistsSync(langDir, this.localesDir)) {
|
|
279
280
|
if (this.options.dryRun) {
|
|
280
281
|
console.log(`š Would create directory: ${langDir}`);
|
|
281
282
|
continue;
|
|
282
283
|
}
|
|
283
|
-
|
|
284
|
+
|
|
284
285
|
fs.mkdirSync(langDir, { recursive: true });
|
|
285
|
-
|
|
286
|
+
|
|
286
287
|
// Create framework-specific translation files
|
|
287
288
|
const commonFile = path.join(langDir, 'common.json');
|
|
288
289
|
const initialContent = {
|
|
@@ -306,21 +307,21 @@ class I18ntkJavaScriptCommand {
|
|
|
306
307
|
}
|
|
307
308
|
}
|
|
308
309
|
};
|
|
309
|
-
|
|
310
|
-
|
|
310
|
+
|
|
311
|
+
SecurityUtils.safeWriteFileSync(commonFile, JSON.stringify(initialContent, null, 2), this.localesDir);
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
}
|
|
314
315
|
|
|
315
316
|
async analyzeFramework(framework) {
|
|
316
317
|
console.log(`š Analyzing ${framework} project...`);
|
|
317
|
-
|
|
318
|
-
const extensions = this.options.typescript
|
|
319
|
-
? ['.js', '.jsx', '.ts', '.tsx']
|
|
318
|
+
|
|
319
|
+
const extensions = this.options.typescript
|
|
320
|
+
? ['.js', '.jsx', '.ts', '.tsx']
|
|
320
321
|
: ['.js', '.jsx'];
|
|
321
|
-
|
|
322
|
+
|
|
322
323
|
const jsFiles = this.findFiles('', extensions);
|
|
323
|
-
|
|
324
|
+
|
|
324
325
|
const analysis = {
|
|
325
326
|
framework,
|
|
326
327
|
typescript: this.options.typescript || false,
|
|
@@ -358,14 +359,14 @@ class I18ntkJavaScriptCommand {
|
|
|
358
359
|
else if (ext === '.ts') analysis.files.typescript++;
|
|
359
360
|
else if (ext === '.jsx') analysis.files.jsx++;
|
|
360
361
|
else if (ext === '.tsx') analysis.files.tsx++;
|
|
361
|
-
|
|
362
|
+
|
|
362
363
|
if (file.includes('.test.') || file.includes('.spec.')) {
|
|
363
364
|
analysis.files.test++;
|
|
364
365
|
}
|
|
365
366
|
|
|
366
367
|
try {
|
|
367
|
-
const content =
|
|
368
|
-
|
|
368
|
+
const content = SecurityUtils.safeReadFileSync(file, path.dirname(file), 'utf8');
|
|
369
|
+
|
|
369
370
|
// Check patterns
|
|
370
371
|
if (content.includes('i18n.t(')) analysis.patterns.i18n_t++;
|
|
371
372
|
if (content.includes('t(')) analysis.patterns.t_function++;
|
|
@@ -374,7 +375,7 @@ class I18ntkJavaScriptCommand {
|
|
|
374
375
|
if (content.includes('translate')) analysis.patterns.translate++;
|
|
375
376
|
if (content.includes('$t(')) analysis.patterns.$t++;
|
|
376
377
|
if (content.includes('gettext(')) analysis.patterns.gettext++;
|
|
377
|
-
|
|
378
|
+
|
|
378
379
|
// Detect frameworks
|
|
379
380
|
if (content.includes('import React') || content.includes('require("react")')) {
|
|
380
381
|
analysis.frameworks.react = true;
|
|
@@ -388,7 +389,7 @@ class I18ntkJavaScriptCommand {
|
|
|
388
389
|
if (content.includes('express') || content.includes('node')) {
|
|
389
390
|
analysis.frameworks.node = true;
|
|
390
391
|
}
|
|
391
|
-
|
|
392
|
+
|
|
392
393
|
} catch (error) {
|
|
393
394
|
// Skip unreadable files
|
|
394
395
|
}
|
|
@@ -398,11 +399,11 @@ class I18ntkJavaScriptCommand {
|
|
|
398
399
|
if (analysis.files.total > 0 && analysis.patterns.i18n_t === 0) {
|
|
399
400
|
analysis.recommendations.push('Consider adding i18n support to your JavaScript/TypeScript files');
|
|
400
401
|
}
|
|
401
|
-
|
|
402
|
+
|
|
402
403
|
if (analysis.frameworks.react && analysis.patterns.FormattedMessage === 0) {
|
|
403
404
|
analysis.recommendations.push('Consider using react-intl or react-i18next for React i18n');
|
|
404
405
|
}
|
|
405
|
-
|
|
406
|
+
|
|
406
407
|
if (analysis.frameworks.vue && analysis.patterns.$t === 0) {
|
|
407
408
|
analysis.recommendations.push('Consider using vue-i18n for Vue.js i18n');
|
|
408
409
|
}
|
|
@@ -410,10 +411,11 @@ class I18ntkJavaScriptCommand {
|
|
|
410
411
|
// Check package.json for dependencies
|
|
411
412
|
try {
|
|
412
413
|
const packageJsonPath = path.join(this.sourceDir, 'package.json');
|
|
413
|
-
if (
|
|
414
|
-
const
|
|
414
|
+
if (SecurityUtils.safeExistsSync(packageJsonPath, this.sourceDir)) {
|
|
415
|
+
const packageJsonContent = SecurityUtils.safeReadFileSync(packageJsonPath, this.sourceDir, 'utf8');
|
|
416
|
+
const packageJson = SecurityUtils.safeParseJSON(packageJsonContent);
|
|
415
417
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
416
|
-
|
|
418
|
+
|
|
417
419
|
for (const [pkg, version] of Object.entries(deps)) {
|
|
418
420
|
if (pkg.includes('i18n') || pkg.includes('intl') || pkg.includes('translate')) {
|
|
419
421
|
analysis.dependencies.push(`${pkg}@${version}`);
|
|
@@ -455,12 +457,12 @@ class I18ntkJavaScriptCommand {
|
|
|
455
457
|
};
|
|
456
458
|
|
|
457
459
|
const reportPath = path.join(this.sourceDir, 'i18ntk-js-report.json');
|
|
458
|
-
|
|
460
|
+
|
|
459
461
|
if (this.options.dryRun) {
|
|
460
462
|
console.log(`š Would create report: ${reportPath}`);
|
|
461
463
|
console.log('š Report contents:', JSON.stringify(report, null, 2));
|
|
462
464
|
} else {
|
|
463
|
-
|
|
465
|
+
SecurityUtils.safeWriteFileSync(reportPath, JSON.stringify(report, null, 2), this.sourceDir);
|
|
464
466
|
console.log(`š Report saved: ${reportPath}`);
|
|
465
467
|
}
|
|
466
468
|
|
|
@@ -469,19 +471,19 @@ class I18ntkJavaScriptCommand {
|
|
|
469
471
|
|
|
470
472
|
async run() {
|
|
471
473
|
try {
|
|
472
|
-
console.log('š i18ntk JavaScript/TypeScript Command v1.10.1');
|
|
473
|
-
console.log('='
|
|
474
|
-
|
|
474
|
+
console.log('š i18ntk JavaScript/TypeScript Command v1.10.1');
|
|
475
|
+
console.log('='.repeat(60));
|
|
476
|
+
|
|
475
477
|
await this.init();
|
|
476
|
-
|
|
478
|
+
|
|
477
479
|
const framework = await this.detectFramework();
|
|
478
480
|
const translations = await this.extractTranslations();
|
|
479
|
-
|
|
481
|
+
|
|
480
482
|
if (!this.options.extractOnly) {
|
|
481
483
|
await this.createLocaleStructure();
|
|
482
484
|
const analysis = await this.analyzeFramework(framework);
|
|
483
485
|
const report = await this.generateReport(analysis, translations);
|
|
484
|
-
|
|
486
|
+
|
|
485
487
|
console.log('\nā
Analysis complete!');
|
|
486
488
|
console.log(`š Framework: ${framework}`);
|
|
487
489
|
console.log(`š Total files: ${analysis.files.total}`);
|
|
@@ -490,7 +492,7 @@ class I18ntkJavaScriptCommand {
|
|
|
490
492
|
} else {
|
|
491
493
|
console.log(`š¦ Extracted ${translations.length} translation keys`);
|
|
492
494
|
}
|
|
493
|
-
|
|
495
|
+
|
|
494
496
|
} catch (error) {
|
|
495
497
|
console.error('ā Error:', error.message);
|
|
496
498
|
if (this.options.debug) {
|
|
@@ -507,4 +509,4 @@ if (require.main === module) {
|
|
|
507
509
|
cmd.run();
|
|
508
510
|
}
|
|
509
511
|
|
|
510
|
-
module.exports = I18ntkJavaScriptCommand;
|
|
512
|
+
module.exports = I18ntkJavaScriptCommand;
|