i18ntk 1.10.2 → 2.0.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/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/utils/cli-helper.js
CHANGED
|
@@ -145,9 +145,9 @@ function showFrameworkWarningOnce(ui) {
|
|
|
145
145
|
try {
|
|
146
146
|
const path = require('path');
|
|
147
147
|
const fs = require('fs');
|
|
148
|
-
const localePath = path.join(__dirname, '..', 'ui-locales', 'en.json');
|
|
149
|
-
if (
|
|
150
|
-
const translations = JSON.parse(
|
|
148
|
+
const localePath = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales', 'en.json');
|
|
149
|
+
if (SecurityUtils.safeExistsSync(localePath)) {
|
|
150
|
+
const translations = JSON.parse(SecurityUtils.safeReadFileSync(localePath, path.dirname(localePath), 'utf8'));
|
|
151
151
|
t = (key) => {
|
|
152
152
|
const keys = key.split('.');
|
|
153
153
|
let result = translations;
|
|
@@ -170,9 +170,9 @@ function showFrameworkWarningOnce(ui) {
|
|
|
170
170
|
const settings = settingsManager.loadSettings();
|
|
171
171
|
const currentLang = settings.uiLanguage || 'en';
|
|
172
172
|
|
|
173
|
-
const localePath = path.join(__dirname, '..', 'ui-locales', `${currentLang}.json`);
|
|
174
|
-
if (
|
|
175
|
-
const translations = JSON.parse(
|
|
173
|
+
const localePath = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales', `${currentLang}.json`);
|
|
174
|
+
if (SecurityUtils.safeExistsSync(localePath)) {
|
|
175
|
+
const translations = JSON.parse(SecurityUtils.safeReadFileSync(localePath, path.dirname(localePath), 'utf8'));
|
|
176
176
|
t = (key) => {
|
|
177
177
|
const keys = key.split('.');
|
|
178
178
|
let result = translations;
|
|
@@ -183,9 +183,9 @@ function showFrameworkWarningOnce(ui) {
|
|
|
183
183
|
};
|
|
184
184
|
} else {
|
|
185
185
|
// Fallback to English
|
|
186
|
-
const enLocalePath = path.join(__dirname, '..', 'ui-locales', 'en.json');
|
|
187
|
-
if (
|
|
188
|
-
const translations = JSON.parse(
|
|
186
|
+
const enLocalePath = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales', 'en.json');
|
|
187
|
+
if (SecurityUtils.safeExistsSync(enLocalePath)) {
|
|
188
|
+
const translations = JSON.parse(SecurityUtils.safeReadFileSync(enLocalePath, path.dirname(enLocalePath), 'utf8'));
|
|
189
189
|
t = (key) => {
|
|
190
190
|
const keys = key.split('.');
|
|
191
191
|
let result = translations;
|
package/utils/config-helper.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Configuration is managed through settings files only
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const configManager = require('./config-manager');
|
|
10
|
-
const SecurityUtils = require('./security');
|
|
11
|
-
const {loadTranslations} = require('./i18n-helper');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const configManager = require('./config-manager');
|
|
10
|
+
const SecurityUtils = require('./security');
|
|
11
|
+
const {loadTranslations} = require('./i18n-helper');
|
|
12
12
|
const SettingsManager = require('../settings/settings-manager');
|
|
13
13
|
const { envManager } = require('./env-manager');
|
|
14
14
|
const settingsManager = new SettingsManager();
|
|
@@ -49,7 +49,7 @@ async function getUnifiedConfig(scriptName, cliArgs = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
settingsDir = safeConfigDir;
|
|
51
51
|
const configFile = path.join(settingsDir, 'i18ntk-config.json');
|
|
52
|
-
cfg =
|
|
52
|
+
cfg = SecurityUtils.safeExistsSync(configFile) ? JSON.parse(SecurityUtils.safeReadFileSync(configFile, settingsDir, 'utf8')) : {};
|
|
53
53
|
projectRoot = settingsDir;
|
|
54
54
|
cfg.projectRoot = projectRoot;
|
|
55
55
|
cfg.sourceDir = path.resolve(projectRoot, toStr(cfg.sourceDir) || './locales');
|
|
@@ -108,7 +108,7 @@ async function getUnifiedConfig(scriptName, cliArgs = {}) {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// Auto-fix i18nDir if missing but sourceDir exists
|
|
111
|
-
if (!
|
|
111
|
+
if (!SecurityUtils.safeExistsSync(cfg.i18nDir) && SecurityUtils.safeExistsSync(cfg.sourceDir)) {
|
|
112
112
|
await configManager.updateConfig({ i18nDir: configManager.toRelative(cfg.sourceDir) });
|
|
113
113
|
cfg.i18nDir = cfg.sourceDir;
|
|
114
114
|
}
|
|
@@ -289,7 +289,7 @@ function parseCommonArgs(args) {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
if (!parsed.uiLanguage) {
|
|
292
|
-
const envLang = envManager.get('
|
|
292
|
+
const envLang = envManager.get('I18NTK_UI_LANGUAGE');
|
|
293
293
|
if (envLang && envLang !== 'en') {
|
|
294
294
|
parsed.uiLanguage = envLang;
|
|
295
295
|
}
|
|
@@ -371,7 +371,7 @@ function displayHelp(scriptName, additionalOptions = {}) {
|
|
|
371
371
|
console.log(`\nEnvironment Variables:`);
|
|
372
372
|
console.log(` I18NTK_LOG_LEVEL Logging level (error, warn, info, debug, silent)`);
|
|
373
373
|
console.log(` I18NTK_OUTDIR Output directory for reports`);
|
|
374
|
-
console.log(`
|
|
374
|
+
console.log(` I18NTK_UI_LANGUAGE UI language (en, de, es, fr, ru, ja, zh)`);
|
|
375
375
|
console.log(` I18NTK_SILENT Run in silent mode (true/false)`);
|
|
376
376
|
console.log(` I18NTK_DEBUG_LOCALES Enable debug logging for locale loading`);
|
|
377
377
|
console.log(` I18NTK_SOURCE_DIR Source directory for scanning`);
|
|
@@ -397,7 +397,11 @@ function displayHelp(scriptName, additionalOptions = {}) {
|
|
|
397
397
|
* @param {string} dirPath - Directory path
|
|
398
398
|
*/
|
|
399
399
|
function ensureDirectory(dirPath) {
|
|
400
|
-
if (!
|
|
400
|
+
if (!dirPath || typeof dirPath !== 'string') {
|
|
401
|
+
// Silently handle undefined or invalid paths to prevent security errors
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (!SecurityUtils.safeExistsSync(dirPath)) {
|
|
401
405
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
402
406
|
}
|
|
403
407
|
}
|
|
@@ -419,83 +423,35 @@ function displayPaths(cfg = {}) {
|
|
|
419
423
|
}
|
|
420
424
|
|
|
421
425
|
// Ensure project has been initialized with source language files
|
|
422
|
-
async function ensureInitialized(cfg) {
|
|
423
|
-
try {
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const langDir = path.join(sourceDir, sourceLanguage);
|
|
443
|
-
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
fs.writeFileSync(configPath, JSON.stringify({
|
|
452
|
-
initialized: true,
|
|
453
|
-
version: '1.8.3',
|
|
454
|
-
timestamp: new Date().toISOString(),
|
|
455
|
-
sourceDir: sourceDir,
|
|
456
|
-
sourceLanguage: sourceLanguage
|
|
457
|
-
}, null, 2));
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const nonInteractive = !process.stdin.isTTY;
|
|
462
|
-
|
|
463
|
-
if (nonInteractive) {
|
|
464
|
-
console.warn(`Missing source language files in ${langDir}. Running initialization...`);
|
|
465
|
-
await initializeSourceFiles(sourceDir, sourceLanguage);
|
|
466
|
-
|
|
467
|
-
// Mark initialization as complete
|
|
468
|
-
const initDir = path.dirname(configPath);
|
|
469
|
-
ensureDirectory(initDir);
|
|
470
|
-
fs.writeFileSync(configPath, JSON.stringify({
|
|
471
|
-
initialized: true,
|
|
472
|
-
version: '1.8.3',
|
|
473
|
-
timestamp: new Date().toISOString(),
|
|
474
|
-
sourceDir: sourceDir,
|
|
475
|
-
sourceLanguage: sourceLanguage
|
|
476
|
-
}, null, 2));
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const answer = await ask(`Source language files not found in ${langDir}. Run initialization now? (y/N) `);
|
|
481
|
-
const { closeGlobalReadline } = require('./cli');
|
|
482
|
-
closeGlobalReadline();
|
|
483
|
-
|
|
484
|
-
if (answer.trim().toLowerCase().startsWith('y')) {
|
|
485
|
-
await initializeSourceFiles(sourceDir, sourceLanguage);
|
|
486
|
-
|
|
487
|
-
// Mark initialization as complete
|
|
488
|
-
const initDir = path.dirname(configPath);
|
|
489
|
-
ensureDirectory(initDir);
|
|
490
|
-
fs.writeFileSync(configPath, JSON.stringify({
|
|
491
|
-
initialized: true,
|
|
492
|
-
version: '1.8.3',
|
|
493
|
-
timestamp: new Date().toISOString(),
|
|
494
|
-
sourceDir: sourceDir,
|
|
495
|
-
sourceLanguage: sourceLanguage
|
|
496
|
-
}, null, 2));
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
426
|
+
async function ensureInitialized(cfg) {
|
|
427
|
+
try {
|
|
428
|
+
const { checkInitialized } = require('./init-helper');
|
|
429
|
+
const sourceDir = cfg?.sourceDir || './locales';
|
|
430
|
+
const sourceLanguage = cfg?.sourceLanguage || 'en';
|
|
431
|
+
|
|
432
|
+
const { initialized } = await checkInitialized({ sourceDir, sourceLanguage });
|
|
433
|
+
if (initialized) {
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const nonInteractive = !process.stdin.isTTY;
|
|
438
|
+
|
|
439
|
+
if (nonInteractive) {
|
|
440
|
+
const langDir = path.join(sourceDir, sourceLanguage);
|
|
441
|
+
console.warn(`Missing source language files in ${langDir}. Running initialization...`);
|
|
442
|
+
await initializeSourceFiles(sourceDir, sourceLanguage);
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const langDir = path.join(sourceDir, sourceLanguage);
|
|
447
|
+
const answer = await ask(`Source language files not found in ${langDir}. Run initialization now? (y/N) `);
|
|
448
|
+
const { closeGlobalReadline } = require('./cli');
|
|
449
|
+
closeGlobalReadline();
|
|
450
|
+
|
|
451
|
+
if (answer.trim().toLowerCase().startsWith('y')) {
|
|
452
|
+
await initializeSourceFiles(sourceDir, sourceLanguage);
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
499
455
|
return false;
|
|
500
456
|
} catch (err) {
|
|
501
457
|
console.error(`Initialization check failed: ${err.message}`);
|
|
@@ -532,36 +488,49 @@ async function initializeSourceFiles(sourceDir, sourceLang) {
|
|
|
532
488
|
ensureDirectory(sourceDir);
|
|
533
489
|
|
|
534
490
|
// Write the default source language file
|
|
535
|
-
|
|
491
|
+
SecurityUtils.safeWriteFileSync(sourceFile, JSON.stringify(defaultContent, null, 2));
|
|
536
492
|
|
|
537
493
|
// Create directories for supported languages
|
|
538
494
|
const supportedLanguages = ['es', 'fr', 'de', 'ja', 'ru', 'zh', 'pt'];
|
|
539
495
|
|
|
540
496
|
supportedLanguages.forEach(lang => {
|
|
541
497
|
const langFile = path.join(sourceDir, `${lang}.json`);
|
|
542
|
-
if (!
|
|
498
|
+
if (!SecurityUtils.safeExistsSync(langFile)) {
|
|
543
499
|
// Create empty object structure for each language
|
|
544
500
|
const emptyStructure = {
|
|
545
501
|
app: {},
|
|
546
502
|
common: {},
|
|
547
503
|
navigation: {}
|
|
548
504
|
};
|
|
549
|
-
|
|
505
|
+
SecurityUtils.safeWriteFileSync(langFile, JSON.stringify(emptyStructure, null, 2));
|
|
550
506
|
}
|
|
551
507
|
});
|
|
552
508
|
|
|
553
|
-
// Create
|
|
554
|
-
const configFile = 'i18ntk-config
|
|
555
|
-
if (!
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
509
|
+
// Create v2 project config if it doesn't exist
|
|
510
|
+
const configFile = '.i18ntk-config';
|
|
511
|
+
if (!SecurityUtils.safeExistsSync(configFile)) {
|
|
512
|
+
const version = (() => {
|
|
513
|
+
try {
|
|
514
|
+
return require('../package.json').version;
|
|
515
|
+
} catch {
|
|
516
|
+
return '2.0.0';
|
|
517
|
+
}
|
|
518
|
+
})();
|
|
519
|
+
const defaultConfig = {
|
|
520
|
+
version,
|
|
521
|
+
sourceDir: sourceDir,
|
|
522
|
+
outputDir: "./i18ntk-reports",
|
|
523
|
+
defaultLanguage: sourceLang,
|
|
524
|
+
supportedLanguages: [sourceLang, 'es', 'fr', 'de', 'ja', 'ru', 'zh', 'pt'],
|
|
525
|
+
setup: {
|
|
526
|
+
completed: true,
|
|
527
|
+
completedAt: new Date().toISOString(),
|
|
528
|
+
version,
|
|
529
|
+
setupId: `setup_${Date.now()}`
|
|
530
|
+
},
|
|
531
|
+
security: {
|
|
532
|
+
adminPinEnabled: true,
|
|
533
|
+
sessionTimeout: 1800000,
|
|
565
534
|
maxFailedAttempts: 3
|
|
566
535
|
},
|
|
567
536
|
performance: {
|
|
@@ -570,7 +539,7 @@ async function initializeSourceFiles(sourceDir, sourceLang) {
|
|
|
570
539
|
batchSize: 1000
|
|
571
540
|
}
|
|
572
541
|
};
|
|
573
|
-
|
|
542
|
+
SecurityUtils.safeWriteFileSync(configFile, JSON.stringify(defaultConfig, null, 2));
|
|
574
543
|
}
|
|
575
544
|
}
|
|
576
545
|
|
|
@@ -586,4 +555,4 @@ module.exports = {
|
|
|
586
555
|
displayPaths,
|
|
587
556
|
ensureInitialized,
|
|
588
557
|
|
|
589
|
-
};
|
|
558
|
+
};
|