i18ntk 2.1.0 → 2.2.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.
Files changed (53) hide show
  1. package/README.md +10 -6
  2. package/main/i18ntk-analyze.js +63 -63
  3. package/main/i18ntk-complete.js +75 -74
  4. package/main/i18ntk-fixer.js +3 -3
  5. package/main/i18ntk-init.js +5 -5
  6. package/main/i18ntk-scanner.js +2 -2
  7. package/main/i18ntk-sizing.js +35 -35
  8. package/main/i18ntk-summary.js +4 -4
  9. package/main/i18ntk-ui.js +95 -96
  10. package/main/i18ntk-usage.js +14 -14
  11. package/main/i18ntk-validate.js +6 -5
  12. package/main/manage/commands/AnalyzeCommand.js +67 -67
  13. package/main/manage/commands/FixerCommand.js +2 -2
  14. package/main/manage/commands/ScannerCommand.js +2 -2
  15. package/main/manage/commands/ValidateCommand.js +9 -9
  16. package/main/manage/index.js +7 -4
  17. package/main/manage/managers/LanguageMenu.js +7 -2
  18. package/main/manage/services/UsageService.js +7 -7
  19. package/package.json +20 -41
  20. package/settings/settings-cli.js +3 -3
  21. package/ui-locales/de.json +12 -11
  22. package/ui-locales/en.json +12 -11
  23. package/ui-locales/es.json +12 -11
  24. package/ui-locales/fr.json +12 -11
  25. package/ui-locales/ja.json +12 -11
  26. package/ui-locales/ru.json +12 -11
  27. package/ui-locales/zh.json +12 -11
  28. package/utils/i18n-helper.js +161 -166
  29. package/{scripts → utils}/locale-optimizer.js +61 -60
  30. package/main/i18ntk-go.js +0 -283
  31. package/main/i18ntk-java.js +0 -380
  32. package/main/i18ntk-js.js +0 -512
  33. package/main/i18ntk-manage.js +0 -1694
  34. package/main/i18ntk-php.js +0 -462
  35. package/main/i18ntk-py.js +0 -379
  36. package/main/i18ntk-settings.js +0 -23
  37. package/main/manage/index-fixed.js +0 -1447
  38. package/scripts/build-lite.js +0 -279
  39. package/scripts/deprecate-versions.js +0 -317
  40. package/scripts/export-translations.js +0 -84
  41. package/scripts/fix-all-i18n.js +0 -236
  42. package/scripts/fix-and-purify-i18n.js +0 -233
  43. package/scripts/fix-locale-control-chars.js +0 -110
  44. package/scripts/lint-locales.js +0 -80
  45. package/scripts/prepublish-dev.js +0 -221
  46. package/scripts/prepublish.js +0 -362
  47. package/scripts/security-check.js +0 -117
  48. package/scripts/sync-translations.js +0 -151
  49. package/scripts/sync-ui-locales.js +0 -20
  50. package/scripts/validate-all-translations.js +0 -195
  51. package/scripts/verify-deprecations.js +0 -157
  52. package/scripts/verify-translations.js +0 -63
  53. package/utils/security-fixed.js +0 -609
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * I18n Sizing Analyzer
@@ -33,10 +33,12 @@
33
33
 
34
34
  const fs = require('fs');
35
35
  const path = require('path');
36
+ const { performance } = require('perf_hooks');
36
37
  const { loadTranslations, t } = require('../utils/i18n-helper');
37
38
  const configManager = require('../settings/settings-manager');
38
39
  const SecurityUtils = require('../utils/security');
39
40
  const { getUnifiedConfig } = require('../utils/config-helper');
41
+ const { logger } = require('../utils/logger');
40
42
  const { getGlobalReadline, closeGlobalReadline } = require('../utils/cli');
41
43
  const SetupEnforcer = require('../utils/setup-enforcer');
42
44
 
