i18ntk 1.10.1 → 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.
Files changed (110) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +141 -1185
  3. package/main/i18ntk-analyze.js +149 -133
  4. package/main/i18ntk-backup-class.js +420 -0
  5. package/main/i18ntk-backup.js +4 -4
  6. package/main/i18ntk-complete.js +90 -65
  7. package/main/i18ntk-doctor.js +123 -103
  8. package/main/i18ntk-fixer.js +61 -725
  9. package/main/i18ntk-go.js +14 -15
  10. package/main/i18ntk-init.js +76 -25
  11. package/main/i18ntk-java.js +27 -32
  12. package/main/i18ntk-js.js +70 -68
  13. package/main/i18ntk-manage.js +128 -29
  14. package/main/i18ntk-php.js +75 -75
  15. package/main/i18ntk-py.js +55 -56
  16. package/main/i18ntk-scanner.js +59 -57
  17. package/main/i18ntk-setup.js +10 -396
  18. package/main/i18ntk-sizing.js +46 -40
  19. package/main/i18ntk-summary.js +21 -18
  20. package/main/i18ntk-ui.js +11 -10
  21. package/main/i18ntk-usage.js +55 -19
  22. package/main/i18ntk-validate.js +13 -13
  23. package/main/manage/commands/AnalyzeCommand.js +1124 -0
  24. package/main/manage/commands/BackupCommand.js +62 -0
  25. package/main/manage/commands/CommandRouter.js +295 -0
  26. package/main/manage/commands/CompleteCommand.js +61 -0
  27. package/main/manage/commands/DoctorCommand.js +60 -0
  28. package/main/manage/commands/FixerCommand.js +624 -0
  29. package/main/manage/commands/InitCommand.js +62 -0
  30. package/main/manage/commands/ScannerCommand.js +654 -0
  31. package/main/manage/commands/SizingCommand.js +60 -0
  32. package/main/manage/commands/SummaryCommand.js +61 -0
  33. package/main/manage/commands/UsageCommand.js +60 -0
  34. package/main/manage/commands/ValidateCommand.js +978 -0
  35. package/main/manage/index-fixed.js +1447 -0
  36. package/main/manage/index.js +1462 -0
  37. package/main/manage/managers/DebugMenu.js +140 -0
  38. package/main/manage/managers/InteractiveMenu.js +177 -0
  39. package/main/manage/managers/LanguageMenu.js +62 -0
  40. package/main/manage/managers/SettingsMenu.js +53 -0
  41. package/main/manage/services/AuthenticationService.js +263 -0
  42. package/main/manage/services/ConfigurationService-fixed.js +449 -0
  43. package/main/manage/services/ConfigurationService.js +449 -0
  44. package/main/manage/services/FileManagementService.js +368 -0
  45. package/main/manage/services/FrameworkDetectionService.js +458 -0
  46. package/main/manage/services/InitService.js +1051 -0
  47. package/main/manage/services/SetupService.js +462 -0
  48. package/main/manage/services/SummaryService.js +450 -0
  49. package/main/manage/services/UsageService.js +1502 -0
  50. package/package.json +32 -30
  51. package/runtime/enhanced.d.ts +221 -221
  52. package/runtime/index.d.ts +29 -29
  53. package/runtime/index.full.d.ts +331 -331
  54. package/runtime/index.js +7 -6
  55. package/scripts/build-lite.js +17 -17
  56. package/scripts/deprecate-versions.js +23 -6
  57. package/scripts/export-translations.js +5 -5
  58. package/scripts/fix-all-i18n.js +3 -3
  59. package/scripts/fix-and-purify-i18n.js +3 -2
  60. package/scripts/fix-locale-control-chars.js +110 -0
  61. package/scripts/lint-locales.js +80 -0
  62. package/scripts/locale-optimizer.js +8 -8
  63. package/scripts/prepublish.js +21 -21
  64. package/scripts/security-check.js +13 -5
  65. package/scripts/sync-translations.js +4 -4
  66. package/scripts/sync-ui-locales.js +9 -8
  67. package/scripts/validate-all-translations.js +8 -7
  68. package/scripts/verify-deprecations.js +23 -15
  69. package/scripts/verify-translations.js +6 -5
  70. package/settings/i18ntk-config.json +282 -282
  71. package/settings/language-config.json +5 -5
  72. package/settings/settings-cli.js +9 -9
  73. package/settings/settings-manager.js +23 -20
  74. package/ui-locales/de.json +2417 -2348
  75. package/ui-locales/en.json +2415 -2352
  76. package/ui-locales/es.json +2425 -2353
  77. package/ui-locales/fr.json +2418 -2348
  78. package/ui-locales/ja.json +2463 -2361
  79. package/ui-locales/ru.json +2463 -2359
  80. package/ui-locales/zh.json +2418 -2351
  81. package/utils/admin-auth.js +2 -2
  82. package/utils/admin-cli.js +297 -297
  83. package/utils/admin-pin.js +9 -9
  84. package/utils/cli-helper.js +9 -9
  85. package/utils/config-helper.js +152 -103
  86. package/utils/config-manager.js +204 -164
  87. package/utils/config.js +5 -4
  88. package/utils/env-manager.js +256 -0
  89. package/utils/framework-detector.js +27 -24
  90. package/utils/i18n-helper.js +85 -41
  91. package/utils/init-helper.js +152 -94
  92. package/utils/json-output.js +98 -98
  93. package/utils/logger.js +6 -2
  94. package/utils/mini-commander.js +179 -0
  95. package/utils/missing-key-validator.js +5 -5
  96. package/utils/plugin-loader.js +29 -11
  97. package/utils/prompt.js +14 -44
  98. package/utils/safe-json.js +40 -0
  99. package/utils/secure-errors.js +3 -3
  100. package/utils/security-check-improved.js +390 -0
  101. package/utils/security-config.js +5 -5
  102. package/utils/security-fixed.js +607 -0
  103. package/utils/security.js +462 -248
  104. package/utils/setup-enforcer.js +136 -44
  105. package/utils/setup-validator.js +33 -32
  106. package/utils/terminal-icons.js +1 -1
  107. package/utils/ultra-performance-optimizer.js +11 -9
  108. package/utils/watch-locales.js +2 -1
  109. package/utils/prompt-fixed.js +0 -55
  110. package/utils/security-check.js +0 -450
