i18ntk 2.1.0 → 2.3.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 (73) hide show
  1. package/README.md +87 -50
  2. package/main/i18ntk-analyze.js +63 -63
  3. package/main/i18ntk-backup-class.js +37 -41
  4. package/main/i18ntk-backup.js +28 -30
  5. package/main/i18ntk-complete.js +75 -74
  6. package/main/i18ntk-doctor.js +7 -6
  7. package/main/i18ntk-fixer.js +3 -3
  8. package/main/i18ntk-init.js +49 -13
  9. package/main/i18ntk-scanner.js +2 -2
  10. package/main/i18ntk-sizing.js +36 -37
  11. package/main/i18ntk-summary.js +4 -4
  12. package/main/i18ntk-ui.js +95 -96
  13. package/main/i18ntk-usage.js +31 -19
  14. package/main/i18ntk-validate.js +78 -27
  15. package/main/manage/commands/AnalyzeCommand.js +71 -73
  16. package/main/manage/commands/CommandRouter.js +15 -12
  17. package/main/manage/commands/FixerCommand.js +94 -38
  18. package/main/manage/commands/ScannerCommand.js +2 -2
  19. package/main/manage/commands/ValidateCommand.js +87 -36
  20. package/main/manage/index.js +165 -152
  21. package/main/manage/managers/DebugMenu.js +6 -6
  22. package/main/manage/managers/InteractiveMenu.js +6 -6
  23. package/main/manage/managers/LanguageMenu.js +12 -6
  24. package/main/manage/managers/SettingsMenu.js +6 -6
  25. package/main/manage/services/AuthenticationService.js +5 -6
  26. package/main/manage/services/ConfigurationService.js +22 -34
  27. package/main/manage/services/FileManagementService.js +6 -6
  28. package/main/manage/services/InitService.js +44 -8
  29. package/main/manage/services/UsageService.js +24 -12
  30. package/package.json +21 -42
  31. package/settings/settings-cli.js +5 -5
  32. package/settings/settings-manager.js +984 -968
  33. package/ui-locales/de.json +12 -11
  34. package/ui-locales/en.json +12 -11
  35. package/ui-locales/es.json +12 -11
  36. package/ui-locales/fr.json +12 -11
  37. package/ui-locales/ja.json +12 -11
  38. package/ui-locales/ru.json +12 -11
  39. package/ui-locales/zh.json +12 -11
  40. package/utils/config-helper.js +27 -16
  41. package/utils/config-manager.js +8 -7
  42. package/utils/i18n-helper.js +161 -166
  43. package/utils/init-helper.js +3 -2
  44. package/utils/json-output.js +11 -10
  45. package/{scripts → utils}/locale-optimizer.js +61 -60
  46. package/utils/logger.js +4 -4
  47. package/utils/safe-json.js +3 -3
  48. package/utils/secure-backup.js +8 -7
  49. package/utils/setup-enforcer.js +63 -98
  50. package/main/i18ntk-go.js +0 -283
  51. package/main/i18ntk-java.js +0 -380
  52. package/main/i18ntk-js.js +0 -512
  53. package/main/i18ntk-manage.js +0 -1694
  54. package/main/i18ntk-php.js +0 -462
  55. package/main/i18ntk-py.js +0 -379
  56. package/main/i18ntk-settings.js +0 -23
  57. package/main/manage/index-fixed.js +0 -1447
  58. package/scripts/build-lite.js +0 -279
  59. package/scripts/deprecate-versions.js +0 -317
  60. package/scripts/export-translations.js +0 -84
  61. package/scripts/fix-all-i18n.js +0 -236
  62. package/scripts/fix-and-purify-i18n.js +0 -233
  63. package/scripts/fix-locale-control-chars.js +0 -110
  64. package/scripts/lint-locales.js +0 -80
  65. package/scripts/prepublish-dev.js +0 -221
  66. package/scripts/prepublish.js +0 -362
  67. package/scripts/security-check.js +0 -117
  68. package/scripts/sync-translations.js +0 -151
  69. package/scripts/sync-ui-locales.js +0 -20
  70. package/scripts/validate-all-translations.js +0 -195
  71. package/scripts/verify-deprecations.js +0 -157
  72. package/scripts/verify-translations.js +0 -63
  73. package/utils/security-fixed.js +0 -609