@@ -83,7 +85,7 @@ class I18nSizingAnalyzer {
83
85
 
84
86
  // Initialize i18n with UI language from config
85
87
  const uiLanguage = options.uiLanguage || config.uiLanguage || 'en';
86
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
88
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
87
89
  this.stats = {
88
90
  files: {},
89
91
  languages: {},
@@ -165,7 +167,7 @@ class I18nSizingAnalyzer {
165
167
 
166
168
  // Analyze file sizes
167
169
  analyzeFileSizes(files) {
168
- SecurityUtils.debugLog('info', t("sizing.analyzing_file_sizes"));
170
+ logger.info(t("sizing.analyzing_file_sizes"));
169
171
 
170
172
  files.forEach(({ language, file, path: filePath, files: langFiles }) => {
171
173
  if (langFiles) {
@@ -220,7 +222,7 @@ class I18nSizingAnalyzer {
220
222
 
221
223
  // Analyze translation content
222
224
  analyzeTranslationContent(files) {
223
- SecurityUtils.debugLog('info', t("sizing.analyzing_translation_content"));
225
+ logger.info(t("sizing.analyzing_translation_content"));
224
226
 
225
227
  files.forEach(({ language, path: filePath, files: langFiles }) => {
226
228
  try {
@@ -266,7 +268,7 @@ class I18nSizingAnalyzer {
266
268
  });
267
269
 
268
270
  } catch (error) {
269
- SecurityUtils.debugLog('error', t("sizing.failed_to_parse_language_error", { language, errorMessage: error.message }));
271
+ logger.error(t("sizing.failed_to_parse_language_error", { language, errorMessage: error.message }));
270
272
  }
271
273
  });
272
274
  }
@@ -316,14 +318,14 @@ class I18nSizingAnalyzer {
316
318
 
317
319
  // Generate size comparison analysis
318
320
  generateSizeComparison() {
319
- SecurityUtils.debugLog('info', t("sizing.generating_size_comparisons"));
321
+ logger.info(t("sizing.generating_size_comparisons"));
320
322
 
321
323
  const languages = Object.keys(this.stats.languages);
322
324
  const baseLanguage = languages[0]; // Use first language as baseline
323
325
 
324
326
  if (!baseLanguage) {
325
- SecurityUtils.debugLog('warn', t("sizing.no_languages_found_for_comparison"));
326
- return;
327
+ logger.warn(t("sizing.no_languages_found_for_comparison"));
328
+ return;
327
329
  }
328
330
 
329
331
  this.stats.summary = {
@@ -495,7 +497,7 @@ class I18nSizingAnalyzer {
495
497
  async generateHumanReadableReport() {
496
498
  if (!this.outputReport) return;
497
499
 
498
- SecurityUtils.debugLog('info', t("sizing.generating_detailed_report"));
500
+ logger.info(t("sizing.generating_detailed_report"));
499
501
 
500
502
  const validatedOutputDir = SecurityUtils.validatePath(this.outputDir, process.cwd());
501
503
  if (!validatedOutputDir) {
@@ -518,7 +520,7 @@ class I18nSizingAnalyzer {
518
520
  let textReport = this.generateTextReport(timestamp);
519
521
  const textSuccess = await SecurityUtils.safeWriteFile(textReportPath, textReport, process.cwd());
520
522
  if (textSuccess) {
521
- SecurityUtils.debugLog('info', t("sizing.human_report_saved", { reportPath: textReportPath }));
523
+ logger.info(t("sizing.human_report_saved", { reportPath: textReportPath }));
522
524
  }
523
525
 
524
526
  // Generate JSON for programmatic access
@@ -664,8 +666,8 @@ Generated: ${new Date().toISOString()}
664
666
 
665
667
  const success = await SecurityUtils.safeWriteFile(csvPath, csvContent, process.cwd());
666
668
  if (success) {
667
- SecurityUtils.debugLog('info', t("sizing.csv_report_saved_to", { csvPath }));
668
- SecurityUtils.logSecurityEvent('CSV report saved', 'info', { csvPath });
669
+ logger.info(t("sizing.csv_report_saved_to", { csvPath }));
670
+ SecurityUtils.logSecurityEvent('CSV report saved', 'info', { csvPath });
669
671
  } else {
670
672
  throw new Error(t("sizing.failedToSaveCsvError"));
671
673
  }
@@ -673,21 +675,20 @@ Generated: ${new Date().toISOString()}
673
675
 
674
676
  // Main analysis method
675
677
  async analyze() {
676
- const perfTimer = SecurityUtils.getPerformanceTimer();
677
- const startTime = perfTimer.now();
678
+ const startTime = performance.now();
678
679
 
679
680
  try {
680
- SecurityUtils.debugLog('info', t("sizing.starting_i18n_sizing_analysis"));
681
- SecurityUtils.debugLog('info', t("sizing.source_directory", { sourceDir: this.sourceDir }));
681
+ logger.info(t("sizing.starting_i18n_sizing_analysis"));
682
+ logger.info(t("sizing.source_directory", { sourceDir: this.sourceDir }));
682
683
 
683
684
  const files = this.getLanguageFiles();
684
685
 
685
686
  if (files.length === 0) {
686
- SecurityUtils.debugLog('warn', t("sizing.no_translation_files_found"));
687
- return;
687
+ logger.warn(t("sizing.no_translation_files_found"));
688
+ return;
688
689
  }
689
690
 
690
- SecurityUtils.debugLog('info', t("sizing.found_languages", { languages: files.map(f => f.language).join(', ') }));
691
+ logger.info(t("sizing.found_languages", { languages: files.map(f => f.language).join(', ') }));
691
692
 
692
693
  this.analyzeFileSizes(files);
693
694
  this.analyzeTranslationContent(files);
@@ -696,17 +697,17 @@ Generated: ${new Date().toISOString()}
696
697
  if (this.format === 'table') {
697
698
  this.displayFolderResults();
698
699
  } else if (this.format === 'json') {
699
- SecurityUtils.debugLog('info', t("sizing.analysisStats", { stats: JSON.stringify(this.stats, null, 2) }));
700
+ logger.info(t("sizing.analysisStats", { stats: JSON.stringify(this.stats, null, 2) }));
700
701
  }
701
702
 
702
703
  await this.generateHumanReadableReport();
703
704
 
704
- const endTime = perfTimer.now();
705
- SecurityUtils.debugLog('info', t("sizing.analysis_completed", { duration: (endTime - startTime).toFixed(2) }));
705
+ const endTime = performance.now();
706
+ logger.info(t("sizing.analysis_completed", { duration: (endTime - startTime).toFixed(2) }));
706
707
 
707
708
  } catch (error) {
708
- SecurityUtils.debugLog('error', t("sizing.analysis_failed", { errorMessage: error.message }));
709
- process.exit(1);
709
+ logger.error(t("sizing.analysis_failed", { errorMessage: error.message }));
710
+ process.exit(1);
710
711
  }
711
712
  }
712
713
 
@@ -906,20 +907,19 @@ Options:
906
907
  // Main analysis method
907
908
  async analyze() {
908
909
  try {
909
- SecurityUtils.debugLog('info', t("sizing.starting_analysis"));
910
- SecurityUtils.debugLog('info', t("sizing.source_directory", { sourceDir: this.sourceDir }));
910
+ logger.info(t("sizing.starting_analysis"));
911
+ logger.info(t("sizing.source_directory", { sourceDir: this.sourceDir }));
911
912
 
912
- const perfTimer = SecurityUtils.getPerformanceTimer();
913
- const startTime = perfTimer.now();
913
+ const startTime = performance.now();
914
914
 
915
915
  // Get language files
916
916
  const files = this.getLanguageFiles();
917
917
  if (files.length === 0) {
918
- SecurityUtils.debugLog('warn', t("sizing.no_translation_files_found"));
919
- return { success: false, error: "No translation files found" };
918
+ logger.warn(t("sizing.no_translation_files_found"));
919
+ return { success: false, error: "No translation files found" };
920
920
  }
921
921
 
922
- SecurityUtils.debugLog('info', t("sizing.found_files", { count: files.length }));
922
+ logger.info(t("sizing.found_files", { count: files.length }));
923
923
 
924
924
  // Analyze file sizes
925
925
  this.analyzeFileSizes(files);
@@ -936,16 +936,16 @@ Options:
936
936
  // Generate reports if requested
937
937
  await this.generateHumanReadableReport();
938
938
 
939
- const endTime = perfTimer.now();
939
+ const endTime = performance.now();
940
940
  const duration = ((endTime - startTime) / 1000).toFixed(2);
941
941
 
942
- SecurityUtils.debugLog('info', t("sizing.analysis_completed", { duration }));
942
+ logger.info(t("sizing.analysis_completed", { duration }));
943
943
 
944
944
  return { success: true, stats: this.stats };
945
945
 
946
946
  } catch (error) {
947
- SecurityUtils.debugLog('error', t("sizing.analysis_failed", { errorMessage: error.message }));
948
- return { success: false, error: error.message };
947
+ logger.error(t("sizing.analysis_failed", { errorMessage: error.message }));
948
+ return { success: false, error: error.message };
949
949
  }
950
950
  }
951
951
  }
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
@@ -19,7 +19,7 @@ const SetupEnforcer = require('../utils/setup-enforcer');
19
19
  }
20
20
  })();
21
21
 
22
- loadTranslations( 'en', path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
22
+ loadTranslations('en', path.resolve(__dirname, '..', 'ui-locales'));
23
23
 
24
24
 
25
25
  class I18nSummaryReporter {
@@ -54,7 +54,7 @@ class I18nSummaryReporter {
54
54
  this.config = baseConfig;
55
55
 
56
56
  const uiLanguage = this.config.uiLanguage || 'en';
57
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
57
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
58
58
 
59
59
  this.sourceDir = this.config.sourceDir;
60
60
 
@@ -831,7 +831,7 @@ class I18nSummaryReporter {
831
831
  this.config = { ...this.config, ...baseConfig };
832
832
 
833
833
  const uiLanguage = this.config.uiLanguage || 'en';
834
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
834
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
835
835
  if (!this.config.sourceDir) {
836
836
  this.config.sourceDir = this.detectI18nDirectory();
837
837
  }
package/main/i18ntk-ui.js CHANGED
@@ -11,13 +11,13 @@ const legacyConfigManager = require('../utils/config-manager');
11
11
  const { getIcon, isUnicodeSupported } = require('../utils/terminal-icons');
12
12
  const configManager = new SettingsManager();
13
13
 
14
- class UIi18n {
15
- constructor() {
16
- this.currentLanguage = 'en';
17
- this.translations = {};
18
- this.uiLocalesDir = this.resolveUiLocalesDir();
19
- this.availableLanguages = [];
20
- this.configFile = path.resolve(configManager.configFile);
14
+ class UIi18n {
15
+ constructor() {
16
+ this.currentLanguage = 'en';
17
+ this.translations = {};
18
+ this.uiLocalesDir = this.resolveUiLocalesDir();
19
+ this.availableLanguages = [];
20
+ this.configFile = path.resolve(configManager.configFile);
21
21
 
22
22
 
23
23
  // Initialize with safe defaults
@@ -25,13 +25,13 @@ this.translations = {};
25
25
  }
26
26
 
27
27
 
28
- initialize() {
29
- try {
30
- const config = configManager.loadSettings ? configManager.loadSettings() : configManager.getConfig ? configManager.getConfig() : {};
31
-
32
- // Use safe defaults if config is not available
33
- this.uiLocalesDir = this.resolveUiLocalesDir();
34
- this.availableLanguages = this.detectAvailableLanguages();
28
+ initialize() {
29
+ try {
30
+ const config = configManager.loadSettings ? configManager.loadSettings() : configManager.getConfig ? configManager.getConfig() : {};
31
+
32
+ // Use safe defaults if config is not available
33
+ this.uiLocalesDir = this.resolveUiLocalesDir();
34
+ this.availableLanguages = this.detectAvailableLanguages();
35
35
 
36
36
 
37
37
  const configuredLanguage = config?.language || config?.uiLanguage || 'en';
@@ -42,71 +42,70 @@ this.translations = {};
42
42
  } else {
43
43
  this.loadLanguage('en');
44
44
  }
45
- } catch (error) {
46
- console.warn('UIi18n: Failed to initialize with config, using defaults:', error.message);
47
- this.uiLocalesDir = this.resolveUiLocalesDir();
48
- this.availableLanguages = this.detectAvailableLanguages();
49
- this.loadLanguage('en');
50
- }
51
- }
52
-
53
- getValidationBase(targetPath) {
54
- const fallbackBase = path.resolve(__dirname, '..');
55
- if (!targetPath || typeof targetPath !== 'string') {
56
- return fallbackBase;
57
- }
58
-
59
- let current = path.resolve(path.dirname(targetPath));
60
- while (true) {
61
- try {
62
- if (fs.statSync(current).isDirectory()) {
63
- return current;
64
- }
65
- } catch (_) {
66
- // Continue walking up until an existing directory is found.
67
- }
68
-
69
- const parent = path.dirname(current);
70
- if (parent === current) {
71
- break;
72
- }
73
- current = parent;
74
- }
75
-
76
- return fallbackBase;
77
- }
78
-
79
- resolveUiLocalesDir() {
80
- const candidates = [
81
- path.resolve(__dirname, '..', 'ui-locales'),
82
- path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales')
83
- ];
84
-
85
- for (const candidate of candidates) {
86
- try {
87
- const stats = SecurityUtils.safeStatSync(candidate, this.getValidationBase(candidate));
88
- if (stats && stats.isDirectory()) {
89
- return candidate;
90
- }
91
- } catch (_) {
92
- // Try next candidate.
93
- }
94
- }
95
-
96
- return candidates[0];
97
- }
45
+ } catch (error) {
46
+ console.warn('UIi18n: Failed to initialize with config, using defaults:', error.message);
47
+ this.uiLocalesDir = this.resolveUiLocalesDir();
48
+ this.availableLanguages = this.detectAvailableLanguages();
49
+ this.loadLanguage('en');
50
+ }
51
+ }
52
+
53
+ getValidationBase(targetPath) {
54
+ const fallbackBase = path.resolve(__dirname, '..');
55
+ if (!targetPath || typeof targetPath !== 'string') {
56
+ return fallbackBase;
57
+ }
58
+
59
+ let current = path.resolve(path.dirname(targetPath));
60
+ while (true) {
61
+ try {
62
+ if (fs.statSync(current).isDirectory()) {
63
+ return current;
64
+ }
65
+ } catch (_) {
66
+ // Continue walking up until an existing directory is found.
67
+ }
68
+
69
+ const parent = path.dirname(current);
70
+ if (parent === current) {
71
+ break;
72
+ }
73
+ current = parent;
74
+ }
75
+
76
+ return fallbackBase;
77
+ }
78
+
79
+ resolveUiLocalesDir() {
80
+ const candidates = [
81
+ path.resolve(__dirname, '..', 'ui-locales')
82
+ ];
83
+
84
+ for (const candidate of candidates) {
85
+ try {
86
+ const stats = SecurityUtils.safeStatSync(candidate, this.getValidationBase(candidate));
87
+ if (stats && stats.isDirectory()) {
88
+ return candidate;
89
+ }
90
+ } catch (_) {
91
+ // Try next candidate.
92
+ }
93
+ }
94
+
95
+ return candidates[0];
96
+ }
98
97
  /**
99
98
  /**
100
99
  * Detect which UI locales are currently installed
101
100
  * @returns {string[]} Array of available language codes
102
101
  */
103
- detectAvailableLanguages() {
104
- const all = ['en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'];
105
- return all.filter(lang => {
106
- const filePath = path.join(this.uiLocalesDir, `${lang}.json`);
107
- return SecurityUtils.safeExistsSync(filePath, this.getValidationBase(filePath));
108
- });
109
- }
102
+ detectAvailableLanguages() {
103
+ const all = ['en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'];
104
+ return all.filter(lang => {
105
+ const filePath = path.join(this.uiLocalesDir, `${lang}.json`);
106
+ return SecurityUtils.safeExistsSync(filePath, this.getValidationBase(filePath));
107
+ });
108
+ }
110
109
 
111
110
  /**
112
111
  * Refresh the list of available languages and ensure current language is valid
@@ -137,13 +136,13 @@ this.translations = {};
137
136
  }
138
137
 
139
138
  try {
140
- // Primary: Use monolith JSON file (en.json, de.json, etc.)
141
- const monolithTranslationFile = path.join(this.uiLocalesDir, `${language}.json`);
142
-
143
- if (SecurityUtils.safeExistsSync(monolithTranslationFile, this.getValidationBase(monolithTranslationFile))) {
144
- try {
145
- const content = SecurityUtils.safeReadFileSync(monolithTranslationFile, path.dirname(monolithTranslationFile), 'utf8');
146
- const fullTranslations = JSON.parse(content);
139
+ // Primary: Use monolith JSON file (en.json, de.json, etc.)
140
+ const monolithTranslationFile = path.join(this.uiLocalesDir, `${language}.json`);
141
+
142
+ if (SecurityUtils.safeExistsSync(monolithTranslationFile, this.getValidationBase(monolithTranslationFile))) {
143
+ try {
144
+ const content = SecurityUtils.safeReadFileSync(monolithTranslationFile, path.dirname(monolithTranslationFile), 'utf8');
145
+ const fullTranslations = JSON.parse(content);
147
146
 
148
147
  // Flatten the nested structure for easier key access
149
148
  this.translations = this.flattenTranslations(fullTranslations);
@@ -157,14 +156,14 @@ this.translations = {};
157
156
  this.translations = {};
158
157
  }
159
158
  } else {
160
- // Fallback: Use folder-based structure if monolith file doesn't exist
161
- const langDir = path.join(this.uiLocalesDir, language);
162
-
163
- const langDirStats = SecurityUtils.safeStatSync(langDir, this.getValidationBase(langDir));
164
- if (langDirStats && langDirStats.isDirectory()) {
165
- const files = fs.readdirSync(langDir).filter(file => file.endsWith('.json'));
166
- if (debugEnabled) {
167
- console.log(`UI: Found files in ${langDir}: ${files.join(', ')}`);
159
+ // Fallback: Use folder-based structure if monolith file doesn't exist
160
+ const langDir = path.join(this.uiLocalesDir, language);
161
+
162
+ const langDirStats = SecurityUtils.safeStatSync(langDir, this.getValidationBase(langDir));
163
+ if (langDirStats && langDirStats.isDirectory()) {
164
+ const files = fs.readdirSync(langDir).filter(file => file.endsWith('.json'));
165
+ if (debugEnabled) {
166
+ console.log(`UI: Found files in ${langDir}: ${files.join(', ')}`);
168
167
  }
169
168
 
170
169
  for (const file of files) {
@@ -428,12 +427,12 @@ this.translations = {};
428
427
  * @param {object} replacements - Object with replacement values
429
428
  * @returns {string|null} English translation or null if not found
430
429
  */
431
- getEnglishFallback(keyPath, replacements = {}) {
432
- try {
433
- const englishFile = path.join(this.uiLocalesDir, 'en.json');
434
- if (SecurityUtils.safeExistsSync(englishFile, this.getValidationBase(englishFile))) {
435
- const englishContent = SecurityUtils.safeReadFileSync(englishFile, path.dirname(englishFile), 'utf8');
436
- const englishTranslations = JSON.parse(englishContent);
430
+ getEnglishFallback(keyPath, replacements = {}) {
431
+ try {
432
+ const englishFile = path.join(this.uiLocalesDir, 'en.json');
433
+ if (SecurityUtils.safeExistsSync(englishFile, this.getValidationBase(englishFile))) {
434
+ const englishContent = SecurityUtils.safeReadFileSync(englishFile, path.dirname(englishFile), 'utf8');
435
+ const englishTranslations = JSON.parse(englishContent);
437
436
 
438
437
  // Use the same flattening approach for consistency
439
438
  const flattenedEnglish = this.flattenTranslations(englishTranslations);
@@ -570,4 +569,4 @@ this.translations = {};
570
569
  }
571
570
 
572
571
  // Export the class, not a singleton instance
573
- module.exports = UIi18n;
572
+ module.exports = UIi18n;
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * I18NTK USAGE ANALYSIS TOOLKIT - Version 1.8.3
4
4
  *
@@ -55,7 +55,7 @@ const SetupEnforcer = require('../utils/setup-enforcer');
55
55
  }
56
56
  })();
57
57
 
58
- loadTranslations( 'en', path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
58
+ loadTranslations('en', path.resolve(__dirname, '..', 'ui-locales'));
59
59
 
60
60
  async function getConfig() {
61
61
  return await getUnifiedConfig('usage');
@@ -120,7 +120,7 @@ class I18nUsageAnalyzer {
120
120
 
121
121
  // Load translations for UI
122
122
  const uiLanguage = (this.config && this.config.uiLanguage) || 'en';
123
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
123
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
124
124
  const projectRoot = path.resolve(this.config.projectRoot || '.');
125
125
  const detected = detectFramework(projectRoot);
126
126
  if (detected) {
@@ -169,9 +169,9 @@ class I18nUsageAnalyzer {
169
169
  this.config.includeExtensions = ['.js', '.jsx', '.ts', '.tsx', '.py', '.pyx', '.pyi'];
170
170
  }
171
171
 
172
- await SecurityUtils.logSecurityEvent(t('usage.analyzerInitialized'), { component: 'i18ntk-usage' });
172
+ await SecurityUtils.logSecurityEvent(t('usage.analyzerInitialized'), 'info', { component: 'i18ntk-usage' });
173
173
  } catch (error) {
174
- await SecurityUtils.logSecurityEvent(t('usage.analyzerInitFailed'), { component: 'i18ntk-usage', error: error.message });
174
+ await SecurityUtils.logSecurityEvent(t('usage.analyzerInitFailed'), 'error', { component: 'i18ntk-usage', error: error.message });
175
175
  throw error;
176
176
  }
177
177
  }
@@ -276,7 +276,7 @@ class I18nUsageAnalyzer {
276
276
  }
277
277
  }
278
278
  } catch (error) {
279
- await SecurityUtils.logSecurityEvent(t('usage.translationDiscoveryError'), {
279
+ await SecurityUtils.logSecurityEvent(t('usage.translationDiscoveryError'), 'error', {
280
280
  component: 'i18ntk-usage',
281
281
  directory: currentDir,
282
282
  error: error.message
@@ -350,7 +350,7 @@ class I18nUsageAnalyzer {
350
350
  }
351
351
  }
352
352
  } catch (error) {
353
- await SecurityUtils.logSecurityEvent(t('usage.fileTraversalError'), {
353
+ await SecurityUtils.logSecurityEvent(t('usage.fileTraversalError'), 'error', {
354
354
  component: 'i18ntk-usage',
355
355
  directory: currentDir,
356
356
  error: error.message
@@ -393,7 +393,7 @@ class I18nUsageAnalyzer {
393
393
  this.config = { ...baseConfig, ...(this.config || {}) };
394
394
 
395
395
  const uiLanguage = (this.config && this.config.uiLanguage) || 'en';
396
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
396
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
397
397
  if (!Array.isArray(this.config.translationPatterns)) {
398
398
  this.config.translationPatterns = [
399
399
  /t\(['"`]([^'"`]+)['"`]/g,
@@ -614,7 +614,7 @@ class I18nUsageAnalyzer {
614
614
  } catch (error) {
615
615
  console.error(t('usage.analysisFailedError'), error.message);
616
616
  this.closeReadline();
617
- SecurityUtils.logSecurityEvent(t('usage.usageAnalysisFailed'), {
617
+ SecurityUtils.logSecurityEvent(t('usage.usageAnalysisFailed'), 'error', {
618
618
  component: 'i18ntk-usage',
619
619
  error: error.message
620
620
  });
@@ -740,7 +740,7 @@ Analysis Features (v1.8.3):
740
740
  if (isDebug) {
741
741
  console.error(error.stack);
742
742
  }
743
- await SecurityUtils.logSecurityEvent(t('usage.translationFileParseError'), {
743
+ await SecurityUtils.logSecurityEvent(t('usage.translationFileParseError'), 'error', {
744
744
  component: 'i18ntk-usage',
745
745
  file: fileInfo.filePath,
746
746
  error: error.message
@@ -748,7 +748,7 @@ Analysis Features (v1.8.3):
748
748
  }
749
749
  }
750
750
  } catch (error) {
751
- await SecurityUtils.logSecurityEvent(t('usage.translationKeysLoadError'), {
751
+ await SecurityUtils.logSecurityEvent(t('usage.translationKeysLoadError'), 'error', {
752
752
  component: 'i18ntk-usage',
753
753
  error: error.message
754
754
  });
@@ -1543,7 +1543,7 @@ Analysis Features (v1.8.3):
1543
1543
  await this.initialize();
1544
1544
  }
1545
1545
 
1546
- await SecurityUtils.logSecurityEvent('analysis_started', { component: 'i18ntk-usage' });
1546
+ await SecurityUtils.logSecurityEvent('analysis_started', 'info', { component: 'i18ntk-usage' });
1547
1547
 
1548
1548
  console.log(t('usage.checkUsage.title'));
1549
1549
  console.log(t("usage.checkUsage.message"));
@@ -1708,7 +1708,7 @@ Analysis Features (v1.8.3):
1708
1708
  outputLines.forEach(line => console.log(line));
1709
1709
  }
1710
1710
 
1711
- await SecurityUtils.logSecurityEvent('analysis_completed', {
1711
+ await SecurityUtils.logSecurityEvent('analysis_completed', 'info', {
1712
1712
  component: 'i18ntk-usage',
1713
1713
  stats: {
1714
1714
  availableKeys: this.availableKeys.size,
@@ -1749,7 +1749,7 @@ Analysis Features (v1.8.3):
1749
1749
  console.error(t("checkUsage.usage_analysis_failed"));
1750
1750
  console.error(error.message);
1751
1751
 
1752
- await SecurityUtils.logSecurityEvent('analysis_failed', {
1752
+ await SecurityUtils.logSecurityEvent('analysis_failed', 'error', {
1753
1753
  component: 'i18ntk-usage',
1754
1754
  error: error.message
1755
1755
  });
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * I18NTK TRANSLATION VALIDATION TOOLKIT
@@ -60,7 +60,7 @@ const SetupEnforcer = require('../utils/setup-enforcer');
60
60
  }
61
61
  })();
62
62
 
63
- loadTranslations( 'en', path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
63
+ loadTranslations('en', path.resolve(__dirname, '..', 'ui-locales'));
64
64
 
65
65
  class I18nValidator {
66
66
  constructor(config = {}) {
@@ -87,7 +87,7 @@ class I18nValidator {
87
87
  this.config = { ...baseConfig, ...(this.config || {}) };
88
88
 
89
89
  const uiLanguage = (this.config && this.config.uiLanguage) || 'en';
90
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
90
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
91
91
 
92
92
  SecurityUtils.logSecurityEvent(
93
93
  'I18n validator initializing',
@@ -892,7 +892,8 @@ class I18nValidator {
892
892
  this.config = { ...baseConfig, ...(this.config || {}) };
893
893
 
894
894
  const uiLanguage = (this.config && this.config.uiLanguage) || 'en';
895
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));this.sourceDir = this.config.sourceDir;
895
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
896
+ this.sourceDir = this.config.sourceDir;
896
897
  this.sourceLanguageDir = path.join(this.sourceDir, this.config.sourceLanguage);
897
898
  } else {
898
899
  await this.initialize();
@@ -983,7 +984,7 @@ if (require.main === module) {
983
984
  // Initialize translations for CLI usage
984
985
  const config = configManager.getConfig();
985
986
  const uiLanguage = config.language || 'en';
986
- loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'resources', 'i18n', 'ui-locales'));
987
+ loadTranslations(uiLanguage, path.resolve(__dirname, '..', 'ui-locales'));
987
988
 
988
989
  SecurityUtils.logSecurityEvent(t('validate.scriptExecution'), 'info', {
989
990
  script: 'i18ntk-validate.js',