i18ntk 1.6.1 β 1.6.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/README.md +21 -18
- package/main/i18ntk-analyze.js +1 -0
- package/main/i18ntk-autorun.js +1 -0
- package/main/i18ntk-complete.js +1 -0
- package/main/i18ntk-init.js +2 -1
- package/main/i18ntk-manage.js +3 -0
- package/main/i18ntk-sizing.js +1 -0
- package/main/i18ntk-summary.js +1 -0
- package/main/i18ntk-usage.js +1 -0
- package/main/i18ntk-validate.js +1 -0
- package/package.json +4 -7
- package/scripts/debug/README.md +33 -33
- package/scripts/debug/debug-translation.js +55 -55
- package/scripts/export-translations.js +83 -83
- package/scripts/locale-optimizer.js +425 -425
- package/scripts/path-utils.test.js +23 -0
- package/scripts/prepublish.js +149 -0
- package/scripts/reset-defaults.test.js +18 -0
- package/scripts/smoke-pack.js +59 -0
- package/scripts/test-runner.js +207 -0
- package/scripts/update-checker.js +224 -224
- package/scripts/validate-all-translations.js +137 -137
- package/settings/.i18n-admin-config.json +7 -0
- package/settings/i18ntk-config.json +219 -0
- package/settings/settings-cli.js +2 -0
- package/settings/settings-manager.js +2 -2
- package/ui-locales/en/common.json +5 -0
- package/utils/config-helper.js +4 -4
- package/utils/config-manager.js +1 -1
- package/utils/i18n-helper.js +134 -126
- package/utils/security-config.js +1 -1
- package/utils/security.js +2 -2
package/README.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
**Version:** 1.6.
|
|
6
|
-
**Last Updated:** 2025-08-
|
|
5
|
+
**Version:** 1.6.2
|
|
6
|
+
**Last Updated:** 2025-08-09
|
|
7
7
|
**GitHub Repository:** [vladnoskv/i18ntk](https://github.com/vladnoskv/i18ntk)
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/i18ntk) [](https://badge.fury.io/js/i18ntk) [](https://nodejs.org/) [](https://www.npmjs.com/package/i18ntk) [](https://github.com/vladnoskv/i18ntk)
|
|
10
10
|
|
|
11
|
+
> **π¨ Latest Update (v1.6.2)**: Critical npm package installation bug resolved from 1.6.0 and 1.6.1.
|
|
12
|
+
|
|
11
13
|
**π The fastest way to manage translations across any framework or vanilla JavaScript projects**
|
|
12
14
|
|
|
13
15
|
**Framework Support:** Auto-detects popular libraries (React i18next, Vue i18n, i18next, Nuxt i18n, Svelte i18n) or works without a framework. i18ntk manages translation files and validationβit does NOT implement translations on pages.
|
|
@@ -75,21 +77,21 @@ i18ntk validate --source ./locales
|
|
|
75
77
|
|
|
76
78
|
## π§ Configuration
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
sourceDir:
|
|
84
|
-
outputDir:
|
|
85
|
-
defaultLanguage:
|
|
86
|
-
supportedLanguages: [
|
|
87
|
-
performance: {
|
|
88
|
-
mode:
|
|
89
|
-
batchSize: 1000,
|
|
90
|
-
concurrency: 16
|
|
80
|
+
Configuration is managed through the `settings/i18ntk-config.json` file:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"version": "1.6.2",
|
|
85
|
+
"sourceDir": "./locales",
|
|
86
|
+
"outputDir": "./i18ntk-reports",
|
|
87
|
+
"defaultLanguage": "en",
|
|
88
|
+
"supportedLanguages": ["en", "es", "fr", "de"],
|
|
89
|
+
"performance": {
|
|
90
|
+
"mode": "extreme",
|
|
91
|
+
"batchSize": 1000,
|
|
92
|
+
"concurrency": 16
|
|
91
93
|
}
|
|
92
|
-
}
|
|
94
|
+
}
|
|
93
95
|
```
|
|
94
96
|
|
|
95
97
|
## π Language Optimization
|
|
@@ -148,8 +150,9 @@ your-project/
|
|
|
148
150
|
β βββ en.json
|
|
149
151
|
β βββ es.json
|
|
150
152
|
β βββ ...
|
|
151
|
-
βββ i18ntk-reports/
|
|
152
|
-
βββ
|
|
153
|
+
βββ i18ntk-reports/ # Generated reports
|
|
154
|
+
βββ settings/ # Configuration directory
|
|
155
|
+
βββ i18ntk-config.json # Main configuration file
|
|
153
156
|
```
|
|
154
157
|
|
|
155
158
|
## π¨ Important Notes
|
package/main/i18ntk-analyze.js
CHANGED
|
@@ -11,6 +11,7 @@ const fs = require('fs');
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const readline = require('readline');
|
|
13
13
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
14
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
14
15
|
const { getUnifiedConfig, parseCommonArgs, displayHelp } = require('../utils/config-helper');
|
|
15
16
|
const SecurityUtils = require('../utils/security');
|
|
16
17
|
const AdminCLI = require('../utils/admin-cli');
|
package/main/i18ntk-autorun.js
CHANGED
|
@@ -14,6 +14,7 @@ const fs = require('fs');
|
|
|
14
14
|
const path = require('path');
|
|
15
15
|
const { spawnSync } = require('child_process');
|
|
16
16
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
17
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
17
18
|
const { getUnifiedConfig, parseCommonArgs, displayHelp, ensureInitialized } = require('../utils/config-helper');
|
|
18
19
|
const SecurityUtils = require('../utils/security');
|
|
19
20
|
const configManager = require('../utils/config-manager');
|
package/main/i18ntk-complete.js
CHANGED
|
@@ -17,6 +17,7 @@ const { execSync } = require('child_process');
|
|
|
17
17
|
const SecurityUtils = require('../utils/security');
|
|
18
18
|
const { getUnifiedConfig, parseCommonArgs, displayHelp } = require('../utils/config-helper');
|
|
19
19
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
20
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
|
package/main/i18ntk-init.js
CHANGED
|
@@ -19,7 +19,8 @@ const configManager = require('../utils/config-manager');
|
|
|
19
19
|
const SecurityUtils = require('../utils/security');
|
|
20
20
|
const AdminAuth = require('../utils/admin-auth');
|
|
21
21
|
const UIi18n = require('./i18ntk-ui');
|
|
22
|
-
|
|
22
|
+
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
23
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
23
24
|
const { getUnifiedConfig, parseCommonArgs, displayHelp } = require('../utils/config-helper');
|
|
24
25
|
|
|
25
26
|
// Language configurations with native names
|
package/main/i18ntk-manage.js
CHANGED
|
@@ -34,6 +34,9 @@ const I18nSizingAnalyzer = require('./i18ntk-sizing');
|
|
|
34
34
|
const SettingsCLI = require('../settings/settings-cli');
|
|
35
35
|
const I18nDebugger = require('../scripts/debug/debugger');
|
|
36
36
|
|
|
37
|
+
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
38
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
39
|
+
|
|
37
40
|
// Use unified configuration system
|
|
38
41
|
const { getUnifiedConfig, ensureInitialized, validateSourceDir } = require('../utils/config-helper');
|
|
39
42
|
|
package/main/i18ntk-sizing.js
CHANGED
|
@@ -35,6 +35,7 @@ const fs = require('fs');
|
|
|
35
35
|
const path = require('path');
|
|
36
36
|
const { performance } = require('perf_hooks');
|
|
37
37
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
38
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
38
39
|
const configManager = require('../utils/config-manager');
|
|
39
40
|
const SecurityUtils = require('../utils/security');
|
|
40
41
|
const { getUnifiedConfig } = require('../utils/config-helper');
|
package/main/i18ntk-summary.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
6
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
6
7
|
const { getUnifiedConfig, parseCommonArgs, displayHelp } = require('../utils/config-helper');
|
|
7
8
|
const SecurityUtils = require('../utils/security');
|
|
8
9
|
const AdminCLI = require('../utils/admin-cli');
|
package/main/i18ntk-usage.js
CHANGED
|
@@ -25,6 +25,7 @@ const fs = require('fs');
|
|
|
25
25
|
const path = require('path');
|
|
26
26
|
const readline = require('readline');
|
|
27
27
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
28
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
28
29
|
const configManager = require('../utils/config-manager');
|
|
29
30
|
const SecurityUtils = require('../utils/security');
|
|
30
31
|
const AdminCLI = require('../utils/admin-cli');
|
package/main/i18ntk-validate.js
CHANGED
|
@@ -38,6 +38,7 @@ if (isUppercase) {
|
|
|
38
38
|
const fs = require('fs');
|
|
39
39
|
const path = require('path');
|
|
40
40
|
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
41
|
+
loadTranslations(process.env.I18NTK_LANG || 'en');
|
|
41
42
|
const configManager = require('../utils/config-manager');
|
|
42
43
|
const SecurityUtils = require('../utils/security');
|
|
43
44
|
const AdminCLI = require('../utils/admin-cli');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18ntk",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "i18ntk (i18n Toolkit) - Ultra-extreme performance enterprise-grade internationalization management toolkit with 97% performance improvement (15.38ms for 200k keys), advanced security with PIN protection, comprehensive backup & recovery, and edge case handling for JavaScript/TypeScript projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -69,11 +69,7 @@
|
|
|
69
69
|
"settings/",
|
|
70
70
|
"ui-locales/",
|
|
71
71
|
"LICENSE",
|
|
72
|
-
"README.md"
|
|
73
|
-
"!scripts/prepublish.js",
|
|
74
|
-
"!scripts/test-runner.js",
|
|
75
|
-
"!scripts/path-utils.test.js",
|
|
76
|
-
"!scripts/reset-defaults.test.js"
|
|
72
|
+
"README.md"
|
|
77
73
|
],
|
|
78
74
|
"scripts": {
|
|
79
75
|
"start": "node main/i18ntk-manage.js",
|
|
@@ -93,7 +89,8 @@
|
|
|
93
89
|
"summary": "node main/i18ntk-summary.js",
|
|
94
90
|
"full-coverage": "npm run complete && npm run analyze",
|
|
95
91
|
"verify-package": "node dev/verify-package.js",
|
|
96
|
-
"
|
|
92
|
+
"smoke:pack": "node scripts/smoke-pack.js",
|
|
93
|
+
"prepublishOnly": "npm run verify-package && npm run smoke:pack",
|
|
97
94
|
"test": "node scripts/test-runner.js",
|
|
98
95
|
"test:all": "node scripts/test-runner.js",
|
|
99
96
|
"test:quick": "node scripts/test-runner.js --quick",
|
package/scripts/debug/README.md
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# Debug Tools
|
|
2
|
-
|
|
3
|
-
This folder contains debugging tools and utilities for the i18nTK project.
|
|
4
|
-
|
|
5
|
-
## Debug Scripts
|
|
6
|
-
|
|
7
|
-
- **debugger.js** - Main debugging script for identifying issues
|
|
8
|
-
- **config-validator.js** - Configuration validation debugger
|
|
9
|
-
- **translation-debugger.js** - Translation-specific debugging tools
|
|
10
|
-
- **performance-profiler.js** - Performance analysis and profiling
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# Run main debugger
|
|
16
|
-
node scripts/debug/debugger.js
|
|
17
|
-
|
|
18
|
-
# Validate configuration
|
|
19
|
-
node scripts/debug/config-validator.js
|
|
20
|
-
|
|
21
|
-
# Debug translations
|
|
22
|
-
node scripts/debug/translation-debugger.js
|
|
23
|
-
|
|
24
|
-
# Profile performance
|
|
25
|
-
node scripts/debug/performance-profiler.js
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Debug Output
|
|
29
|
-
|
|
30
|
-
Debug logs and reports are saved to `scripts/debug/logs/` with timestamps.
|
|
31
|
-
|
|
32
|
-
## Version 1.5.0 Update
|
|
33
|
-
|
|
1
|
+
# Debug Tools
|
|
2
|
+
|
|
3
|
+
This folder contains debugging tools and utilities for the i18nTK project.
|
|
4
|
+
|
|
5
|
+
## Debug Scripts
|
|
6
|
+
|
|
7
|
+
- **debugger.js** - Main debugging script for identifying issues
|
|
8
|
+
- **config-validator.js** - Configuration validation debugger
|
|
9
|
+
- **translation-debugger.js** - Translation-specific debugging tools
|
|
10
|
+
- **performance-profiler.js** - Performance analysis and profiling
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Run main debugger
|
|
16
|
+
node scripts/debug/debugger.js
|
|
17
|
+
|
|
18
|
+
# Validate configuration
|
|
19
|
+
node scripts/debug/config-validator.js
|
|
20
|
+
|
|
21
|
+
# Debug translations
|
|
22
|
+
node scripts/debug/translation-debugger.js
|
|
23
|
+
|
|
24
|
+
# Profile performance
|
|
25
|
+
node scripts/debug/performance-profiler.js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Debug Output
|
|
29
|
+
|
|
30
|
+
Debug logs and reports are saved to `scripts/debug/logs/` with timestamps.
|
|
31
|
+
|
|
32
|
+
## Version 1.5.0 Update
|
|
33
|
+
|
|
34
34
|
**Critical Bug Fix**: These debug tools were moved from `/dev/debug/` to `/scripts/debug/` in v1.5.0 to resolve MODULE_NOT_FOUND errors when using `npx i18ntk`.
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
function getAllKeys(obj, prefix = '') {
|
|
5
|
-
let keys = [];
|
|
6
|
-
for (const key in obj) {
|
|
7
|
-
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
8
|
-
keys = keys.concat(getAllKeys(obj[key], prefix ? `${prefix}.${key}` : key));
|
|
9
|
-
} else {
|
|
10
|
-
keys.push(prefix ? `${prefix}.${key}` : key);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return keys;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function loadLanguageData(lang) {
|
|
17
|
-
const baseDir = './ui-locales';
|
|
18
|
-
const langDir = path.join(baseDir, lang);
|
|
19
|
-
const files = fs.readdirSync(langDir).filter(f => f.endsWith('.json'));
|
|
20
|
-
|
|
21
|
-
let langData = {};
|
|
22
|
-
for (const file of files) {
|
|
23
|
-
const filePath = path.join(langDir, file);
|
|
24
|
-
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
25
|
-
langData = { ...langData, [file.replace('.json', '')]: content };
|
|
26
|
-
}
|
|
27
|
-
return langData;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log('π Checking translation consistency...\n');
|
|
31
|
-
|
|
32
|
-
const enData = loadLanguageData('en');
|
|
33
|
-
const zhData = loadLanguageData('zh');
|
|
34
|
-
|
|
35
|
-
const enKeys = getAllKeys(enData);
|
|
36
|
-
const zhKeys = getAllKeys(zhData);
|
|
37
|
-
|
|
38
|
-
console.log(`English keys: ${enKeys.length}`);
|
|
39
|
-
console.log(`Chinese keys: ${zhKeys.length}`);
|
|
40
|
-
|
|
41
|
-
const missingInZh = enKeys.filter(key => !zhKeys.includes(key));
|
|
42
|
-
const extraInZh = zhKeys.filter(key => !enKeys.includes(key));
|
|
43
|
-
|
|
44
|
-
if (missingInZh.length > 0) {
|
|
45
|
-
console.log('\nβ Missing in Chinese:');
|
|
46
|
-
missingInZh.forEach(key => console.log(` - ${key}`));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (extraInZh.length > 0) {
|
|
50
|
-
console.log('\nβ οΈ Extra in Chinese:');
|
|
51
|
-
extraInZh.forEach(key => console.log(` - ${key}`));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (missingInZh.length === 0 && extraInZh.length === 0) {
|
|
55
|
-
console.log('β
All translations are consistent!');
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function getAllKeys(obj, prefix = '') {
|
|
5
|
+
let keys = [];
|
|
6
|
+
for (const key in obj) {
|
|
7
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
8
|
+
keys = keys.concat(getAllKeys(obj[key], prefix ? `${prefix}.${key}` : key));
|
|
9
|
+
} else {
|
|
10
|
+
keys.push(prefix ? `${prefix}.${key}` : key);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return keys;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function loadLanguageData(lang) {
|
|
17
|
+
const baseDir = './ui-locales';
|
|
18
|
+
const langDir = path.join(baseDir, lang);
|
|
19
|
+
const files = fs.readdirSync(langDir).filter(f => f.endsWith('.json'));
|
|
20
|
+
|
|
21
|
+
let langData = {};
|
|
22
|
+
for (const file of files) {
|
|
23
|
+
const filePath = path.join(langDir, file);
|
|
24
|
+
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
25
|
+
langData = { ...langData, [file.replace('.json', '')]: content };
|
|
26
|
+
}
|
|
27
|
+
return langData;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log('π Checking translation consistency...\n');
|
|
31
|
+
|
|
32
|
+
const enData = loadLanguageData('en');
|
|
33
|
+
const zhData = loadLanguageData('zh');
|
|
34
|
+
|
|
35
|
+
const enKeys = getAllKeys(enData);
|
|
36
|
+
const zhKeys = getAllKeys(zhData);
|
|
37
|
+
|
|
38
|
+
console.log(`English keys: ${enKeys.length}`);
|
|
39
|
+
console.log(`Chinese keys: ${zhKeys.length}`);
|
|
40
|
+
|
|
41
|
+
const missingInZh = enKeys.filter(key => !zhKeys.includes(key));
|
|
42
|
+
const extraInZh = zhKeys.filter(key => !enKeys.includes(key));
|
|
43
|
+
|
|
44
|
+
if (missingInZh.length > 0) {
|
|
45
|
+
console.log('\nβ Missing in Chinese:');
|
|
46
|
+
missingInZh.forEach(key => console.log(` - ${key}`));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (extraInZh.length > 0) {
|
|
50
|
+
console.log('\nβ οΈ Extra in Chinese:');
|
|
51
|
+
extraInZh.forEach(key => console.log(` - ${key}`));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (missingInZh.length === 0 && extraInZh.length === 0) {
|
|
55
|
+
console.log('β
All translations are consistent!');
|
|
56
56
|
}
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
6
|
-
|
|
7
|
-
// Load translations
|
|
8
|
-
loadTranslations('en');
|
|
9
|
-
|
|
10
|
-
// Configuration
|
|
11
|
-
const SOURCE_DIR = path.join(__dirname, '..', 'ui-locales');
|
|
12
|
-
const TARGET_LANGUAGES = ['de', 'fr', 'es', 'ru', 'ja', 'zh'];
|
|
13
|
-
|
|
14
|
-
function createLanguageTemplate(lang) {
|
|
15
|
-
const langDir = path.join(SOURCE_DIR, lang);
|
|
16
|
-
|
|
17
|
-
if (!fs.existsSync(langDir)) {
|
|
18
|
-
fs.mkdirSync(langDir, { recursive: true });
|
|
19
|
-
console.log(t('exportTranslations.createdDirectory', { dir: langDir }));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const enDir = path.join(SOURCE_DIR, 'en');
|
|
23
|
-
const enFiles = fs.readdirSync(enDir).filter(file => file.endsWith('.json'));
|
|
24
|
-
|
|
25
|
-
console.log(t('exportTranslations.foundFiles', { count: enFiles.length }));
|
|
26
|
-
enFiles.forEach(file => {
|
|
27
|
-
console.log(` - ${file}`);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
enFiles.forEach(file => {
|
|
31
|
-
const sourceFile = path.join(enDir, file);
|
|
32
|
-
const targetFile = path.join(langDir, file);
|
|
33
|
-
|
|
34
|
-
if (!fs.existsSync(targetFile)) {
|
|
35
|
-
const sourceContent = JSON.parse(fs.readFileSync(sourceFile, 'utf8'));
|
|
36
|
-
const templateContent = createTemplateFromEnglish(sourceContent);
|
|
37
|
-
fs.writeFileSync(targetFile, JSON.stringify(templateContent, null, 2));
|
|
38
|
-
console.log(t('exportTranslations.createdTemplate', { lang, file }));
|
|
39
|
-
} else {
|
|
40
|
-
console.log(t('exportTranslations.skippedExisting', { lang, file }));
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function createTemplateFromEnglish(obj) {
|
|
46
|
-
if (typeof obj === 'string') {
|
|
47
|
-
return 'β οΈ TRANSLATION NEEDED β οΈ';
|
|
48
|
-
} else if (typeof obj === 'object' && obj !== null) {
|
|
49
|
-
const result = {};
|
|
50
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
51
|
-
result[key] = createTemplateFromEnglish(value);
|
|
52
|
-
}
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
return obj;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function main() {
|
|
59
|
-
console.log(`\n${t('exportTranslations.title')}\n`);
|
|
60
|
-
console.log(t('exportTranslations.creatingTemplates', { count: TARGET_LANGUAGES.length }));
|
|
61
|
-
console.log();
|
|
62
|
-
|
|
63
|
-
TARGET_LANGUAGES.forEach(lang => {
|
|
64
|
-
createLanguageTemplate(lang);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const enFiles = fs.readdirSync(path.join(SOURCE_DIR, 'en')).filter(file => file.endsWith('.json'));
|
|
68
|
-
|
|
69
|
-
console.log(`\n${t('exportTranslations.summary')}`);
|
|
70
|
-
console.log(t('exportTranslations.summaryLanguages', { count: TARGET_LANGUAGES.length }));
|
|
71
|
-
console.log(t('exportTranslations.summaryFilesPerLanguage', { count: enFiles.length }));
|
|
72
|
-
console.log(t('exportTranslations.summaryTotalFiles', { count: TARGET_LANGUAGES.length * enFiles.length }));
|
|
73
|
-
|
|
74
|
-
console.log(`\n${t('exportTranslations.success')}`);
|
|
75
|
-
console.log(t('exportTranslations.location', { dir: SOURCE_DIR }));
|
|
76
|
-
console.log(t('exportTranslations.nextSteps'));
|
|
77
|
-
console.log();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (require.main === module) {
|
|
81
|
-
main();
|
|
82
|
-
}
|
|
83
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
6
|
+
|
|
7
|
+
// Load translations
|
|
8
|
+
loadTranslations('en');
|
|
9
|
+
|
|
10
|
+
// Configuration
|
|
11
|
+
const SOURCE_DIR = path.join(__dirname, '..', 'ui-locales');
|
|
12
|
+
const TARGET_LANGUAGES = ['de', 'fr', 'es', 'ru', 'ja', 'zh'];
|
|
13
|
+
|
|
14
|
+
function createLanguageTemplate(lang) {
|
|
15
|
+
const langDir = path.join(SOURCE_DIR, lang);
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(langDir)) {
|
|
18
|
+
fs.mkdirSync(langDir, { recursive: true });
|
|
19
|
+
console.log(t('exportTranslations.createdDirectory', { dir: langDir }));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const enDir = path.join(SOURCE_DIR, 'en');
|
|
23
|
+
const enFiles = fs.readdirSync(enDir).filter(file => file.endsWith('.json'));
|
|
24
|
+
|
|
25
|
+
console.log(t('exportTranslations.foundFiles', { count: enFiles.length }));
|
|
26
|
+
enFiles.forEach(file => {
|
|
27
|
+
console.log(` - ${file}`);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
enFiles.forEach(file => {
|
|
31
|
+
const sourceFile = path.join(enDir, file);
|
|
32
|
+
const targetFile = path.join(langDir, file);
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(targetFile)) {
|
|
35
|
+
const sourceContent = JSON.parse(fs.readFileSync(sourceFile, 'utf8'));
|
|
36
|
+
const templateContent = createTemplateFromEnglish(sourceContent);
|
|
37
|
+
fs.writeFileSync(targetFile, JSON.stringify(templateContent, null, 2));
|
|
38
|
+
console.log(t('exportTranslations.createdTemplate', { lang, file }));
|
|
39
|
+
} else {
|
|
40
|
+
console.log(t('exportTranslations.skippedExisting', { lang, file }));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function createTemplateFromEnglish(obj) {
|
|
46
|
+
if (typeof obj === 'string') {
|
|
47
|
+
return 'β οΈ TRANSLATION NEEDED β οΈ';
|
|
48
|
+
} else if (typeof obj === 'object' && obj !== null) {
|
|
49
|
+
const result = {};
|
|
50
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
51
|
+
result[key] = createTemplateFromEnglish(value);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
return obj;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function main() {
|
|
59
|
+
console.log(`\n${t('exportTranslations.title')}\n`);
|
|
60
|
+
console.log(t('exportTranslations.creatingTemplates', { count: TARGET_LANGUAGES.length }));
|
|
61
|
+
console.log();
|
|
62
|
+
|
|
63
|
+
TARGET_LANGUAGES.forEach(lang => {
|
|
64
|
+
createLanguageTemplate(lang);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const enFiles = fs.readdirSync(path.join(SOURCE_DIR, 'en')).filter(file => file.endsWith('.json'));
|
|
68
|
+
|
|
69
|
+
console.log(`\n${t('exportTranslations.summary')}`);
|
|
70
|
+
console.log(t('exportTranslations.summaryLanguages', { count: TARGET_LANGUAGES.length }));
|
|
71
|
+
console.log(t('exportTranslations.summaryFilesPerLanguage', { count: enFiles.length }));
|
|
72
|
+
console.log(t('exportTranslations.summaryTotalFiles', { count: TARGET_LANGUAGES.length * enFiles.length }));
|
|
73
|
+
|
|
74
|
+
console.log(`\n${t('exportTranslations.success')}`);
|
|
75
|
+
console.log(t('exportTranslations.location', { dir: SOURCE_DIR }));
|
|
76
|
+
console.log(t('exportTranslations.nextSteps'));
|
|
77
|
+
console.log();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (require.main === module) {
|
|
81
|
+
main();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
84
|
module.exports = { createLanguageTemplate };
|