i18ntk 1.6.0 β†’ 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 CHANGED
@@ -2,12 +2,14 @@
2
2
 
3
3
  ![i18ntk Logo](docs/screenshots/i18ntk-logo-public.PNG)
4
4
 
5
- **Version:** 1.6.0
6
- **Last Updated:** 2025-08-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
  [![npm](https://img.shields.io/npm/dt/i18ntk.svg)](https://www.npmjs.com/package/i18ntk) [![npm version](https://badge.fury.io/js/i18ntk.svg)](https://badge.fury.io/js/i18ntk) [![Node.js Version](https://img.shields.io/badge/node-%3E%3D16.0.0-brightgreen.svg)](https://nodejs.org/) [![Downloads](https://img.shields.io/npm/dm/i18ntk.svg)](https://www.npmjs.com/package/i18ntk) [![GitHub stars](https://img.shields.io/github/stars/vladnoskv/i18ntk?style=social)](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
- Create `.i18ntk.config.js`:
79
-
80
- ```javascript
81
- module.exports = {
82
- // All paths are relative to your project root
83
- sourceDir: './locales',
84
- outputDir: './i18ntk-reports',
85
- defaultLanguage: 'en',
86
- supportedLanguages: ['en', 'es', 'fr', 'de'],
87
- performance: {
88
- mode: 'extreme', // extreme | ultra | optimized
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/ # Generated reports
152
- └── .i18ntk.config.js # Configuration
153
+ β”œβ”€β”€ i18ntk-reports/ # Generated reports
154
+ └── settings/ # Configuration directory
155
+ └── i18ntk-config.json # Main configuration file
153
156
  ```
154
157
 
155
158
  ## 🚨 Important Notes
@@ -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');
@@ -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');
@@ -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
 
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  const fs = require('fs');
3
3
  const { getUnifiedConfig } = require('../utils/config-helper');
4
4
 
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * I18N INITIALIZATION SCRIPT
4
4
  *
@@ -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
@@ -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
 
@@ -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');
@@ -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');
@@ -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');
@@ -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.0",
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",
@@ -49,16 +49,15 @@
49
49
  "main": "main/i18ntk-manage.js",
50
50
  "bin": {
51
51
  "i18ntk": "main/i18ntk-manage.js",
52
- "i18ntk-manage": "main/i18ntk-manage.js",
53
52
  "i18ntk-init": "main/i18ntk-init.js",
54
53
  "i18ntk-analyze": "main/i18ntk-analyze.js",
55
54
  "i18ntk-validate": "main/i18ntk-validate.js",
56
55
  "i18ntk-usage": "main/i18ntk-usage.js",
57
56
  "i18ntk-complete": "main/i18ntk-complete.js",
58
57
  "i18ntk-sizing": "main/i18ntk-sizing.js",
58
+ "i18ntk-autorun": "main/i18ntk-autorun.js",
59
59
  "i18ntk-summary": "main/i18ntk-summary.js",
60
- "i18ntk-ui": "main/i18ntk-ui.js",
61
- "i18ntk-autorun": "main/i18ntk-autorun.js"
60
+ "i18ntk-doctor": "main/i18ntk-doctor.js"
62
61
  },
63
62
  "directories": {
64
63
  "doc": "docs"
@@ -70,24 +69,10 @@
70
69
  "settings/",
71
70
  "ui-locales/",
72
71
  "LICENSE",
73
- "README.md",
74
- "!scripts/prepublish.js",
75
- "!scripts/test-runner.js",
76
- "!scripts/path-utils.test.js",
77
- "!scripts/reset-defaults.test.js"
72
+ "README.md"
78
73
  ],
79
74
  "scripts": {
80
75
  "start": "node main/i18ntk-manage.js",
81
- "i18ntk": "node main/i18ntk-manage.js",
82
- "i18ntk:init": "node main/i18ntk-init.js --yes",
83
- "i18ntk:analyze": "node main/i18ntk-analyze.js",
84
- "i18ntk:validate": "node main/i18ntk-validate.js",
85
- "i18ntk:usage": "node main/i18ntk-usage.js",
86
- "i18ntk:complete": "node main/i18ntk-complete.js",
87
- "i18ntk:sizing": "node main/i18ntk-sizing.js",
88
- "i18ntk:sizing:detailed": "node main/i18ntk-sizing.js --detailed",
89
- "i18ntk:debug": "node main/i18ntk-manage.js --command=debug",
90
- "i18ntk:settings": "node settings/settings-cli.js",
91
76
  "settings": "node settings/settings-cli.js",
92
77
  "i18ntk:doctor": "node main/i18ntk-doctor.js",
93
78
  "i18ntk:summary": "node main/i18ntk-summary.js",
@@ -104,7 +89,8 @@
104
89
  "summary": "node main/i18ntk-summary.js",
105
90
  "full-coverage": "npm run complete && npm run analyze",
106
91
  "verify-package": "node dev/verify-package.js",
107
- "prepublishOnly": "npm run verify-package && node scripts/prepublish.js",
92
+ "smoke:pack": "node scripts/smoke-pack.js",
93
+ "prepublishOnly": "npm run verify-package && npm run smoke:pack",
108
94
  "test": "node scripts/test-runner.js",
109
95
  "test:all": "node scripts/test-runner.js",
110
96
  "test:quick": "node scripts/test-runner.js --quick",
@@ -122,8 +108,8 @@
122
108
  "security:audit": "npm audit --audit-level=moderate",
123
109
  "security:fix": "npm audit fix",
124
110
  "security:check": "node utils/security-check.js",
125
- "security:config": "node utils/security-config.js",
126
- "languages:select": "node settings/settings-cli.js",
111
+ "security:config": "node utils/security-config.js",
112
+ "languages:select": "node settings/settings-cli.js",
127
113
  "languages:list": "node settings/settings-cli.js --list-languages",
128
114
  "languages:status": "node settings/settings-cli.js --language-status",
129
115
  "languages:restore": "echo 'Language restoration - use settings CLI for manual configuration'"
@@ -137,7 +123,7 @@
137
123
  },
138
124
  "preferGlobal": true,
139
125
  "versionInfo": {
140
- "version": "1.6.0",
126
+ "version": "1.6.1",
141
127
  "releaseDate": "08/08/2025",
142
128
  "lastUpdated": "08/08/2025",
143
129
  "maintainer": "Vladimir Noskov",
@@ -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 };