@@ -1,151 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Translation Sync Script
5
- *
6
- * This script completely replaces all foreign language UI translation files with English content,
7
- * except for Chinese (zh) which is already fully translated.
8
- * This shows engineers exactly what needs to be translated without any prefixes.
9
- *
10
- * Usage: node scripts/sync-translations.js
11
- */
12
-
13
- const fs = require('fs');
14
- const path = require('path');
15
-
16
- // Configuration
17
- const UI_LOCALES_DIR = path.join(__dirname, '..', 'resources', 'i18n', 'ui-locales');
18
- const ENGLISH_DIR = path.join(UI_LOCALES_DIR, 'en');
19
- const TARGET_LANGUAGES = ['de', 'es', 'fr', 'ru', 'ja']; // Exclude Chinese (zh) as it's fully translated
20
-
21
- /**
22
- * Get all JSON files in the English directory
23
- */
24
- function getEnglishFiles() {
25
- try {
26
- const files = fs.readdirSync(ENGLISH_DIR);
27
- return files.filter(file => file.endsWith('.json'));
28
- } catch (error) {
29
- console.error('Error reading English directory:', error.message);
30
- return [];
31
- }
32
- }
33
-
34
- /**
35
- * Read and parse JSON file
36
- */
37
- function readJsonFile(filePath) {
38
- try {
39
- const content = SecurityUtils.safeReadFileSync(filePath, path.dirname(filePath), 'utf8');
40
- return JSON.parse(content);
41
- } catch (error) {
42
- console.error(`Error reading JSON file ${filePath}:`, error.message);
43
- return {};
44
- }
45
- }
46
-
47
- /**
48
- * Write JSON file with proper formatting
49
- */
50
- function writeJsonFile(filePath, data) {
51
- try {
52
- const jsonString = JSON.stringify(data, null, 2);
53
- SecurityUtils.safeWriteFileSync(filePath, jsonString + '\n');
54
- return true;
55
- } catch (error) {
56
- console.error(`Error writing JSON file ${filePath}:`, error.message);
57
- return false;
58
- }
59
- }
60
-
61
- /**
62
- * Copy English content directly to target language
63
- */
64
- function copyEnglishContent(source) {
65
- return JSON.parse(JSON.stringify(source)); // Deep copy of English content
66
- }
67
-
68
- /**
69
- * Sync translations for a specific language - completely replace with English
70
- */
71
- function syncLanguage(language) {
72
- console.log(`šŸ”„ Syncing translations for ${language}...`);
73
-
74
- const languageDir = path.join(UI_LOCALES_DIR, language);
75
-
76
- // Ensure language directory exists
77
- if (!SecurityUtils.safeExistsSync(languageDir)) {
78
- fs.mkdirSync(languageDir, { recursive: true });
79
- }
80
-
81
- const englishFiles = getEnglishFiles();
82
- let syncedFiles = 0;
83
-
84
- for (const file of englishFiles) {
85
- const englishFilePath = path.join(ENGLISH_DIR, file);
86
- const targetFilePath = path.join(languageDir, file);
87
-
88
- const englishData = readJsonFile(englishFilePath);
89
-
90
- // Directly copy English content (no merging, no prefixes)
91
- const newData = copyEnglishContent(englishData);
92
-
93
- // Write updated file (completely replaces existing content)
94
- if (writeJsonFile(targetFilePath, newData)) {
95
- syncedFiles++;
96
- console.log(` āœ… ${file}: Replaced with English content`);
97
- }
98
- }
99
-
100
- console.log(`āœ… ${language}: Synced ${syncedFiles} files with English content`);
101
- return { language, syncedFiles };
102
- }
103
-
104
- /**
105
- * Main sync function
106
- */
107
- function syncAllTranslations() {
108
- console.log('šŸŒ Starting translation synchronization...');
109
- console.log(`šŸ“ Source: ${ENGLISH_DIR}`);
110
- console.log(`šŸŽÆ Target languages: ${TARGET_LANGUAGES.join(', ')}`);
111
- console.log(`ā„¹ļø Chinese (zh) skipped - already fully translated`);
112
- console.log('');
113
-
114
- const englishFiles = getEnglishFiles();
115
- if (englishFiles.length === 0) {
116
- console.error('āŒ No English translation files found!');
117
- process.exit(1);
118
- }
119
-
120
- console.log(`šŸ“‹ Found ${englishFiles.length} English files to sync:`);
121
- englishFiles.forEach(file => console.log(` šŸ“„ ${file}`));
122
- console.log('');
123
-
124
- const results = [];
125
- for (const language of TARGET_LANGUAGES) {
126
- const result = syncLanguage(language);
127
- results.push(result);
128
- }
129
-
130
- console.log('');
131
- console.log('šŸŽ‰ Translation synchronization completed!');
132
- console.log('');
133
- console.log('šŸ“Š Summary:');
134
- results.forEach(result => {
135
- console.log(` ${result.language}: ${result.syncedFiles} files updated`);
136
- });
137
-
138
- console.log('');
139
- console.log('šŸ’” Next steps:');
140
- console.log(' 1. All non-Chinese locales now contain English content');
141
- console.log(' 2. Engineers can see exactly what text needs translation');
142
- console.log(' 3. Translate each string to the target language');
143
- console.log(' 4. Follow the same practices as the Chinese locale');
144
- }
145
-
146
- // Run the sync
147
- if (require.main === module) {
148
- syncAllTranslations();
149
- }
150
-
151
- module.exports = { syncAllTranslations, syncLanguage };
@@ -1,20 +0,0 @@
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'));
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; }
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; }
8
- const enFlat = flatten(en);
9
- for (const file of fs.readdirSync(baseDir)) {
10
- if (!file.endsWith('.json') || file==='en.json') continue;
11
- const p = path.join(baseDir,file);
12
- const data = JSON.parse(SecurityUtils.safeReadFileSync(p, baseDir, 'utf8'));
13
- const flat = flatten(data);
14
- let changed = false;
15
- for (const [k,v] of Object.entries(enFlat)) {
16
- if (!(k in flat)) { flat[k] = v || 'NOT_TRANSLATED'; changed = true; }
17
- }
18
- if (changed) { SecurityUtils.safeWriteFileSync(p, JSON.stringify(unflatten(flat), null, 2), path.dirname(p), 'utf8'); }
19
- }
20
- console.log('UI locales synced.');
@@ -1,195 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * validate-all-translations.js
4
- * ----------------------------
5
- * Validates i18n translation files:
6
- * 1. All locales have same keys as English
7
- * 2. No missing or extra keys
8
- * 3. No placeholder markers
9
- * 4. No leftover country code prefixes in non-English locales
10
- * 5. Reports English-equal values in two buckets:
11
- * - raw: exact string equality with English
12
- * - actionable: likely untranslated user-facing text
13
- */
14
-
15
- const fs = require('fs');
16
- const path = require('path');
17
- const SecurityUtils = require('../utils/security');
18
-
19
- const argv = Object.fromEntries(
20
- process.argv.slice(2).map((a) => {
21
- const m = a.match(/^--([^=]+)(?:=(.*))?$/);
22
- return m ? [m[1], m[2] === undefined ? true : m[2]] : [a, true];
23
- })
24
- );
25
-
26
- const I18N_DIR = path.resolve(argv['i18n-dir'] || './resources/i18n/ui-locales');
27
- const LANGS = (argv.languages || 'en,de,es,fr,ru,ja,zh').split(',').map((s) => s.trim());
28
- const MARKER = argv.marker || 'TRANSLATION NEEDED';
29
- const SHARED_TERMS = new Set(['error', 'errors', 'no', 'yes', 'navigation', 'system', 'modular', 'long']);
30
-
31
- function readJSON(p) {
32
- try {
33
- const raw = SecurityUtils.safeReadFileSync(p, path.dirname(p), 'utf8');
34
- return raw ? JSON.parse(raw) : {};
35
- } catch {
36
- return {};
37
- }
38
- }
39
-
40
- function flatten(obj, prefix = '') {
41
- const out = {};
42
- if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
43
- for (const [k, v] of Object.entries(obj)) {
44
- const full = prefix ? `${prefix}.${k}` : k;
45
- Object.assign(out, flatten(v, full));
46
- }
47
- return out;
48
- }
49
- out[prefix] = obj;
50
- return out;
51
- }
52
-
53
- function listLocaleFile(lang) {
54
- const file = path.join(I18N_DIR, `${lang}.json`);
55
- if (SecurityUtils.safeExistsSync(file, path.dirname(file))) return file;
56
- throw new Error(`Locale file not found: ${file}`);
57
- }
58
-
59
- function isActionableEnglishLeftover(value) {
60
- if (typeof value !== 'string') return false;
61
- const v = value.trim();
62
- if (!v) return false;
63
-
64
- if (!/[A-Za-z]/.test(v)) return false;
65
- if (/^[=\-_*#\s]+$/.test(v)) return false;
66
- if (/^[ā€¢āœ…āŒāš ļøšŸ“„šŸ“šŸ”‘\s]+$/.test(v)) return false;
67
-
68
- if (/^[-•]?\s*\{[^}]+\}$/.test(v)) return false;
69
- if (/^\{[^}]+\}[:%\s]/.test(v)) return false;
70
- if (/^[a-z]+(?:_[a-z0-9]+)+$/i.test(v)) return false;
71
-
72
- if (/^(?:node|npm|npx|pnpm|yarn|i18ntk)\b/i.test(v)) return false;
73
- if (/^[A-Za-z]:\\/.test(v) || /^https?:\/\//i.test(v)) return false;
74
- if (v === '\\n') return false;
75
- if (/^[yn]$/i.test(v)) return false;
76
-
77
- const compact = v.replace(/[^\w]/g, '').toLowerCase();
78
- if (SHARED_TERMS.has(compact)) return false;
79
-
80
- const scrubbed = v
81
- .replace(/\{[^}]+\}/g, ' ')
82
- .replace(/`[^`]*`/g, ' ')
83
- .replace(/[ā€¢āœ…āŒāš ļøšŸ“„šŸ“šŸ”‘ā†’:()"'[\].,_/%-]/g, ' ')
84
- .replace(/\s+/g, ' ')
85
- .trim();
86
- if (!/[A-Za-z]/.test(scrubbed)) return false;
87
-
88
- const words = scrubbed.split(/\s+/).map((w) => w.toLowerCase()).filter(Boolean);
89
- const technicalWords = new Set([
90
- 'react',
91
- 'vue',
92
- 'nuxt',
93
- 'svelte',
94
- 'i18n',
95
- 'i18next',
96
- 'nuxtjs',
97
- 'index',
98
- 'displayname',
99
- 'current',
100
- 'filename',
101
- 'language',
102
- 'file',
103
- 'path',
104
- 'keypath',
105
- 'value',
106
- 'stepname',
107
- 'status',
108
- 'number',
109
- 'recommendation',
110
- 'message'
111
- ]);
112
- if (words.length > 0 && words.every((word) => technicalWords.has(word))) return false;
113
-
114
- return true;
115
- }
116
-
117
- function validate() {
118
- console.log(`Validating translations in: ${I18N_DIR}`);
119
- console.log(`Languages: ${LANGS.join(', ')}`);
120
- console.log('');
121
-
122
- const enFlat = flatten(readJSON(listLocaleFile('en')));
123
- const report = {};
124
-
125
- LANGS.forEach((lang) => {
126
- const langFile = listLocaleFile(lang);
127
- const flat = flatten(readJSON(langFile));
128
-
129
- const missing = [];
130
- const extra = [];
131
- const markers = [];
132
- const countryCodeLeftovers = [];
133
- const englishLeftovers = [];
134
- const actionableEnglishLeftovers = [];
135
-
136
- for (const k of Object.keys(enFlat)) {
137
- if (!(k in flat)) {
138
- missing.push(k);
139
- } else {
140
- const val = flat[k];
141
- if (typeof val === 'string') {
142
- if (val.includes(MARKER)) {
143
- markers.push(k);
144
- }
145
- if (lang !== 'en' && /^\[[A-Z]{2}\]/.test(val.trim())) {
146
- countryCodeLeftovers.push(k);
147
- }
148
- if (lang !== 'en' && val.trim() === enFlat[k]?.trim()) {
149
- englishLeftovers.push(k);
150
- if (isActionableEnglishLeftover(val)) {
151
- actionableEnglishLeftovers.push(k);
152
- }
153
- }
154
- }
155
- }
156
- }
157
-
158
- for (const k of Object.keys(flat)) {
159
- if (!(k in enFlat)) {
160
- extra.push(k);
161
- }
162
- }
163
-
164
- report[lang] = {
165
- missing,
166
- extra,
167
- markers,
168
- countryCodeLeftovers,
169
- englishLeftovers,
170
- actionableEnglishLeftovers
171
- };
172
-
173
- console.log(`${lang.toUpperCase()}:`);
174
- console.log(` Missing: ${missing.length}`);
175
- console.log(` Extra: ${extra.length}`);
176
- console.log(` Markers: ${markers.length}`);
177
- if (lang !== 'en') {
178
- console.log(` Country code leftovers: ${countryCodeLeftovers.length}`);
179
- console.log(` English leftovers (raw): ${englishLeftovers.length}`);
180
- console.log(` English leftovers (actionable): ${actionableEnglishLeftovers.length}`);
181
- }
182
- console.log('');
183
- });
184
-
185
- const reportFile = path.join(I18N_DIR, 'validation-purity-report.json');
186
- SecurityUtils.safeWriteFileSync(reportFile, JSON.stringify(report, null, 2), path.dirname(reportFile), 'utf8');
187
- console.log(`Validation report saved: ${reportFile}`);
188
- }
189
-
190
- try {
191
- validate();
192
- } catch (err) {
193
- console.error('Validation failed:', err.message);
194
- process.exit(1);
195
- }
@@ -1,157 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * i18ntk Deprecation Verification Script
5
- *
6
- * This script verifies that versions have been properly deprecated
7
- */
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
-
12
- // Read package.json to get deprecation list
13
- const packageJsonPath = path.join(__dirname, '..', 'package.json');
14
- const packageJson = JSON.parse(SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8'));
15
-
16
- console.log('šŸ” i18ntk Deprecation Verification');
17
- console.log('=====================================');
18
- console.log(`šŸ“¦ Package: ${packageJson.name}`);
19
- console.log(`šŸŽÆ Current Version: ${packageJson.version}`);
20
- console.log('=====================================\n');
21
-
22
- // Get deprecation info for all versions
23
- async function getDeprecationInfo() {
24
- try {
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
- }
36
-
37
- if (packageInfo.versions) {
38
- const deprecatedVersions = [];
39
- const activeVersions = [];
40
-
41
- // Check each version for deprecation
42
- for (const version of Object.keys(packageInfo.versions)) {
43
- const versionInfo = packageInfo.versions[version];
44
- if (versionInfo.deprecated) {
45
- deprecatedVersions.push({
46
- version,
47
- reason: versionInfo.deprecated
48
- });
49
- } else {
50
- activeVersions.push(version);
51
- }
52
- }
53
-
54
- return { deprecatedVersions, activeVersions };
55
- }
56
- } catch (error) {
57
- console.error('āŒ Failed to get deprecation info:', error.message);
58
- return null;
59
- }
60
- }
61
-
62
- // Main verification process
63
- async function verifyDeprecations() {
64
- console.log('šŸ“Š Checking deprecation status...\n');
65
-
66
- const deprecationInfo = await getDeprecationInfo();
67
-
68
- if (!deprecationInfo) {
69
- console.log('āŒ Could not retrieve deprecation information');
70
- return;
71
- }
72
-
73
- const { deprecatedVersions, activeVersions } = deprecationInfo;
74
- const currentVersion = packageJson.version;
75
- const deprecationList = packageJson.versionInfo.deprecations;
76
-
77
- console.log(`šŸ“ˆ Total Published Versions: ${deprecatedVersions.length + activeVersions.length}`);
78
- console.log(`āœ… Deprecated Versions: ${deprecatedVersions.length}`);
79
- console.log(`šŸ”„ Active Versions: ${activeVersions.length}`);
80
- console.log(`šŸŽÆ Current Version: ${currentVersion}`);
81
- console.log(`šŸ“‹ Expected Deprecations: ${deprecationList.length}`);
82
- console.log('');
83
-
84
- // Check if current version is active
85
- const currentVersionActive = activeVersions.includes(currentVersion);
86
- if (currentVersionActive) {
87
- console.log(`āœ… Current version ${currentVersion} is active (correct)`);
88
- } else {
89
- console.log(`āŒ Current version ${currentVersion} is not active (problem)`);
90
- }
91
-
92
- // Check deprecated versions
93
- console.log('\nšŸ“‹ Deprecated Versions:');
94
- if (deprecatedVersions.length > 0) {
95
- deprecatedVersions.forEach(({ version, reason }) => {
96
- console.log(` āŒ ${version}: ${reason}`);
97
- });
98
- } else {
99
- console.log(' (None)');
100
- }
101
-
102
- // Check active versions (should only be current version)
103
- console.log('\nšŸ”„ Active Versions:');
104
- if (activeVersions.length > 0) {
105
- activeVersions.forEach(version => {
106
- if (version === currentVersion) {
107
- console.log(` āœ… ${version} (current version - correct)`);
108
- } else {
109
- console.log(` āš ļø ${version} (should be deprecated)`);
110
- }
111
- });
112
- } else {
113
- console.log(' (None)');
114
- }
115
-
116
- // Summary
117
- console.log('\n=====================================');
118
- console.log('šŸŽÆ Verification Summary');
119
- console.log('=====================================');
120
-
121
- const expectedDeprecated = deprecationList.length;
122
- const actualDeprecated = deprecatedVersions.length;
123
- const successRate = expectedDeprecated > 0 ? (actualDeprecated / expectedDeprecated * 100).toFixed(1) : 0;
124
-
125
- console.log(`šŸ“Š Expected deprecated: ${expectedDeprecated}`);
126
- console.log(`šŸ“Š Actually deprecated: ${actualDeprecated}`);
127
- console.log(`šŸ“Š Success rate: ${successRate}%`);
128
-
129
- if (activeVersions.length === 1 && activeVersions[0] === currentVersion) {
130
- console.log('āœ… Status: All previous versions deprecated, current version active');
131
- } else {
132
- console.log('āš ļø Status: Some versions may still need deprecation');
133
- }
134
-
135
- console.log('=====================================');
136
- }
137
-
138
- // Handle command line arguments
139
- const args = process.argv.slice(2);
140
- if (args.includes('--help') || args.includes('-h')) {
141
- console.log(`
142
- i18ntk Deprecation Verification Script
143
-
144
- Usage:
145
- node scripts/verify-deprecations.js [options]
146
-
147
- Description:
148
- This script verifies that i18ntk versions have been properly deprecated.
149
-
150
- Examples:
151
- node scripts/verify-deprecations.js
152
- `);
153
- process.exit(0);
154
- }
155
-
156
- // Run verification
157
- verifyDeprecations();
@@ -1,63 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const SecurityUtils = require('../utils/security');
4
-
5
- // Load all language files
6
- const localesPath = path.join(__dirname, '../resources/i18n/ui-locales');
7
- const files = fs.readdirSync(localesPath).filter(file => file.endsWith('.json') && file !== 'en.json');
8
-
9
- // Load English as the base for comparison
10
- const enContent = JSON.parse(SecurityUtils.safeReadFileSync(path.join(localesPath, 'en.json'), localesPath, 'utf8'));
11
-
12
- // Function to get all keys from an object
13
- function getAllKeys(obj, prefix = '') {
14
- return Object.entries(obj).reduce((keys, [key, value]) => {
15
- const fullKey = prefix ? `${prefix}.${key}` : key;
16
- if (value && typeof value === 'object' && !Array.isArray(value)) {
17
- return [...keys, ...getAllKeys(value, fullKey)];
18
- }
19
- return [...keys, fullKey];
20
- }, []);
21
- }
22
-
23
- // Get all keys from English file
24
- const enKeys = new Set(getAllKeys(enContent));
25
-
26
- // Check each language file
27
- console.log('\nšŸ” Verifying translation keys across all language files...\n');
28
-
29
- files.forEach(file => {
30
- const langCode = path.basename(file, '.json');
31
- const filePath = path.join(localesPath, file);
32
- const content = JSON.parse(SecurityUtils.safeReadFileSync(filePath, localesPath, 'utf8'));
33
- const langKeys = new Set(getAllKeys(content));
34
-
35
- // Find missing keys
36
- const missingKeys = [...enKeys].filter(key => !langKeys.has(key));
37
-
38
- // Find extra keys (not in English)
39
- const extraKeys = [...langKeys].filter(key => !enKeys.has(key));
40
-
41
- console.log(`🌐 ${file}:`);
42
- console.log(` Total keys: ${langKeys.size}/${enKeys.size} (${Math.round((langKeys.size / enKeys.size) * 100)}%)`);
43
-
44
- if (missingKeys.length > 0) {
45
- console.log(` āŒ Missing ${missingKeys.length} keys:`);
46
- missingKeys.slice(0, 5).forEach(key => console.log(` - ${key}`));
47
- if (missingKeys.length > 5) console.log(` ...and ${missingKeys.length - 5} more`);
48
- }
49
-
50
- if (extraKeys.length > 0) {
51
- console.log(` āš ļø Found ${extraKeys.length} extra keys (not in English):`);
52
- extraKeys.slice(0, 3).forEach(key => console.log(` - ${key}`));
53
- if (extraKeys.length > 3) console.log(` ...and ${extraKeys.length - 3} more`);
54
- }
55
-
56
- if (missingKeys.length === 0 && extraKeys.length === 0) {
57
- console.log(' āœ… All keys match the English version!');
58
- }
59
-
60
- console.log('');
61
- });
62
-
63
- console.log('āœ… Verification complete!');