@@ -30,7 +30,7 @@ class PrepublishCleaner {
30
30
  // Essential files that must exist for release
31
31
  this.essentialFiles = [
32
32
  'package.json',
33
- 'main/i18ntk-manage.js',
33
+ 'main/manage/index.js',
34
34
  'main/i18ntk-init.js',
35
35
  'main/i18ntk-analyze.js',
36
36
  'main/i18ntk-validate.js',
@@ -49,13 +49,13 @@ class PrepublishCleaner {
49
49
 
50
50
  // Essential locale files
51
51
  this.essentialLocales = [
52
- 'ui-locales/en.json',
53
- 'ui-locales/es.json',
54
- 'ui-locales/fr.json',
55
- 'ui-locales/de.json',
56
- 'ui-locales/ja.json',
57
- 'ui-locales/ru.json',
58
- 'ui-locales/zh.json'
52
+ 'resources/i18n/ui-locales/en.json',
53
+ 'resources/i18n/ui-locales/es.json',
54
+ 'resources/i18n/ui-locales/fr.json',
55
+ 'resources/i18n/ui-locales/de.json',
56
+ 'resources/i18n/ui-locales/ja.json',
57
+ 'resources/i18n/ui-locales/ru.json',
58
+ 'resources/i18n/ui-locales/zh.json'
59
59
  ];
60
60
  }
61
61
 
@@ -95,7 +95,7 @@ class PrepublishCleaner {
95
95
  }
96
96
 
97
97
  async cleanDirectory(dirPath) {
98
- if (!fs.existsSync(dirPath)) {
98
+ if (!SecurityUtils.safeExistsSync(dirPath)) {
99
99
  return;
100
100
  }
101
101
 
@@ -138,7 +138,7 @@ class PrepublishCleaner {
138
138
  const dir = path.dirname(searchPath);
139
139
  const filenamePattern = path.basename(searchPath);
140
140
 
141
- if (fs.existsSync(dir)) {
141
+ if (SecurityUtils.safeExistsSync(dir)) {
142
142
  const files = fs.readdirSync(dir);
143
143
  const regex = new RegExp(filenamePattern.replace('*', '.*'));
144
144
 
@@ -152,7 +152,7 @@ class PrepublishCleaner {
152
152
  }
153
153
  } else {
154
154
  // Handle exact files
155
- if (fs.existsSync(searchPath)) {
155
+ if (SecurityUtils.safeExistsSync(searchPath)) {
156
156
  fs.unlinkSync(searchPath);
157
157
  this.log(`Deleted ${path.relative(this.projectRoot, searchPath)}`);
158
158
  }
@@ -165,7 +165,7 @@ class PrepublishCleaner {
165
165
  let missingFiles = [];
166
166
  for (const file of this.essentialFiles) {
167
167
  const filePath = path.join(this.projectRoot, file);
168
- if (!fs.existsSync(filePath)) {
168
+ if (!SecurityUtils.safeExistsSync(filePath)) {
169
169
  missingFiles.push(file);
170
170
  } else if (!fs.statSync(filePath).isFile()) {
171
171
  this.log(`❌ ${file} is not a file`);
@@ -187,13 +187,13 @@ class PrepublishCleaner {
187
187
  let invalidFiles = [];
188
188
  for (const localeFile of this.essentialLocales) {
189
189
  const filePath = path.join(this.projectRoot, localeFile);
190
- if (!fs.existsSync(filePath)) {
190
+ if (!SecurityUtils.safeExistsSync(filePath)) {
191
191
  invalidFiles.push(localeFile);
192
192
  continue;
193
193
  }
194
194
 
195
195
  try {
196
- const content = fs.readFileSync(filePath, 'utf8');
196
+ const content = SecurityUtils.safeReadFileSync(filePath, path.dirname(filePath), 'utf8');
197
197
  const parsed = JSON.parse(content);
198
198
 
199
199
  // Validate structure
@@ -224,7 +224,7 @@ class PrepublishCleaner {
224
224
 
225
225
  const packagePath = path.join(this.projectRoot, 'package.json');
226
226
  try {
227
- const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
227
+ const pkg = JSON.parse(SecurityUtils.safeReadFileSync(packagePath, path.dirname(packagePath), 'utf8'));
228
228
 
229
229
  // Validate required fields
230
230
  const requiredFields = ['name', 'version', 'description', 'main', 'bin', 'files'];
@@ -255,7 +255,7 @@ class PrepublishCleaner {
255
255
  }
256
256
 
257
257
  const binPath = path.join(this.projectRoot, pkg.bin[bin]);
258
- if (!fs.existsSync(binPath)) {
258
+ if (!SecurityUtils.safeExistsSync(binPath)) {
259
259
  this.log(`❌ Missing bin script: ${pkg.bin[bin]}`);
260
260
  process.exit(1);
261
261
  }
@@ -282,14 +282,14 @@ class PrepublishCleaner {
282
282
 
283
283
  for (const artifact of devArtifacts) {
284
284
  const artifactPath = path.join(this.projectRoot, artifact);
285
- if (fs.existsSync(artifactPath)) {
285
+ if (SecurityUtils.safeExistsSync(artifactPath)) {
286
286
  this.log(`⚠️ Development artifact found: ${artifact}`);
287
287
  }
288
288
  }
289
289
 
290
290
  // Validate file permissions for executable scripts
291
291
  const scripts = [
292
- 'main/i18ntk-manage.js',
292
+ 'main/manage/index.js',
293
293
  'main/i18ntk-init.js',
294
294
  'main/i18ntk-analyze.js',
295
295
  'main/i18ntk-validate.js',
@@ -303,7 +303,7 @@ class PrepublishCleaner {
303
303
 
304
304
  for (const script of scripts) {
305
305
  const scriptPath = path.join(this.projectRoot, script);
306
- if (fs.existsSync(scriptPath)) {
306
+ if (SecurityUtils.safeExistsSync(scriptPath)) {
307
307
  try {
308
308
  fs.accessSync(scriptPath, fs.constants.X_OK);
309
309
  } catch (e) {
@@ -318,7 +318,7 @@ class PrepublishCleaner {
318
318
  async resetSecuritySettings() {
319
319
  const configPath = path.join(require('../settings/settings-manager').configDir, '.i18n-admin-config.json');
320
320
 
321
- if (fs.existsSync(configPath)) {
321
+ if (SecurityUtils.safeExistsSync(configPath)) {
322
322
  const defaultConfig = {
323
323
  enabled: false,
324
324
  pinHash: null,
@@ -330,7 +330,7 @@ class PrepublishCleaner {
330
330
  lockedUntil: null
331
331
  };
332
332
 
333
- fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
333
+ SecurityUtils.safeWriteFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
334
334
  this.log('Reset security settings to defaults');
335
335
  }
336
336
  }
@@ -18,12 +18,13 @@ class SecurityCheck {
18
18
  /execFileSync\(/,
19
19
  /spawn\(/,
20
20
  /exec\(/,
21
- /execFile\(/
21
+ /execFile\(/
22
22
  ];
23
23
  this.allowedFiles = [
24
24
  'dev/', // Development files allowed to use child_process
25
25
  'benchmarks/', // Benchmark scripts
26
26
  'test/', // Test files
27
+ 'scripts/deprecate-versions.js', // Allowed to use child_process for npm commands
27
28
  'verify-package.js' // Package verification (development)
28
29
  ];
29
30
  this.violations = [];
@@ -52,7 +53,7 @@ class SecurityCheck {
52
53
  async checkDirectory(dir) {
53
54
  const dirPath = path.join(process.cwd(), dir);
54
55
 
55
- if (!fs.existsSync(dirPath)) {
56
+ if (!SecurityUtils.safeExistsSync(dirPath)) {
56
57
  return;
57
58
  }
58
59
 
@@ -81,7 +82,15 @@ class SecurityCheck {
81
82
  }
82
83
 
83
84
  async checkFile(filePath) {
84
- const content = fs.readFileSync(filePath, 'utf8');
85
+ const relativePath = path.relative(process.cwd(), filePath).replace(/\\/g, '/');
86
+
87
+ for (const allowed of this.allowedFiles) {
88
+ if (relativePath.startsWith(allowed)) {
89
+ return;
90
+ }
91
+ }
92
+
93
+ const content = SecurityUtils.safeReadFileSync(filePath, path.dirname(filePath), 'utf8');
85
94
  const lines = content.split('\n');
86
95
 
87
96
  for (let i = 0; i < lines.length; i++) {
@@ -89,7 +98,6 @@ class SecurityCheck {
89
98
 
90
99
  for (const pattern of this.forbiddenPatterns) {
91
100
  if (pattern.test(line)) {
92
- const relativePath = path.relative(process.cwd(), filePath);
93
101
  this.violations.push({
94
102
  file: relativePath,
95
103
  line: i + 1,
@@ -106,4 +114,4 @@ if (require.main === module) {
106
114
  check.run().catch(console.error);
107
115
  }
108
116
 
109
- module.exports = SecurityCheck;
117
+ module.exports = SecurityCheck;
@@ -14,7 +14,7 @@ const fs = require('fs');
14
14
  const path = require('path');
15
15
 
16
16
  // Configuration
17
- const UI_LOCALES_DIR = path.join(__dirname, '..', 'ui-locales');
17
+ const UI_LOCALES_DIR = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales');
18
18
  const ENGLISH_DIR = path.join(UI_LOCALES_DIR, 'en');
19
19
  const TARGET_LANGUAGES = ['de', 'es', 'fr', 'ru', 'ja']; // Exclude Chinese (zh) as it's fully translated
20
20
 
@@ -36,7 +36,7 @@ function getEnglishFiles() {
36
36
  */
37
37
  function readJsonFile(filePath) {
38
38
  try {
39
- const content = fs.readFileSync(filePath, 'utf8');
39
+ const content = SecurityUtils.safeReadFileSync(filePath, path.dirname(filePath), 'utf8');
40
40
  return JSON.parse(content);
41
41
  } catch (error) {
42
42
  console.error(`Error reading JSON file ${filePath}:`, error.message);
@@ -50,7 +50,7 @@ function readJsonFile(filePath) {
50
50
  function writeJsonFile(filePath, data) {
51
51
  try {
52
52
  const jsonString = JSON.stringify(data, null, 2);
53
- fs.writeFileSync(filePath, jsonString + '\n');
53
+ SecurityUtils.safeWriteFileSync(filePath, jsonString + '\n');
54
54
  return true;
55
55
  } catch (error) {
56
56
  console.error(`Error writing JSON file ${filePath}:`, error.message);
@@ -74,7 +74,7 @@ function syncLanguage(language) {
74
74
  const languageDir = path.join(UI_LOCALES_DIR, language);
75
75
 
76
76
  // Ensure language directory exists
77
- if (!fs.existsSync(languageDir)) {
77
+ if (!SecurityUtils.safeExistsSync(languageDir)) {
78
78
  fs.mkdirSync(languageDir, { recursive: true });
79
79
  }
80
80
 
@@ -1,19 +1,20 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const baseDir = path.join(__dirname, '..', 'ui-locales');
4
- const en = JSON.parse(fs.readFileSync(path.join(baseDir,'en.json'),'utf8'));
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const SecurityUtils = require('../utils/security');
4
+ const baseDir = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales');
5
+ const en = JSON.parse(SecurityUtils.safeReadFileSync(path.join(baseDir,'en.json'), baseDir, 'utf8'));
5
6
  function flatten(obj,pfx='',out={}){ for(const [k,v] of Object.entries(obj)){ const nk=pfx?`${pfx}.${k}`:k; if(v && typeof v==='object' && !Array.isArray(v)) flatten(v,nk,out); else out[nk]=v; } return out; }
6
7
  function unflatten(map){ const root={}; for(const [k,v] of Object.entries(map)){ const parts=k.split('.'); let cur=root; while(parts.length>1){ const p=parts.shift(); cur[p]=cur[p]||{}; cur=cur[p]; } cur[parts[0]]=v; } return root; }
7
8
  const enFlat = flatten(en);
8
9
  for (const file of fs.readdirSync(baseDir)) {
9
10
  if (!file.endsWith('.json') || file==='en.json') continue;
10
11
  const p = path.join(baseDir,file);
11
- const data = JSON.parse(fs.readFileSync(p,'utf8'));
12
+ const data = JSON.parse(SecurityUtils.safeReadFileSync(p, baseDir, 'utf8'));
12
13
  const flat = flatten(data);
13
14
  let changed = false;
14
15
  for (const [k,v] of Object.entries(enFlat)) {
15
16
  if (!(k in flat)) { flat[k] = v || 'NOT_TRANSLATED'; changed = true; }
16
17
  }
17
- if (changed) { fs.writeFileSync(p, JSON.stringify(unflatten(flat), null, 2)); }
18
- }
19
- console.log('UI locales synced.');
18
+ if (changed) { SecurityUtils.safeWriteFileSync(p, JSON.stringify(unflatten(flat), null, 2), path.dirname(p), 'utf8'); }
19
+ }
20
+ console.log('UI locales synced.');
@@ -15,8 +15,9 @@
15
15
  * --languages=en,de,es,fr,ru,ja,zh
16
16
  */
17
17
 
18
- const fs = require('fs');
19
- const path = require('path');
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+ const SecurityUtils = require('../utils/security');
20
21
 
21
22
  const argv = Object.fromEntries(
22
23
  process.argv.slice(2).map(a => {
@@ -25,13 +26,13 @@ const argv = Object.fromEntries(
25
26
  })
26
27
  );
27
28
 
28
- const I18N_DIR = path.resolve(argv['i18n-dir'] || './ui-locales');
29
+ const I18N_DIR = path.resolve(argv['i18n-dir'] || './resources/i18n/ui-locales');
29
30
  const LANGS = (argv.languages || 'en,de,es,fr,ru,ja,zh').split(',').map(s => s.trim());
30
31
  const MARKER = argv.marker || '⚠️ TRANSLATION NEEDED ⚠️';
31
32
 
32
33
  // ------------ helpers ------------
33
34
  function readJSON(p) {
34
- try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
35
+ try { return JSON.parse(SecurityUtils.safeReadFileSync(p, path.dirname(p), 'utf8')); }
35
36
  catch { return {}; }
36
37
  }
37
38
 
@@ -50,7 +51,7 @@ function flatten(obj, prefix = '') {
50
51
 
51
52
  function listLocaleFile(lang) {
52
53
  const file = path.join(I18N_DIR, `${lang}.json`);
53
- if (fs.existsSync(file)) return file;
54
+ if (SecurityUtils.safeExistsSync(file)) return file;
54
55
  throw new Error(`Locale file not found: ${file}`);
55
56
  }
56
57
 
@@ -124,7 +125,7 @@ function validate() {
124
125
  });
125
126
 
126
127
  const reportFile = path.join(I18N_DIR, 'validation-purity-report.json');
127
- fs.writeFileSync(reportFile, JSON.stringify(report, null, 2), 'utf8');
128
+ SecurityUtils.safeWriteFileSync(reportFile, JSON.stringify(report, null, 2), path.dirname(reportFile), 'utf8');
128
129
  console.log(`✅ Validation report saved: ${reportFile}`);
129
130
  console.log(` Review this file for full details of problematic keys.`);
130
131
  }
@@ -135,4 +136,4 @@ try {
135
136
  } catch (err) {
136
137
  console.error('❌ Validation failed:', err.message);
137
138
  process.exit(1);
138
- }
139
+ }
@@ -6,13 +6,12 @@
6
6
  * This script verifies that versions have been properly deprecated
7
7
  */
8
8
 
9
- const { execSync } = require('child_process');
10
9
  const fs = require('fs');
11
10
  const path = require('path');
12
11
 
13
12
  // Read package.json to get deprecation list
14
13
  const packageJsonPath = path.join(__dirname, '..', 'package.json');
15
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
14
+ const packageJson = JSON.parse(SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8'));
16
15
 
17
16
  console.log('🔍 i18ntk Deprecation Verification');
18
17
  console.log('=====================================');
@@ -21,10 +20,19 @@ console.log(`🎯 Current Version: ${packageJson.version}`);
21
20
  console.log('=====================================\n');
22
21
 
23
22
  // Get deprecation info for all versions
24
- function getDeprecationInfo() {
23
+ async function getDeprecationInfo() {
25
24
  try {
26
- const output = execSync('npm view i18ntk --json', { encoding: 'utf8' });
27
- const packageInfo = JSON.parse(output);
25
+ // Deprecation information is no longer fetched from npmjs.org
26
+ // This script now relies on local deprecation-config.json if available.
27
+ const deprecationConfigPath = path.join(__dirname, '..', 'deprecation-config.json');
28
+ let packageInfo = { versions: {} };
29
+
30
+ if (SecurityUtils.safeExistsSync(deprecationConfigPath)) {
31
+ packageInfo = JSON.parse(SecurityUtils.safeReadFileSync(deprecationConfigPath, path.dirname(deprecationConfigPath), 'utf8'));
32
+ } else {
33
+ console.warn('⚠️ deprecation-config.json not found. Cannot verify deprecations locally.');
34
+ return;
35
+ }
28
36
 
29
37
  if (packageInfo.versions) {
30
38
  const deprecatedVersions = [];
@@ -52,10 +60,10 @@ function getDeprecationInfo() {
52
60
  }
53
61
 
54
62
  // Main verification process
55
- function verifyDeprecations() {
63
+ async function verifyDeprecations() {
56
64
  console.log('📊 Checking deprecation status...\n');
57
65
 
58
- const deprecationInfo = getDeprecationInfo();
66
+ const deprecationInfo = await getDeprecationInfo();
59
67
 
60
68
  if (!deprecationInfo) {
61
69
  console.log('❌ Could not retrieve deprecation information');
@@ -131,19 +139,19 @@ function verifyDeprecations() {
131
139
  const args = process.argv.slice(2);
132
140
  if (args.includes('--help') || args.includes('-h')) {
133
141
  console.log(`
134
- i18ntk Deprecation Verification Script
142
+ i18ntk Deprecation Verification Script
135
143
 
136
- Usage:
137
- node scripts/verify-deprecations.js [options]
144
+ Usage:
145
+ node scripts/verify-deprecations.js [options]
138
146
 
139
- Description:
140
- This script verifies that i18ntk versions have been properly deprecated.
147
+ Description:
148
+ This script verifies that i18ntk versions have been properly deprecated.
141
149
 
142
- Examples:
143
- node scripts/verify-deprecations.js
150
+ Examples:
151
+ node scripts/verify-deprecations.js
144
152
  `);
145
153
  process.exit(0);
146
154
  }
147
155
 
148
156
  // Run verification
149
- verifyDeprecations();
157
+ verifyDeprecations();
@@ -1,12 +1,13 @@
1
- const fs = require('fs');
2
- const path = require('path');
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const SecurityUtils = require('../utils/security');
3
4
 
4
5
  // Load all language files
5
- const localesPath = path.join(__dirname, '../ui-locales');
6
+ const localesPath = path.join(__dirname, '../resources/i18n/ui-locales');
6
7
  const files = fs.readdirSync(localesPath).filter(file => file.endsWith('.json') && file !== 'en.json');
7
8
 
8
9
  // Load English as the base for comparison
9
- const enContent = JSON.parse(fs.readFileSync(path.join(localesPath, 'en.json'), 'utf8'));
10
+ const enContent = JSON.parse(SecurityUtils.safeReadFileSync(path.join(localesPath, 'en.json'), localesPath, 'utf8'));
10
11
 
11
12
  // Function to get all keys from an object
12
13
  function getAllKeys(obj, prefix = '') {
@@ -28,7 +29,7 @@ console.log('\n🔍 Verifying translation keys across all language files...\n');
28
29
  files.forEach(file => {
29
30
  const langCode = path.basename(file, '.json');
30
31
  const filePath = path.join(localesPath, file);
31
- const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
32
+ const content = JSON.parse(SecurityUtils.safeReadFileSync(filePath, localesPath, 'utf8'));
32
33
  const langKeys = new Set(getAllKeys(content));
33
34
 
34
35
  // Find missing keys